Coverage Report

Created: 2026-11-12 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/wolfssl-install/include/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
    #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
        #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
    #define DRBG_SEED_LEN (440/8)
210
#endif
211
212
#ifdef WOLFSSL_DRBG_SHA512
213
    #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
        #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
    #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
        #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
        #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
#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
    #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
#define WC_DRBG_MAX_SEED_SZ    (WC_DRBG_SEED_SZ + WC_DRBG_SEED_SZ/2 + \
445
                                SEED_BLOCK_SZ)
446
447
#ifndef NO_SHA256
448
    #define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4)
449
#endif
450
#ifdef WOLFSSL_DRBG_SHA512
451
    #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
#define WC_RNG_FLAG_FAIL_FAST              (1U << 4)
525
#define WC_RNG_FLAG_NO_RBGC_PARENT         (1U << 5)
526
#define WC_RNG_FLAG_ONLY_PRIMARY_SEED      (1U << 6)
527
#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
#define WC_RNG_FLAGS_SETTABLE   (WC_RNG_FLAG_FAIL_FAST | \
532
                                 WC_RNG_FLAG_ONLY_PRIMARY_SEED | \
533
                                 WC_RNG_FLAG_NO_PRIMARY_SEED)
534
#define WC_RNG_FLAGS_CLEARABLE  (WC_RNG_FLAG_FAIL_FAST | \
535
                                 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
#define WC_RNG_INIT_FLAG_NONE            0
778
#define WC_RNG_INIT_FLAG_LOCK_REQUIRED   (1U << 0)
779
#define WC_RNG_INIT_FLAG_LOCK_INITIALLY  (1U << 1)
780
#define WC_RNG_INIT_FLAG_USE_FULL_MUTEX  (1U << 2)
781
#define WC_RNG_INIT_FLAG_UPGRADE_FROM_NEXT_SEED (1U << 3)
782
#define WC_RNG_INIT_FLAG_USE_AUTO_LOCK   (1U << 4)
783
#define WC_RNG_INIT_FLAG_NO_AUTO_LOCK    (1U << 5)
784
#define WC_RNG_INIT_FLAG_PRESERVE_LOCK   (1U << 6)
785
#define WC_RNG_INIT_FLAG_NO_PRIMARY_SEED (1U << 7)
786
#define WC_RNG_INIT_FLAG_TEST_USER_SEED  (1U << 8)
787
#define WC_RNG_INIT_FLAG_FAIL_FAST       (1U << 9)
788
#define WC_RNG_INIT_FLAG_DRBG_SHA256     (1U << 10)
789
#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
    (((e) == WC_NO_ERR_TRACE(BUSY_E)) ||            \
798
     ((e) == WC_NO_ERR_TRACE(NOT_READY_E)) ||       \
799
     ((e) == WC_NO_ERR_TRACE(NEEDS_RECOVERY_E)) ||  \
800
     ((e) == WC_NO_ERR_TRACE(RAN_BLOCK_E)) ||       \
801
     ((e) == WC_NO_ERR_TRACE(ENTROPY_RT_E)) ||      \
802
     ((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
    #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
0
    {
1137
0
        wc_RNG_entropy_epoch_t epoch_export;
1138
0
        epoch_export = WOLFSSL_ATOMIC_LOAD(epoch->low);
1139
0
        /* A tear here will always preserve the epoch mismatch via the low word,
1140
0
         * and at worst have the wrong high word. */
1141
0
        epoch_export |=
1142
0
            (wc_RNG_entropy_epoch_t)WOLFSSL_ATOMIC_LOAD(epoch->high) <<
1143
0
            (wc_RNG_entropy_epoch_t)32;
1144
0
        return epoch_export;
1145
0
    }
Unexecuted instantiation: fuzz_asn_cert.c:wc_RNG_entropy_epoch_export
Unexecuted instantiation: tpm2_asn.c:wc_RNG_entropy_epoch_export
Unexecuted instantiation: tpm2_wrap.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: fuzz_asn_cert.c:wc_RNG_entropy_epoch_import
Unexecuted instantiation: tpm2_asn.c:wc_RNG_entropy_epoch_import
Unexecuted instantiation: tpm2_wrap.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
0
            /* Note this is a benign tear between .low and .high here -- worst
1181
0
             * case, the returned value glitches high by 2^32 - 1, resulting in
1182
0
             * an extra cycle of invalidation and recovery. */
1183
0
            new_epoch +=
1184
0
                (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: fuzz_asn_cert.c:wc_RNG_entropy_epoch_increment_atomic
Unexecuted instantiation: tpm2_asn.c:wc_RNG_entropy_epoch_increment_atomic
Unexecuted instantiation: tpm2_wrap.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