Leancrypto 1.6.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
lc_xdrbg.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_XDRBG_DRNG_H
21#define LC_XDRBG_DRNG_H
22
23#if defined __has_include
24#if __has_include("lc_ascon_hash.h")
25#include "lc_ascon_hash.h"
26#define LC_XDRBG_ASCON_ENABLED
27#endif
28#if __has_include("lc_sha3.h")
29#include "lc_sha3.h"
30#define LC_XDRBG_SHAKE_ENABLED
31#endif
32#else
33#error "Compiler misses __has_include"
34#endif
35
36#include "lc_rng.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
43#define LC_XDRBG_DRNG_INITIALLY_SEEDED 0x8
44#define LC_XDRBG_DRNG_KEYSIZE_MASK 0x7
45
46enum lc_xdrbg_status_keysize {
47 lc_xdrbg_keysize_undefined,
48 lc_xdrbg_keysize_xdrbg128,
49 lc_xdrbg_keysize_xdrbg256,
50 lc_xdrbg_keysize_xdrbg512
51};
52
53struct lc_xdrbg_drng_state {
54 uint16_t chunksize;
55 uint8_t status;
56 /*
57 * NOTE: keep the lc_hash pointer before the v variable, because
58 * lc_hash is aligned to 8 bytes and has a size of 8 bytes. This ensures
59 * that v is aligned to 8 bytes as well.
60 */
61 const struct lc_hash *xof;
62 uint8_t v[];
63};
64
65/* Helper, do not call directly */
66#define LC_XDRBG_DRNG_CTX_ON_STACK(name, ctxsize) \
67 _Pragma("GCC diagnostic push") _Pragma( \
68 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
69 LC_ALIGNED_BUFFER(name##_ctx_buf, ctxsize, \
70 LC_HASH_COMMON_ALIGNMENT); \
71 struct lc_rng_ctx *name = (struct lc_rng_ctx *)name##_ctx_buf; \
72 _Pragma("GCC diagnostic pop")
74
75/***************************** SHAKE-based XDRBG ******************************/
76
77#ifdef LC_XDRBG_SHAKE_ENABLED
78
80extern const struct lc_rng *lc_xdrbg256_drng;
81extern const struct lc_rng *lc_xdrbg512_drng;
82
83#define LC_XDRBG256_DRNG_KEYSIZE 64
84/*
85 * For streamlining the access requests, the max chunk size plus the key size
86 * should be a full multiple of the SHAKE rate. As the key size is not
87 * exactly the rate size, the chunk size needs to consider it
88 */
89#define LC_XDRBG256_DRNG_MAX_CHUNK \
90 (LC_SHAKE_256_SIZE_BLOCK * 3 - LC_XDRBG256_DRNG_KEYSIZE)
91#define LC_XDRBG256_DRNG_STATE_SIZE \
92 (sizeof(struct lc_xdrbg_drng_state) + LC_XDRBG256_DRNG_KEYSIZE)
93#define LC_XDRBG256_DRNG_CTX_SIZE \
94 (sizeof(struct lc_rng) + LC_XDRBG256_DRNG_STATE_SIZE)
95
96#define LC_XDRBG256_RNG_CTX(name) \
97 LC_RNG_CTX(name, lc_xdrbg256_drng); \
98 struct lc_xdrbg_drng_state *__name = name->rng_state; \
99 __name->status = lc_xdrbg_keysize_xdrbg256; \
100 __name->xof = lc_shake256; \
101 __name->chunksize = LC_XDRBG256_DRNG_MAX_CHUNK; \
102 lc_xdrbg256_drng->zero(name->rng_state);
104
120#define LC_XDRBG256_DRNG_CTX_ON_STACK(name) \
121 LC_XDRBG_DRNG_CTX_ON_STACK(name, LC_XDRBG256_DRNG_CTX_SIZE); \
122 LC_XDRBG256_RNG_CTX(name)
123
137int lc_xdrbg256_drng_alloc(struct lc_rng_ctx **state);
138
140#define LC_XDRBG512_DRNG_KEYSIZE 128
141/*
142 * For streamlining the access requests, the max chunk size plus the key size
143 * should be a full multiple of the SHAKE rate. As the key size is not
144 * exactly the rate size, the chunk size needs to consider it. As the rate is
145 * 576 bits and the keysize is 1024 bits, use 6 rate size blocks as the actual
146 * returned data size is 576 * 6 - 1024 == 2432 which is in the vicinity
147 * defined for XDRBG256. The XDRBG allows a slightly different maximum chunk
148 * size if you have an argument for it.
149 */
150#define LC_XDRBG512_DRNG_MAX_CHUNK \
151 (LC_SHAKE_512_SIZE_BLOCK * 6 - LC_XDRBG512_DRNG_KEYSIZE)
152#define LC_XDRBG512_DRNG_STATE_SIZE \
153 (sizeof(struct lc_xdrbg_drng_state) + LC_XDRBG512_DRNG_KEYSIZE)
154#define LC_XDRBG512_DRNG_CTX_SIZE \
155 (sizeof(struct lc_rng) + LC_XDRBG512_DRNG_STATE_SIZE)
156
157#define LC_XDRBG512_RNG_CTX(name) \
158 LC_RNG_CTX(name, lc_xdrbg512_drng); \
159 struct lc_xdrbg_drng_state *__name = name->rng_state; \
160 __name->status = lc_xdrbg_keysize_xdrbg512; \
161 __name->xof = lc_shake512; \
162 __name->chunksize = LC_XDRBG512_DRNG_MAX_CHUNK; \
163 lc_xdrbg512_drng->zero(name->rng_state);
165
181#define LC_XDRBG512_DRNG_CTX_ON_STACK(name) \
182 LC_XDRBG_DRNG_CTX_ON_STACK(name, LC_XDRBG512_DRNG_CTX_SIZE); \
183 LC_XDRBG512_RNG_CTX(name)
184
198int lc_xdrbg512_drng_alloc(struct lc_rng_ctx **state);
199
200#endif /* LC_XDRBG_SHAKE_ENABLED */
201
202/***************************** Ascon-based XDRBG ******************************/
203
204#ifdef LC_XDRBG_ASCON_ENABLED
205
207extern const struct lc_rng *lc_xdrbg128_drng;
208
209#define LC_XDRBG128_DRNG_KEYSIZE 32
210
211/*
212 * For streamlining the access requests, the max chunk size plus the key size
213 * should be a full multiple of the Ascon rate. As the key size is already
214 * exactly the rate size, the chunk size does not need to consider it.
215 */
216#define LC_XDRBG128_DRNG_MAX_CHUNK (LC_ASCON_HASH_RATE * 32)
217#define LC_XDRBG128_DRNG_STATE_SIZE \
218 (sizeof(struct lc_xdrbg_drng_state) + LC_XDRBG128_DRNG_KEYSIZE)
219#define LC_XDRBG128_DRNG_CTX_SIZE \
220 (sizeof(struct lc_rng) + LC_XDRBG128_DRNG_STATE_SIZE)
221
222#define LC_XDRBG128_RNG_CTX(name) \
223 LC_RNG_CTX(name, lc_xdrbg128_drng); \
224 struct lc_xdrbg_drng_state *__name = name->rng_state; \
225 __name->status = lc_xdrbg_keysize_xdrbg128; \
226 __name->xof = lc_ascon_xof; \
227 __name->chunksize = LC_XDRBG128_DRNG_MAX_CHUNK; \
228 lc_xdrbg128_drng->zero(name->rng_state);
230
247#define LC_XDRBG128_DRNG_CTX_ON_STACK(name) \
248 LC_XDRBG_DRNG_CTX_ON_STACK(name, LC_XDRBG128_DRNG_CTX_SIZE); \
249 LC_XDRBG128_RNG_CTX(name)
250
264int lc_xdrbg128_drng_alloc(struct lc_rng_ctx **state);
265
266#endif /* LC_XDRBG_ASCON_ENABLED */
267
268#ifdef __cplusplus
269}
270#endif
271
272#endif /* LC_XDRBG_DRNG_H */
int lc_hash(const struct lc_hash *hash, const uint8_t *in, size_t inlen, uint8_t *digest)
Calculate message digest - one-shot.