/src/wolfssl-sp-math-all/wolfssl/wolfcrypt/random.h
Line | Count | Source |
1 | | /* random.h |
2 | | * |
3 | | * Copyright (C) 2006-2026 wolfSSL Inc. |
4 | | * |
5 | | * This file is part of wolfSSL. |
6 | | * |
7 | | * wolfSSL is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * wolfSSL is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
20 | | */ |
21 | | |
22 | | /*! |
23 | | \file wolfssl/wolfcrypt/random.h |
24 | | */ |
25 | | |
26 | | |
27 | | |
28 | | #ifndef WOLF_CRYPT_RANDOM_H |
29 | | #define WOLF_CRYPT_RANDOM_H |
30 | | |
31 | | #include <wolfssl/wolfcrypt/types.h> |
32 | | |
33 | | #if FIPS_VERSION3_GE(2,0,0) |
34 | | #include <wolfssl/wolfcrypt/fips.h> |
35 | | #endif /* HAVE_FIPS_VERSION >= 2 */ |
36 | | |
37 | | /* One lock per WC_RNG so threads can share it. WC_RNG_NO_AUTO_LOCK opts out; |
38 | | * kernel modules have their own lock-free design and CMSIS-RTOS v1 has only |
39 | | * a ten-mutex pool. Bank builds keep it: they still hand out plain instances. */ |
40 | | /* WC_RNG_WANT_AUTO_LOCK forces the lock on where policy would skip it. The |
41 | | * tests below it are hard prerequisites and nothing can override those. */ |
42 | | #if (defined(WC_RNG_WANT_AUTO_LOCK) || \ |
43 | | (!defined(WOLFSSL_CMSIS_RTOS) && \ |
44 | | !defined(WOLFSSL_KERNEL_MODE) && \ |
45 | | !defined(WOLFSSL_KERNEL_MODE_DEFAULTS))) && \ |
46 | | !defined(SINGLE_THREADED) && \ |
47 | | !defined(WC_RNG_NO_AUTO_LOCK) && !defined(WC_NO_RNG) && \ |
48 | | !defined(WC_NO_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) && \ |
49 | | !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) |
50 | | #define WC_RNG_HAVE_AUTO_LOCK |
51 | | #else |
52 | | #undef WC_RNG_HAVE_AUTO_LOCK |
53 | | #endif |
54 | | |
55 | | /* Whether an instance gets the lock when the caller names neither |
56 | | * WC_RNG_INIT_FLAG_USE_AUTO_LOCK nor WC_RNG_INIT_FLAG_NO_AUTO_LOCK. */ |
57 | | #if defined(WC_RNG_HAVE_AUTO_LOCK) && defined(WC_RNG_AUTO_LOCK_DEFAULT_OFF) |
58 | | #define WC_RNG_AUTO_LOCK_DEFAULT 0 |
59 | | #else |
60 | 0 | #define WC_RNG_AUTO_LOCK_DEFAULT 1 |
61 | | #endif |
62 | | |
63 | | /* pthread_atfork handlers so a forked child can keep using its WC_RNG. |
64 | | * configure and CMake define WC_RNG_AUTOFORK where the dlclose pin and unnamed |
65 | | * semaphores exist; builds whose locks the handlers cannot cover are left out. |
66 | | * getpid() is required alongside them: it is what makes the child throw away |
67 | | * the pooled and banked bytes it inherited, which the handlers themselves do |
68 | | * not touch. */ |
69 | | #if defined(WC_RNG_HAVE_AUTO_LOCK) && defined(WOLFSSL_PTHREADS) && \ |
70 | | defined(WC_RNG_AUTOFORK) && !defined(__APPLE__) && \ |
71 | | defined(HAVE_THREAD_LS) && !defined(NO_THREAD_LS) && \ |
72 | | defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \ |
73 | | !defined(WOLFSSL_NO_MALLOC) && !defined(HAVE_ENTROPY_MEMUSE) && \ |
74 | | !defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFSSL_CHECK_MEM_ZERO) && \ |
75 | | !defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_MEM_FAIL_COUNT) |
76 | | #define WC_RNG_LOCK_ATFORK |
77 | | #else |
78 | | #undef WC_RNG_LOCK_ATFORK |
79 | | #endif |
80 | | |
81 | | #ifdef __cplusplus |
82 | | extern "C" { |
83 | | #endif |
84 | | |
85 | | #if FIPS_VERSION3_GE(6,0,0) |
86 | | extern const unsigned int wolfCrypt_FIPS_drbg_ro_sanity[2]; |
87 | | WOLFSSL_LOCAL int wolfCrypt_FIPS_DRBG_sanity(void); |
88 | | #endif |
89 | | |
90 | | /***** Setup for RNG extra features *****/ |
91 | | |
92 | | #if (defined(WC_RNG_EXTRAS) || defined(WC_RNG_WANT_LOCK)) && \ |
93 | | !defined(WC_RNG_NO_LOCK) && !defined(WC_NO_RNG) |
94 | | #define WC_RNG_HAVE_LOCK |
95 | | #ifdef WOLFSSL_NO_ATOMICS |
96 | | typedef word32 WC_RNG_lock_t; |
97 | | typedef word32 WC_RNG_lock_arg_t; |
98 | | #else |
99 | | typedef wolfSSL_Atomic_Uint WC_RNG_lock_t; |
100 | | typedef WC_ATOMIC_UINT_ARG WC_RNG_lock_arg_t; |
101 | | #endif |
102 | | #else |
103 | | #undef WC_RNG_HAVE_LOCK |
104 | | #endif |
105 | | |
106 | | #if defined(WC_RNG_WANT_LOCK_FULL_MUTEX) && !defined(WC_NO_RNG) |
107 | | #ifndef WC_RNG_HAVE_LOCK |
108 | | #error FULL_MUTEX depends on WC_RNG_HAVE_LOCK. |
109 | | #endif |
110 | | #define WC_RNG_HAVE_LOCK_FULL_MUTEX |
111 | | #else |
112 | | #undef WC_RNG_HAVE_LOCK_FULL_MUTEX |
113 | | #endif |
114 | | |
115 | | #if (defined(WC_RNG_EXTRAS) || defined(WC_RNG_WANT_RBGC)) && \ |
116 | | !defined(WC_RNG_NO_RBGC) && defined(HAVE_HASHDRBG) && \ |
117 | | !defined(CUSTOM_RAND_GENERATE_BLOCK) && !defined(WC_NO_RNG) |
118 | | #define WC_RNG_HAVE_RBGC |
119 | | #else |
120 | | #undef WC_RNG_HAVE_RBGC |
121 | | #endif |
122 | | |
123 | | #if (defined(WC_RNG_EXTRAS) || defined(WC_RNG_WANT_NEXT_SEED)) && \ |
124 | | !defined(WC_RNG_NO_NEXT_SEED) && defined(HAVE_HASHDRBG) && \ |
125 | | !defined(CUSTOM_RAND_GENERATE_BLOCK) && !defined(WC_NO_RNG) |
126 | | #define WC_RNG_HAVE_NEXT_SEED |
127 | | #ifdef WOLFSSL_NO_ATOMICS |
128 | | typedef sword32 WC_DRBG_nextSeedLen_t; |
129 | | #else |
130 | | typedef wolfSSL_Atomic_Int WC_DRBG_nextSeedLen_t; |
131 | | #endif |
132 | | #else |
133 | | #undef WC_RNG_HAVE_NEXT_SEED |
134 | | #endif |
135 | | #if defined(WC_RNG_HAVE_NEXT_SEED) && !defined(WC_RNG_HAVE_LOCK) && \ |
136 | | defined(HAVE_FIPS) |
137 | | /* FIPS builds: pregenerated output requires the full invalidation/purge |
138 | | * protocol, which rides the lock facility. */ |
139 | | #error WC_RNG_WANT_NEXT_SEED requires WC_RNG_WANT_LOCK in FIPS builds. |
140 | | #endif |
141 | | |
142 | | #if (defined(WC_RNG_EXTRAS) || defined(WC_RNG_WANT_POOL)) && \ |
143 | | !defined(WC_RNG_NO_POOL) && !defined(WC_NO_RNG) |
144 | | #define WC_RNG_HAVE_POOL |
145 | | #ifdef WOLFSSL_NO_ATOMICS |
146 | | typedef word32 WC_RNG_pool_pos_t; |
147 | | #else |
148 | | typedef wolfSSL_Atomic_Uint WC_RNG_pool_pos_t; |
149 | | #endif |
150 | | #else |
151 | | #undef WC_RNG_HAVE_POOL |
152 | | #endif |
153 | | #if defined(WC_RNG_HAVE_POOL) && !defined(WC_RNG_HAVE_LOCK) && \ |
154 | | defined(HAVE_FIPS) |
155 | | /* FIPS builds: pregenerated output requires the full invalidation/purge |
156 | | * protocol, which rides the lock facility. */ |
157 | | #error WC_RNG_WANT_POOL requires WC_RNG_WANT_LOCK in FIPS builds. |
158 | | #endif |
159 | | |
160 | | #if (defined(WC_RNG_EXTRAS) || defined(WC_RNG_WANT_FREE_HOOK)) && \ |
161 | | !defined(WC_RNG_NO_FREE_HOOK) && !defined(WC_NO_RNG) |
162 | | #define WC_RNG_HAVE_FREE_HOOK |
163 | | struct WC_RNG; |
164 | | typedef int (*wc_RNG_free_hook_cb_t)(const struct WC_RNG *rng, void *arg); |
165 | | #else |
166 | | #undef WC_RNG_HAVE_FREE_HOOK |
167 | | #endif |
168 | | |
169 | | #ifdef WC_RNG_NO_BANKREF_SUPPORT |
170 | | #undef WC_RNG_WANT_BANKREF_SUPPORT |
171 | | #endif |
172 | | #if defined(WC_RNG_WANT_BANKREF_SUPPORT) && !defined(WC_NO_RNG) |
173 | | #if defined(HAVE_FIPS) && \ |
174 | | !defined(WOLFSSL_FIPS_DEV) && !defined(WOLFSSL_EXPERIMENTAL_SETTINGS) |
175 | | #error HAVE_FIPS is incompatible with WC_RNG_WANT_BANKREF_SUPPORT. |
176 | | #endif |
177 | | #ifndef HAVE_WC_RNG_BANK |
178 | | #error WC_RNG_WANT_BANKREF_SUPPORT requires HAVE_WC_RNG_BANK. |
179 | | #endif |
180 | | #define WC_HAVE_RNG_BANKREF |
181 | | #else |
182 | | #undef WC_HAVE_RNG_BANKREF |
183 | | #endif |
184 | | |
185 | | #if defined(WC_RNG_HAVE_LOCK) && defined(WC_RNG_HAVE_RBGC) && \ |
186 | | !defined(WC_NO_RNG) |
187 | | #define WC_RNG_HAVE_GLOBAL_FALLBACK_RNG |
188 | | #endif |
189 | | |
190 | | #if defined(HAVE_FIPS) && defined(WC_RNG_HAVE_RBGC) && \ |
191 | | !defined(WC_RNG_HAVE_LOCK) |
192 | | /* FIPS SP 800-90C RBGC lineage persistence depends on the lock facility. */ |
193 | | #error HAVE_FIPS with WC_RNG_WANT_RBGC requires WC_RNG_WANT_LOCK. |
194 | | #endif |
195 | | |
196 | | /***** End setup for RNG extra features *****/ |
197 | | |
198 | | /* Maximum generate block length */ |
199 | | #ifndef RNG_MAX_BLOCK_LEN |
200 | | #ifdef HAVE_INTEL_QA |
201 | | #define RNG_MAX_BLOCK_LEN 0xFFFFL |
202 | | #else |
203 | 436k | #define RNG_MAX_BLOCK_LEN 0x10000L |
204 | | #endif |
205 | | #endif |
206 | | |
207 | | /* Size of the DRBG seed (SHA-256) */ |
208 | | #ifndef DRBG_SEED_LEN |
209 | 0 | #define DRBG_SEED_LEN (440/8) |
210 | | #endif |
211 | | |
212 | | #ifdef WOLFSSL_DRBG_SHA512 |
213 | 3.01M | #define DRBG_SHA512_SEED_LEN (888/8) /* 111 bytes per SP 800-90A Table 2 */ |
214 | | #endif |
215 | | |
216 | | |
217 | | #if !defined(CUSTOM_RAND_TYPE) |
218 | | /* To maintain compatibility the default is byte */ |
219 | | #define CUSTOM_RAND_TYPE byte |
220 | | #endif |
221 | | |
222 | | /* make sure Hash DRBG is enabled, unless WC_NO_HASHDRBG is defined |
223 | | or CUSTOM_RAND_GENERATE_BLOCK is defined */ |
224 | | #if !defined(WC_NO_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) |
225 | | #undef HAVE_HASHDRBG |
226 | | #define HAVE_HASHDRBG |
227 | | #ifndef WC_RESEED_INTERVAL |
228 | 1.03M | #define WC_RESEED_INTERVAL 1000000 |
229 | | #endif |
230 | | #endif |
231 | | |
232 | | |
233 | | |
234 | | /* avoid redefinition of structs */ |
235 | | #if !defined(HAVE_FIPS) || \ |
236 | | (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) |
237 | | |
238 | | /* RNG supports the following sources (in order): |
239 | | * 1. CUSTOM_RAND_GENERATE_BLOCK: Defines name of function as RNG source and |
240 | | * bypasses the options below. |
241 | | * 2. HAVE_INTEL_RDRAND: Uses the Intel RDRAND if supported by CPU. |
242 | | * 3. HAVE_HASHDRBG (requires SHA256 enabled): Uses SHA256 based P-RNG |
243 | | * seeded via wc_GenerateSeed. This is the default source. |
244 | | */ |
245 | | |
246 | | /* Seed source can be overridden by defining one of these: |
247 | | CUSTOM_RAND_GENERATE_SEED |
248 | | CUSTOM_RAND_GENERATE_SEED_OS |
249 | | CUSTOM_RAND_GENERATE */ |
250 | | |
251 | | |
252 | | #if defined(CUSTOM_RAND_GENERATE_BLOCK) |
253 | | /* To use define the following: |
254 | | * #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc |
255 | | * extern int myRngFunc(byte* output, word32 sz); |
256 | | */ |
257 | | #if defined(CUSTOM_RAND_GENERATE_BLOCK) && defined(WOLFSSL_KCAPI) |
258 | | #undef CUSTOM_RAND_GENERATE_BLOCK |
259 | | #define CUSTOM_RAND_GENERATE_BLOCK wc_hwrng_generate_block |
260 | | WOLFSSL_LOCAL int wc_hwrng_generate_block(byte *output, word32 sz); |
261 | | #endif |
262 | | #elif defined(HAVE_HASHDRBG) |
263 | | #ifdef NO_SHA256 |
264 | | #ifndef WOLFSSL_DRBG_SHA512 |
265 | | #error "Hash DRBG requires SHA-256 or SHA-512." |
266 | | #endif |
267 | | #endif /* NO_SHA256 */ |
268 | | #ifndef NO_SHA256 |
269 | | #include <wolfssl/wolfcrypt/sha256.h> |
270 | | #endif |
271 | | #ifdef WOLFSSL_DRBG_SHA512 |
272 | | #include <wolfssl/wolfcrypt/sha512.h> |
273 | | #endif |
274 | | #elif defined(HAVE_INTEL_RDRAND) |
275 | | /* Intel RDRAND or RDSEED */ |
276 | | #elif defined(WOLF_CRYPTO_CB) |
277 | | /* Requires registered Crypto Callback to service RNG, with devId set */ |
278 | | #elif !defined(WC_NO_RNG) |
279 | | #error No RNG source defined! |
280 | | #endif |
281 | | |
282 | | #ifdef WOLFSSL_ASYNC_CRYPT |
283 | | #include <wolfssl/wolfcrypt/async.h> |
284 | | #endif |
285 | | |
286 | | |
287 | | #if defined(USE_WINDOWS_API) |
288 | | #if defined(_WIN64) |
289 | | typedef unsigned __int64 ProviderHandle; |
290 | | /* type HCRYPTPROV, avoid #include <windows.h> */ |
291 | | #else |
292 | | typedef unsigned long ProviderHandle; |
293 | | #endif |
294 | | |
295 | | #ifdef WIN_REUSE_CRYPT_HANDLE |
296 | | /* called from wolfCrypt_Init() and wolfCrypt_Cleanup() */ |
297 | | WOLFSSL_LOCAL int wc_WinCryptHandleInit(void); |
298 | | WOLFSSL_LOCAL void wc_WinCryptHandleCleanup(void); |
299 | | #endif |
300 | | #endif |
301 | | |
302 | | #ifndef WC_OS_SEED_TYPE_DEFINED |
303 | | typedef struct OS_Seed OS_Seed; |
304 | | #define WC_OS_SEED_TYPE_DEFINED |
305 | | #endif |
306 | | #ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */ |
307 | | typedef struct WC_RNG WC_RNG; |
308 | | #ifdef WC_RNG_SEED_CB |
309 | | typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz); |
310 | | #endif |
311 | | #define WC_RNG_TYPE_DEFINED |
312 | | #endif |
313 | | |
314 | | /* OS specific seeder */ |
315 | | struct OS_Seed { |
316 | | #if defined(USE_WINDOWS_API) |
317 | | ProviderHandle handle; |
318 | | #else |
319 | | int fd; |
320 | | #if defined(WOLFSSL_KEEP_RNG_SEED_FD_OPEN) |
321 | | WC_BITFIELD seedFdOpen:1; |
322 | | WC_BITFIELD keepSeedFdOpen:1; |
323 | | #endif |
324 | | #endif |
325 | | #if defined(WOLF_CRYPTO_CB) |
326 | | int devId; |
327 | | #endif |
328 | | }; |
329 | | |
330 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
331 | | /* Length of the DRBG-flavor-independent stir buffer */ |
332 | | #define WC_RNG_NEXT_STIR_LEN 64 |
333 | | #endif |
334 | | |
335 | | #ifdef HAVE_HASHDRBG |
336 | | |
337 | | /* The security strength for the RNG is the target number of bits of |
338 | | * entropy you are looking for in a seed. */ |
339 | | /* RNG_SECURITY_STRENGTH is unprefixed for backward compat. */ |
340 | | #ifndef RNG_SECURITY_STRENGTH |
341 | | /* SHA-256 requires a minimum of 256-bits of entropy. */ |
342 | 239k | #define RNG_SECURITY_STRENGTH 256 |
343 | | #endif |
344 | | |
345 | | /* wolfentropy.h will define for HAVE_ENTROPY_MEMUSE */ |
346 | | #ifdef HAVE_ENTROPY_MEMUSE |
347 | | #include <wolfssl/wolfcrypt/wolfentropy.h> |
348 | | #else |
349 | | /* Maximum entropy bits that can be produced. */ |
350 | | #define MAX_ENTROPY_BITS 256 |
351 | | #endif |
352 | | |
353 | | /* ENTROPY_SCALE_FACTOR is unprefixed for backward compat. */ |
354 | | #ifndef ENTROPY_SCALE_FACTOR |
355 | | /* The entropy scale factor should be the whole number inverse of the |
356 | | * minimum bits of entropy per bit of NDRNG output. */ |
357 | | #if defined(HAVE_AMD_RDSEED) |
358 | | /* This will yield a SEED_SZ of 16kb. Since nonceSz will be 0, |
359 | | * we'll add an additional 8kb on top. |
360 | | * |
361 | | * See "AMD RNG ESV Public Use Document". Version 0.7 of October 24, |
362 | | * 2024 specifies 0.656 to 1.312 bits of entropy per 128 bit block of |
363 | | * RDSEED output, depending on CPU family. |
364 | | */ |
365 | | #define ENTROPY_SCALE_FACTOR 512 |
366 | | #elif defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) |
367 | | /* The value of 2 applies to Intel's RDSEED which provides about |
368 | | * 0.5 bits minimum of entropy per bit. The value of 4 gives a |
369 | | * conservative margin for FIPS. */ |
370 | | #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ |
371 | | (HAVE_FIPS_VERSION >= 2) |
372 | | #define ENTROPY_SCALE_FACTOR (2*4) |
373 | | #else |
374 | | /* Not FIPS, but Intel RDSEED, only double. */ |
375 | | #define ENTROPY_SCALE_FACTOR 2 |
376 | | #endif |
377 | | #elif defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ |
378 | | (HAVE_FIPS_VERSION >= 2) |
379 | | /* If doing a FIPS build without a specific scale factor, default |
380 | | * to 4. This will give 1024 bits of entropy. More is better, but |
381 | | * more is also slower. */ |
382 | | #define ENTROPY_SCALE_FACTOR 4 |
383 | | #else |
384 | | /* Setting the default to 1. */ |
385 | 239k | #define ENTROPY_SCALE_FACTOR 1 |
386 | | #endif |
387 | | /* tells test.c the seed-callback known answers apply */ |
388 | | #define WC_DRBG_ENTROPY_SCALE_FACTOR_DEFAULTED |
389 | | #endif /* !ENTROPY_SCALE_FACTOR */ |
390 | | |
391 | | /* SEED_BLOCK_SZ is unprefixed for backward compat. */ |
392 | | #ifndef SEED_BLOCK_SZ |
393 | | /* The seed block size, is the size of the output of the underlying NDRNG. |
394 | | * This value is used for testing the output of the NDRNG. */ |
395 | | #if defined(HAVE_AMD_RDSEED) |
396 | | /* AMD's RDSEED instruction works in 128-bit blocks read 64-bits |
397 | | * at a time. */ |
398 | | #define SEED_BLOCK_SZ (sizeof(word64)*2) |
399 | | #elif defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) |
400 | | /* RDSEED outputs in blocks of 64-bits. */ |
401 | | #define SEED_BLOCK_SZ sizeof(word64) |
402 | | #else |
403 | | /* Setting the default to 4. */ |
404 | 393k | #define SEED_BLOCK_SZ 4 |
405 | | #endif |
406 | | #define WC_DRBG_SEED_BLOCK_SZ_DEFAULTED |
407 | | #endif |
408 | | |
409 | | #define WC_DRBG_SEED_BLOCK_SZ SEED_BLOCK_SZ |
410 | | |
411 | | /* WC_DRBG_SEED_SZ is the number of bytes of raw entropy gathered from the |
412 | | * NDRNG at instantiation and reseed. We deliberately "overseed" beyond the |
413 | | * NIST minimum (security_strength bits) to account for entropy sources that |
414 | | * may deliver fewer than 1 bit of real entropy per bit of output. With the |
415 | | * default FIPS ENTROPY_SCALE_FACTOR of 4 this yields 256*4/8 = 128 bytes = |
416 | | * 1024 bits of raw seed material, guaranteeing at least 256 bits of real |
417 | | * entropy even if the source provides only 1 good bit per 4. |
418 | | * |
419 | | * Hash_df then compresses this seed material into the internal V and C state |
420 | | * vectors (seedlen = 440 bits for SHA-256, 888 bits for SHA-512 per |
421 | | * SP 800-90A Table 2). |
422 | | * |
423 | | * In FIPS mode (ENTROPY_SCALE_FACTOR >= 4) the base is already >= 128 bytes |
424 | | * which exceeds DRBG_SHA512_SEED_LEN (111), so both DRBGs use the same |
425 | | * seed size. In non-FIPS mode we use the base for both DRBGs so that |
426 | | * enabling SHA-512 DRBG does not inflate the per-init entropy cost. |
427 | | * SP 800-90A requires only security_strength bits (256 = 32 bytes) of |
428 | | * entropy regardless of hash size; hash_df compresses the seed material |
429 | | * into the internal V/C state vectors. */ |
430 | 239k | #define WC_DRBG_SEED_SZ_BASE (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8) |
431 | | |
432 | | #if defined(HAVE_FIPS) && defined(WOLFSSL_DRBG_SHA512) && \ |
433 | | (WC_DRBG_SEED_SZ_BASE < DRBG_SHA512_SEED_LEN) |
434 | | #define WC_DRBG_SEED_SZ DRBG_SHA512_SEED_LEN |
435 | | #else |
436 | 239k | #define WC_DRBG_SEED_SZ WC_DRBG_SEED_SZ_BASE |
437 | | #endif |
438 | | |
439 | | /* The maximum seed size will be the seed size plus a seed block for the |
440 | | * test, and an additional half of the seed size. This additional half |
441 | | * is in case the user does not supply a nonce. A nonce will be obtained |
442 | | * from the NDRNG. FIPS builds draw it from the seed source even when a |
443 | | * nonce is supplied. */ |
444 | 79.7k | #define WC_DRBG_MAX_SEED_SZ (WC_DRBG_SEED_SZ + WC_DRBG_SEED_SZ/2 + \ |
445 | 79.7k | SEED_BLOCK_SZ) |
446 | | |
447 | | #ifndef NO_SHA256 |
448 | 0 | #define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4) |
449 | | #endif |
450 | | #ifdef WOLFSSL_DRBG_SHA512 |
451 | 236k | #define RNG_HEALTH_TEST_CHECK_SIZE_SHA512 (WC_SHA512_DIGEST_SIZE * 4) |
452 | | #endif |
453 | | |
454 | | #define WC_DRBG_SEED_BUF_SIZE (WC_DRBG_SEED_SZ + WC_DRBG_SEED_BLOCK_SZ) |
455 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
456 | | #define WC_DRBG_NEXT_SEED_LEN WC_DRBG_SEED_BUF_SIZE |
457 | | #endif |
458 | | |
459 | | #ifndef WC_DRBG_RESEED_CTR_TYPE_DEFINED |
460 | | #define WC_DRBG_RESEED_CTR_TYPE_DEFINED |
461 | | #ifdef WORD64_AVAILABLE |
462 | | typedef word64 wc_drbg_reseed_ctr_t; |
463 | | #else |
464 | | typedef word32 wc_drbg_reseed_ctr_t; |
465 | | #endif |
466 | | #endif |
467 | | |
468 | | #ifndef NO_SHA256 |
469 | | struct DRBG_internal { |
470 | | byte V[DRBG_SEED_LEN]; |
471 | | byte C[DRBG_SEED_LEN]; |
472 | | void* heap; |
473 | | #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) |
474 | | int devId; |
475 | | #endif |
476 | | #ifdef WOLFSSL_SMALL_STACK_CACHE |
477 | | wc_Sha256 sha256; |
478 | | byte seed_scratch[DRBG_SEED_LEN * 2]; |
479 | | byte digest_scratch[WC_SHA256_DIGEST_SIZE]; |
480 | | byte newSeed_buf[WC_DRBG_SEED_BUF_SIZE]; |
481 | | #endif |
482 | | }; |
483 | | #endif /* !NO_SHA256 */ |
484 | | |
485 | | #ifdef WOLFSSL_DRBG_SHA512 |
486 | | struct DRBG_SHA512_internal { |
487 | | byte V[DRBG_SHA512_SEED_LEN]; |
488 | | byte C[DRBG_SHA512_SEED_LEN]; |
489 | | void* heap; |
490 | | #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) |
491 | | int devId; |
492 | | #endif |
493 | | #ifdef WOLFSSL_SMALL_STACK_CACHE |
494 | | wc_Sha512 sha512; |
495 | | byte seed_scratch[DRBG_SHA512_SEED_LEN * 2]; |
496 | | byte digest_scratch[WC_SHA512_DIGEST_SIZE]; |
497 | | byte newSeed_buf[WC_DRBG_SEED_BUF_SIZE]; |
498 | | #endif |
499 | | }; |
500 | | #endif /* WOLFSSL_DRBG_SHA512 */ |
501 | | #endif /* HAVE_HASHDRBG */ |
502 | | |
503 | | /* DRBG type enum */ |
504 | | #ifdef HAVE_HASHDRBG |
505 | | enum wc_DrbgType { |
506 | | WC_DRBG_SHA256 = 0, |
507 | | WC_DRBG_SHA512 = 1 |
508 | | }; |
509 | | #endif |
510 | | |
511 | | /* RNG health states */ |
512 | | enum wc_RngHealthState { |
513 | | WC_DRBG_NOT_INIT = 0, |
514 | | WC_DRBG_OK = 1, |
515 | | WC_DRBG_FAILED = 2, |
516 | | WC_DRBG_CONT_FAILED = 3 |
517 | | }; |
518 | | |
519 | | #define WC_RNG_FLAG_NONE 0 |
520 | | #define WC_RNG_FLAG_RBGC_NEXT_SEED (1U << 0) |
521 | | #define WC_RNG_FLAG_BANKREF (1U << 1) |
522 | | #define WC_RNG_FLAG_FULL_MUTEX (1U << 2) |
523 | | #define WC_RNG_FLAG_UPGRADE_FROM_NEXT_SEED (1U << 3) |
524 | 0 | #define WC_RNG_FLAG_FAIL_FAST (1U << 4) |
525 | 0 | #define WC_RNG_FLAG_NO_RBGC_PARENT (1U << 5) |
526 | 0 | #define WC_RNG_FLAG_ONLY_PRIMARY_SEED (1U << 6) |
527 | 0 | #define WC_RNG_FLAG_NO_PRIMARY_SEED (1U << 7) |
528 | | |
529 | | /* Bits a caller may change after init, via wc_RNG_{Set,Clear}Flags(). The |
530 | | * remainder are structural (set by init or by the module) and refused. */ |
531 | 0 | #define WC_RNG_FLAGS_SETTABLE (WC_RNG_FLAG_FAIL_FAST | \ |
532 | 0 | WC_RNG_FLAG_ONLY_PRIMARY_SEED | \ |
533 | 0 | WC_RNG_FLAG_NO_PRIMARY_SEED) |
534 | 0 | #define WC_RNG_FLAGS_CLEARABLE (WC_RNG_FLAG_FAIL_FAST | \ |
535 | 0 | WC_RNG_FLAG_ONLY_PRIMARY_SEED) |
536 | | |
537 | | #ifndef WC_RNG_RBGC_USER_SEED_STRATUM |
538 | | #define WC_RNG_RBGC_USER_SEED_STRATUM 65536 |
539 | | #endif |
540 | | wc_static_assert(WC_RNG_RBGC_USER_SEED_STRATUM >= 256); |
541 | | |
542 | | #if defined(HAVE_FIPS) && !defined(WC_RNG_RBGC_STRATUM_IMMUTABLE) |
543 | | #define WC_RNG_RBGC_STRATUM_IMMUTABLE |
544 | | #endif |
545 | | |
546 | | #ifdef WC_RNG_WANT_DEBUG_STATS |
547 | | #define WC_RNG_DEBUG_STATS |
548 | | #endif |
549 | | |
550 | | #if defined(WC_RNG_DEBUG_STATS) && !defined(WC_RNG_HAVE_LOCK) && \ |
551 | | !defined(WC_NO_RNG) |
552 | | #error WC_RNG_DEBUG_STATS requires the RNG lock facility (WC_RNG_WANT_LOCK). |
553 | | #endif |
554 | | |
555 | | #ifdef WC_RNG_DEBUG_STATS |
556 | | #ifdef WORD64_AVAILABLE |
557 | | typedef word64 wc_rng_debug_counter_t; |
558 | | #else |
559 | | typedef word32 wc_rng_debug_counter_t; |
560 | | #endif |
561 | | #endif |
562 | | |
563 | | #if ((defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED) && \ |
564 | | defined(WORD64_AVAILABLE)) || \ |
565 | | defined(WC_RNG_WANT_ENTROPY_EPOCH)) && \ |
566 | | !defined(WC_RNG_NO_ENTROPY_EPOCH) && !defined(WC_NO_RNG) |
567 | | #if !defined(WOLFSSL_ATOMIC_OPS) || !defined(WORD64_AVAILABLE) |
568 | | #error WC_RNG_HAVE_ENTROPY_EPOCH requires WOLFSSL_ATOMIC_OPS and WORD64_AVAILABLE. |
569 | | #endif |
570 | | #define WC_RNG_HAVE_ENTROPY_EPOCH |
571 | | typedef word64 wc_RNG_entropy_epoch_t; |
572 | | #endif |
573 | | |
574 | | /* RNG context */ |
575 | | struct WC_RNG { |
576 | | struct OS_Seed seed; |
577 | | void* heap; |
578 | | byte status; |
579 | | word32 flags; |
580 | | #ifdef WC_RNG_HAVE_ENTROPY_EPOCH |
581 | | wc_RNG_entropy_epoch_t entropy_epoch; |
582 | | #endif |
583 | | #ifdef WC_RNG_DEBUG_STATS |
584 | | wc_rng_debug_counter_t _stats_total_bytes_requested; |
585 | | wc_rng_debug_counter_t _stats_total_bytes_produced; |
586 | | wc_rng_debug_counter_t _stats_total_requests; |
587 | | wc_rng_debug_counter_t _stats_reseeds; |
588 | | wc_rng_debug_counter_t _stats_stirs; |
589 | | wc_rng_debug_counter_t _stats_seed_failures; |
590 | | #endif |
591 | | #ifdef WC_RNG_HAVE_RBGC |
592 | | int RBGCStratum; |
593 | | #ifdef WC_RNG_DEBUG_STATS |
594 | | wc_rng_debug_counter_t _stats_RBGC_bytes_produced; |
595 | | wc_rng_debug_counter_t _stats_RBGC_reseeds; |
596 | | #endif |
597 | | #endif /* WC_RNG_HAVE_RBGC */ |
598 | | #ifdef WC_RNG_HAVE_LOCK |
599 | | WC_RNG_lock_t lock; |
600 | | #ifdef WC_RNG_HAVE_RBGC |
601 | | wolfSSL_Atomic_Uint RBGC_refcount; |
602 | | struct WC_RNG *RBGC_parent; |
603 | | #endif /* WC_RNG_HAVE_LOCK */ |
604 | | #endif |
605 | | /* Both lock facilities use this one mutex, so it is declared once here. |
606 | | * The fork handler build holds a wc_ForkLock instead and needs no mutex. */ |
607 | | #if defined(WC_RNG_HAVE_LOCK_FULL_MUTEX) || \ |
608 | | (defined(WC_RNG_HAVE_AUTO_LOCK) && !defined(WC_RNG_LOCK_ATFORK)) |
609 | | wolfSSL_Mutex mutex; |
610 | | #endif |
611 | | #ifdef WC_RNG_HAVE_LOCK |
612 | | #ifdef WC_RNG_DEBUG_STATS |
613 | | wc_rng_debug_counter_t _stats_locks_taken; |
614 | | wc_rng_debug_counter_t _stats_locks_released; |
615 | | wc_rng_debug_counter_t _stats_locks_refused; /* racy */ |
616 | | #endif |
617 | | #endif |
618 | | #ifdef WC_RNG_HAVE_FREE_HOOK |
619 | | wc_RNG_free_hook_cb_t free_hook; |
620 | | void *free_hook_arg; |
621 | | #endif |
622 | | #ifdef WC_RNG_HAVE_POOL |
623 | | byte* pool; /* heap ring; lifecycle arbitrated by poolHead */ |
624 | | word16 poolSize; |
625 | | WC_RNG_pool_pos_t poolHead; /* {state:2, epoch:14, pos:16} -- written by |
626 | | * writer/purger/allocator/teardown, CAS. |
627 | | * Survives _InitRng()'s wipe (atomically |
628 | | * set to the unallocated sentinel). */ |
629 | | WC_RNG_pool_pos_t poolTail; /* {0, epoch, pos} written by reader only, |
630 | | * plain. */ |
631 | | #ifdef WC_RNG_DEBUG_STATS |
632 | | wc_rng_debug_counter_t _stats_pool_bytes_produced; |
633 | | wc_rng_debug_counter_t _stats_pool_bytes_missed; |
634 | | #endif |
635 | | #endif |
636 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
637 | | byte nextStir[WC_RNG_NEXT_STIR_LEN]; |
638 | | WC_DRBG_nextSeedLen_t nextStirLen; |
639 | | #endif |
640 | | |
641 | | #ifdef WC_RNG_DEBUG_STATS |
642 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
643 | | wc_rng_debug_counter_t _stats_nextseedsprimary_redeemed; |
644 | | wc_rng_debug_counter_t _stats_nextseedsRBGC_redeemed; |
645 | | wc_rng_debug_counter_t _stats_nextstirs_redeemed; |
646 | | wc_rng_debug_counter_t _stats_nextseedsbanked; |
647 | | wc_rng_debug_counter_t _stats_nextstirs_banked; |
648 | | #endif |
649 | | #endif |
650 | | |
651 | | #ifdef HAVE_HASHDRBG |
652 | | /* Common members for DRBG cores, here for safe lock-free access. */ |
653 | | byte drbgType; /* WC_DRBG_SHA256 or WC_DRBG_SHA512 */ |
654 | | wc_drbg_reseed_ctr_t reseedCtr; /* SP 800-90A reseed budget */ |
655 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
656 | | byte *nextSeed; |
657 | | #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) |
658 | | byte nextSeed_data[WC_DRBG_SEED_BUF_SIZE]; |
659 | | #endif |
660 | | WC_DRBG_nextSeedLen_t nextSeedLen; |
661 | | #ifdef WC_RNG_HAVE_RBGC |
662 | | int nextSeedRBGCStratum; |
663 | | #endif |
664 | | #endif |
665 | | #endif /* HAVE_HASHDRBG */ |
666 | | |
667 | | #if defined(HAVE_HASHDRBG) || defined(WC_HAVE_RNG_BANKREF) |
668 | | |
669 | | #ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES |
670 | | union { |
671 | | #endif |
672 | | |
673 | | #ifdef WC_HAVE_RNG_BANKREF |
674 | | struct wc_rng_bank *bankref; |
675 | | #endif |
676 | | |
677 | | #if defined(HAVE_HASHDRBG) && !defined(NO_SHA256) |
678 | | #ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES |
679 | | struct { |
680 | | #endif |
681 | | /* SHA-256 Hash-based Deterministic Random Bit Generator */ |
682 | | struct DRBG* drbg; |
683 | | #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) |
684 | | struct DRBG_internal drbg_data; |
685 | | #endif |
686 | | #ifdef WOLFSSL_SMALL_STACK_CACHE |
687 | | /* SHA-256 scratch buffers -- preallocated by _InitRng(). */ |
688 | | struct DRBG_internal *drbg_scratch; |
689 | | byte *health_check_scratch; |
690 | | #endif |
691 | | #ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES |
692 | | }; |
693 | | #endif |
694 | | #endif /* HAVE_HASHDRBG && !NO_SHA256 */ |
695 | | |
696 | | #if defined(HAVE_HASHDRBG) && defined(WOLFSSL_DRBG_SHA512) |
697 | | #ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES |
698 | | struct { |
699 | | #endif |
700 | | /* SHA-512 Hash-based Deterministic Random Bit Generator */ |
701 | | struct DRBG_SHA512* drbg512; |
702 | | #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) |
703 | | struct DRBG_SHA512_internal drbg512_data; |
704 | | #endif |
705 | | #ifdef WOLFSSL_SMALL_STACK_CACHE |
706 | | /* SHA-512 scratch buffers -- preallocated by _InitRng(). */ |
707 | | struct DRBG_SHA512_internal *drbg512_scratch; |
708 | | byte *health_check_scratch_512; |
709 | | #endif |
710 | | #ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES |
711 | | }; |
712 | | #endif |
713 | | #endif /* HAVE_HASHDRBG && WOLFSSL_DRBG_SHA512 */ |
714 | | #ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES |
715 | | }; |
716 | | #endif |
717 | | |
718 | | #endif /* HAVE_HASHDRBG || WC_HAVE_RNG_BANKREF */ |
719 | | |
720 | | #if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) |
721 | | pid_t pid; |
722 | | #endif |
723 | | #ifdef WOLFSSL_ASYNC_CRYPT |
724 | | WC_ASYNC_DEV asyncDev; |
725 | | #endif |
726 | | #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) |
727 | | int devId; |
728 | | #endif |
729 | | #ifdef WC_RNG_LOCK_ATFORK |
730 | | /* NULL until wc_InitRng succeeds. Initialize only a new or freed WC_RNG: |
731 | | * wc_InitRng over a live one leaks this and grows the fork registry that |
732 | | * every fork() walks. */ |
733 | | struct wc_ForkLock* autoLock; /* defined in wc_port.c */ |
734 | | #elif defined(WC_RNG_HAVE_AUTO_LOCK) |
735 | | byte autoLockInited; /* nonzero once lock exists */ |
736 | | int autoLockCancel; /* the holder's cancel state, back on exit */ |
737 | | #endif |
738 | | }; |
739 | | |
740 | | #define WC_RNG_STATIC_INITIALIZER WC_STATIC_STRUCT_INITIALIZER |
741 | | |
742 | | #endif /* NO FIPS or have FIPS v2*/ |
743 | | |
744 | | /* NO_OLD_RNGNAME removes RNG struct name to prevent possible type conflicts, |
745 | | * can't be used with CTaoCrypt FIPS */ |
746 | | #if !defined(NO_OLD_RNGNAME) && !defined(HAVE_FIPS) |
747 | | #define RNG WC_RNG |
748 | | #endif |
749 | | |
750 | | WOLFSSL_API int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz); |
751 | | |
752 | | |
753 | | #ifndef WC_NO_RNG |
754 | | |
755 | | /* Note, wc_rng_new*, wc_InitRng*, wc_InitRng_BankRef, wc_FreeRng and |
756 | | * wc_rng_free do return unlocked instances, unless a flag-recognizing variant |
757 | | * is used and WC_RNG_INIT_FLAG_LOCK_INITIALLY is passed. */ |
758 | | |
759 | | WOLFSSL_ABI WOLFSSL_API WC_RNG* wc_rng_new(byte* nonce, word32 nonceSz, |
760 | | void* heap); |
761 | | WOLFSSL_API int wc_rng_new_ex(WC_RNG **rng, byte* nonce, word32 nonceSz, |
762 | | void* heap, int devId); |
763 | | WOLFSSL_ABI WOLFSSL_API void wc_rng_free(WC_RNG* rng); |
764 | | |
765 | | WOLFSSL_ABI WOLFSSL_API int wc_InitRng(WC_RNG* rng); |
766 | | WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId); |
767 | | #if FIPS_VERSION3_GE(7,0,0) && defined(HAVE_HASHDRBG) && \ |
768 | | defined(BUILDING_WOLFSSL) |
769 | | /* Fixed seed start for the module's own known answer tests. seedSz must be |
770 | | * over SEED_BLOCK_SZ and no more than WC_DRBG_MAX_SEED_SZ; the leading |
771 | | * SEED_BLOCK_SZ bytes are checked but do not reach the DRBG. */ |
772 | | WOLFSSL_LOCAL int wc_InitRngFixedSeed(WC_RNG* rng, const byte* seed, |
773 | | word32 seedSz); |
774 | | #endif |
775 | | WOLFSSL_API int wc_InitRngNonce(WC_RNG* rng, const byte* nonce, word32 nonceSz); |
776 | | |
777 | 85.7k | #define WC_RNG_INIT_FLAG_NONE 0 |
778 | 155k | #define WC_RNG_INIT_FLAG_LOCK_REQUIRED (1U << 0) |
779 | 79.7k | #define WC_RNG_INIT_FLAG_LOCK_INITIALLY (1U << 1) |
780 | 231k | #define WC_RNG_INIT_FLAG_USE_FULL_MUTEX (1U << 2) |
781 | 79.7k | #define WC_RNG_INIT_FLAG_UPGRADE_FROM_NEXT_SEED (1U << 3) |
782 | 79.7k | #define WC_RNG_INIT_FLAG_USE_AUTO_LOCK (1U << 4) |
783 | 75.9k | #define WC_RNG_INIT_FLAG_NO_AUTO_LOCK (1U << 5) |
784 | 79.7k | #define WC_RNG_INIT_FLAG_PRESERVE_LOCK (1U << 6) |
785 | 79.7k | #define WC_RNG_INIT_FLAG_NO_PRIMARY_SEED (1U << 7) |
786 | 79.7k | #define WC_RNG_INIT_FLAG_TEST_USER_SEED (1U << 8) |
787 | 79.7k | #define WC_RNG_INIT_FLAG_FAIL_FAST (1U << 9) |
788 | 239k | #define WC_RNG_INIT_FLAG_DRBG_SHA256 (1U << 10) |
789 | 404k | #define WC_RNG_INIT_FLAG_DRBG_SHA512 (1U << 11) |
790 | | |
791 | | /* Codes from the seed source or the instance that mean "not now", not |
792 | | * "not ever": a caller that can wait may retry the instantiation, reseed or |
793 | | * recovery that returned one. wc_InitRng*() passes these through from the |
794 | | * source rather than folding them into RNG_FAILURE_E, and rng_bank.c keys |
795 | | * its retry loops on the same set. */ |
796 | | #define WC_RNG_ERR_IS_TRANSIENT(e) \ |
797 | 0 | (((e) == WC_NO_ERR_TRACE(BUSY_E)) || \ |
798 | 0 | ((e) == WC_NO_ERR_TRACE(NOT_READY_E)) || \ |
799 | 0 | ((e) == WC_NO_ERR_TRACE(NEEDS_RECOVERY_E)) || \ |
800 | 0 | ((e) == WC_NO_ERR_TRACE(RAN_BLOCK_E)) || \ |
801 | 0 | ((e) == WC_NO_ERR_TRACE(ENTROPY_RT_E)) || \ |
802 | 0 | ((e) == WC_NO_ERR_TRACE(ENTROPY_APT_E))) |
803 | | |
804 | | WOLFSSL_API int wc_InitRng_ex2(WC_RNG* rng, void* heap, int devId, |
805 | | word32 flags); |
806 | | WOLFSSL_API int wc_InitRngNonce_ex2(WC_RNG* rng, const byte* nonce, word32 nonceSz, |
807 | | const byte *perso, word32 persoSz, |
808 | | void* heap, int devId, word32 flags); |
809 | | WOLFSSL_API int wc_InitRngNonce_ex(WC_RNG* rng, const byte* nonce, word32 nonceSz, |
810 | | void* heap, int devId); |
811 | | WOLFSSL_API int wc_InitRngNonce_UserSeed(WC_RNG* rng, |
812 | | const byte* seed, word32 seedSz, |
813 | | const byte* nonce, word32 nonceSz, |
814 | | const byte *perso, word32 persoSz, |
815 | | void* heap, int devId, word32 flags); |
816 | | #ifdef WC_RNG_HAVE_GLOBAL_FALLBACK_RNG |
817 | | WOLFSSL_API int wc_RNG_global_fallback_init(const byte* nonce, word32 nonceSz, |
818 | | const byte *perso, word32 persoSz, |
819 | | void* heap, int devId, word32 flags); |
820 | | WOLFSSL_API int wc_RNG_global_fallback_init_user_seed(const byte* seed, word32 seedSz, |
821 | | const byte* nonce, word32 nonceSz, |
822 | | const byte *perso, word32 persoSz, |
823 | | void* heap, int devId, word32 flags); |
824 | | WOLFSSL_API int wc_RNG_global_fallback_get(WC_RNG **rng); |
825 | | WOLFSSL_API int wc_RNG_global_fallback_free(void); |
826 | | #endif |
827 | | |
828 | | WOLFSSL_API int wc_RNG_Status(const WC_RNG *rng); |
829 | | |
830 | | WOLFSSL_ABI WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz); |
831 | | WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG* rng, byte* b); |
832 | | /* Note, when WC_RNG_HAVE_LOCK, wc_FreeRng() takes the instance lock itself, so |
833 | | * it mustn't be called with the lock already held (use wc_FreeRng_PreLocked() |
834 | | * for that). A STILL_REFERENCED_E return has persistent side effects: |
835 | | * sensitive state is wiped, but the object stays pinned by its RBGC children |
836 | | * and must outlive them. */ |
837 | | WOLFSSL_API int wc_FreeRng(WC_RNG* rng); |
838 | | #ifdef WC_RNG_HAVE_LOCK |
839 | | /* Note, caller must hold the instance lock, which is retained on return. */ |
840 | | WOLFSSL_API int wc_FreeRng_PreLocked(WC_RNG* rng); |
841 | | #endif |
842 | | #else |
843 | | #include <wolfssl/wolfcrypt/error-crypt.h> |
844 | | #define wc_InitRng(rng) NOT_COMPILED_IN |
845 | | #define wc_InitRng_ex(rng, h, d) NOT_COMPILED_IN |
846 | | #define wc_InitRngNonce(rng, n, s) NOT_COMPILED_IN |
847 | | #define wc_InitRngNonce_ex(rng, n, s, h, d) NOT_COMPILED_IN |
848 | | #define wc_InitRng_ex2(rng, h, d, f) NOT_COMPILED_IN |
849 | | #define wc_InitRngNonce_ex2(rng, n, s, p, ps, h, d, f) NOT_COMPILED_IN |
850 | | #if defined(__ghs__) || defined(WC_NO_RNG_SIMPLE) |
851 | | /* some older compilers do not like macro function in expression */ |
852 | | #define wc_RNG_GenerateBlock(rng, b, s) NOT_COMPILED_IN |
853 | | #else |
854 | | #ifdef _MSC_VER |
855 | | #define wc_RNG_GenerateBlock(rng, b, s) (int)(NOT_COMPILED_IN) |
856 | | #else |
857 | | #define wc_RNG_GenerateBlock(rng, b, s) \ |
858 | | ({(void)rng; (void)b; (void)s; NOT_COMPILED_IN;}) |
859 | | #endif |
860 | | #endif |
861 | | #define wc_RNG_GenerateByte(rng, b) NOT_COMPILED_IN |
862 | | #define wc_FreeRng(rng) (void)NOT_COMPILED_IN |
863 | | #endif |
864 | | |
865 | | #ifdef WOLFSSL_FIPS_EXPORT_LOCAL_APIS |
866 | | #define WC_FIPS_LOCAL_API WOLFSSL_API |
867 | | #else |
868 | | #define WC_FIPS_LOCAL_API WOLFSSL_LOCAL |
869 | | #endif |
870 | | |
871 | | #ifdef WC_RNG_SEED_CB |
872 | | WOLFSSL_API int wc_SetSeed_Cb(wc_RngSeed_Cb cb); |
873 | | #endif |
874 | | |
875 | | WOLFSSL_API int wc_RNG_GetStatus(const WC_RNG* rng); |
876 | | WOLFSSL_API int wc_RNG_DRBG_Present(const WC_RNG* rng); |
877 | | |
878 | | /* Post-init flag policy: only bits in WC_RNG_FLAGS_SETTABLE / |
879 | | * WC_RNG_FLAGS_CLEARABLE, only with exclusive ownership (SINGLE_THREADED, or |
880 | | * WC_RNG_HAVE_LOCK with the instance _LOCK_REQUIRED and the lease held). */ |
881 | | WOLFSSL_API int wc_RNG_SetFlags(WC_RNG* rng, word32 flags); |
882 | | WOLFSSL_API int wc_RNG_ClearFlags(WC_RNG* rng, word32 flags); |
883 | | WOLFSSL_API int wc_RNG_GetFlags(const WC_RNG* rng, word32 *flags); |
884 | | |
885 | | #ifdef HAVE_HASHDRBG |
886 | | WOLFSSL_API int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, |
887 | | word32 seedSz); |
888 | | WOLFSSL_API int wc_RNG_DRBG_Reseed_AddIn(WC_RNG* rng, const byte* seed, |
889 | | word32 seedSz, const byte *addIn, |
890 | | word32 addInSz); |
891 | | /* Capability markers for code compiled against a random.h of uncertain |
892 | | * vintage (FIPS builds substitute the module's pinned random.[ch] for |
893 | | * the tree's): consumers outside the boundary gate on these rather than |
894 | | * on FIPS version arithmetic or on WC_RNG_RBGC_STRATUM_IMMUTABLE. */ |
895 | | #define WC_RNG_HAVE_STIR |
896 | | WOLFSSL_API int wc_RNG_DRBG_Stir(WC_RNG* rng, |
897 | | const byte* seed, |
898 | | word32 seedSz); |
899 | | WOLFSSL_API int wc_RNG_DRBG_Stir_AddIn( |
900 | | WC_RNG* rng, const byte* seed, word32 seedSz, |
901 | | const byte *addIn, word32 addInSz); |
902 | | #define WC_RNG_HAVE_RESEED_NOW |
903 | | WOLFSSL_API int wc_RNG_DRBG_Reseed_Now(WC_RNG* rng, const byte* addIn, |
904 | | word32 addInSz); |
905 | | WOLFSSL_API int wc_RNG_DRBG_Reseed_Now_Primary(WC_RNG* rng, |
906 | | const byte* addIn, word32 addInSz); |
907 | | WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz); |
908 | | |
909 | | #ifdef WC_RNG_HAVE_RBGC |
910 | | WOLFSSL_API int wc_RNG_DRBG_GetRBGCStratum(const WC_RNG* rng); |
911 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
912 | | WOLFSSL_API int wc_RNG_DRBG_GetNextSeedRBGCStratum(const WC_RNG* rng); |
913 | | #endif |
914 | | #ifdef WC_RNG_HAVE_LOCK |
915 | | /* get a racy snapshot of the refcount, e.g. to pre-screen deallocation |
916 | | * eligibility. */ |
917 | | #define WC_RNG_RBGC_REFCOUNT(rng) WOLFSSL_ATOMIC_LOAD((rng)->RBGC_refcount) |
918 | | #endif |
919 | | #endif /* WC_RNG_HAVE_RBGC */ |
920 | | /* The reseed counter is treated as potentially sensitive internal state -- |
921 | | * only internal users are allowed. */ |
922 | | WOLFSSL_LOCAL int wc_RNG_DRBG_GetReseedCtr(const WC_RNG* rng, |
923 | | wc_drbg_reseed_ctr_t* reseedCtr); |
924 | | WOLFSSL_API int wc_RNG_DRBG_ScheduleReseed(WC_RNG* rng); |
925 | | |
926 | | #ifndef NO_SHA256 |
927 | | /* SHA-256 Hash_DRBG health test entry points. SHA-512-only builds |
928 | | * (NO_SHA256 + WOLFSSL_DRBG_SHA512) use wc_RNG_HealthTest_SHA512_ex |
929 | | * declared below. */ |
930 | | WC_FIPS_LOCAL_API int wc_RNG_HealthTest(int reseed, |
931 | | const byte* seedA, word32 seedASz, |
932 | | const byte* seedB, word32 seedBSz, |
933 | | byte* output, word32 outputSz); |
934 | | WC_FIPS_LOCAL_API int wc_RNG_HealthTest_ex(int reseed, |
935 | | const byte* nonce, word32 nonceSz, |
936 | | const byte* seedA, word32 seedASz, |
937 | | const byte* seedB, word32 seedBSz, |
938 | | byte* output, word32 outputSz, |
939 | | void* heap, int devId); |
940 | | #endif /* !NO_SHA256 */ |
941 | | #if !defined(NO_SHA256) && !defined(HAVE_SELFTEST) && \ |
942 | | (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) |
943 | | /* Extended SHA-256 Hash_DRBG health test per SP 800-90A. |
944 | | * Flexible output size, prediction resistance, personalization |
945 | | * strings, and additional input support. */ |
946 | | WC_FIPS_LOCAL_API int wc_RNG_HealthTest_SHA256_ex( |
947 | | int predResistance, |
948 | | const byte* nonce, word32 nonceSz, |
949 | | const byte* persoString, |
950 | | word32 persoStringSz, |
951 | | const byte* entropyA, |
952 | | word32 entropyASz, |
953 | | const byte* entropyB, |
954 | | word32 entropyBSz, |
955 | | const byte* entropyC, |
956 | | word32 entropyCsz, |
957 | | const byte* additionalA, |
958 | | word32 additionalASz, |
959 | | const byte* additionalB, |
960 | | word32 additionalBSz, |
961 | | const byte* additionalReseed, |
962 | | word32 additionalReseedSz, |
963 | | byte* output, word32 outputSz, |
964 | | void* heap, int devId); |
965 | | #endif /* !NO_SHA256 && !HAVE_SELFTEST && FIPS v7+ */ |
966 | | #if defined(WOLFSSL_DRBG_SHA512) && !defined(HAVE_SELFTEST) && \ |
967 | | (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) |
968 | | WC_FIPS_LOCAL_API int wc_RNG_HealthTest_SHA512(int reseed, |
969 | | const byte* seedA, word32 seedASz, |
970 | | const byte* seedB, word32 seedBSz, |
971 | | byte* output, word32 outputSz); |
972 | | WC_FIPS_LOCAL_API int wc_RNG_HealthTest_SHA512_ex(int reseed, |
973 | | const byte* nonce, word32 nonceSz, |
974 | | const byte* persoString, |
975 | | word32 persoStringSz, |
976 | | const byte* seedA, word32 seedASz, |
977 | | const byte* seedB, word32 seedBSz, |
978 | | const byte* additionalA, |
979 | | word32 additionalASz, |
980 | | const byte* additionalB, |
981 | | word32 additionalBSz, |
982 | | byte* output, word32 outputSz, |
983 | | void* heap, int devId); |
984 | | /* Extended SHA-512 Hash_DRBG health test per SP 800-90A. |
985 | | * Flexible output size, prediction resistance support. |
986 | | * predResistance=1: additionalA/B go to Reseed per SP 800-90A 9.3.1, |
987 | | * Generate gets NULL additional input. |
988 | | * predResistance=0: additionalReseed goes to Reseed, additionalA/B go |
989 | | * to Generate calls 1 and 2 respectively. */ |
990 | | WC_FIPS_LOCAL_API int wc_RNG_HealthTest_SHA512_ex2( |
991 | | int predResistance, |
992 | | const byte* nonce, word32 nonceSz, |
993 | | const byte* persoString, |
994 | | word32 persoStringSz, |
995 | | const byte* entropyA, |
996 | | word32 entropyASz, |
997 | | const byte* entropyB, |
998 | | word32 entropyBSz, |
999 | | const byte* entropyC, |
1000 | | word32 entropyCsz, |
1001 | | const byte* additionalA, |
1002 | | word32 additionalASz, |
1003 | | const byte* additionalB, |
1004 | | word32 additionalBSz, |
1005 | | const byte* additionalReseed, |
1006 | | word32 additionalReseedSz, |
1007 | | byte* output, word32 outputSz, |
1008 | | void* heap, int devId); |
1009 | | #endif /* WOLFSSL_DRBG_SHA512 && !HAVE_SELFTEST && FIPS v7+ */ |
1010 | | |
1011 | | /* Runtime DRBG disable/enable API */ |
1012 | | WOLFSSL_API int wc_Sha256Drbg_Disable(void); |
1013 | | WOLFSSL_API int wc_Sha256Drbg_Enable(void); |
1014 | | WOLFSSL_API int wc_Sha256Drbg_IsDisabled(void); |
1015 | | #ifdef WOLFSSL_DRBG_SHA512 |
1016 | | WOLFSSL_API int wc_Sha512Drbg_Disable(void); |
1017 | | WOLFSSL_API int wc_Sha512Drbg_Enable(void); |
1018 | | WOLFSSL_API int wc_Sha512Drbg_IsDisabled(void); |
1019 | | #endif |
1020 | | |
1021 | | #endif /* HAVE_HASHDRBG */ |
1022 | | |
1023 | | #ifdef WC_RNG_HAVE_RBGC |
1024 | | /* SP 800-90C RBG-chain spawn: instantiate child as a subordinate DRBG |
1025 | | * seeded from parent's generate output. The _New variants allocate the |
1026 | | * child from parent's heap; release them with ordinary wc_rng_free(). */ |
1027 | | WOLFSSL_API int wc_InitRngRBGC(WC_RNG* child, WC_RNG* parent, word32 flags); |
1028 | | WOLFSSL_API int wc_InitRngNonceRBGC(WC_RNG* child, WC_RNG* parent, |
1029 | | const byte* nonce, word32 nonceSz, |
1030 | | const byte *perso, word32 persoSz, |
1031 | | word32 flags); |
1032 | | #ifndef WC_NO_CONSTRUCTORS |
1033 | | /* Flags are per-object (WC_RNG_INIT_FLAG_*), deliberately not |
1034 | | * inherited from the parent: a child's lock policy is its own. */ |
1035 | | WOLFSSL_API int wc_InitRngRBGC_New(WC_RNG** child, WC_RNG* parent, |
1036 | | word32 flags); |
1037 | | WOLFSSL_API int wc_InitRngNonceRBGC_New(WC_RNG** child, WC_RNG* parent, |
1038 | | const byte* nonce, word32 nonceSz, |
1039 | | const byte *perso, word32 persoSz, |
1040 | | word32 flags); |
1041 | | #endif /* !WC_NO_CONSTRUCTORS */ |
1042 | | WOLFSSL_API int wc_RNG_DRBG_ReseedRBGC(WC_RNG* rng, WC_RNG* root, |
1043 | | const byte* addIn, word32 addInSz); |
1044 | | WOLFSSL_API int wc_RNG_DRBG_StirRBGC(WC_RNG* rng, |
1045 | | WC_RNG* root, |
1046 | | const byte* addIn, |
1047 | | word32 addInSz); |
1048 | | #endif /* WC_RNG_HAVE_RBGC */ |
1049 | | |
1050 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
1051 | | #define WC_DRBG_NEXT_SEED_EMPTY 0 |
1052 | | /* All sentinel states are negative; non-negative values are banked byte |
1053 | | * counts. */ |
1054 | | #define WC_DRBG_NEXT_SEED_PRODUCING (-1) |
1055 | | #define WC_DRBG_NEXT_SEED_READY (-2) |
1056 | | #define WC_DRBG_NEXT_SEED_CONSUMING (-3) |
1057 | | #define WC_DRBG_NEXT_SEED_PURGED (-4) |
1058 | | #define WC_DRBG_NEXT_SEED_TORNDOWN (-5) |
1059 | | |
1060 | | WOLFSSL_API int wc_RNG_DRBG_NextSeedGenerate(WC_RNG* rng, word32 n); |
1061 | | WOLFSSL_API int wc_RNG_DRBG_NextSeedGenerate_Primary(WC_RNG* rng, word32 n); |
1062 | | #ifdef WC_RNG_HAVE_RBGC |
1063 | | WOLFSSL_API int wc_RNG_DRBG_NextSeedGenerate_RBGC(WC_RNG* rng, |
1064 | | WC_RNG *root, |
1065 | | word32 n); |
1066 | | #endif |
1067 | | WOLFSSL_API int wc_RNG_DRBG_NextSeedCurrent(const WC_RNG* rng, |
1068 | | WC_ATOMIC_INT_ARG* n); |
1069 | | WOLFSSL_API int wc_RNG_DRBG_NextSeedNow_AddIn(WC_RNG* rng, |
1070 | | const byte* addIn, |
1071 | | word32 addInSz); |
1072 | | WOLFSSL_API int wc_RNG_DRBG_NextSeedNow(WC_RNG* rng); |
1073 | | WOLFSSL_API int wc_RNG_DRBG_NextStirStore( |
1074 | | WC_RNG* rng, const byte *addIn, word32 addInSz); |
1075 | | WOLFSSL_API int wc_RNG_DRBG_NextStirNow(WC_RNG* rng); |
1076 | | |
1077 | | #endif /* WC_RNG_HAVE_NEXT_SEED */ |
1078 | | |
1079 | | #ifdef WC_RNG_HAVE_LOCK |
1080 | | #define WC_RNG_LOCK_FREE 0 |
1081 | | #define WC_RNG_LOCK_HELD (1U<<0) |
1082 | | #define WC_RNG_LOCK_REQUIRED (1U<<1) |
1083 | | #define WC_RNG_LOCK_ENTROPY_INVALIDATED (1U<<2) |
1084 | | #define WC_RNG_LOCK_ENTROPY_RECOVERING (1U<<3) |
1085 | | /* The lease was held across a fork() by a holder absent in this process: |
1086 | | * set by the first post-fork contender (wc_RNG_lock_get() and kin report |
1087 | | * OBJECT_ORPHANED_E), sticky until the instance's owner adopts the lease |
1088 | | * (wc_FreeRng_PreLocked(), then wc_InitRng_ex2() with |
1089 | | * WC_RNG_INIT_FLAG_PRESERVE_LOCK) or a surviving holder releases or |
1090 | | * recovers it, either of which proves the lease live after all. */ |
1091 | | #define WC_RNG_LOCK_ORPHANED (1U<<4) |
1092 | | /* consumers' annotation bits start here (see e.g. rng_bank.h) */ |
1093 | | #define WC_RNG_LOCK_EXTRA_SHIFT 5U |
1094 | | |
1095 | | WOLFSSL_API int wc_RNG_lock_get(WC_RNG* rng, WC_RNG_lock_arg_t extra_bits); |
1096 | | WOLFSSL_API int wc_RNG_lock_get_conditional( |
1097 | | WC_RNG* rng, |
1098 | | WC_RNG_lock_arg_t expected_extra_bits, |
1099 | | WC_RNG_lock_arg_t want_extra_bits); |
1100 | | WOLFSSL_LOCAL int wc_RNG_lock_get_unconditional(WC_RNG* rng); |
1101 | | WOLFSSL_LOCAL void wc_RNG_lock_put_unconditional(WC_RNG* rng); |
1102 | | WOLFSSL_API int wc_RNG_lock_put(WC_RNG* rng, WC_RNG_lock_arg_t extra_bits); |
1103 | | WOLFSSL_API int wc_RNG_lock_put_conditional( |
1104 | | WC_RNG* rng, |
1105 | | WC_RNG_lock_arg_t expected_extra_bits, |
1106 | | WC_RNG_lock_arg_t want_extra_bits); |
1107 | | WOLFSSL_API int wc_RNG_lock_read(const WC_RNG* rng, |
1108 | | WC_RNG_lock_arg_t* state); |
1109 | | WOLFSSL_API int wc_RNG_lock_set_extra(WC_RNG* rng, |
1110 | | WC_RNG_lock_arg_t extra_bits); |
1111 | | WOLFSSL_API int wc_RNG_lock_add_extra(WC_RNG* rng, |
1112 | | WC_RNG_lock_arg_t extra_bits); |
1113 | | WOLFSSL_API int wc_RNG_lock_clear_extra(WC_RNG* rng, |
1114 | | WC_RNG_lock_arg_t extra_bits); |
1115 | | #endif /* WC_RNG_HAVE_LOCK */ |
1116 | | |
1117 | | WOLFSSL_API int wc_RNG_invalidate_entropy(WC_RNG* rng); |
1118 | | WOLFSSL_API int wc_RNG_entropy_needs_recovery(WC_RNG* rng); |
1119 | | |
1120 | | #ifdef WC_RNG_HAVE_ENTROPY_EPOCH |
1121 | | struct wc_RNG_entropy_epoch_atomic { |
1122 | | wolfSSL_Atomic_Uint high; |
1123 | | wolfSSL_Atomic_Uint low; |
1124 | | }; |
1125 | | #define WC_RNG_ENTROPY_EPOCH_ATOMIC_INITIALIZER { \ |
1126 | | WOLFSSL_ATOMIC_INITIALIZER(0U), \ |
1127 | | WOLFSSL_ATOMIC_INITIALIZER(1U) \ |
1128 | | } |
1129 | | #define WC_RNG_ENTROPY_EPOCH_ATOMIC_INVALID { \ |
1130 | | WOLFSSL_ATOMIC_INITIALIZER(0U), \ |
1131 | | WOLFSSL_ATOMIC_INITIALIZER(0U) \ |
1132 | | } |
1133 | 0 | #define WC_RNG_ENTROPY_EPOCH_INVALID 0 |
1134 | | static WC_INLINE wc_RNG_entropy_epoch_t wc_RNG_entropy_epoch_export( |
1135 | | struct wc_RNG_entropy_epoch_atomic *epoch) |
1136 | 530k | { |
1137 | 530k | wc_RNG_entropy_epoch_t epoch_export; |
1138 | 530k | epoch_export = WOLFSSL_ATOMIC_LOAD(epoch->low); |
1139 | | /* A tear here will always preserve the epoch mismatch via the low word, |
1140 | | * and at worst have the wrong high word. */ |
1141 | 530k | epoch_export |= |
1142 | 530k | (wc_RNG_entropy_epoch_t)WOLFSSL_ATOMIC_LOAD(epoch->high) << |
1143 | 530k | (wc_RNG_entropy_epoch_t)32; |
1144 | 530k | return epoch_export; |
1145 | 530k | } Unexecuted instantiation: module.cpp:wc_RNG_entropy_epoch_export(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: bn_ops.cpp:wc_RNG_entropy_epoch_export(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: bn_helper.cpp:wc_RNG_entropy_epoch_export(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_generic.cpp:wc_RNG_entropy_epoch_export(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_448.cpp:wc_RNG_entropy_epoch_export(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_25519.cpp:wc_RNG_entropy_epoch_export(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: aes.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: asn.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: chacha20_poly1305.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: cmac.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: coding.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: cryptocb.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: curve25519.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: curve448.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: des3.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: dh.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: ecc.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: eccsi.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: ed25519.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: ed448.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: ge_448.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: ge_operations.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: hash.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: hmac.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: kdf.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: pwdbased.c:wc_RNG_entropy_epoch_export random.c:wc_RNG_entropy_epoch_export Line | Count | Source | 1136 | 530k | { | 1137 | 530k | wc_RNG_entropy_epoch_t epoch_export; | 1138 | 530k | epoch_export = WOLFSSL_ATOMIC_LOAD(epoch->low); | 1139 | | /* A tear here will always preserve the epoch mismatch via the low word, | 1140 | | * and at worst have the wrong high word. */ | 1141 | 530k | epoch_export |= | 1142 | | (wc_RNG_entropy_epoch_t)WOLFSSL_ATOMIC_LOAD(epoch->high) << | 1143 | 530k | (wc_RNG_entropy_epoch_t)32; | 1144 | 530k | return epoch_export; | 1145 | 530k | } |
Unexecuted instantiation: rsa.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sha.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sha256.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sha3.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sha512.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sm2.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sm3.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sm4.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: sp_int.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: wc_encrypt.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: wc_mlkem.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: wc_mlkem_poly.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: wc_port.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: wolfmath.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: ssl.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: tls.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: tls13.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: internal.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: keys.c:wc_RNG_entropy_epoch_export Unexecuted instantiation: wolfio.c:wc_RNG_entropy_epoch_export |
1146 | | static WC_INLINE int wc_RNG_entropy_epoch_import( |
1147 | | wc_RNG_entropy_epoch_t old_epoch, |
1148 | | wc_RNG_entropy_epoch_t new_epoch, |
1149 | | struct wc_RNG_entropy_epoch_atomic *dest) |
1150 | 0 | { |
1151 | 0 | int ret = 1; |
1152 | 0 | WC_ATOMIC_UINT_ARG expected_low = (WC_ATOMIC_UINT_ARG)old_epoch; |
1153 | 0 | WC_ATOMIC_UINT_ARG expected_high = |
1154 | 0 | (WC_ATOMIC_UINT_ARG)(old_epoch >> |
1155 | 0 | (wc_RNG_entropy_epoch_t)32); |
1156 | 0 | if (! wolfSSL_Atomic_Uint_CompareExchange( |
1157 | 0 | &dest->low, |
1158 | 0 | &expected_low, |
1159 | 0 | (WC_ATOMIC_UINT_ARG)new_epoch)) |
1160 | 0 | ret = 0; |
1161 | 0 | if (((new_epoch >> 32) != (old_epoch >> 32)) && |
1162 | 0 | (! wolfSSL_Atomic_Uint_CompareExchange( |
1163 | 0 | &dest->high, |
1164 | 0 | &expected_high, |
1165 | 0 | (WC_ATOMIC_UINT_ARG)(new_epoch >> (wc_RNG_entropy_epoch_t)32)))) |
1166 | 0 | ret = 0; |
1167 | 0 | return ret; |
1168 | 0 | } Unexecuted instantiation: module.cpp:wc_RNG_entropy_epoch_import(unsigned long, unsigned long, wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: bn_ops.cpp:wc_RNG_entropy_epoch_import(unsigned long, unsigned long, wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: bn_helper.cpp:wc_RNG_entropy_epoch_import(unsigned long, unsigned long, wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_generic.cpp:wc_RNG_entropy_epoch_import(unsigned long, unsigned long, wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_448.cpp:wc_RNG_entropy_epoch_import(unsigned long, unsigned long, wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_25519.cpp:wc_RNG_entropy_epoch_import(unsigned long, unsigned long, wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: aes.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: asn.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: chacha20_poly1305.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: cmac.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: coding.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: cryptocb.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: curve25519.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: curve448.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: des3.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: dh.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: ecc.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: eccsi.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: ed25519.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: ed448.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: ge_448.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: ge_operations.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: hash.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: hmac.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: kdf.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: pwdbased.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: random.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: rsa.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sha.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sha256.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sha3.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sha512.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sm2.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sm3.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sm4.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: sp_int.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: wc_encrypt.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: wc_mlkem.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: wc_mlkem_poly.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: wc_port.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: wolfmath.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: ssl.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: tls.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: tls13.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: internal.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: keys.c:wc_RNG_entropy_epoch_import Unexecuted instantiation: wolfio.c:wc_RNG_entropy_epoch_import |
1169 | | static WC_INLINE wc_RNG_entropy_epoch_t wc_RNG_entropy_epoch_increment_atomic( |
1170 | | struct wc_RNG_entropy_epoch_atomic *epoch) |
1171 | 0 | { |
1172 | 0 | wc_RNG_entropy_epoch_t new_epoch = |
1173 | 0 | wolfSSL_Atomic_Uint_AddFetch(&epoch->low, 1U); |
1174 | 0 | if (new_epoch == 0) |
1175 | 0 | new_epoch += |
1176 | 0 | (wc_RNG_entropy_epoch_t)wolfSSL_Atomic_Uint_AddFetch( |
1177 | 0 | &epoch->high, 1U) << |
1178 | 0 | (wc_RNG_entropy_epoch_t)32; |
1179 | 0 | else { |
1180 | | /* Note this is a benign tear between .low and .high here -- worst |
1181 | | * case, the returned value glitches high by 2^32 - 1, resulting in |
1182 | | * an extra cycle of invalidation and recovery. */ |
1183 | 0 | new_epoch += |
1184 | | (wc_RNG_entropy_epoch_t)WOLFSSL_ATOMIC_LOAD(epoch->high) << |
1185 | 0 | (wc_RNG_entropy_epoch_t)32; |
1186 | 0 | } |
1187 | 0 | return new_epoch; |
1188 | 0 | } Unexecuted instantiation: module.cpp:wc_RNG_entropy_epoch_increment_atomic(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: bn_ops.cpp:wc_RNG_entropy_epoch_increment_atomic(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: bn_helper.cpp:wc_RNG_entropy_epoch_increment_atomic(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_generic.cpp:wc_RNG_entropy_epoch_increment_atomic(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_448.cpp:wc_RNG_entropy_epoch_increment_atomic(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: ecdsa_25519.cpp:wc_RNG_entropy_epoch_increment_atomic(wc_RNG_entropy_epoch_atomic*) Unexecuted instantiation: aes.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: asn.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: chacha20_poly1305.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: cmac.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: coding.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: cryptocb.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: curve25519.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: curve448.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: des3.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: dh.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: ecc.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: eccsi.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: ed25519.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: ed448.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: ge_448.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: ge_operations.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: hash.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: hmac.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: kdf.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: pwdbased.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: random.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: rsa.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sha.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sha256.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sha3.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sha512.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sm2.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sm3.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sm4.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: sp_int.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: wc_encrypt.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: wc_mlkem.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: wc_mlkem_poly.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: wc_port.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: wolfmath.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: ssl.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: tls.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: tls13.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: internal.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: keys.c:wc_RNG_entropy_epoch_increment_atomic Unexecuted instantiation: wolfio.c:wc_RNG_entropy_epoch_increment_atomic |
1189 | | WOLFSSL_API wc_RNG_entropy_epoch_t wc_RNG_global_invalidate_entropy(void); |
1190 | | WOLFSSL_API wc_RNG_entropy_epoch_t wc_RNG_get_global_entropy_epoch(void); |
1191 | | typedef void (*wc_RNG_entropy_epoch_extra_inv_handler_t)( |
1192 | | wc_RNG_entropy_epoch_t epoch, void *arg); |
1193 | | WOLFSSL_API int wc_RNG_entropy_epoch_extra_inv_init( |
1194 | | wc_RNG_entropy_epoch_extra_inv_handler_t handler, void *arg); |
1195 | | WOLFSSL_TEST_VIS int wc_RNG_entropy_epoch_extra_inv_reset( |
1196 | | wc_RNG_entropy_epoch_extra_inv_handler_t *handler, void **arg); |
1197 | | typedef wc_RNG_entropy_epoch_t (*wc_RNG_extra_entropy_epoch_get_handler_t)( |
1198 | | void *arg); |
1199 | | WOLFSSL_API int wc_RNG_extra_entropy_epoch_init( |
1200 | | wc_RNG_extra_entropy_epoch_get_handler_t handler, |
1201 | | void *arg); |
1202 | | WOLFSSL_TEST_VIS int wc_RNG_extra_entropy_epoch_reset( |
1203 | | wc_RNG_extra_entropy_epoch_get_handler_t *handler, |
1204 | | void **arg); |
1205 | | #endif |
1206 | | |
1207 | | #ifdef WC_RNG_HAVE_FREE_HOOK |
1208 | | /* Register a callback fired by wc_FreeRng() immediately before state |
1209 | | * destruction, e.g. to unlink the object from an external registry. |
1210 | | * One-shot: cleared before firing. A NULL free_hook unregisters. |
1211 | | * Reinitialization (wc_InitRng*() on a live object) clears any |
1212 | | * registered hook without firing it: hooks are per-lifetime. */ |
1213 | | WOLFSSL_API int wc_RNG_register_free_hook(WC_RNG* rng, |
1214 | | wc_RNG_free_hook_cb_t free_hook, |
1215 | | void *arg); |
1216 | | #endif |
1217 | | |
1218 | | #ifdef WC_RNG_HAVE_POOL |
1219 | | WOLFSSL_API int wc_RNG_Pool_Alloc(WC_RNG* rng, word32 size); |
1220 | | WOLFSSL_API int wc_RNG_Pool_Collect(WC_RNG* rng, word32 n); |
1221 | | WOLFSSL_API int wc_RNG_Pool_Collect2(WC_RNG* rng_dest, WC_RNG* rng_src, |
1222 | | word32 n); |
1223 | | WOLFSSL_API int wc_RNG_Pool_Extract(WC_RNG* rng, byte* out, word32* n); |
1224 | | WOLFSSL_API int wc_RNG_Pool_Current(const WC_RNG* rng, word32* n); |
1225 | | #endif /* WC_RNG_HAVE_POOL */ |
1226 | | |
1227 | | #ifdef WC_RNG_DEBUG_STATS |
1228 | | struct wc_rng_debug_stats_snapshot { |
1229 | | wc_rng_debug_counter_t _stats_total_bytes_requested; |
1230 | | wc_rng_debug_counter_t _stats_total_bytes_produced; |
1231 | | wc_rng_debug_counter_t _stats_total_requests; |
1232 | | wc_rng_debug_counter_t _stats_reseeds; |
1233 | | wc_rng_debug_counter_t _stats_stirs; |
1234 | | wc_rng_debug_counter_t _stats_seed_failures; |
1235 | | wc_rng_debug_counter_t _stats_locks_taken; |
1236 | | wc_rng_debug_counter_t _stats_locks_released; |
1237 | | wc_rng_debug_counter_t _stats_locks_refused; |
1238 | | #ifdef WC_RNG_HAVE_RBGC |
1239 | | wc_rng_debug_counter_t _stats_RBGC_bytes_produced; |
1240 | | wc_rng_debug_counter_t _stats_RBGC_reseeds; |
1241 | | #endif |
1242 | | #ifdef WC_RNG_HAVE_POOL |
1243 | | wc_rng_debug_counter_t _stats_pool_bytes_produced; |
1244 | | wc_rng_debug_counter_t _stats_pool_bytes_missed; |
1245 | | #endif |
1246 | | #ifdef WC_RNG_HAVE_NEXT_SEED |
1247 | | wc_rng_debug_counter_t _stats_nextseedsprimary_redeemed; |
1248 | | wc_rng_debug_counter_t _stats_nextseedsRBGC_redeemed; |
1249 | | wc_rng_debug_counter_t _stats_nextstirs_redeemed; |
1250 | | wc_rng_debug_counter_t _stats_nextseedsbanked; |
1251 | | wc_rng_debug_counter_t _stats_nextstirs_banked; |
1252 | | #endif |
1253 | | }; |
1254 | | |
1255 | | WOLFSSL_API int wc_rng_debug_stats_snap(struct wc_rng_debug_stats_snapshot *s, |
1256 | | const WC_RNG *rng); |
1257 | | WOLFSSL_API int wc_rng_debug_stats_restore( |
1258 | | const struct wc_rng_debug_stats_snapshot *s, |
1259 | | WC_RNG *rng); |
1260 | | WOLFSSL_API int wc_rng_debug_stats_sum(struct wc_rng_debug_stats_snapshot *s, |
1261 | | const WC_RNG *rng); |
1262 | | #endif /* WC_RNG_DEBUG_STATS */ |
1263 | | |
1264 | | #ifdef __cplusplus |
1265 | | } /* extern "C" */ |
1266 | | #endif |
1267 | | |
1268 | | #endif /* WOLF_CRYPT_RANDOM_H */ |
1269 | | |