Leancrypto 0.12.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
lc_hmac.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 - 2024, Stephan Mueller <smueller@chronox.de>
3 *
4 * License: see LICENSE file in root directory
5 *
6 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
7 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
9 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
10 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
11 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
12 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
13 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
14 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
16 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE.
18 */
19
20#ifndef LC_HMAC_H
21#define LC_HMAC_H
22
23#include "lc_hash.h"
24#include "lc_sha3.h"
25#include "lc_memset_secure.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
32#if LC_SHA3_MAX_SIZE_BLOCK
33#define LC_SHA_MAX_SIZE_BLOCK LC_SHA3_MAX_SIZE_BLOCK
34#elif LC_SHA512_SIZE_BLOCK
35#define LC_SHA_MAX_SIZE_BLOCK LC_SHA512_SIZE_BLOCK
36#elif LC_SHA256_SIZE_BLOCK
37#define LC_SHA_MAX_SIZE_BLOCK LC_SHA256_SIZE_BLOCK
38#else
39#error "No known maximum block size defined - include sha3.h, sha512.h or sha256.h before hmac.h"
40#endif
41
42struct lc_hmac_ctx {
43 uint8_t *k_opad;
44 uint8_t *k_ipad;
45 struct lc_hash_ctx hash_ctx;
46};
47
48#define LC_HMAC_STATE_SIZE(x) \
49 (LC_HASH_STATE_SIZE(x) + 2 * LC_SHA_MAX_SIZE_BLOCK)
50#define LC_HMAC_CTX_SIZE(x) (LC_HMAC_STATE_SIZE(x) + sizeof(struct lc_hmac_ctx))
51
52#define _LC_HMAC_SET_CTX(name, hashname, ctx, offset) \
53 _LC_HASH_SET_CTX((&name->hash_ctx), hashname, ctx, offset); \
54 name->k_opad = (uint8_t *)((uint8_t *)ctx + offset + \
55 LC_HASH_STATE_SIZE(hashname)); \
56 name->k_ipad = (uint8_t *)((uint8_t *)ctx + offset + \
57 LC_HASH_STATE_SIZE(hashname) + \
58 LC_SHA_MAX_SIZE_BLOCK)
59
60#define LC_HMAC_SET_CTX(name, hashname) \
61 _LC_HMAC_SET_CTX(name, hashname, name, sizeof(struct lc_hmac_ctx))
63
80void lc_hmac_init(struct lc_hmac_ctx *hmac_ctx, const uint8_t *key,
81 size_t keylen);
82
93void lc_hmac_reinit(struct lc_hmac_ctx *hmac_ctx);
94
104void lc_hmac_update(struct lc_hmac_ctx *hmac_ctx, const uint8_t *in,
105 size_t inlen);
106
119void lc_hmac_final(struct lc_hmac_ctx *hmac_ctx, uint8_t *mac);
120
131int lc_hmac_alloc(const struct lc_hash *hash, struct lc_hmac_ctx **hmac_ctx);
132
139void lc_hmac_zero_free(struct lc_hmac_ctx *hmac_ctx);
140
148static inline void lc_hmac_zero(struct lc_hmac_ctx *hmac_ctx)
149{
150 struct lc_hash_ctx *hash_ctx = &hmac_ctx->hash_ctx;
151 const struct lc_hash *hash = hash_ctx->hash;
152
153 lc_memset_secure((uint8_t *)hmac_ctx + sizeof(struct lc_hmac_ctx), 0,
154 LC_HMAC_STATE_SIZE(hash));
155}
156
165#define LC_HMAC_CTX_ON_STACK(name, hashname) \
166 _Pragma("GCC diagnostic push") \
167 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
168 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
169 LC_ALIGNED_BUFFER(name##_ctx_buf, \
170 LC_HMAC_CTX_SIZE(hashname), \
171 LC_HASH_COMMON_ALIGNMENT); \
172 struct lc_hmac_ctx *name = (struct lc_hmac_ctx *)name##_ctx_buf; \
173 LC_HMAC_SET_CTX(name, hashname); \
174 lc_hmac_zero(name); \
175 _Pragma("GCC diagnostic pop")
176
185static inline size_t lc_hmac_macsize(struct lc_hmac_ctx *hmac_ctx)
186{
187 struct lc_hash_ctx *hash_ctx = &hmac_ctx->hash_ctx;
188
189 return lc_hash_digestsize(hash_ctx);
190}
191
206static inline void lc_hmac(const struct lc_hash *hash, const uint8_t *key,
207 size_t keylen, const uint8_t *in, size_t inlen,
208 uint8_t *mac)
209{
210 LC_HMAC_CTX_ON_STACK(hmac_ctx, hash);
211
212 lc_hmac_init(hmac_ctx, key, keylen);
213 lc_hmac_update(hmac_ctx, in, inlen);
214 lc_hmac_final(hmac_ctx, mac);
215
216 lc_hmac_zero(hmac_ctx);
217}
218
219#ifdef __cplusplus
220}
221#endif
222
223#endif /* LC_HMAC_H */
void lc_hmac_init(struct lc_hmac_ctx *hmac_ctx, const uint8_t *key, size_t keylen)
Initialize HMAC context.
void lc_hmac_reinit(struct lc_hmac_ctx *hmac_ctx)
Re-initialize HMAC context after a hmac_final operation.
#define LC_HMAC_CTX_ON_STACK(name, hashname)
Allocate stack memory for the HMAC context.
Definition lc_hmac.h:165
static size_t lc_hmac_macsize(struct lc_hmac_ctx *hmac_ctx)
Return the MAC size.
Definition lc_hmac.h:185
static void lc_hmac(const struct lc_hash *hash, const uint8_t *key, size_t keylen, const uint8_t *in, size_t inlen, uint8_t *mac)
Calculate HMAC - one-shot.
Definition lc_hmac.h:206
static void lc_hmac_zero(struct lc_hmac_ctx *hmac_ctx)
Zeroize HMAC context allocated with either HMAC_CTX_ON_STACK or hmac_alloc.
Definition lc_hmac.h:148
void lc_hmac_final(struct lc_hmac_ctx *hmac_ctx, uint8_t *mac)
Calculate HMAC mac.
void lc_hmac_update(struct lc_hmac_ctx *hmac_ctx, const uint8_t *in, size_t inlen)
Update HMAC.
int lc_hmac_alloc(const struct lc_hash *hash, struct lc_hmac_ctx **hmac_ctx)
Allocate HMAC context on heap.
void lc_hmac_zero_free(struct lc_hmac_ctx *hmac_ctx)
Zeroize and free HMAC context.
static size_t lc_hash_digestsize(struct lc_hash_ctx *hash_ctx)
Get the size of the message digest.
Definition lc_hash.h:231
void lc_hash(const struct lc_hash *hash, const uint8_t *in, size_t inlen, uint8_t *digest)
Calculate message digest - one-shot.
static void lc_memset_secure(void *s, int c, size_t n)