Leancrypto 1.6.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
lc_kmac.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 - 2025, 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_KMAC_H
21#define LC_KMAC_H
22
23#include "lc_hash.h"
24#include "lc_rng.h"
25#include "lc_sha3.h"
26#include "lc_memset_secure.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
33struct lc_kmac_ctx {
34 uint8_t final_called : 1;
35 uint8_t rng_initialized : 1;
36 uint8_t *shadow_ctx;
37 struct lc_hash_ctx hash_ctx;
38};
39
40#define LC_KMAC_STATE_SIZE(x) (LC_HASH_STATE_SIZE(x))
41#define LC_KMAC_STATE_SIZE_REINIT(x) (2 * LC_HASH_STATE_SIZE(x))
42#define LC_KMAC_CTX_SIZE(x) (LC_KMAC_STATE_SIZE(x) + sizeof(struct lc_kmac_ctx))
43#define LC_KMAC_CTX_SIZE_REINIT(x) \
44 (LC_KMAC_STATE_SIZE_REINIT(x) + sizeof(struct lc_kmac_ctx))
45
46#define _LC_KMAC_SET_CTX(name, hashname, ctx, offset) \
47 _LC_HASH_SET_CTX((&name->hash_ctx), hashname, ctx, offset); \
48 name->shadow_ctx = NULL
49
50#define LC_KMAC_SET_CTX(name, hashname) \
51 _LC_KMAC_SET_CTX(name, hashname, name, sizeof(struct lc_kmac_ctx))
52
53#define _LC_KMAC_SET_CTX_REINIT(name, hashname, ctx, offset) \
54 _LC_HASH_SET_CTX((&name->hash_ctx), hashname, ctx, offset); \
55 name->shadow_ctx = (uint8_t *)((uint8_t *)ctx + offset + \
56 LC_HASH_STATE_SIZE(hashname))
57
58#define LC_KMAC_SET_CTX_REINIT(name, hashname) \
59 _LC_KMAC_SET_CTX_REINIT(name, hashname, name, \
60 sizeof(struct lc_kmac_ctx))
62
66
83int lc_kmac_init(struct lc_kmac_ctx *kmac_ctx, const uint8_t *key, size_t klen,
84 const uint8_t *s, size_t slen);
85
96void lc_kmac_reinit(struct lc_kmac_ctx *kmac_ctx);
97
107void lc_kmac_update(struct lc_kmac_ctx *kmac_ctx, const uint8_t *in,
108 size_t inlen);
109
123void lc_kmac_final(struct lc_kmac_ctx *kmac_ctx, uint8_t *mac, size_t maclen);
124
155void lc_kmac_final_xof(struct lc_kmac_ctx *kmac_ctx, uint8_t *mac,
156 size_t maclen);
157
171int lc_kmac_alloc(const struct lc_hash *hash, struct lc_kmac_ctx **kmac_ctx,
172 uint32_t flags);
173
174/*
175 * Support re-initialization of state. You set a key during kmac_init,
176 * perform a full KMAC operation. After a kmac_final, the re-initialization
177 * support allows you to call kmac_reinit and reuse the state for a new
178 * operation without providing the keys again. If in doubt, initialize
179 * the context with re-init support. The difference is that more memory is
180 * allocated to retain the initialized state.
181 */
182#define LC_KMAC_FLAGS_SUPPORT_REINIT (1 << 0)
183
190void lc_kmac_zero_free(struct lc_kmac_ctx *kmac_ctx);
191
199void lc_kmac_zero(struct lc_kmac_ctx *kmac_ctx);
200
212#define LC_KMAC_CTX_ON_STACK(name, hashname) \
213 _Pragma("GCC diagnostic push") \
214 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
215 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
216 LC_ALIGNED_BUFFER(name##_ctx_buf, \
217 LC_KMAC_CTX_SIZE(hashname), \
218 LC_HASH_COMMON_ALIGNMENT); \
219 struct lc_kmac_ctx *name = (struct lc_kmac_ctx *)name##_ctx_buf; \
220 LC_KMAC_SET_CTX(name, hashname); \
221 lc_kmac_zero(name); \
222 _Pragma("GCC diagnostic pop")
223
236#define LC_KMAC_CTX_ON_STACK_REINIT(name, hashname) \
237 _Pragma("GCC diagnostic push") \
238 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
239 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
240 LC_ALIGNED_BUFFER(name##_ctx_buf, \
241 LC_KMAC_CTX_SIZE_REINIT(hashname), \
242 LC_HASH_COMMON_ALIGNMENT); \
243 struct lc_kmac_ctx *name = (struct lc_kmac_ctx *)name##_ctx_buf; \
244 LC_KMAC_SET_CTX_REINIT(name, hashname); \
245 lc_kmac_zero(name); \
246 _Pragma("GCC diagnostic pop")
247
256size_t lc_kmac_macsize(struct lc_kmac_ctx *kmac_ctx);
257
277int lc_kmac(const struct lc_hash *hash, const uint8_t *key, size_t keylen,
278 const uint8_t *s, size_t slen, const uint8_t *in, size_t inlen,
279 uint8_t *mac, size_t maclen);
280
300int lc_kmac_xof(const struct lc_hash *hash, const uint8_t *key, size_t keylen,
301 const uint8_t *s, size_t slen, const uint8_t *in, size_t inlen,
302 uint8_t *mac, size_t maclen);
303
304/******************************** KMAC as RNG *********************************/
305
317
318/* KMAC DRNG implementation */
319extern const struct lc_rng *lc_kmac_rng;
320
322#define LC_KMAC_KDF_DRNG_CTX_SIZE(hashname) \
323 (sizeof(struct lc_rng_ctx) + LC_KMAC_CTX_SIZE(hashname))
324
325#define LC_KMAC_KDF_DRNG_SET_CTX(name, hashname) LC_KMAC_SET_CTX(name, hashname)
326
327#define LC_KMAC_KDF_RNG_CTX(name, hashname) \
328 LC_RNG_CTX(name, lc_kmac_rng); \
329 LC_KMAC_KDF_DRNG_SET_CTX(((struct lc_kmac_ctx *)(name->rng_state)), \
330 hashname); \
331 lc_rng_zero(name)
333
344#define LC_KMAC_KDF_DRNG_CTX_ON_STACK(name, hashname) \
345 _Pragma("GCC diagnostic push") \
346 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
347 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
348 LC_ALIGNED_BUFFER(name##_ctx_buf, \
349 LC_KMAC_KDF_DRNG_CTX_SIZE(hashname), \
350 LC_HASH_COMMON_ALIGNMENT); \
351 struct lc_rng_ctx *name = (struct lc_rng_ctx *)name##_ctx_buf; \
352 LC_KMAC_KDF_RNG_CTX(name, hashname); \
353 _Pragma("GCC diagnostic pop")
354
371int lc_kmac_rng_alloc(struct lc_rng_ctx **state, const struct lc_hash *hash);
372
373#ifdef __cplusplus
374}
375#endif
376
377#endif /* LC_KMAC_H */
int lc_hash(const struct lc_hash *hash, const uint8_t *in, size_t inlen, uint8_t *digest)
Calculate message digest - one-shot.
const struct lc_rng * lc_kmac_rng
int lc_kmac_rng_alloc(struct lc_rng_ctx **state, const struct lc_hash *hash)
Allocation of a KMAC DRNG context.
void lc_kmac_final(struct lc_kmac_ctx *kmac_ctx, uint8_t *mac, size_t maclen)
Calculate KMAC MAC.
int lc_kmac_xof(const struct lc_hash *hash, const uint8_t *key, size_t keylen, const uint8_t *s, size_t slen, const uint8_t *in, size_t inlen, uint8_t *mac, size_t maclen)
Calculate KMAC in XOF mode - one-shot.
int lc_kmac_init(struct lc_kmac_ctx *kmac_ctx, const uint8_t *key, size_t klen, const uint8_t *s, size_t slen)
Initialize KMAC context.
int lc_kmac_alloc(const struct lc_hash *hash, struct lc_kmac_ctx **kmac_ctx, uint32_t flags)
Allocate KMAC context on heap.
void lc_kmac_zero(struct lc_kmac_ctx *kmac_ctx)
Zeroize KMAC context allocated with either LC_KMAC_CTX_ON_STACK or lc_kmac_alloc.
void lc_kmac_final_xof(struct lc_kmac_ctx *kmac_ctx, uint8_t *mac, size_t maclen)
Calculate KMAC MAC in XOF mode.
int lc_kmac(const struct lc_hash *hash, const uint8_t *key, size_t keylen, const uint8_t *s, size_t slen, const uint8_t *in, size_t inlen, uint8_t *mac, size_t maclen)
Calculate KMAC - one-shot.
void lc_kmac_update(struct lc_kmac_ctx *kmac_ctx, const uint8_t *in, size_t inlen)
Update KMAC.
size_t lc_kmac_macsize(struct lc_kmac_ctx *kmac_ctx)
Return the MAC size.
void lc_kmac_zero_free(struct lc_kmac_ctx *kmac_ctx)
Zeroize and free KMAC context.
void lc_kmac_reinit(struct lc_kmac_ctx *kmac_ctx)
Re-initialize KMAC context after a kmac_final operation.