Coverage Report

Created: 2025-07-23 06:59

/src/wolfssl-openssl-api/wolfcrypt/src/random.c
Line
Count
Source (jump to first uncovered line)
1
/* random.c
2
 *
3
 * Copyright (C) 2006-2025 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
24
DESCRIPTION
25
This library contains implementation for the random number generator.
26
27
*/
28
29
/* Possible defines:
30
 *   ENTROPY_NUM_UPDATE                                         default: 18
31
 *     Number of updates to perform. A hash is created and memory accessed
32
 *     based on the hash values in each update of a sample.
33
 *     More updates will result in better entropy quality but longer sample
34
 *     times.
35
 *   ENTROPY_NUM_UPDATES_BITS                                   default: 5
36
 *     Number of bits needed to represent ENTROPY_NUM_UPDATE.
37
 *      = upper(log2(ENTROPY_NUM_UPDATE))
38
 *   ENTROPY_NUM_WORDS_BITS                                     default: 14
39
 *     State has 2^ENTROPY_NUMN_WORDS_BITS entries.             Range: 8-30
40
 *     The value should be based on the cache sizes.
41
 *     Use a value that is at least as large as the L1 cache if possible.
42
 *     The higher the value, the more likely there will be cache misses and
43
 *     better the entropy quality.
44
 *     A larger value will use more static memory.
45
 */
46
47
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
48
49
/* on HPUX 11 you may need to install /dev/random see
50
   http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
51
52
*/
53
#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR >= 5
54
    #include <esp_random.h>
55
#endif
56
57
#if defined(HAVE_FIPS) && \
58
    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
59
60
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
61
    #define FIPS_NO_WRAPPERS
62
63
    #ifdef USE_WINDOWS_API
64
        #pragma code_seg(".fipsA$i")
65
        #pragma const_seg(".fipsB$i")
66
    #endif
67
#endif
68
69
70
#include <wolfssl/wolfcrypt/random.h>
71
#include <wolfssl/wolfcrypt/cpuid.h>
72
#ifdef HAVE_ENTROPY_MEMUSE
73
#include <wolfssl/wolfcrypt/sha3.h>
74
#if defined(__APPLE__) || defined(__MACH__)
75
#include <mach/mach_time.h>
76
#endif
77
#endif
78
79
80
#ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */
81
82
#include <wolfssl/wolfcrypt/sha256.h>
83
84
#ifdef WOLF_CRYPTO_CB
85
    #include <wolfssl/wolfcrypt/cryptocb.h>
86
#endif
87
88
#ifdef NO_INLINE
89
    #include <wolfssl/wolfcrypt/misc.h>
90
#else
91
    #define WOLFSSL_MISC_INCLUDED
92
    #include <wolfcrypt/src/misc.c>
93
#endif
94
95
#if defined(WOLFSSL_SGX)
96
    #include <sgx_trts.h>
97
#elif defined(USE_WINDOWS_API)
98
    #ifndef _WIN32_WINNT
99
        #define _WIN32_WINNT 0x0400
100
    #endif
101
    #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */
102
    #include <windows.h>
103
    #include <wincrypt.h>
104
    #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */
105
#elif defined(HAVE_WNR)
106
    #include <wnr.h>
107
    wolfSSL_Mutex wnr_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wnr_mutex);    /* global netRandom mutex */
108
    int wnr_timeout     = 0;    /* entropy timeout, milliseconds */
109
    #ifndef WOLFSSL_MUTEX_INITIALIZER
110
    int wnr_mutex_inited = 0;   /* flag for mutex init */
111
    #endif
112
    int wnr_inited = 0;    /* flag for whether wc_InitNetRandom() has been called */
113
    wnr_context*  wnr_ctx;      /* global netRandom context */
114
#elif defined(FREESCALE_KSDK_2_0_TRNG)
115
    #include "fsl_trng.h"
116
#elif defined(FREESCALE_KSDK_2_0_RNGA)
117
    #include "fsl_rnga.h"
118
#elif defined(WOLFSSL_WICED)
119
    #include "wiced_crypto.h"
120
#elif defined(WOLFSSL_NETBURNER)
121
    #include <predef.h>
122
    #include <basictypes.h>
123
    #include <random.h>
124
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
125
    #include "wolfssl/wolfcrypt/port/xilinx/xil-versal-trng.h"
126
#elif defined(WOLFSSL_RPIPICO)
127
    #include "wolfssl/wolfcrypt/port/rpi_pico/pico.h"
128
#elif defined(NO_DEV_RANDOM)
129
#elif defined(CUSTOM_RAND_GENERATE)
130
#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
131
#elif defined(CUSTOM_RAND_GENERATE_SEED)
132
#elif defined(WOLFSSL_GENSEED_FORTEST)
133
#elif defined(WOLFSSL_MDK_ARM)
134
#elif defined(WOLFSSL_IAR_ARM)
135
#elif defined(WOLFSSL_ROWLEY_ARM)
136
#elif defined(WOLFSSL_EMBOS)
137
#elif defined(WOLFSSL_DEOS)
138
#elif defined(MICRIUM)
139
#elif defined(WOLFSSL_NUCLEUS)
140
#elif defined(WOLFSSL_PB)
141
#elif defined(WOLFSSL_ZEPHYR)
142
#elif defined(WOLFSSL_TELIT_M2MB)
143
#elif defined(WOLFSSL_RENESAS_TSIP)
144
    /* for wc_tsip_GenerateRandBlock */
145
    #include "wolfssl/wolfcrypt/port/Renesas/renesas_tsip_internal.h"
146
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG)
147
#elif defined(WOLFSSL_IMXRT1170_CAAM)
148
#elif defined(CY_USING_HAL) && defined(COMPONENT_WOLFSSL)
149
    #include "cyhal_trng.h" /* Infineon/Cypress HAL RNG implementation */
150
#elif defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
151
    #include "wolfssl/wolfcrypt/port/maxim/max3266x.h"
152
#else
153
    #if defined(WOLFSSL_GETRANDOM) || defined(HAVE_GETRANDOM)
154
        #include <errno.h>
155
        #include <sys/random.h>
156
    #endif
157
    /* include headers that may be needed to get good seed */
158
    #include <fcntl.h>
159
    #ifndef EBSNET
160
        #include <unistd.h>
161
    #endif
162
#endif
163
164
#if defined(WOLFSSL_SILABS_SE_ACCEL)
165
#include <wolfssl/wolfcrypt/port/silabs/silabs_random.h>
166
#endif
167
168
#if defined(WOLFSSL_IOTSAFE) && defined(HAVE_IOTSAFE_HWRNG)
169
#include <wolfssl/wolfcrypt/port/iotsafe/iotsafe.h>
170
#endif
171
172
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_RNG)
173
#include <wolfssl/wolfcrypt/port/psa/psa.h>
174
#endif
175
176
#if FIPS_VERSION3_GE(6,0,0)
177
    const unsigned int wolfCrypt_FIPS_drbg_ro_sanity[2] =
178
                                                     { 0x1a2b3c4d, 0x00000011 };
179
    int wolfCrypt_FIPS_DRBG_sanity(void)
180
    {
181
        return 0;
182
    }
183
#endif
184
185
#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED) || \
186
    defined(HAVE_AMD_RDSEED)
187
    static word32 intel_flags = 0;
188
    static void wc_InitRng_IntelRD(void)
189
    {
190
        intel_flags = cpuid_get_flags();
191
    }
192
    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_AMD_RDSEED)
193
    static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz);
194
    #endif
195
    #ifdef HAVE_INTEL_RDRAND
196
    static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);
197
    #endif
198
199
#ifdef USE_WINDOWS_API
200
    #define USE_INTEL_INTRINSICS
201
#elif !defined __GNUC__ || defined __clang__ || __GNUC__ > 4
202
    #define USE_INTEL_INTRINSICS
203
#else
204
    #undef USE_INTEL_INTRINSICS
205
#endif
206
207
#ifdef USE_INTEL_INTRINSICS
208
    #include <immintrin.h>
209
    /* Before clang 7 or GCC 9, immintrin.h did not define _rdseed64_step() */
210
    #ifndef HAVE_INTEL_RDSEED
211
    #elif defined __clang__ && __clang_major__ > 6
212
    #elif !defined __GNUC__
213
    #elif __GNUC__ > 8
214
    #else
215
        #ifndef __clang__
216
            #pragma GCC push_options
217
            #pragma GCC target("rdseed")
218
        #else
219
            #define __RDSEED__
220
        #endif
221
        #include <x86intrin.h>
222
        #ifndef __clang__
223
            #pragma GCC pop_options
224
        #endif
225
    #endif
226
#endif /* USE_WINDOWS_API */
227
#endif
228
229
/* Start NIST DRBG code */
230
#ifdef HAVE_HASHDRBG
231
232
10.8M
#define OUTPUT_BLOCK_LEN  (WC_SHA256_DIGEST_SIZE)
233
#define MAX_REQUEST_LEN   (0x10000)
234
235
236
/* The security strength for the RNG is the target number of bits of
237
 * entropy you are looking for in a seed. */
238
#ifndef RNG_SECURITY_STRENGTH
239
    /* SHA-256 requires a minimum of 256-bits of entropy. */
240
330k
    #define RNG_SECURITY_STRENGTH (256)
241
#endif
242
243
#ifndef ENTROPY_SCALE_FACTOR
244
    /* The entropy scale factor should be the whole number inverse of the
245
     * minimum bits of entropy per bit of NDRNG output. */
246
    #if defined(HAVE_ENTROPY_MEMUSE)
247
        /* Full strength, conditioned entropy is requested of MemUse Entropy. */
248
        #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
249
            (HAVE_FIPS_VERSION >= 2)
250
            #define ENTROPY_SCALE_FACTOR (4)
251
        #else
252
            #define ENTROPY_SCALE_FACTOR (1)
253
        #endif
254
    #elif defined(HAVE_AMD_RDSEED)
255
        /* This will yield a SEED_SZ of 16kb. Since nonceSz will be 0,
256
         * we'll add an additional 8kb on top.
257
         *
258
         * See "AMD RNG ESV Public Use Document".  Version 0.7 of October 24,
259
         * 2024 specifies 0.656 to 1.312 bits of entropy per 128 bit block of
260
         * RDSEED output, depending on CPU family.
261
         */
262
        #define ENTROPY_SCALE_FACTOR  (512)
263
    #elif defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
264
        /* The value of 2 applies to Intel's RDSEED which provides about
265
         * 0.5 bits minimum of entropy per bit. The value of 4 gives a
266
         * conservative margin for FIPS. */
267
        #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
268
            (HAVE_FIPS_VERSION >= 2)
269
            #define ENTROPY_SCALE_FACTOR (2*4)
270
        #else
271
            /* Not FIPS, but Intel RDSEED, only double. */
272
            #define ENTROPY_SCALE_FACTOR (2)
273
        #endif
274
    #elif defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
275
        (HAVE_FIPS_VERSION >= 2)
276
        /* If doing a FIPS build without a specific scale factor, default
277
         * to 4. This will give 1024 bits of entropy. More is better, but
278
         * more is also slower. */
279
        #define ENTROPY_SCALE_FACTOR (4)
280
    #else
281
        /* Setting the default to 1. */
282
330k
        #define ENTROPY_SCALE_FACTOR (1)
283
    #endif
284
#endif
285
286
#ifndef SEED_BLOCK_SZ
287
    /* The seed block size, is the size of the output of the underlying NDRNG.
288
     * This value is used for testing the output of the NDRNG. */
289
    #if defined(HAVE_AMD_RDSEED)
290
        /* AMD's RDSEED instruction works in 128-bit blocks read 64-bits
291
        * at a time. */
292
        #define SEED_BLOCK_SZ (sizeof(word64)*2)
293
    #elif defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
294
        /* RDSEED outputs in blocks of 64-bits. */
295
        #define SEED_BLOCK_SZ sizeof(word64)
296
    #else
297
        /* Setting the default to 4. */
298
4.78M
        #define SEED_BLOCK_SZ 4
299
    #endif
300
#endif
301
302
330k
#define SEED_SZ        (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8)
303
304
/* The maximum seed size will be the seed size plus a seed block for the
305
 * test, and an additional half of the seed size. This additional half
306
 * is in case the user does not supply a nonce. A nonce will be obtained
307
 * from the NDRNG. */
308
110k
#define MAX_SEED_SZ    (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ)
309
310
311
#ifdef WC_RNG_SEED_CB
312
313
#ifndef HAVE_FIPS
314
static wc_RngSeed_Cb seedCb = wc_GenerateSeed;
315
#else
316
static wc_RngSeed_Cb seedCb = NULL;
317
#endif
318
319
int wc_SetSeed_Cb(wc_RngSeed_Cb cb)
320
{
321
    seedCb = cb;
322
    return 0;
323
}
324
325
#endif
326
327
328
/* Internal return codes */
329
5.62M
#define DRBG_SUCCESS      0
330
1.62M
#define DRBG_FAILURE      1
331
255k
#define DRBG_NEED_RESEED  2
332
21.0k
#define DRBG_CONT_FAILURE 3
333
#define DRBG_NO_SEED_CB   4
334
335
/* RNG health states */
336
221k
#define DRBG_NOT_INIT     0
337
358k
#define DRBG_OK           1
338
6.63k
#define DRBG_FAILED       2
339
7.20k
#define DRBG_CONT_FAILED  3
340
341
516k
#define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4)
342
343
/* Verify max gen block len */
344
#if RNG_MAX_BLOCK_LEN > MAX_REQUEST_LEN
345
    #error RNG_MAX_BLOCK_LEN is larger than NIST DBRG max request length
346
#endif
347
348
enum {
349
    drbgInitC     = 0,
350
    drbgReseed    = 1,
351
    drbgGenerateW = 2,
352
    drbgGenerateH = 3,
353
    drbgInitV     = 4
354
};
355
356
typedef struct DRBG_internal DRBG_internal;
357
358
static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId);
359
360
/* Hash Derivation Function */
361
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
362
static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type,
363
                                                  const byte* inA, word32 inASz,
364
                                                  const byte* inB, word32 inBSz)
365
618k
{
366
618k
    int ret = DRBG_FAILURE;
367
618k
    byte ctr;
368
618k
    word32 i;
369
618k
    word32 len;
370
618k
    word32 bits = (outSz * 8); /* reverse byte order */
371
#ifdef WOLFSSL_SMALL_STACK_CACHE
372
    wc_Sha256* sha = &drbg->sha256;
373
#else
374
618k
    wc_Sha256 sha[1];
375
618k
#endif
376
618k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
377
618k
    byte* digest;
378
#else
379
    byte digest[WC_SHA256_DIGEST_SIZE];
380
#endif
381
382
618k
    if (drbg == NULL) {
383
0
        return DRBG_FAILURE;
384
0
    }
385
386
618k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
387
618k
    digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap,
388
618k
        DYNAMIC_TYPE_DIGEST);
389
618k
    if (digest == NULL)
390
89
        return DRBG_FAILURE;
391
618k
#endif
392
393
618k
#ifdef LITTLE_ENDIAN_ORDER
394
618k
    bits = ByteReverseWord32(bits);
395
618k
#endif
396
618k
    len = (outSz / OUTPUT_BLOCK_LEN)
397
618k
        + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
398
399
618k
    ctr = 1;
400
1.85M
    for (i = 0; i < len; i++) {
401
1.23M
#ifndef WOLFSSL_SMALL_STACK_CACHE
402
1.23M
    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
403
1.23M
        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
404
    #else
405
        ret = wc_InitSha256(sha);
406
    #endif
407
1.23M
        if (ret != 0)
408
0
            break;
409
1.23M
#endif
410
1.23M
        ret = wc_Sha256Update(sha, &ctr, sizeof(ctr));
411
1.23M
        if (ret == 0) {
412
1.23M
            ctr++;
413
1.23M
            ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits));
414
1.23M
        }
415
416
1.23M
        if (ret == 0) {
417
            /* churning V is the only string that doesn't have the type added */
418
1.23M
            if (type != drbgInitV)
419
618k
                ret = wc_Sha256Update(sha, &type, sizeof(type));
420
1.23M
        }
421
1.23M
        if (ret == 0)
422
1.23M
            ret = wc_Sha256Update(sha, inA, inASz);
423
1.23M
        if (ret == 0) {
424
1.23M
            if (inB != NULL && inBSz > 0)
425
205k
                ret = wc_Sha256Update(sha, inB, inBSz);
426
1.23M
        }
427
1.23M
        if (ret == 0)
428
1.23M
            ret = wc_Sha256Final(sha, digest);
429
430
1.23M
#ifndef WOLFSSL_SMALL_STACK_CACHE
431
1.23M
        wc_Sha256Free(sha);
432
1.23M
#endif
433
1.23M
        if (ret == 0) {
434
1.21M
            if (outSz > OUTPUT_BLOCK_LEN) {
435
618k
                XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
436
618k
                outSz -= OUTPUT_BLOCK_LEN;
437
618k
                out += OUTPUT_BLOCK_LEN;
438
618k
            }
439
601k
            else {
440
601k
                XMEMCPY(out, digest, outSz);
441
601k
            }
442
1.21M
        }
443
1.23M
    }
444
445
618k
    ForceZero(digest, WC_SHA256_DIGEST_SIZE);
446
447
618k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
448
618k
    XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST);
449
618k
#endif
450
451
618k
    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
452
618k
}
453
454
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
455
static int Hash_DRBG_Reseed(DRBG_internal* drbg, const byte* seed, word32 seedSz)
456
0
{
457
0
    int ret;
458
0
#ifdef WOLFSSL_SMALL_STACK
459
0
    byte* newV;
460
#else
461
    byte newV[DRBG_SEED_LEN];
462
#endif
463
464
0
    if (drbg == NULL) {
465
0
        return DRBG_FAILURE;
466
0
    }
467
468
0
#ifdef WOLFSSL_SMALL_STACK
469
0
    newV = (byte*)XMALLOC(DRBG_SEED_LEN, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER);
470
0
    if (newV == NULL) {
471
0
        return MEMORY_E;
472
0
    }
473
0
#endif
474
0
    XMEMSET(newV, 0, DRBG_SEED_LEN);
475
476
0
    ret = Hash_df(drbg, newV, DRBG_SEED_LEN, drbgReseed,
477
0
                drbg->V, sizeof(drbg->V), seed, seedSz);
478
0
    if (ret == DRBG_SUCCESS) {
479
0
        XMEMCPY(drbg->V, newV, sizeof(drbg->V));
480
0
        ForceZero(newV, DRBG_SEED_LEN);
481
482
0
        ret = Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
483
0
                                    sizeof(drbg->V), NULL, 0);
484
0
    }
485
0
    if (ret == DRBG_SUCCESS) {
486
0
        drbg->reseedCtr = 1;
487
0
    }
488
489
0
#ifdef WOLFSSL_SMALL_STACK
490
0
    XFREE(newV, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER);
491
0
#endif
492
0
    return ret;
493
0
}
494
495
/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
496
int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz)
497
0
{
498
0
    if (rng == NULL || seed == NULL) {
499
0
        return BAD_FUNC_ARG;
500
0
    }
501
502
0
    if (rng->drbg == NULL) {
503
    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
504
        if (IS_INTEL_RDRAND(intel_flags)) {
505
            /* using RDRAND not DRBG, so return success */
506
            return 0;
507
        }
508
        return BAD_FUNC_ARG;
509
    #endif
510
0
    }
511
512
0
    return Hash_DRBG_Reseed((DRBG_internal *)rng->drbg, seed, seedSz);
513
0
}
514
515
static WC_INLINE void array_add_one(byte* data, word32 dataSz)
516
2.03M
{
517
2.03M
    int i;
518
2.03M
    for (i = (int)dataSz - 1; i >= 0; i--) {
519
2.03M
        data[i]++;
520
2.03M
        if (data[i] != 0) break;
521
2.03M
    }
522
2.03M
}
523
524
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
525
static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V)
526
664k
{
527
664k
    int ret = DRBG_FAILURE;
528
664k
#ifdef WOLFSSL_SMALL_STACK
529
664k
    byte* data;
530
664k
    byte* digest;
531
#else
532
    byte data[DRBG_SEED_LEN];
533
    byte digest[WC_SHA256_DIGEST_SIZE];
534
#endif
535
664k
    word32 i;
536
664k
    word32 len;
537
#ifdef WOLFSSL_SMALL_STACK_CACHE
538
    wc_Sha256* sha = &drbg->sha256;
539
#else
540
664k
    wc_Sha256 sha[1];
541
664k
#endif
542
543
664k
    if (drbg == NULL) {
544
0
        return DRBG_FAILURE;
545
0
    }
546
547
664k
#ifdef WOLFSSL_SMALL_STACK
548
664k
    data = (byte*)XMALLOC(DRBG_SEED_LEN, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER);
549
664k
    digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap,
550
664k
        DYNAMIC_TYPE_DIGEST);
551
664k
    if (data == NULL || digest == NULL) {
552
2.15k
        XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST);
553
2.15k
        XFREE(data, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER);
554
2.15k
        return DRBG_FAILURE;
555
2.15k
    }
556
661k
#endif
557
558
    /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
559
     * the continuous test. */
560
561
661k
    if (outSz == 0) {
562
0
        outSz = 1;
563
0
    }
564
565
661k
    len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
566
567
661k
    XMEMCPY(data, V, DRBG_SEED_LEN);
568
2.73M
    for (i = 0; i < len; i++) {
569
2.06M
#ifndef WOLFSSL_SMALL_STACK_CACHE
570
2.06M
    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
571
2.06M
        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
572
    #else
573
        ret = wc_InitSha256(sha);
574
    #endif
575
2.06M
        if (ret == 0)
576
2.06M
#endif
577
2.06M
            ret = wc_Sha256Update(sha, data, DRBG_SEED_LEN);
578
2.06M
        if (ret == 0)
579
2.06M
            ret = wc_Sha256Final(sha, digest);
580
2.06M
#ifndef WOLFSSL_SMALL_STACK_CACHE
581
2.06M
        wc_Sha256Free(sha);
582
2.06M
#endif
583
584
2.06M
        if (ret == 0) {
585
2.06M
            if (out != NULL && outSz != 0) {
586
2.06M
                if (outSz >= OUTPUT_BLOCK_LEN) {
587
1.88M
                    XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
588
1.88M
                    outSz -= OUTPUT_BLOCK_LEN;
589
1.88M
                    out += OUTPUT_BLOCK_LEN;
590
1.88M
                    array_add_one(data, DRBG_SEED_LEN);
591
1.88M
                }
592
181k
                else {
593
181k
                    XMEMCPY(out, digest, outSz);
594
181k
                    outSz = 0;
595
181k
                }
596
2.06M
            }
597
2.06M
        }
598
739
        else {
599
            /* wc_Sha256Update or wc_Sha256Final returned error */
600
739
            break;
601
739
        }
602
2.06M
    }
603
661k
    ForceZero(data, DRBG_SEED_LEN);
604
605
661k
#ifdef WOLFSSL_SMALL_STACK
606
661k
    XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST);
607
661k
    XFREE(data, drbg->heap, DYNAMIC_TYPE_TMP_BUFFER);
608
661k
#endif
609
610
661k
    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
611
664k
}
612
613
static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
614
2.35M
{
615
2.35M
    if (dLen > 0 && sLen > 0 && dLen >= sLen) {
616
2.35M
        int sIdx, dIdx;
617
2.35M
        word16 carry = 0;
618
619
2.35M
        dIdx = (int)dLen - 1;
620
76.8M
        for (sIdx = (int)sLen - 1; sIdx >= 0; sIdx--) {
621
74.4M
            carry = (word16)(carry + d[dIdx] + s[sIdx]);
622
74.4M
            d[dIdx] = (byte)carry;
623
74.4M
            carry >>= 8;
624
74.4M
            dIdx--;
625
74.4M
        }
626
627
57.2M
        for (; dIdx >= 0; dIdx--) {
628
54.8M
            carry = (word16)(carry + d[dIdx]);
629
54.8M
            d[dIdx] = (byte)carry;
630
54.8M
            carry >>= 8;
631
54.8M
        }
632
2.35M
    }
633
2.35M
}
634
635
/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
636
static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
637
667k
{
638
667k
    int ret;
639
#ifdef WOLFSSL_SMALL_STACK_CACHE
640
    wc_Sha256* sha = &drbg->sha256;
641
#else
642
667k
    wc_Sha256 sha[1];
643
667k
#endif
644
667k
    byte type;
645
667k
#ifdef WORD64_AVAILABLE
646
667k
    word64 reseedCtr;
647
#else
648
    word32 reseedCtr;
649
#endif
650
651
667k
    if (drbg == NULL) {
652
0
        return DRBG_FAILURE;
653
0
    }
654
655
667k
    if (drbg->reseedCtr >= WC_RESEED_INTERVAL) {
656
    #if defined(DEBUG_WOLFSSL) || defined(DEBUG_DRBG_RESEEDS)
657
        printf("DRBG reseed triggered, reseedCtr == %lu",
658
               (unsigned long)drbg->reseedCtr);
659
    #endif
660
0
        return DRBG_NEED_RESEED;
661
0
    }
662
667k
    else {
663
667k
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
664
667k
        byte* digest = (byte*)XMALLOC(WC_SHA256_DIGEST_SIZE, drbg->heap,
665
667k
            DYNAMIC_TYPE_DIGEST);
666
667k
        if (digest == NULL)
667
3.31k
            return DRBG_FAILURE;
668
    #else
669
        byte digest[WC_SHA256_DIGEST_SIZE];
670
    #endif
671
672
664k
        type = drbgGenerateH;
673
664k
        reseedCtr = drbg->reseedCtr;
674
675
664k
        ret = Hash_gen(drbg, out, outSz, drbg->V);
676
664k
        if (ret == DRBG_SUCCESS) {
677
661k
#ifndef WOLFSSL_SMALL_STACK_CACHE
678
661k
        #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
679
661k
            ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
680
        #else
681
            ret = wc_InitSha256(sha);
682
        #endif
683
661k
            if (ret == 0)
684
661k
#endif
685
661k
                ret = wc_Sha256Update(sha, &type, sizeof(type));
686
661k
            if (ret == 0)
687
661k
                ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));
688
661k
            if (ret == 0)
689
661k
                ret = wc_Sha256Final(sha, digest);
690
691
661k
#ifndef WOLFSSL_SMALL_STACK_CACHE
692
661k
            wc_Sha256Free(sha);
693
661k
#endif
694
695
661k
            if (ret == 0) {
696
660k
                array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE);
697
660k
                array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
698
660k
            #ifdef LITTLE_ENDIAN_ORDER
699
660k
                #ifdef WORD64_AVAILABLE
700
660k
                reseedCtr = ByteReverseWord64(reseedCtr);
701
                #else
702
                reseedCtr = ByteReverseWord32(reseedCtr);
703
                #endif
704
660k
            #endif
705
660k
                array_add(drbg->V, sizeof(drbg->V),
706
660k
                                          (byte*)&reseedCtr, sizeof(reseedCtr));
707
660k
                ret = DRBG_SUCCESS;
708
660k
            }
709
661k
            drbg->reseedCtr++;
710
661k
        }
711
664k
        ForceZero(digest, WC_SHA256_DIGEST_SIZE);
712
664k
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_LINUXKM)
713
664k
        XFREE(digest, drbg->heap, DYNAMIC_TYPE_DIGEST);
714
664k
    #endif
715
664k
    }
716
717
664k
    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
718
667k
}
719
720
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
721
static int Hash_DRBG_Instantiate(DRBG_internal* drbg, const byte* seed, word32 seedSz,
722
                                             const byte* nonce, word32 nonceSz,
723
                                             void* heap, int devId)
724
335k
{
725
335k
    int ret = DRBG_FAILURE;
726
727
335k
    XMEMSET(drbg, 0, sizeof(DRBG_internal));
728
335k
    drbg->heap = heap;
729
335k
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
730
335k
    drbg->devId = devId;
731
#else
732
    (void)devId;
733
#endif
734
735
#ifdef WOLFSSL_SMALL_STACK_CACHE
736
    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
737
        ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId);
738
    #else
739
        ret = wc_InitSha256(&drbg->sha256);
740
    #endif
741
    if (ret != 0)
742
        return ret;
743
#endif
744
745
335k
    if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
746
335k
                                              nonce, nonceSz) == DRBG_SUCCESS &&
747
335k
        Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
748
335k
                                    sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
749
750
335k
        drbg->reseedCtr = 1;
751
335k
        ret = DRBG_SUCCESS;
752
335k
    }
753
754
335k
    return ret;
755
335k
}
756
757
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
758
static int Hash_DRBG_Uninstantiate(DRBG_internal* drbg)
759
335k
{
760
335k
    word32 i;
761
335k
    int    compareSum = 0;
762
335k
    byte*  compareDrbg = (byte*)drbg;
763
764
#ifdef WOLFSSL_SMALL_STACK_CACHE
765
    wc_Sha256Free(&drbg->sha256);
766
#endif
767
768
335k
    ForceZero(drbg, sizeof(DRBG_internal));
769
770
45.7M
    for (i = 0; i < sizeof(DRBG_internal); i++) {
771
45.4M
        compareSum |= compareDrbg[i] ^ 0;
772
45.4M
    }
773
774
335k
    return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
775
335k
}
776
777
778
int wc_RNG_TestSeed(const byte* seed, word32 seedSz)
779
111k
{
780
111k
    int ret = 0;
781
782
    /* Check the seed for duplicate words. */
783
111k
    word32 seedIdx = 0;
784
111k
    word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ);
785
786
1.45M
    while (seedIdx < seedSz - SEED_BLOCK_SZ) {
787
1.34M
        if (ConstantCompare(seed + seedIdx,
788
1.34M
                            seed + seedIdx + scratchSz,
789
1.34M
                            (int)scratchSz) == 0) {
790
791
0
            ret = DRBG_CONT_FAILURE;
792
0
        }
793
1.34M
        seedIdx += SEED_BLOCK_SZ;
794
1.34M
        scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx));
795
1.34M
    }
796
797
111k
    return ret;
798
111k
}
799
#endif /* HAVE_HASHDRBG */
800
/* End NIST DRBG Code */
801
802
#ifdef HAVE_ENTROPY_MEMUSE
803
/* Define ENTROPY_MEMUSE_THREAD to force use of counter in a new thread.
804
 * Only do this when high resolution timer not otherwise available.
805
 */
806
807
/* Number of bytes that will hold the maximum entropy bits. */
808
#define MAX_ENTROPY_BYTES    (MAX_ENTROPY_BITS / 8)
809
/* Number of bits stored for one sample. */
810
#define ENTROPY_BITS_USED    8
811
812
/* Minimum entropy from a sample. */
813
#define ENTROPY_MIN          1
814
/* Number of extra samples to ensure full entropy. */
815
#define ENTROPY_EXTRA        64
816
/* Maximum number of bytes to sample to produce max entropy. */
817
#define MAX_NOISE_CNT        (MAX_ENTROPY_BITS * 8 + ENTROPY_EXTRA)
818
819
/* MemUse entropy global state initialized. */
820
static int entropy_memuse_initialized = 0;
821
/* Global SHA-3 object used for conditioning entropy and creating noise. */
822
static wc_Sha3 entropyHash;
823
/* Reset the health tests. */
824
static void Entropy_HealthTest_Reset(void);
825
826
#ifdef CUSTOM_ENTROPY_TIMEHIRES
827
static WC_INLINE word64 Entropy_TimeHiRes(void)
828
{
829
    return CUSTOM_ENTROPY_TIMEHIRES();
830
}
831
#elif !defined(ENTROPY_MEMUSE_THREAD) && \
832
      (defined(__x86_64__) || defined(__i386__))
833
/* Get the high resolution time counter.
834
 *
835
 * @return  64-bit count of CPU cycles.
836
 */
837
static WC_INLINE word64 Entropy_TimeHiRes(void)
838
{
839
    unsigned int lo_c, hi_c;
840
    __asm__ __volatile__ (
841
        "rdtsc"
842
            : "=a"(lo_c), "=d"(hi_c)   /* out */
843
            : "a"(0)                   /* in */
844
            : "%ebx", "%ecx");         /* clobber */
845
    return ((word64)lo_c) | (((word64)hi_c) << 32);
846
}
847
#elif !defined(ENTROPY_MEMUSE_THREAD) && \
848
      (defined(__APPLE__) || defined(__MACH__))
849
/* Get the high resolution time counter.
850
 *
851
 * @return  64-bit time in nanoseconds.
852
 */
853
static WC_INLINE word64 Entropy_TimeHiRes(void)
854
{
855
    return clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW);
856
}
857
#elif !defined(ENTROPY_MEMUSE_THREAD) && defined(__aarch64__)
858
/* Get the high resolution time counter.
859
 *
860
 * @return  64-bit timer count.
861
 */
862
static WC_INLINE word64 Entropy_TimeHiRes(void)
863
{
864
    word64 cnt;
865
    __asm__ __volatile__ (
866
        "mrs %[cnt], cntvct_el0"
867
        : [cnt] "=r"(cnt)
868
        :
869
        :
870
    );
871
    return cnt;
872
}
873
#elif !defined(ENTROPY_MEMUSE_THREAD) && defined(__MICROBLAZE__)
874
875
#define LPD_SCNTR_BASE_ADDRESS 0xFF250000
876
877
/* Get the high resolution time counter.
878
 * Collect ticks from LPD_SCNTR
879
 * @return  64-bit tick count.
880
 */
881
static WC_INLINE word64 Entropy_TimeHiRes(void)
882
{
883
    word64 cnt;
884
    word32 *ptr;
885
886
    ptr = (word32*)LPD_SCNTR_BASE_ADDRESS;
887
    cnt = *(ptr+1);
888
    cnt = cnt << 32;
889
    cnt |= *ptr;
890
891
    return cnt;
892
}
893
#elif !defined(ENTROPY_MEMUSE_THREAD) && (_POSIX_C_SOURCE >= 199309L)
894
/* Get the high resolution time counter.
895
 *
896
 * @return  64-bit time that is the nanoseconds of current time.
897
 */
898
static WC_INLINE word64 Entropy_TimeHiRes(void)
899
{
900
    struct timespec now;
901
902
    clock_gettime(CLOCK_REALTIME, &now);
903
904
    return now.tv_nsec;
905
}
906
#elif defined(_WIN32) /* USE_WINDOWS_API */
907
/* Get the high resolution time counter.
908
 *
909
 * @return  64-bit timer
910
 */
911
static WC_INLINE word64 Entropy_TimeHiRes(void)
912
{
913
    LARGE_INTEGER count;
914
    QueryPerformanceCounter(&count);
915
    return (word64)(count.QuadPart);
916
}
917
#elif defined(WOLFSSL_THREAD_NO_JOIN)
918
919
/* Start and stop thread that counts as a proxy for time counter. */
920
#define ENTROPY_MEMUSE_THREADED
921
922
/* Data for entropy thread. */
923
typedef struct ENTROPY_THREAD_DATA {
924
    /* Current counter - proxy for time. */
925
    word64 counter;
926
    /* Whether to stop thread. */
927
    int stop;
928
} ENTROPY_THREAD_DATA;
929
930
/* Track whether entropy thread has been started already. */
931
static int entropy_thread_started = 0;
932
/* Data for thread to update/observer. */
933
static volatile ENTROPY_THREAD_DATA entropy_thread_data = { 0, 0 };
934
935
/* Get the high resolution time counter. Counter incremented in thread.
936
 *
937
 * @return  64-bit counter.
938
 */
939
static WC_INLINE word64 Entropy_TimeHiRes(void)
940
{
941
    /* Return counter update in thread. */
942
    return entropy_thread_data.counter;
943
}
944
945
/* Thread that increments counter while not told to stop.
946
 *
947
 * @param [in,out] args  Entropy data including: counter and stop flag.
948
 * @return  NULL always.
949
 */
950
static THREAD_RETURN_NOJOIN WOLFSSL_THREAD_NO_JOIN
951
    Entropy_IncCounter(void* args)
952
{
953
    (void)args;
954
955
    /* Keep going until caller tells us to stop and exit. */
956
    while (!entropy_thread_data.stop) {
957
        /* Increment counter acting as high resolution timer. */
958
        entropy_thread_data.counter++;
959
    }
960
961
#ifdef WOLFSSL_DEBUG_ENTROPY_MEMUSE
962
    fprintf(stderr, "EXITING ENTROPY COUNTER THREAD\n");
963
#endif
964
965
    /* Exit from thread. */
966
    RETURN_FROM_THREAD_NOJOIN(0);
967
}
968
969
/* Start a thread that increments counter if not one already.
970
 *
971
 * Won't start a new thread if one already running.
972
 * Waits for thread to start by waiting for counter to have incremented.
973
 *
974
 * @return  0 on success.
975
 * @return  Negative on failure.
976
 */
977
static int Entropy_StartThread(void)
978
{
979
    int ret = 0;
980
981
    /* Only continue if we haven't started a thread. */
982
    if (!entropy_thread_started) {
983
        /* Get counter before starting thread. */
984
        word64 start_counter = entropy_thread_data.counter;
985
986
        /* In case of restarting thread, set stop indicator to false. */
987
        entropy_thread_data.stop = 0;
988
989
    #ifdef WOLFSSL_DEBUG_ENTROPY_MEMUSE
990
        fprintf(stderr, "STARTING ENTROPY COUNTER THREAD\n");
991
    #endif
992
        /* Create a thread that increments the counter in the data. */
993
        /* Thread resources to be disposed of. */
994
        ret = wolfSSL_NewThreadNoJoin(Entropy_IncCounter, NULL);
995
        if (ret == 0) {
996
            /* Wait for the counter to increase indicating thread started. */
997
            while (entropy_thread_data.counter == start_counter) {
998
                sched_yield();
999
            }
1000
        }
1001
1002
        entropy_thread_started = (ret == 0);
1003
    }
1004
1005
    return ret;
1006
}
1007
1008
/* Tell thread to stop and wait for it to complete.
1009
 *
1010
 * Called by wolfCrypt_Cleanup().
1011
 */
1012
static void Entropy_StopThread(void)
1013
{
1014
    /* Only stop a thread if one is running. */
1015
    if (entropy_thread_started) {
1016
        /* Tell thread to stop. */
1017
        entropy_thread_data.stop = 1;
1018
        /* Stopped thread so no thread started anymore. */
1019
        entropy_thread_started = 0;
1020
    }
1021
}
1022
    /* end if defined(HAVE_PTHREAD) */
1023
1024
#else
1025
1026
#error "No high precision time available for MemUse Entropy."
1027
1028
#endif
1029
1030
#ifndef ENTROPY_NUM_WORDS_BITS
1031
    /* Number of bits to count of 64-bit words in state. */
1032
    #define ENTROPY_NUM_WORDS_BITS      14
1033
#endif
1034
1035
/* Floor of 8 yields pool of 256x 64-bit word samples
1036
 * 9  -> 512x 64-bit word samples
1037
 * 10 -> 1,024x 64-bit word samples
1038
 * 11 -> 2,048x 64-bit word samples
1039
 * 12 -> 4,096x 64-bit word samples
1040
 * 13 -> 8,192x 64-bit word samples
1041
 * 14 -> 16,384x 64-bit word samples
1042
 * 15 -> 32,768x 64-bit word samples
1043
 * ... doubling every time up to a maximum of:
1044
 * 30 -> 1,073,741,824x 64-bit word samples
1045
 * 1 billion+ samples should be more then sufficient for any use-case
1046
 */
1047
#if ENTROPY_NUM_WORDS_BITS < 8
1048
    #error "ENTROPY_NUM_WORDS_BITS must be 8 or more"
1049
#elif ENTROPY_NUM_WORDS_BITS > 30
1050
    #error "ENTROPY_NUM_WORDS_BITS must be less than 31"
1051
#endif
1052
/* Number of 64-bit words in state. */
1053
#define ENTROPY_NUM_WORDS               (1 << ENTROPY_NUM_WORDS_BITS)
1054
1055
/* Size of one block of 64-bit words. */
1056
#define ENTROPY_BLOCK_SZ                (ENTROPY_NUM_WORDS_BITS - 8)
1057
1058
#ifndef ENTROPY_NUM_UPDATES
1059
    /* Number of times to update random blocks.
1060
     * Less than 2^ENTROPY_BLOCK_SZ (default: 2^6 = 64).
1061
     * Maximize value to maximize entropy per sample.
1062
     * Limit value to ensure entropy is collected in a timely manner.
1063
     */
1064
    #define ENTROPY_NUM_UPDATES         18
1065
    /* Upper round of log2(ENTROPY_NUM_UPDATES) */
1066
    #define ENTROPY_NUM_UPDATES_BITS    5
1067
#elif !defined(ENTROPY_NUM_UPDATES_BITS)
1068
    #define ENTROPY_NUM_UPDATES_BITS     ENTROPY_BLOCK_SZ
1069
#endif
1070
#ifndef ENTROPY_NUM_UPDATES_BITS
1071
    #error "ENTROPY_NUM_UPDATES_BITS must be defined - " \
1072
           "upper(log2(ENTROPY_NUM_UPDATES))"
1073
#endif
1074
#if ENTROPY_NUM_UPDATES_BITS != 0
1075
    /* Amount to shift offset to get better coverage of a block */
1076
    #define ENTROPY_OFFSET_SHIFTING          \
1077
        (ENTROPY_BLOCK_SZ / ENTROPY_NUM_UPDATES_BITS)
1078
#else
1079
    /* Amount to shift offset to get better coverage of a block */
1080
    #define ENTROPY_OFFSET_SHIFTING          ENTROPY_BLOCK_SZ
1081
#endif
1082
1083
#ifndef ENTROPY_NUM_64BIT_WORDS
1084
    /* Number of 64-bit words to update - 32. */
1085
    #define ENTROPY_NUM_64BIT_WORDS     WC_SHA3_256_DIGEST_SIZE
1086
#elif ENTROPY_NUM_64BIT_WORDS > WC_SHA3_256_DIGEST_SIZE
1087
    #error "ENTROPY_NUM_64BIT_WORDS must be <= SHA3-256 digest size in bytes"
1088
#endif
1089
1090
#if ENTROPY_BLOCK_SZ < ENTROPY_NUM_UPDATES_BITS
1091
#define EXTRA_ENTROPY_WORDS             ENTROPY_NUM_UPDATES
1092
#else
1093
#define EXTRA_ENTROPY_WORDS             0
1094
#endif
1095
1096
/* State to update that is multiple cache lines long. */
1097
static word64 entropy_state[ENTROPY_NUM_WORDS + EXTRA_ENTROPY_WORDS] = {0};
1098
1099
/* Using memory will take different amount of times depending on the CPU's
1100
 * caches and business.
1101
 */
1102
static void Entropy_MemUse(void)
1103
{
1104
    int i;
1105
    static byte d[WC_SHA3_256_DIGEST_SIZE];
1106
    int j;
1107
1108
    for (j = 0; j < ENTROPY_NUM_UPDATES; j++) {
1109
        /* Hash the first 32 64-bit words of state. */
1110
        wc_Sha3_256_Update(&entropyHash, (byte*)entropy_state,
1111
            sizeof(*entropy_state) * ENTROPY_NUM_64BIT_WORDS);
1112
        /* Get pseudo-random indices. */
1113
        wc_Sha3_256_Final(&entropyHash, d);
1114
1115
        for (i = 0; i < ENTROPY_NUM_64BIT_WORDS; i++) {
1116
            /* Choose a 64-bit word from a pseudo-random block.*/
1117
            int idx = ((int)d[i] << ENTROPY_BLOCK_SZ) +
1118
                      (j << ENTROPY_OFFSET_SHIFTING);
1119
            /* Update a pseudo-random 64-bit word with a pseudo-random value. */
1120
            entropy_state[idx] += Entropy_TimeHiRes();
1121
            /* Ensure part of state that is hashed is updated. */
1122
            entropy_state[i] += entropy_state[idx];
1123
        }
1124
    }
1125
}
1126
1127
1128
/* Last time entropy sample was gathered. */
1129
static word64 entropy_last_time = 0;
1130
1131
/* Get a sample of noise.
1132
 *
1133
 * Value is time taken to use memory.
1134
 *
1135
 * Called to test raw entropy.
1136
 *
1137
 * @return  64-bit value that is the noise.
1138
 */
1139
static word64 Entropy_GetSample(void)
1140
{
1141
    word64 now;
1142
    word64 ret;
1143
1144
#ifdef HAVE_FIPS
1145
    /* First sample must be disregard when in FIPS. */
1146
    if (entropy_last_time == 0) {
1147
        /* Get sample which triggers CAST in FIPS mode. */
1148
        Entropy_MemUse();
1149
        /* Start entropy time after CASTs. */
1150
        entropy_last_time = Entropy_TimeHiRes();
1151
    }
1152
#endif
1153
1154
    /* Use memory such that it will take an unpredictable amount of time. */
1155
    Entropy_MemUse();
1156
1157
    /* Get the time now to subtract from previous end time. */
1158
    now = Entropy_TimeHiRes();
1159
    /* Calculate time diff since last sampling. */
1160
    ret = now - entropy_last_time;
1161
    /* Store last time. */
1162
    entropy_last_time = now;
1163
1164
    return ret;
1165
}
1166
1167
/* Get as many samples of noise as required.
1168
 *
1169
 * One sample is one byte.
1170
 *
1171
 * @param [out] noise    Buffer to hold samples.
1172
 * @param [in]  samples  Number of one byte samples to get.
1173
 */
1174
static void Entropy_GetNoise(unsigned char* noise, int samples)
1175
{
1176
    int i;
1177
1178
    /* Do it once to get things going. */
1179
    Entropy_MemUse();
1180
1181
    /* Get as many samples as required. */
1182
    for (i = 0; i < samples; i++) {
1183
       noise[i] = (byte)Entropy_GetSample();
1184
    }
1185
}
1186
1187
/* Generate raw entropy for performing assessment.
1188
 *
1189
 * @param [out] raw  Buffer to hold raw entropy data.
1190
 * @param [in]  cnt  Number of bytes of raw entropy to get.
1191
 * @return  0 on success.
1192
 * @return  Negative when creating a thread fails - when no high resolution
1193
 * clock available.
1194
 */
1195
int wc_Entropy_GetRawEntropy(unsigned char* raw, int cnt)
1196
{
1197
    int ret = 0;
1198
1199
#ifdef ENTROPY_MEMUSE_THREADED
1200
    /* Start the counter thread as a proxy for time counter. */
1201
    ret = Entropy_StartThread();
1202
    if (ret == 0)
1203
#endif
1204
    {
1205
        Entropy_GetNoise(raw, cnt);
1206
    }
1207
#ifdef ENTROPY_MEMUSE_THREADED
1208
    /* Stop the counter thread to avoid thrashing the system. */
1209
    Entropy_StopThread();
1210
#endif
1211
1212
    return ret;
1213
}
1214
1215
#if ENTROPY_MIN == 1
1216
/* SP800-90b 4.4.1 - Repetition Test
1217
 * C = 1 + upper(-log2(alpha) / H)
1218
 * When alpha = 2^-30 and H = 1,
1219
 * C = 1 + upper(30 / 1) = 31
1220
 */
1221
#define REP_CUTOFF           31
1222
#else
1223
#error "Minimum entropy not defined to a recognized value."
1224
#endif
1225
1226
/* Have valid previous sample for repetition test. */
1227
static int rep_have_prev = 0;
1228
/* Previous sample value. */
1229
static byte rep_prev_noise;
1230
1231
static void Entropy_HealthTest_Repetition_Reset(void)
1232
{
1233
    /* No previous stored. */
1234
    rep_have_prev = 0;
1235
    /* Clear previous. */
1236
    rep_prev_noise = 0;
1237
}
1238
1239
/* Test sample value with repetition test.
1240
 *
1241
 * @param [in] noise  Sample to test.
1242
 * @return  0 on success.
1243
 * @return  ENTROPY_RT_E on failure.
1244
 */
1245
static int Entropy_HealthTest_Repetition(byte noise)
1246
{
1247
    int ret = 0;
1248
    /* Number of times previous value has been seen continuously. */
1249
    static int rep_cnt = 0;
1250
1251
    /* If we don't have a previous then store this one for next time. */
1252
    if (!rep_have_prev) {
1253
        rep_prev_noise = noise;
1254
        rep_have_prev = 1;
1255
        rep_cnt = 1;
1256
    }
1257
    /* Check whether this sample matches last. */
1258
    else if (noise == rep_prev_noise) {
1259
        /* Update count of repetitions. */
1260
        rep_cnt++;
1261
        /* Fail if we reach cutoff. */
1262
        if (rep_cnt >= REP_CUTOFF) {
1263
        #ifdef WOLFSSL_DEBUG_ENTROPY_MEMUSE
1264
            fprintf(stderr, "REPETITION FAILED: %d\n", noise);
1265
        #endif
1266
            Entropy_HealthTest_Repetition_Reset();
1267
            ret = ENTROPY_RT_E;
1268
        }
1269
    }
1270
    else {
1271
        /* Cache new previous and seen one so far. */
1272
        rep_prev_noise = noise;
1273
        rep_cnt = 1;
1274
    }
1275
1276
    return ret;
1277
}
1278
1279
/* SP800-90b 4.4.2 - Adaptive Proportion Test
1280
 * Para 2
1281
 *   ... The window size W is selected based on the alphabet size ... 512 if
1282
 *   the noise source is not binary ...
1283
 */
1284
#define PROP_WINDOW_SIZE     512
1285
#if ENTROPY_MIN == 1
1286
/* SP800-90b 4.4.2 - Adaptive Proportion Test
1287
 * Note 10
1288
 * C = 1 + CRITBINOM(W, power(2,( -H)),1-alpha)
1289
 * alpha = 2^-30 = POWER(2,-30), H = 1, W = 512
1290
 * C = 1 + CRITBINOM(512, 0.5, 1-POWER(2,-30)) = 1 + 324 = 325
1291
 */
1292
#define PROP_CUTOFF          325
1293
#else
1294
#error "Minimum entropy not defined to a recognized value."
1295
#endif
1296
1297
/* Total number of samples storef for Adaptive proportion test.
1298
 * Need the next 512 samples to compare this this one.
1299
 */
1300
static word16 prop_total = 0;
1301
/* Index of first sample. */
1302
static word16 prop_first = 0;
1303
/* Index to put next sample in. */
1304
static word16 prop_last = 0;
1305
/* Count of each value seen in queue. */
1306
static word16 prop_cnt[1 << ENTROPY_BITS_USED] = { 0 };
1307
/* Circular queue of samples. */
1308
static word16 prop_samples[PROP_WINDOW_SIZE];
1309
1310
/* Resets the data for the Adaptive Proportion Test.
1311
 */
1312
static void Entropy_HealthTest_Proportion_Reset(void)
1313
{
1314
    /* Clear out samples. */
1315
    XMEMSET(prop_samples, 0, sizeof(prop_samples));
1316
    /* Clear out counts. */
1317
    XMEMSET(prop_cnt, 0, sizeof(prop_cnt));
1318
    /* Clear stored count. */
1319
    prop_total = 0;
1320
    /* Reset first and last index for samples. */
1321
    prop_first = 0;
1322
    prop_last = 0;
1323
}
1324
1325
/* Add sample to Adaptive Proportion test.
1326
 *
1327
 * SP800-90b 4.4.2 - Adaptive Proportion Test
1328
 *
1329
 * Sample is accumulated into buffer until required successive values seen.
1330
 *
1331
 * @param [in] noise  Sample to test.
1332
 * @return  0 on success.
1333
 * @return  ENTROPY_APT_E on failure.
1334
 */
1335
static int Entropy_HealthTest_Proportion(byte noise)
1336
{
1337
    int ret = 0;
1338
1339
    /* Need minimum samples in queue to test with - keep adding while we have
1340
     * less. */
1341
    if (prop_total < PROP_CUTOFF - 1) {
1342
        /* Store sample at last position in circular queue. */
1343
        prop_samples[prop_last++] = noise;
1344
        /* Update count of seen value based on new sample. */
1345
        prop_cnt[noise]++;
1346
        /* Update count of store values. */
1347
        prop_total++;
1348
    }
1349
    else {
1350
        /* We have at least a minimum set of samples in queue. */
1351
        /* Store new sample at end of queue. */
1352
        prop_samples[prop_last] = noise;
1353
        /* Update last index now that we have added new sample to queue. */
1354
        prop_last = (prop_last + 1) % PROP_WINDOW_SIZE;
1355
        /* Added sample to queue - add count. */
1356
        prop_cnt[noise]++;
1357
        /* Update count of store values. */
1358
        prop_total++;
1359
1360
        /* Check whether first value has too many repetitions in queue. */
1361
        if (prop_cnt[noise] >= PROP_CUTOFF) {
1362
        #ifdef WOLFSSL_DEBUG_ENTROPY_MEMUSE
1363
            fprintf(stderr, "PROPORTION FAILED: %d %d\n", val, prop_cnt[noise]);
1364
        #endif
1365
            Entropy_HealthTest_Proportion_Reset();
1366
            /* Error code returned. */
1367
            ret = ENTROPY_APT_E;
1368
        }
1369
        else if (prop_total == PROP_WINDOW_SIZE) {
1370
            /* Return to 511 samples in queue. */
1371
            /* Get first value in queue - value to test. */
1372
            byte val = (byte)prop_samples[prop_first];
1373
            /* Update first index to remove first sample from the queue. */
1374
            prop_first = (prop_first + 1) % PROP_WINDOW_SIZE;
1375
            /* Removed first sample from queue - remove count. */
1376
            prop_cnt[val]--;
1377
            /* Update count of store values. */
1378
            prop_total--;
1379
        }
1380
    }
1381
1382
    return ret;
1383
}
1384
1385
/* SP800-90b 4.3 - Requirements for Health Tests
1386
 * 1.4: The entropy source's startup tests shall run the continuous health
1387
 * tests over at least 1024 consecutive samples.
1388
 *
1389
 * Adaptive Proportion Test requires a number of samples to compared too.
1390
 */
1391
#define ENTROPY_INITIAL_COUNT   (1024 + PROP_WINDOW_SIZE)
1392
1393
/* Perform startup health testing.
1394
 *
1395
 * Fill adaptive proportion test buffer and then do 1024 samples.
1396
 * Perform repetition test on all samples expect last.
1397
 *
1398
 * Discards samples from health tests on failure.
1399
 *
1400
 * @return  0 on success.
1401
 * @return  ENTROPY_RT_E or ENTROPY_APT_E on failure.
1402
 */
1403
static int Entropy_HealthTest_Startup(void)
1404
{
1405
    int ret = 0;
1406
    byte initial[ENTROPY_INITIAL_COUNT];
1407
    int i;
1408
1409
#ifdef WOLFSSL_DEBUG_ENTROPY_MEMUSE
1410
    fprintf(stderr, "STARTUP HEALTH TEST\n");
1411
#endif
1412
1413
    /* Reset cached values before testing. */
1414
    Entropy_HealthTest_Reset();
1415
1416
    /* Fill initial sample buffer with noise. */
1417
    Entropy_GetNoise(initial, ENTROPY_INITIAL_COUNT);
1418
    /* Health check initial noise. */
1419
    for (i = 0; (ret == 0) && (i < ENTROPY_INITIAL_COUNT); i++) {
1420
        ret = Entropy_HealthTest_Repetition(initial[i]);
1421
        if (ret == 0) {
1422
            ret = Entropy_HealthTest_Proportion(initial[i]);
1423
        }
1424
    }
1425
1426
    if (ret != 0) {
1427
        /* Failing test only resets its own data. */
1428
        Entropy_HealthTest_Reset();
1429
    }
1430
1431
    return ret;
1432
}
1433
1434
/* Condition raw entropy noise using SHA-3-256.
1435
 *
1436
 * Put noise into a hash function: SHA-3-256.
1437
 * Add the current time counter to help with uniqueness.
1438
 *
1439
 * @param [out]  output     Buffer to conditioned data.
1440
 * @param [in]   len        Number of bytes to put into output buffer.
1441
 * @param [in]   noise      Buffer with raw noise data.
1442
 * @param [in]   noise_len  Length of noise data in bytes.
1443
 * @return  0 on success.
1444
 * @return  Negative on failure.
1445
 */
1446
static int Entropy_Condition(byte* output, word32 len, byte* noise,
1447
    word32 noise_len)
1448
{
1449
    int ret;
1450
1451
    /* Add noise to initialized hash. */
1452
    ret = wc_Sha3_256_Update(&entropyHash, noise, noise_len);
1453
    if (ret == 0) {
1454
        word64 now = Entropy_TimeHiRes();
1455
        /* Add time now counter. */
1456
        ret = wc_Sha3_256_Update(&entropyHash, (byte*)&now, sizeof(now));
1457
    }
1458
    if (ret == 0) {
1459
        /* Finalize into output buffer. */
1460
        if (len == WC_SHA3_256_DIGEST_SIZE) {
1461
            ret = wc_Sha3_256_Final(&entropyHash, output);
1462
        }
1463
        else {
1464
            byte hash[WC_SHA3_256_DIGEST_SIZE];
1465
1466
            ret = wc_Sha3_256_Final(&entropyHash, hash);
1467
            if (ret == 0) {
1468
                XMEMCPY(output, hash, len);
1469
            }
1470
        }
1471
    }
1472
1473
    return ret;
1474
}
1475
1476
/* Mutex to prevent multiple callers requesting entropy operations at the
1477
 * same time.
1478
 */
1479
static wolfSSL_Mutex entropy_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(entropy_mutex);
1480
1481
/* Get entropy of specified strength.
1482
 *
1483
 * SP800-90b 2.3.1 - GetEntropy: An Interface to the Entropy Source
1484
 *
1485
 * In threaded environment, only one thread at a time can get entropy.
1486
 *
1487
 * @param [in]  bits     Number of entropy bits. 256 is max value.
1488
 * @param [out] entropy  Buffer to hold entropy.
1489
 * @param [in]  len      Length of data to put into buffer in bytes.
1490
 * @return  0 on success.
1491
 * @return  ENTROPY_RT_E or ENTROPY_APT_E on failure.
1492
 * @return  BAD_MUTEX_E when unable to lock mutex.
1493
 */
1494
int wc_Entropy_Get(int bits, unsigned char* entropy, word32 len)
1495
{
1496
    int ret = 0;
1497
#ifdef WOLFSSL_SMALL_STACK
1498
    byte *noise = NULL;
1499
#else
1500
    byte noise[MAX_NOISE_CNT];
1501
#endif
1502
    /* Noise length is the number of 8 byte samples required to get the bits of
1503
     * entropy requested. */
1504
    int noise_len = (bits + ENTROPY_EXTRA) / ENTROPY_MIN;
1505
1506
#ifdef WOLFSSL_SMALL_STACK
1507
    noise = (byte *)XMALLOC(MAX_NOISE_CNT, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1508
    if (noise == NULL)
1509
        return MEMORY_E;
1510
#endif
1511
1512
    /* Lock the mutex as collection uses globals. */
1513
    if ((ret == 0) && (wc_LockMutex(&entropy_mutex) != 0)) {
1514
        ret = BAD_MUTEX_E;
1515
    }
1516
1517
#ifdef ENTROPY_MEMUSE_THREADED
1518
    if (ret == 0) {
1519
        /* Start the counter thread as a proxy for time counter. */
1520
        ret = Entropy_StartThread();
1521
    }
1522
#endif
1523
1524
    /* Check we have had a startup health check pass. */
1525
    if ((ret == 0) && ((prop_total == 0) || (!rep_have_prev))) {
1526
        /* Try again as check failed. */
1527
        ret = Entropy_HealthTest_Startup();
1528
    }
1529
1530
    /* Keep putting data into buffer until full. */
1531
    while ((ret == 0) && (len > 0)) {
1532
        int i;
1533
        word32 entropy_len = WC_SHA3_256_DIGEST_SIZE;
1534
1535
        /* Output 32 bytes at a time unless buffer has fewer bytes remaining. */
1536
        if (len < entropy_len) {
1537
            entropy_len = len;
1538
        }
1539
1540
        /* Get raw entropy noise. */
1541
        Entropy_GetNoise(noise, noise_len);
1542
        /* Health check each noise value. */
1543
        for (i = 0; (ret == 0) && (i < noise_len); i++) {
1544
            ret = Entropy_HealthTest_Repetition(noise[i]);
1545
            if (ret == 0) {
1546
                ret = Entropy_HealthTest_Proportion(noise[i]);
1547
            }
1548
        }
1549
1550
        if (ret == 0) {
1551
            /* Condition noise value down to 32-bytes or less. */
1552
            ret = Entropy_Condition(entropy, entropy_len, noise, noise_len);
1553
        }
1554
        if (ret == 0) {
1555
            /* Update buffer pointer and count of bytes left to generate. */
1556
            entropy += entropy_len;
1557
            len -= entropy_len;
1558
        }
1559
    }
1560
1561
#ifdef ENTROPY_MEMUSE_THREADED
1562
    /* Stop the counter thread to avoid thrashing the system. */
1563
    Entropy_StopThread();
1564
#endif
1565
1566
    if (ret != WC_NO_ERR_TRACE(BAD_MUTEX_E)) {
1567
        /* Unlock mutex now we are done. */
1568
        wc_UnLockMutex(&entropy_mutex);
1569
    }
1570
1571
#ifdef WOLFSSL_SMALL_STACK
1572
    XFREE(noise, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1573
#endif
1574
1575
    return ret;
1576
}
1577
1578
/* Performs on-demand testing.
1579
 *
1580
 * In threaded environment, locks out other threads from getting entropy.
1581
 *
1582
 * @return  0 on success.
1583
 * @return  ENTROPY_RT_E or ENTROPY_APT_E on failure.
1584
 * @return  BAD_MUTEX_E when unable to lock mutex.
1585
 */
1586
int wc_Entropy_OnDemandTest(void)
1587
{
1588
    int ret = 0;
1589
1590
    /* Lock the mutex as we don't want collecting to happen during testing. */
1591
    if (wc_LockMutex(&entropy_mutex) != 0) {
1592
        ret = BAD_MUTEX_E;
1593
    }
1594
1595
    if (ret == 0) {
1596
        /* Perform startup tests. */
1597
        ret = Entropy_HealthTest_Startup();
1598
    }
1599
1600
    if (ret != WC_NO_ERR_TRACE(BAD_MUTEX_E)) {
1601
        /* Unlock mutex now we are done. */
1602
        wc_UnLockMutex(&entropy_mutex);
1603
    }
1604
    return ret;
1605
}
1606
1607
/* Initialize global state for MemUse Entropy and do startup health test.
1608
 *
1609
 * @return  0 on success.
1610
 * @return  Negative on failure.
1611
 */
1612
int Entropy_Init(void)
1613
{
1614
    int ret = 0;
1615
1616
    /* Check whether initialization has succeeded before. */
1617
    if (!entropy_memuse_initialized) {
1618
    #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
1619
        ret = wc_InitMutex(&entropy_mutex);
1620
    #endif
1621
        if (ret == 0) {
1622
            /* Initialize a SHA3-256 object for use in entropy operations. */
1623
            ret = wc_InitSha3_256(&entropyHash, NULL, INVALID_DEVID);
1624
        }
1625
        /* Set globals initialized. */
1626
        entropy_memuse_initialized = (ret == 0);
1627
        if (ret == 0) {
1628
        #ifdef ENTROPY_MEMUSE_THREADED
1629
            /* Start the counter thread as a proxy for time counter. */
1630
            ret = Entropy_StartThread();
1631
            if (ret == 0)
1632
        #endif
1633
            {
1634
                /* Do first startup test now. */
1635
                ret = Entropy_HealthTest_Startup();
1636
            }
1637
        #ifdef ENTROPY_MEMUSE_THREADED
1638
            /* Stop the counter thread to avoid thrashing the system. */
1639
            Entropy_StopThread();
1640
        #endif
1641
        }
1642
    }
1643
1644
    return ret;
1645
}
1646
1647
/* Finalize the data associated with the MemUse Entropy source.
1648
 */
1649
void Entropy_Final(void)
1650
{
1651
    /* Only finalize when initialized. */
1652
    if (entropy_memuse_initialized) {
1653
        /* Dispose of the SHA3-356 hash object. */
1654
        wc_Sha3_256_Free(&entropyHash);
1655
    #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
1656
        wc_FreeMutex(&entropy_mutex);
1657
    #endif
1658
        /* Clear health test data. */
1659
        Entropy_HealthTest_Reset();
1660
        /* No longer initialized. */
1661
        entropy_memuse_initialized = 0;
1662
    }
1663
}
1664
1665
/* Reset the data associated with the MemUse Entropy health tests.
1666
 */
1667
static void Entropy_HealthTest_Reset(void)
1668
{
1669
    Entropy_HealthTest_Repetition_Reset();
1670
    Entropy_HealthTest_Proportion_Reset();
1671
}
1672
1673
#endif /* HAVE_ENTROPY_MEMUSE */
1674
1675
static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
1676
                    void* heap, int devId)
1677
110k
{
1678
110k
    int ret = 0;
1679
110k
#ifdef HAVE_HASHDRBG
1680
110k
    word32 seedSz = SEED_SZ + SEED_BLOCK_SZ;
1681
110k
#endif
1682
1683
110k
    (void)nonce;
1684
110k
    (void)nonceSz;
1685
1686
110k
    if (rng == NULL)
1687
0
        return BAD_FUNC_ARG;
1688
110k
    if (nonce == NULL && nonceSz != 0)
1689
0
        return BAD_FUNC_ARG;
1690
1691
#ifdef WOLFSSL_HEAP_TEST
1692
    rng->heap = (void*)WOLFSSL_HEAP_TEST;
1693
    (void)heap;
1694
#else
1695
110k
    rng->heap = heap;
1696
110k
#endif
1697
110k
#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID)
1698
110k
    rng->pid = getpid();
1699
110k
#endif
1700
110k
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
1701
110k
    rng->devId = devId;
1702
110k
    #if defined(WOLF_CRYPTO_CB)
1703
110k
        rng->seed.devId = devId;
1704
110k
    #endif
1705
#else
1706
    (void)devId;
1707
#endif
1708
1709
110k
#ifdef HAVE_HASHDRBG
1710
    /* init the DBRG to known values */
1711
110k
    rng->drbg = NULL;
1712
110k
    rng->status = DRBG_NOT_INIT;
1713
110k
#endif
1714
1715
#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) || \
1716
    defined(HAVE_AMD_RDSEED)
1717
    /* init the intel RD seed and/or rand */
1718
    wc_InitRng_IntelRD();
1719
#endif
1720
1721
    /* configure async RNG source if available */
1722
#ifdef WOLFSSL_ASYNC_CRYPT
1723
    ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG,
1724
                                                        rng->heap, rng->devId);
1725
    if (ret != 0) {
1726
    #ifdef HAVE_HASHDRBG
1727
        rng->status = DRBG_OK;
1728
    #endif
1729
        return ret;
1730
    }
1731
#endif
1732
1733
#ifdef HAVE_INTEL_RDRAND
1734
    /* if CPU supports RDRAND, use it directly and by-pass DRBG init */
1735
    if (IS_INTEL_RDRAND(intel_flags)) {
1736
    #ifdef HAVE_HASHDRBG
1737
        rng->status = DRBG_OK;
1738
    #endif
1739
        return 0;
1740
    }
1741
#endif
1742
1743
#ifdef WOLFSSL_XILINX_CRYPT_VERSAL
1744
    ret = wc_VersalTrngInit(nonce, nonceSz);
1745
    if (ret) {
1746
    #ifdef HAVE_HASHDRBG
1747
        rng->status = DRBG_OK;
1748
    #endif
1749
        return ret;
1750
    }
1751
#endif
1752
1753
#ifdef CUSTOM_RAND_GENERATE_BLOCK
1754
    ret = 0; /* success */
1755
#else
1756
1757
 /* not CUSTOM_RAND_GENERATE_BLOCK follows */
1758
110k
#ifdef HAVE_HASHDRBG
1759
110k
    if (nonceSz == 0) {
1760
110k
        seedSz = MAX_SEED_SZ;
1761
110k
    }
1762
1763
110k
    ret = wc_RNG_HealthTestLocal(0, rng->heap, devId);
1764
110k
    if (ret != 0) {
1765
        #if defined(DEBUG_WOLFSSL)
1766
        WOLFSSL_MSG_EX("wc_RNG_HealthTestLocal failed err = %d", ret);
1767
        #endif
1768
7.20k
        ret = DRBG_CONT_FAILURE;
1769
7.20k
    }
1770
102k
    else {
1771
    #ifndef WOLFSSL_SMALL_STACK
1772
        byte seed[MAX_SEED_SZ];
1773
    #else
1774
102k
        byte* seed = (byte*)XMALLOC(MAX_SEED_SZ, rng->heap,
1775
102k
            DYNAMIC_TYPE_SEED);
1776
102k
        if (seed == NULL)
1777
4
            return MEMORY_E;
1778
102k
    #endif
1779
1780
102k
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
1781
102k
        rng->drbg =
1782
102k
                (struct DRBG*)XMALLOC(sizeof(DRBG_internal), rng->heap,
1783
102k
                                                          DYNAMIC_TYPE_RNG);
1784
102k
        if (rng->drbg == NULL) {
1785
    #if defined(DEBUG_WOLFSSL)
1786
            WOLFSSL_MSG_EX("_InitRng XMALLOC failed to allocate %d bytes",
1787
                           sizeof(DRBG_internal));
1788
    #endif
1789
4
            ret = MEMORY_E;
1790
4
            rng->status = DRBG_FAILED;
1791
4
        }
1792
#else
1793
        rng->drbg = (struct DRBG*)&rng->drbg_data;
1794
#endif /* WOLFSSL_NO_MALLOC or WOLFSSL_STATIC_MEMORY */
1795
1796
102k
        if (ret != 0) {
1797
#if defined(DEBUG_WOLFSSL)
1798
            WOLFSSL_MSG_EX("_InitRng failed. err = %d", ret);
1799
#endif
1800
4
        }
1801
102k
        else {
1802
#ifdef WC_RNG_SEED_CB
1803
            if (seedCb == NULL) {
1804
                ret = DRBG_NO_SEED_CB;
1805
            }
1806
            else {
1807
                ret = seedCb(&rng->seed, seed, seedSz);
1808
                if (ret != 0) {
1809
                    ret = DRBG_FAILURE;
1810
                }
1811
            }
1812
#else
1813
102k
            ret = wc_GenerateSeed(&rng->seed, seed, seedSz);
1814
102k
#endif /* WC_RNG_SEED_CB */
1815
102k
            if (ret != 0) {
1816
    #if defined(DEBUG_WOLFSSL)
1817
                WOLFSSL_MSG_EX("Seed generation failed... %d", ret);
1818
    #endif
1819
0
                ret = DRBG_FAILURE;
1820
0
                rng->status = DRBG_FAILED;
1821
0
            }
1822
1823
102k
            if (ret == 0)
1824
102k
                ret = wc_RNG_TestSeed(seed, seedSz);
1825
    #if defined(DEBUG_WOLFSSL)
1826
            if (ret != 0) {
1827
                WOLFSSL_MSG_EX("wc_RNG_TestSeed failed... %d", ret);
1828
            }
1829
    #endif
1830
102k
            if (ret == DRBG_SUCCESS)
1831
102k
                ret = Hash_DRBG_Instantiate((DRBG_internal *)rng->drbg,
1832
102k
                            seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,
1833
102k
                            nonce, nonceSz, rng->heap, devId);
1834
1835
102k
            if (ret != DRBG_SUCCESS) {
1836
18
            #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
1837
18
                XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);
1838
18
            #endif
1839
18
                rng->drbg = NULL;
1840
18
            }
1841
102k
        } /* ret == 0 */
1842
1843
102k
        ForceZero(seed, seedSz);
1844
102k
    #ifdef WOLFSSL_SMALL_STACK
1845
102k
        XFREE(seed, rng->heap, DYNAMIC_TYPE_SEED);
1846
102k
    #endif
1847
102k
    } /* else swc_RNG_HealthTestLocal was successful */
1848
1849
110k
    if (ret == DRBG_SUCCESS) {
1850
#ifdef WOLFSSL_CHECK_MEM_ZERO
1851
    #ifdef HAVE_HASHDRBG
1852
        struct DRBG_internal* drbg = (struct DRBG_internal*)rng->drbg;
1853
        wc_MemZero_Add("DRBG V", &drbg->V, sizeof(drbg->V));
1854
        wc_MemZero_Add("DRBG C", &drbg->C, sizeof(drbg->C));
1855
    #endif
1856
#endif
1857
1858
102k
        rng->status = DRBG_OK;
1859
102k
        ret = 0;
1860
102k
    }
1861
7.22k
    else if (ret == DRBG_CONT_FAILURE) {
1862
7.20k
        rng->status = DRBG_CONT_FAILED;
1863
7.20k
        ret = DRBG_CONT_FIPS_E;
1864
7.20k
    }
1865
22
    else if (ret == DRBG_FAILURE) {
1866
18
        rng->status = DRBG_FAILED;
1867
18
        ret = RNG_FAILURE_E;
1868
18
    }
1869
4
    else {
1870
4
        rng->status = DRBG_FAILED;
1871
4
    }
1872
110k
#endif /* HAVE_HASHDRBG */
1873
110k
#endif /* CUSTOM_RAND_GENERATE_BLOCK */
1874
1875
110k
    return ret;
1876
110k
}
1877
1878
1879
WOLFSSL_ABI
1880
WC_RNG* wc_rng_new(byte* nonce, word32 nonceSz, void* heap)
1881
0
{
1882
0
    WC_RNG* rng;
1883
1884
0
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG);
1885
0
    if (rng) {
1886
0
        int error = _InitRng(rng, nonce, nonceSz, heap, INVALID_DEVID) != 0;
1887
0
        if (error) {
1888
0
            XFREE(rng, heap, DYNAMIC_TYPE_RNG);
1889
0
            rng = NULL;
1890
0
        }
1891
0
    }
1892
1893
0
    return rng;
1894
0
}
1895
1896
1897
int wc_rng_new_ex(WC_RNG **rng, byte* nonce, word32 nonceSz,
1898
                  void* heap, int devId)
1899
0
{
1900
0
    int ret;
1901
1902
0
    *rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG);
1903
0
    if (*rng == NULL) {
1904
0
        return MEMORY_E;
1905
0
    }
1906
1907
0
    ret = _InitRng(*rng, nonce, nonceSz, heap, devId);
1908
0
    if (ret != 0) {
1909
0
        XFREE(*rng, heap, DYNAMIC_TYPE_RNG);
1910
0
        *rng = NULL;
1911
0
    }
1912
1913
0
    return ret;
1914
0
}
1915
1916
1917
WOLFSSL_ABI
1918
void wc_rng_free(WC_RNG* rng)
1919
0
{
1920
0
    if (rng) {
1921
0
        void* heap = rng->heap;
1922
1923
0
        wc_FreeRng(rng);
1924
0
        ForceZero(rng, sizeof(WC_RNG));
1925
0
        XFREE(rng, heap, DYNAMIC_TYPE_RNG);
1926
0
        (void)heap;
1927
0
    }
1928
0
}
1929
1930
WOLFSSL_ABI
1931
int wc_InitRng(WC_RNG* rng)
1932
1.37k
{
1933
1.37k
    return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);
1934
1.37k
}
1935
1936
1937
int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
1938
117k
{
1939
117k
    return _InitRng(rng, NULL, 0, heap, devId);
1940
117k
}
1941
1942
1943
int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)
1944
0
{
1945
0
    return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);
1946
0
}
1947
1948
1949
int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
1950
                       void* heap, int devId)
1951
0
{
1952
0
    return _InitRng(rng, nonce, nonceSz, heap, devId);
1953
0
}
1954
1955
#ifdef HAVE_HASHDRBG
1956
static int PollAndReSeed(WC_RNG* rng)
1957
0
{
1958
0
    int ret   = DRBG_NEED_RESEED;
1959
0
    int devId = INVALID_DEVID;
1960
0
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
1961
0
    devId = rng->devId;
1962
0
#endif
1963
0
    if (wc_RNG_HealthTestLocal(1, rng->heap, devId) == 0) {
1964
    #ifndef WOLFSSL_SMALL_STACK
1965
        byte newSeed[SEED_SZ + SEED_BLOCK_SZ];
1966
        ret = DRBG_SUCCESS;
1967
    #else
1968
0
        byte* newSeed = (byte*)XMALLOC(SEED_SZ + SEED_BLOCK_SZ, rng->heap,
1969
0
            DYNAMIC_TYPE_SEED);
1970
0
        ret = (newSeed == NULL) ? MEMORY_E : DRBG_SUCCESS;
1971
0
    #endif
1972
0
        if (ret == DRBG_SUCCESS) {
1973
        #ifdef WC_RNG_SEED_CB
1974
            if (seedCb == NULL) {
1975
                ret = DRBG_NO_SEED_CB;
1976
            }
1977
            else {
1978
                ret = seedCb(&rng->seed, newSeed, SEED_SZ + SEED_BLOCK_SZ);
1979
                if (ret != 0) {
1980
                    ret = DRBG_FAILURE;
1981
                }
1982
            }
1983
        #else
1984
0
            ret = wc_GenerateSeed(&rng->seed, newSeed,
1985
0
                              SEED_SZ + SEED_BLOCK_SZ);
1986
0
        #endif
1987
0
            if (ret != 0)
1988
0
                ret = DRBG_FAILURE;
1989
0
        }
1990
0
        if (ret == DRBG_SUCCESS)
1991
0
            ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ);
1992
1993
0
        if (ret == DRBG_SUCCESS)
1994
0
            ret = Hash_DRBG_Reseed((DRBG_internal *)rng->drbg,
1995
0
                                   newSeed + SEED_BLOCK_SZ, SEED_SZ);
1996
0
    #ifdef WOLFSSL_SMALL_STACK
1997
0
        if (newSeed != NULL) {
1998
0
            ForceZero(newSeed, SEED_SZ + SEED_BLOCK_SZ);
1999
0
        }
2000
0
        XFREE(newSeed, rng->heap, DYNAMIC_TYPE_SEED);
2001
    #else
2002
        ForceZero(newSeed, sizeof(newSeed));
2003
    #endif
2004
0
    }
2005
0
    else {
2006
0
        ret = DRBG_CONT_FAILURE;
2007
0
    }
2008
2009
0
    return ret;
2010
0
}
2011
#endif
2012
2013
/* place a generated block in output */
2014
WOLFSSL_ABI
2015
int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
2016
263k
{
2017
263k
    int ret;
2018
2019
263k
    if (rng == NULL || output == NULL)
2020
0
        return BAD_FUNC_ARG;
2021
2022
263k
    if (sz == 0)
2023
684
        return 0;
2024
2025
263k
#ifdef WOLF_CRYPTO_CB
2026
263k
    #ifndef WOLF_CRYPTO_CB_FIND
2027
263k
    if (rng->devId != INVALID_DEVID)
2028
7.56k
    #endif
2029
7.56k
    {
2030
7.56k
        ret = wc_CryptoCb_RandomBlock(rng, output, sz);
2031
7.56k
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2032
7.56k
            return ret;
2033
        /* fall-through when unavailable */
2034
7.56k
    }
2035
255k
#endif
2036
2037
#ifdef HAVE_INTEL_RDRAND
2038
    if (IS_INTEL_RDRAND(intel_flags))
2039
        return wc_GenerateRand_IntelRD(NULL, output, sz);
2040
#endif
2041
2042
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_TRNG)
2043
    return silabs_GenerateRand(output, sz);
2044
#endif
2045
2046
#if defined(WOLFSSL_ASYNC_CRYPT)
2047
    if (rng->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) {
2048
        /* these are blocking */
2049
    #ifdef HAVE_CAVIUM
2050
        return NitroxRngGenerateBlock(rng, output, sz);
2051
    #elif defined(HAVE_INTEL_QA) && defined(QAT_ENABLE_RNG)
2052
        return IntelQaDrbg(&rng->asyncDev, output, sz);
2053
    #else
2054
        /* simulator not supported */
2055
    #endif
2056
    }
2057
#endif
2058
2059
#ifdef CUSTOM_RAND_GENERATE_BLOCK
2060
    XMEMSET(output, 0, sz);
2061
    ret = (int)CUSTOM_RAND_GENERATE_BLOCK(output, sz);
2062
#else
2063
2064
255k
#ifdef HAVE_HASHDRBG
2065
255k
    if (sz > RNG_MAX_BLOCK_LEN)
2066
0
        return BAD_FUNC_ARG;
2067
2068
255k
    if (rng->status != DRBG_OK)
2069
16
        return RNG_FAILURE_E;
2070
2071
255k
#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID)
2072
255k
    if (rng->pid != getpid()) {
2073
0
        rng->pid = getpid();
2074
0
        ret = PollAndReSeed(rng);
2075
0
        if (ret != DRBG_SUCCESS) {
2076
0
            rng->status = DRBG_FAILED;
2077
0
            return RNG_FAILURE_E;
2078
0
        }
2079
0
    }
2080
255k
#endif
2081
2082
255k
    ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz);
2083
255k
    if (ret == DRBG_NEED_RESEED) {
2084
0
        ret = PollAndReSeed(rng);
2085
0
        if (ret == DRBG_SUCCESS)
2086
0
            ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz);
2087
0
    }
2088
2089
255k
    if (ret == DRBG_SUCCESS) {
2090
248k
        ret = 0;
2091
248k
    }
2092
6.61k
    else if (ret == DRBG_CONT_FAILURE) {
2093
0
        ret = DRBG_CONT_FIPS_E;
2094
0
        rng->status = DRBG_CONT_FAILED;
2095
0
    }
2096
6.61k
    else {
2097
6.61k
        ret = RNG_FAILURE_E;
2098
6.61k
        rng->status = DRBG_FAILED;
2099
6.61k
    }
2100
#else
2101
2102
    /* if we get here then there is an RNG configuration error */
2103
    ret = RNG_FAILURE_E;
2104
2105
#endif /* HAVE_HASHDRBG */
2106
255k
#endif /* CUSTOM_RAND_GENERATE_BLOCK */
2107
2108
255k
    return ret;
2109
255k
}
2110
2111
2112
int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
2113
0
{
2114
0
    return wc_RNG_GenerateBlock(rng, b, 1);
2115
0
}
2116
2117
2118
int wc_FreeRng(WC_RNG* rng)
2119
111k
{
2120
111k
    int ret = 0;
2121
2122
111k
    if (rng == NULL)
2123
0
        return BAD_FUNC_ARG;
2124
2125
#if defined(WOLFSSL_ASYNC_CRYPT)
2126
    wolfAsync_DevCtxFree(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG);
2127
#endif
2128
2129
111k
#ifdef HAVE_HASHDRBG
2130
111k
    if (rng->drbg != NULL) {
2131
111k
      if (Hash_DRBG_Uninstantiate((DRBG_internal *)rng->drbg) != DRBG_SUCCESS)
2132
0
            ret = RNG_FAILURE_E;
2133
2134
111k
    #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
2135
111k
        XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);
2136
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
2137
        wc_MemZero_Check(rng->drbg, sizeof(DRBG_internal));
2138
    #endif
2139
111k
        rng->drbg = NULL;
2140
111k
    }
2141
2142
111k
    rng->status = DRBG_NOT_INIT;
2143
111k
#endif /* HAVE_HASHDRBG */
2144
2145
#ifdef WOLFSSL_XILINX_CRYPT_VERSAL
2146
    /* don't overwrite previously set error */
2147
    if (wc_VersalTrngReset() && !ret)
2148
        ret = WC_HW_E;
2149
#endif
2150
2151
111k
    return ret;
2152
111k
}
2153
2154
#ifdef HAVE_HASHDRBG
2155
int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
2156
                                  const byte* seedB, word32 seedBSz,
2157
                                  byte* output, word32 outputSz)
2158
0
{
2159
0
    return wc_RNG_HealthTest_ex(reseed, NULL, 0,
2160
0
                                seedA, seedASz, seedB, seedBSz,
2161
0
                                output, outputSz,
2162
0
                                NULL, INVALID_DEVID);
2163
0
}
2164
2165
2166
int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
2167
                                  const byte* seedA, word32 seedASz,
2168
                                  const byte* seedB, word32 seedBSz,
2169
                                  byte* output, word32 outputSz,
2170
                                  void* heap, int devId)
2171
206k
{
2172
206k
    int ret = -1;
2173
206k
    DRBG_internal* drbg;
2174
#ifndef WOLFSSL_SMALL_STACK
2175
    DRBG_internal  drbg_var;
2176
#endif
2177
2178
206k
    if (seedA == NULL || output == NULL) {
2179
0
        return BAD_FUNC_ARG;
2180
0
    }
2181
2182
206k
    if (reseed != 0 && seedB == NULL) {
2183
0
        return BAD_FUNC_ARG;
2184
0
    }
2185
2186
206k
    if (outputSz != RNG_HEALTH_TEST_CHECK_SIZE) {
2187
0
        return ret;
2188
0
    }
2189
2190
206k
#ifdef WOLFSSL_SMALL_STACK
2191
206k
    drbg = (DRBG_internal*)XMALLOC(sizeof(DRBG_internal), heap,
2192
206k
        DYNAMIC_TYPE_RNG);
2193
206k
    if (drbg == NULL) {
2194
135
        return MEMORY_E;
2195
135
    }
2196
#else
2197
    drbg = &drbg_var;
2198
#endif
2199
2200
206k
    if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz,
2201
206k
                              heap, devId) != 0) {
2202
409
        goto exit_rng_ht;
2203
409
    }
2204
2205
206k
    if (reseed) {
2206
0
        if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) {
2207
0
            goto exit_rng_ht;
2208
0
        }
2209
0
    }
2210
2211
    /* This call to generate is prescribed by the NIST DRBGVS
2212
     * procedure. The results are thrown away. The known
2213
     * answer test checks the second block of DRBG out of
2214
     * the generator to ensure the internal state is updated
2215
     * as expected. */
2216
206k
    if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
2217
111
        goto exit_rng_ht;
2218
111
    }
2219
2220
205k
    if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
2221
74
        goto exit_rng_ht;
2222
74
    }
2223
2224
    /* Mark success */
2225
205k
    ret = 0;
2226
2227
206k
exit_rng_ht:
2228
2229
    /* This is safe to call even if Hash_DRBG_Instantiate fails */
2230
206k
    if (Hash_DRBG_Uninstantiate(drbg) != 0) {
2231
0
        ret = -1;
2232
0
    }
2233
2234
206k
#ifdef WOLFSSL_SMALL_STACK
2235
206k
    XFREE(drbg, heap, DYNAMIC_TYPE_RNG);
2236
206k
#endif
2237
2238
206k
    return ret;
2239
205k
}
2240
2241
2242
const FLASH_QUALIFIER byte seedA_data[] = {
2243
    0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
2244
    0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
2245
    0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
2246
    0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
2247
};
2248
2249
const FLASH_QUALIFIER byte reseedSeedA_data[] = {
2250
    0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
2251
    0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
2252
    0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
2253
};
2254
2255
const FLASH_QUALIFIER byte outputA_data[] = {
2256
    0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
2257
    0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
2258
    0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
2259
    0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
2260
    0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
2261
    0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
2262
    0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
2263
    0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
2264
    0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
2265
    0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
2266
    0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
2267
};
2268
2269
const FLASH_QUALIFIER byte seedB_data[] = {
2270
    0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
2271
    0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
2272
    0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
2273
    0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,
2274
    0xdb, 0xcb, 0xcc, 0x2e
2275
};
2276
2277
const FLASH_QUALIFIER byte outputB_data[] = {
2278
    0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
2279
    0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
2280
    0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
2281
    0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
2282
    0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
2283
    0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
2284
    0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
2285
    0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
2286
    0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
2287
    0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
2288
    0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
2289
};
2290
2291
2292
static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId)
2293
110k
{
2294
110k
    int ret = 0;
2295
110k
#ifdef WOLFSSL_SMALL_STACK
2296
110k
    byte* check;
2297
#else
2298
    byte  check[RNG_HEALTH_TEST_CHECK_SIZE];
2299
#endif
2300
2301
110k
#ifdef WOLFSSL_SMALL_STACK
2302
110k
    check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, heap,
2303
110k
                           DYNAMIC_TYPE_TMP_BUFFER);
2304
110k
    if (check == NULL) {
2305
6.46k
        return MEMORY_E;
2306
6.46k
    }
2307
103k
#endif
2308
2309
103k
    if (reseed) {
2310
#ifdef WOLFSSL_USE_FLASHMEM
2311
        byte* seedA = (byte*)XMALLOC(sizeof(seedA_data), heap,
2312
                             DYNAMIC_TYPE_TMP_BUFFER);
2313
        byte* reseedSeedA = (byte*)XMALLOC(sizeof(reseedSeedA_data), heap,
2314
                             DYNAMIC_TYPE_TMP_BUFFER);
2315
        byte* outputA = (byte*)XMALLOC(sizeof(outputA_data), heap,
2316
                             DYNAMIC_TYPE_TMP_BUFFER);
2317
2318
        if (!seedA || !reseedSeedA || !outputA) {
2319
            XFREE(seedA, heap, DYNAMIC_TYPE_TMP_BUFFER);
2320
            XFREE(reseedSeedA, heap, DYNAMIC_TYPE_TMP_BUFFER);
2321
            XFREE(outputA, heap, DYNAMIC_TYPE_TMP_BUFFER);
2322
            ret = MEMORY_E;
2323
        }
2324
        else {
2325
            XMEMCPY_P(seedA, seedA_data, sizeof(seedA_data));
2326
            XMEMCPY_P(reseedSeedA, reseedSeedA_data, sizeof(reseedSeedA_data));
2327
            XMEMCPY_P(outputA, outputA_data, sizeof(outputA_data));
2328
#else
2329
0
        const byte* seedA = seedA_data;
2330
0
        const byte* reseedSeedA = reseedSeedA_data;
2331
0
        const byte* outputA = outputA_data;
2332
0
#endif
2333
0
        ret = wc_RNG_HealthTest_ex(1, NULL, 0,
2334
0
                                   seedA, sizeof(seedA_data),
2335
0
                                   reseedSeedA, sizeof(reseedSeedA_data),
2336
0
                                   check, RNG_HEALTH_TEST_CHECK_SIZE,
2337
0
                                   heap, devId);
2338
0
        if (ret == 0) {
2339
0
            if (ConstantCompare(check, outputA,
2340
0
                                RNG_HEALTH_TEST_CHECK_SIZE) != 0)
2341
0
                ret = -1;
2342
0
        }
2343
2344
#ifdef WOLFSSL_USE_FLASHMEM
2345
            XFREE(seedA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2346
            XFREE(reseedSeedA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2347
            XFREE(outputA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2348
        }
2349
#endif
2350
0
    }
2351
103k
    else {
2352
#ifdef WOLFSSL_USE_FLASHMEM
2353
        byte* seedB = (byte*)XMALLOC(sizeof(seedB_data), heap,
2354
                             DYNAMIC_TYPE_TMP_BUFFER);
2355
        byte* outputB = (byte*)XMALLOC(sizeof(outputB_data), heap,
2356
                               DYNAMIC_TYPE_TMP_BUFFER);
2357
2358
        if (!seedB || !outputB) {
2359
            XFREE(seedB, heap, DYNAMIC_TYPE_TMP_BUFFER);
2360
            XFREE(outputB, heap, DYNAMIC_TYPE_TMP_BUFFER);
2361
            ret = MEMORY_E;
2362
        }
2363
        else {
2364
            XMEMCPY_P(seedB, seedB_data, sizeof(seedB_data));
2365
            XMEMCPY_P(outputB, outputB_data, sizeof(outputB_data));
2366
#else
2367
103k
        const byte* seedB = seedB_data;
2368
103k
        const byte* outputB = outputB_data;
2369
103k
#endif
2370
#if defined(DEBUG_WOLFSSL)
2371
        WOLFSSL_MSG_EX("RNG_HEALTH_TEST_CHECK_SIZE = %d",
2372
                        RNG_HEALTH_TEST_CHECK_SIZE);
2373
        WOLFSSL_MSG_EX("sizeof(seedB_data)         = %d",
2374
                        (int)sizeof(outputB_data));
2375
#endif
2376
103k
        ret = wc_RNG_HealthTest_ex(0, NULL, 0,
2377
103k
                                   seedB, sizeof(seedB_data),
2378
103k
                                   NULL, 0,
2379
103k
                                   check, RNG_HEALTH_TEST_CHECK_SIZE,
2380
103k
                                   heap, devId);
2381
103k
        if (ret != 0) {
2382
            #if defined(DEBUG_WOLFSSL)
2383
            WOLFSSL_MSG_EX("RNG_HealthTest failed: err = %d", ret);
2384
            #endif
2385
632
        }
2386
102k
        else {
2387
102k
            ret = ConstantCompare(check, outputB,
2388
102k
                                RNG_HEALTH_TEST_CHECK_SIZE);
2389
102k
            if (ret != 0) {
2390
                #if defined(DEBUG_WOLFSSL)
2391
                WOLFSSL_MSG_EX("Random ConstantCompare failed: err = %d", ret);
2392
                #endif
2393
8
                ret = -1;
2394
8
            }
2395
102k
        }
2396
2397
        /* The previous test cases use a large seed instead of a seed and nonce.
2398
         * seedB is actually from a test case with a seed and nonce, and
2399
         * just concatenates them. The pivot point between seed and nonce is
2400
         * byte 32, feed them into the health test separately. */
2401
103k
        if (ret == 0) {
2402
102k
            ret = wc_RNG_HealthTest_ex(0,
2403
102k
                                       seedB + 32, sizeof(seedB_data) - 32,
2404
102k
                                       seedB, 32,
2405
102k
                                       NULL, 0,
2406
102k
                                       check, RNG_HEALTH_TEST_CHECK_SIZE,
2407
102k
                                       heap, devId);
2408
102k
            if (ret == 0) {
2409
102k
                if (ConstantCompare(check, outputB, sizeof(outputB_data)) != 0)
2410
4
                    ret = -1;
2411
102k
            }
2412
102k
        }
2413
2414
#ifdef WOLFSSL_USE_FLASHMEM
2415
            XFREE(seedB, heap, DYNAMIC_TYPE_TMP_BUFFER);
2416
            XFREE(outputB, heap, DYNAMIC_TYPE_TMP_BUFFER);
2417
        }
2418
#endif
2419
103k
    }
2420
2421
103k
#ifdef WOLFSSL_SMALL_STACK
2422
103k
    XFREE(check, heap, DYNAMIC_TYPE_TMP_BUFFER);
2423
103k
#endif
2424
2425
103k
    return ret;
2426
110k
}
2427
2428
#endif /* HAVE_HASHDRBG */
2429
2430
2431
#ifdef HAVE_WNR
2432
2433
/*
2434
 * Init global Whitewood netRandom context
2435
 * Returns 0 on success, negative on error
2436
 */
2437
int wc_InitNetRandom(const char* configFile, wnr_hmac_key hmac_cb, int timeout)
2438
{
2439
    int ret;
2440
2441
    if (configFile == NULL || timeout < 0)
2442
        return BAD_FUNC_ARG;
2443
2444
#ifndef WOLFSSL_MUTEX_INITIALIZER
2445
    if (wnr_mutex_inited > 0) {
2446
        WOLFSSL_MSG("netRandom context already created, skipping");
2447
        return 0;
2448
    }
2449
2450
    if (wc_InitMutex(&wnr_mutex) != 0) {
2451
        WOLFSSL_MSG("Bad Init Mutex wnr_mutex");
2452
        return BAD_MUTEX_E;
2453
    }
2454
2455
    wnr_mutex_inited = 1;
2456
#endif
2457
2458
    if (wnr_inited > 0) {
2459
        WOLFSSL_MSG("netRandom context already created, skipping");
2460
        return 0;
2461
    }
2462
2463
    if (wc_LockMutex(&wnr_mutex) != 0) {
2464
        WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
2465
        return BAD_MUTEX_E;
2466
    }
2467
2468
    /* store entropy timeout */
2469
    wnr_timeout = timeout;
2470
2471
    /* create global wnr_context struct */
2472
    if (wnr_create(&wnr_ctx) != WNR_ERROR_NONE) {
2473
        WOLFSSL_MSG("Error creating global netRandom context");
2474
        ret = RNG_FAILURE_E;
2475
        goto out;
2476
    }
2477
2478
    /* load config file */
2479
    if (wnr_config_loadf(wnr_ctx, (char*)configFile) != WNR_ERROR_NONE) {
2480
        WOLFSSL_MSG("Error loading config file into netRandom context");
2481
        wnr_destroy(wnr_ctx);
2482
        wnr_ctx = NULL;
2483
        ret = RNG_FAILURE_E;
2484
        goto out;
2485
    }
2486
2487
    /* create/init polling mechanism */
2488
    if (wnr_poll_create() != WNR_ERROR_NONE) {
2489
        WOLFSSL_MSG("Error initializing netRandom polling mechanism");
2490
        wnr_destroy(wnr_ctx);
2491
        wnr_ctx = NULL;
2492
        ret = RNG_FAILURE_E;
2493
        goto out;
2494
    }
2495
2496
    /* validate config, set HMAC callback (optional) */
2497
    if (wnr_setup(wnr_ctx, hmac_cb) != WNR_ERROR_NONE) {
2498
        WOLFSSL_MSG("Error setting up netRandom context");
2499
        wnr_destroy(wnr_ctx);
2500
        wnr_ctx = NULL;
2501
        wnr_poll_destroy();
2502
        ret = RNG_FAILURE_E;
2503
        goto out;
2504
    }
2505
2506
    wnr_inited = 1;
2507
2508
out:
2509
2510
    wc_UnLockMutex(&wnr_mutex);
2511
2512
    return ret;
2513
}
2514
2515
/*
2516
 * Free global Whitewood netRandom context
2517
 * Returns 0 on success, negative on error
2518
 */
2519
int wc_FreeNetRandom(void)
2520
{
2521
    if (wnr_inited > 0) {
2522
2523
        if (wc_LockMutex(&wnr_mutex) != 0) {
2524
            WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
2525
            return BAD_MUTEX_E;
2526
        }
2527
2528
        if (wnr_ctx != NULL) {
2529
            wnr_destroy(wnr_ctx);
2530
            wnr_ctx = NULL;
2531
        }
2532
        wnr_poll_destroy();
2533
2534
        wc_UnLockMutex(&wnr_mutex);
2535
2536
#ifndef WOLFSSL_MUTEX_INITIALIZER
2537
        wc_FreeMutex(&wnr_mutex);
2538
        wnr_mutex_inited = 0;
2539
#endif
2540
2541
        wnr_inited = 0;
2542
    }
2543
2544
    return 0;
2545
}
2546
2547
#endif /* HAVE_WNR */
2548
2549
2550
#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED) || \
2551
    defined(HAVE_AMD_RDSEED)
2552
2553
#ifdef WOLFSSL_ASYNC_CRYPT
2554
    /* need more retries if multiple cores */
2555
    #define INTELRD_RETRY (32 * 8)
2556
#else
2557
    #define INTELRD_RETRY 32
2558
#endif
2559
2560
#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_AMD_RDSEED)
2561
2562
#ifndef USE_INTEL_INTRINSICS
2563
2564
    /* return 0 on success */
2565
    static WC_INLINE int IntelRDseed64(word64* seed)
2566
    {
2567
        unsigned char ok;
2568
2569
        __asm__ volatile("rdseed %0; setc %1":"=r"(*seed), "=qm"(ok));
2570
        return (ok) ? 0 : -1;
2571
    }
2572
2573
#else /* USE_INTEL_INTRINSICS */
2574
    /* The compiler Visual Studio uses does not allow inline assembly.
2575
     * It does allow for Intel intrinsic functions. */
2576
2577
    /* return 0 on success */
2578
# ifdef __GNUC__
2579
    __attribute__((target("rdseed")))
2580
# endif
2581
    static WC_INLINE int IntelRDseed64(word64* seed)
2582
    {
2583
        int ok;
2584
2585
        ok = _rdseed64_step((unsigned long long*) seed);
2586
        return (ok) ? 0 : -1;
2587
    }
2588
2589
#endif /* USE_INTEL_INTRINSICS */
2590
2591
/* return 0 on success */
2592
static WC_INLINE int IntelRDseed64_r(word64* rnd)
2593
{
2594
    int i;
2595
    for (i = 0; i < INTELRD_RETRY; i++) {
2596
        if (IntelRDseed64(rnd) == 0)
2597
            return 0;
2598
    }
2599
    return -1;
2600
}
2601
2602
/* return 0 on success */
2603
static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
2604
{
2605
    int ret;
2606
    word64 rndTmp;
2607
2608
    (void)os;
2609
2610
    if (!IS_INTEL_RDSEED(intel_flags))
2611
        return -1;
2612
2613
    for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
2614
                                                    output += sizeof(word64)) {
2615
        ret = IntelRDseed64_r((word64*)output);
2616
        if (ret != 0)
2617
            return ret;
2618
    }
2619
    if (sz == 0)
2620
        return 0;
2621
2622
    /* handle unaligned remainder */
2623
    ret = IntelRDseed64_r(&rndTmp);
2624
    if (ret != 0)
2625
        return ret;
2626
2627
    XMEMCPY(output, &rndTmp, sz);
2628
    ForceZero(&rndTmp, sizeof(rndTmp));
2629
2630
    return 0;
2631
}
2632
2633
#endif /* HAVE_INTEL_RDSEED || HAVE_AMD_RDSEED */
2634
2635
#ifdef HAVE_INTEL_RDRAND
2636
2637
#ifndef USE_INTEL_INTRINSICS
2638
2639
/* return 0 on success */
2640
static WC_INLINE int IntelRDrand64(word64 *rnd)
2641
{
2642
    unsigned char ok;
2643
2644
    __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok));
2645
2646
    return (ok) ? 0 : -1;
2647
}
2648
2649
#else /* USE_INTEL_INTRINSICS */
2650
    /* The compiler Visual Studio uses does not allow inline assembly.
2651
     * It does allow for Intel intrinsic functions. */
2652
2653
/* return 0 on success */
2654
# ifdef __GNUC__
2655
__attribute__((target("rdrnd")))
2656
# endif
2657
static WC_INLINE int IntelRDrand64(word64 *rnd)
2658
{
2659
    int ok;
2660
2661
    ok = _rdrand64_step((unsigned long long*) rnd);
2662
2663
    return (ok) ? 0 : -1;
2664
}
2665
2666
#endif /* USE_INTEL_INTRINSICS */
2667
2668
/* return 0 on success */
2669
static WC_INLINE int IntelRDrand64_r(word64 *rnd)
2670
{
2671
    int i;
2672
    for (i = 0; i < INTELRD_RETRY; i++) {
2673
        if (IntelRDrand64(rnd) == 0)
2674
            return 0;
2675
    }
2676
    return -1;
2677
}
2678
2679
/* return 0 on success */
2680
static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
2681
{
2682
    int ret;
2683
    word64 rndTmp;
2684
2685
    (void)os;
2686
2687
    if (!IS_INTEL_RDRAND(intel_flags))
2688
        return -1;
2689
2690
    for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
2691
                                                    output += sizeof(word64)) {
2692
        ret = IntelRDrand64_r((word64 *)output);
2693
        if (ret != 0)
2694
            return ret;
2695
    }
2696
    if (sz == 0)
2697
        return 0;
2698
2699
    /* handle unaligned remainder */
2700
    ret = IntelRDrand64_r(&rndTmp);
2701
    if (ret != 0)
2702
        return ret;
2703
2704
    XMEMCPY(output, &rndTmp, sz);
2705
2706
    return 0;
2707
}
2708
2709
#endif /* HAVE_INTEL_RDRAND */
2710
#endif /* HAVE_INTEL_RDRAND || HAVE_INTEL_RDSEED || HAVE_AMD_RDSEED */
2711
2712
2713
/* Begin wc_GenerateSeed Implementations */
2714
#if defined(CUSTOM_RAND_GENERATE_SEED)
2715
2716
    /* Implement your own random generation function
2717
     * Return 0 to indicate success
2718
     * int rand_gen_seed(byte* output, word32 sz);
2719
     * #define CUSTOM_RAND_GENERATE_SEED  rand_gen_seed */
2720
2721
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2722
    {
2723
        (void)os; /* Suppress unused arg warning */
2724
        return CUSTOM_RAND_GENERATE_SEED(output, sz);
2725
    }
2726
2727
#elif defined(CUSTOM_RAND_GENERATE_SEED_OS)
2728
2729
    /* Implement your own random generation function,
2730
     *  which includes OS_Seed.
2731
     * Return 0 to indicate success
2732
     * int rand_gen_seed(OS_Seed* os, byte* output, word32 sz);
2733
     * #define CUSTOM_RAND_GENERATE_SEED_OS  rand_gen_seed */
2734
2735
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2736
    {
2737
        return CUSTOM_RAND_GENERATE_SEED_OS(os, output, sz);
2738
    }
2739
2740
#elif defined(CUSTOM_RAND_GENERATE)
2741
2742
   /* Implement your own random generation function
2743
    * word32 rand_gen(void);
2744
    * #define CUSTOM_RAND_GENERATE  rand_gen  */
2745
2746
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2747
    {
2748
        word32 i = 0;
2749
2750
        (void)os;
2751
2752
        while (i < sz)
2753
        {
2754
            /* If not aligned or there is odd/remainder */
2755
            if( (i + sizeof(CUSTOM_RAND_TYPE)) > sz ||
2756
                ((wc_ptr_t)&output[i] % sizeof(CUSTOM_RAND_TYPE)) != 0
2757
            ) {
2758
                /* Single byte at a time */
2759
                output[i++] = (byte)CUSTOM_RAND_GENERATE();
2760
            }
2761
            else {
2762
                /* Use native 8, 16, 32 or 64 copy instruction */
2763
                *((CUSTOM_RAND_TYPE*)&output[i]) = CUSTOM_RAND_GENERATE();
2764
                i += sizeof(CUSTOM_RAND_TYPE);
2765
            }
2766
        }
2767
2768
        return 0;
2769
    }
2770
2771
#elif defined(WOLFSSL_SGX)
2772
2773
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2774
{
2775
    int ret = !SGX_SUCCESS;
2776
    int i, read_max = 10;
2777
2778
    for (i = 0; i < read_max && ret != SGX_SUCCESS; i++) {
2779
        ret = sgx_read_rand(output, sz);
2780
    }
2781
2782
    (void)os;
2783
    return (ret == SGX_SUCCESS) ? 0 : 1;
2784
}
2785
2786
#elif defined(USE_WINDOWS_API)
2787
2788
#ifdef WIN_REUSE_CRYPT_HANDLE
2789
/* shared crypt handle for RNG use */
2790
static ProviderHandle gHandle = 0;
2791
2792
int wc_WinCryptHandleInit(void)
2793
{
2794
    int ret = 0;
2795
    if (gHandle == 0) {
2796
        if(!CryptAcquireContext(&gHandle, 0, 0, PROV_RSA_FULL,
2797
                                        CRYPT_VERIFYCONTEXT)) {
2798
            DWORD dw = GetLastError();
2799
            WOLFSSL_MSG("CryptAcquireContext failed!");
2800
            WOLFSSL_ERROR((int)dw);
2801
            ret = WINCRYPT_E;
2802
        }
2803
    }
2804
    return ret;
2805
}
2806
2807
void wc_WinCryptHandleCleanup(void)
2808
{
2809
    if (gHandle != 0) {
2810
        CryptReleaseContext(gHandle, 0);
2811
        gHandle = 0;
2812
    }
2813
}
2814
#endif /* WIN_REUSE_CRYPT_HANDLE */
2815
2816
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2817
{
2818
#ifdef WOLF_CRYPTO_CB
2819
    int ret;
2820
2821
    if (os != NULL
2822
    #ifndef WOLF_CRYPTO_CB_FIND
2823
        && os->devId != INVALID_DEVID)
2824
    #endif
2825
    {
2826
        ret = wc_CryptoCb_RandomSeed(os, output, sz);
2827
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2828
            return ret;
2829
        /* fall-through when unavailable */
2830
    }
2831
#endif
2832
2833
    #ifdef HAVE_INTEL_RDSEED
2834
        if (IS_INTEL_RDSEED(intel_flags)) {
2835
             if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) {
2836
                 /* success, we're done */
2837
                 return 0;
2838
             }
2839
        #ifdef FORCE_FAILURE_RDSEED
2840
             /* don't fall back to CryptoAPI */
2841
             return READ_RAN_E;
2842
        #endif
2843
        }
2844
    #endif /* HAVE_INTEL_RDSEED */
2845
2846
#ifdef WIN_REUSE_CRYPT_HANDLE
2847
    /* Check that handle was initialized.
2848
     * Note: initialization should be done through:
2849
     * wolfSSL_Init -> wolfCrypt_Init -> wc_WinCryptHandleInit
2850
     */
2851
    if (wc_WinCryptHandleInit() != 0) {
2852
        return WINCRYPT_E;
2853
    }
2854
    if (!CryptGenRandom(gHandle, sz, output))
2855
        return CRYPTGEN_E;
2856
#else
2857
    if (!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
2858
                            CRYPT_VERIFYCONTEXT)) {
2859
        return WINCRYPT_E;
2860
    }
2861
    if (!CryptGenRandom(os->handle, sz, output)) {
2862
        return CRYPTGEN_E;
2863
    }
2864
    CryptReleaseContext(os->handle, 0);
2865
    os->handle = 0;
2866
#endif
2867
2868
    return 0;
2869
}
2870
2871
2872
#elif defined(HAVE_RTP_SYS) || defined(EBSNET)
2873
2874
#include "rtprand.h"   /* rtp_rand () */
2875
2876
#if (defined(HAVE_RTP_SYS) || (defined(RTPLATFORM) && (RTPLATFORM != 0)))
2877
#include "rtptime.h"   /* rtp_get_system_msec() */
2878
2879
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2880
{
2881
    word32 i;
2882
2883
    rtp_srand(rtp_get_system_msec());
2884
    for (i = 0; i < sz; i++ ) {
2885
        output[i] = rtp_rand() % 256;
2886
    }
2887
2888
    return 0;
2889
}
2890
#else
2891
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2892
{
2893
    word32 i;
2894
    KS_SEED(ks_get_ticks());
2895
2896
    for (i = 0; i < sz; i++ ) {
2897
        output[i] = KS_RANDOM() % 256;
2898
    }
2899
2900
    return 0;
2901
}
2902
#endif /* defined(HAVE_RTP_SYS) || (defined(RTPLATFORM) && (RTPLATFORM != 0)) */
2903
2904
#elif (defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC_RNG)) && \
2905
      !defined(WOLFSSL_PIC32MZ_RNG)
2906
    /* enable ATECC RNG unless using PIC32MZ one instead */
2907
    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
2908
2909
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2910
    {
2911
        int ret = 0;
2912
2913
        (void)os;
2914
        if (output == NULL) {
2915
            return BUFFER_E;
2916
        }
2917
2918
        ret = atmel_get_random_number(sz, output);
2919
2920
        return ret;
2921
    }
2922
2923
#elif defined(MICROCHIP_PIC32) || defined(MICROCHIP_MPLAB_HARMONY)
2924
2925
    #ifdef MICROCHIP_MPLAB_HARMONY
2926
        #ifdef MICROCHIP_MPLAB_HARMONY_3
2927
            #include "system/time/sys_time.h"
2928
            #define PIC32_SEED_COUNT SYS_TIME_CounterGet
2929
        #else
2930
            #define PIC32_SEED_COUNT _CP0_GET_COUNT
2931
        #endif
2932
    #else
2933
        #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
2934
            #include <peripheral/timer.h>
2935
        #endif
2936
        extern word32 ReadCoreTimer(void);
2937
        #define PIC32_SEED_COUNT ReadCoreTimer
2938
    #endif
2939
2940
    #ifdef WOLFSSL_PIC32MZ_RNG
2941
        #include "xc.h"
2942
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2943
        {
2944
            int i;
2945
            byte rnd[8];
2946
            word32 *rnd32 = (word32 *)rnd;
2947
            word32 size = sz;
2948
            byte* op = output;
2949
2950
#if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C'))
2951
            RNGNUMGEN1 = _CP0_GET_COUNT();
2952
            RNGPOLY1 = _CP0_GET_COUNT();
2953
            RNGPOLY2 = _CP0_GET_COUNT();
2954
            RNGNUMGEN2 = _CP0_GET_COUNT();
2955
#else
2956
            /* All others can be seeded from the TRNG */
2957
            RNGCONbits.TRNGMODE = 1;
2958
            RNGCONbits.TRNGEN = 1;
2959
            while (RNGCNT < 64);
2960
            RNGCONbits.LOAD = 1;
2961
            while (RNGCONbits.LOAD == 1);
2962
            while (RNGCNT < 64);
2963
            RNGPOLY2 = RNGSEED2;
2964
            RNGPOLY1 = RNGSEED1;
2965
#endif
2966
2967
            RNGCONbits.PLEN = 0x40;
2968
            RNGCONbits.PRNGEN = 1;
2969
            for (i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
2970
                volatile int x, y;
2971
                x = RNGNUMGEN1;
2972
                y = RNGNUMGEN2;
2973
                (void)x;
2974
                (void)y;
2975
            }
2976
            do {
2977
                rnd32[0] = RNGNUMGEN1;
2978
                rnd32[1] = RNGNUMGEN2;
2979
2980
                for(i=0; i<8; i++, op++) {
2981
                    *op = rnd[i];
2982
                    size --;
2983
                    if(size==0)break;
2984
                }
2985
            } while(size);
2986
            return 0;
2987
        }
2988
    #else  /* WOLFSSL_PIC32MZ_RNG */
2989
        /* uses the core timer, in nanoseconds to seed srand */
2990
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2991
        {
2992
            int i;
2993
            srand(PIC32_SEED_COUNT() * 25);
2994
2995
            for (i = 0; i < sz; i++ ) {
2996
                output[i] = rand() % 256;
2997
                if ( (i % 8) == 7)
2998
                    srand(PIC32_SEED_COUNT() * 25);
2999
            }
3000
            return 0;
3001
        }
3002
    #endif /* WOLFSSL_PIC32MZ_RNG */
3003
3004
#elif defined(FREESCALE_K70_RNGA) || defined(FREESCALE_RNGA)
3005
    /*
3006
     * wc_Generates a RNG seed using the Random Number Generator Accelerator
3007
     * on the Kinetis K70. Documentation located in Chapter 37 of
3008
     * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
3009
     */
3010
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3011
    {
3012
        word32 i;
3013
3014
        /* turn on RNGA module */
3015
        #if defined(SIM_SCGC3_RNGA_MASK)
3016
            SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
3017
        #endif
3018
        #if defined(SIM_SCGC6_RNGA_MASK)
3019
            /* additionally needed for at least K64F */
3020
            SIM_SCGC6 |= SIM_SCGC6_RNGA_MASK;
3021
        #endif
3022
3023
        /* set SLP bit to 0 - "RNGA is not in sleep mode" */
3024
        RNG_CR &= ~RNG_CR_SLP_MASK;
3025
3026
        /* set HA bit to 1 - "security violations masked" */
3027
        RNG_CR |= RNG_CR_HA_MASK;
3028
3029
        /* set GO bit to 1 - "output register loaded with data" */
3030
        RNG_CR |= RNG_CR_GO_MASK;
3031
3032
        for (i = 0; i < sz; i++) {
3033
3034
            /* wait for RNG FIFO to be full */
3035
            while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
3036
3037
            /* get value */
3038
            output[i] = RNG_OR;
3039
        }
3040
3041
        return 0;
3042
    }
3043
3044
#elif defined(FREESCALE_K53_RNGB) || defined(FREESCALE_RNGB)
3045
    /*
3046
     * wc_Generates a RNG seed using the Random Number Generator (RNGB)
3047
     * on the Kinetis K53. Documentation located in Chapter 33 of
3048
     * K53 Sub-Family Reference Manual (see note in the README for link).
3049
     */
3050
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3051
    {
3052
        int i;
3053
3054
        /* turn on RNGB module */
3055
        SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
3056
3057
        /* reset RNGB */
3058
        RNG_CMD |= RNG_CMD_SR_MASK;
3059
3060
        /* FIFO generate interrupt, return all zeros on underflow,
3061
         * set auto reseed */
3062
        RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
3063
3064
        /* gen seed, clear interrupts, clear errors */
3065
        RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
3066
3067
        /* wait for seeding to complete */
3068
        while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
3069
3070
        for (i = 0; i < sz; i++) {
3071
3072
            /* wait for a word to be available from FIFO */
3073
            while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
3074
3075
            /* get value */
3076
            output[i] = RNG_OUT;
3077
        }
3078
3079
        return 0;
3080
    }
3081
3082
#elif defined(FREESCALE_KSDK_2_0_TRNG)
3083
    #ifndef TRNG0
3084
    #define TRNG0 TRNG
3085
    #endif
3086
3087
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3088
    {
3089
        status_t status;
3090
        status = TRNG_GetRandomData(TRNG0, output, sz);
3091
        (void)os;
3092
        if (status == kStatus_Success)
3093
        {
3094
            return(0);
3095
        }
3096
        return RAN_BLOCK_E;
3097
    }
3098
3099
#elif defined(FREESCALE_KSDK_2_0_RNGA)
3100
3101
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3102
    {
3103
        status_t status;
3104
        status = RNGA_GetRandomData(RNG, output, sz);
3105
        (void)os;
3106
        if (status == kStatus_Success)
3107
        {
3108
            return(0);
3109
        }
3110
        return RAN_BLOCK_E;
3111
    }
3112
3113
3114
#elif defined(FREESCALE_RNGA)
3115
3116
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3117
    {
3118
        status_t status;
3119
        status = RNGA_GetRandomData(RNG, output, sz);
3120
        (void)os;
3121
        if (status == kStatus_Success)
3122
        {
3123
            return(0);
3124
        }
3125
        return RAN_BLOCK_E;
3126
    }
3127
#elif !defined(WOLFSSL_CAAM) && \
3128
    (defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \
3129
     defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS))
3130
    /*
3131
     * Fallback to USE_TEST_GENSEED if a FREESCALE platform did not match any
3132
     * of the TRNG/RNGA/RNGB support
3133
     */
3134
    #define USE_TEST_GENSEED
3135
3136
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
3137
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3138
    {
3139
        (void)os;
3140
        return silabs_GenerateRand(output, sz);
3141
    }
3142
3143
#elif defined(STM32_RNG)
3144
     /* Generate a RNG seed using the hardware random number generator
3145
      * on the STM32F2/F4/F7/L4. */
3146
3147
    #ifdef WOLFSSL_STM32_CUBEMX
3148
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3149
    {
3150
        int ret;
3151
        RNG_HandleTypeDef hrng;
3152
        word32 i = 0;
3153
        (void)os;
3154
3155
        ret = wolfSSL_CryptHwMutexLock();
3156
        if (ret != 0) {
3157
            return ret;
3158
        }
3159
3160
        /* enable RNG clock source */
3161
        __HAL_RCC_RNG_CLK_ENABLE();
3162
3163
        /* enable RNG peripheral */
3164
        XMEMSET(&hrng, 0, sizeof(hrng));
3165
        hrng.Instance = RNG;
3166
        HAL_RNG_Init(&hrng);
3167
3168
        while (i < sz) {
3169
            /* If not aligned or there is odd/remainder */
3170
            if( (i + sizeof(word32)) > sz ||
3171
                ((wc_ptr_t)&output[i] % sizeof(word32)) != 0
3172
            ) {
3173
                /* Single byte at a time */
3174
                uint32_t tmpRng = 0;
3175
                if (HAL_RNG_GenerateRandomNumber(&hrng, &tmpRng) != HAL_OK) {
3176
                    wolfSSL_CryptHwMutexUnLock();
3177
                    return RAN_BLOCK_E;
3178
                }
3179
                output[i++] = (byte)tmpRng;
3180
            }
3181
            else {
3182
                /* Use native 32 instruction */
3183
                if (HAL_RNG_GenerateRandomNumber(&hrng, (uint32_t*)&output[i]) != HAL_OK) {
3184
                    wolfSSL_CryptHwMutexUnLock();
3185
                    return RAN_BLOCK_E;
3186
                }
3187
                i += sizeof(word32);
3188
            }
3189
        }
3190
3191
        HAL_RNG_DeInit(&hrng);
3192
3193
        wolfSSL_CryptHwMutexUnLock();
3194
3195
        return 0;
3196
    }
3197
    #elif defined(WOLFSSL_STM32F427_RNG) || defined(WOLFSSL_STM32_RNG_NOLIB) \
3198
        || defined(STM32_NUTTX_RNG)
3199
3200
    #ifdef STM32_NUTTX_RNG
3201
        #include "hardware/stm32_rng.h"
3202
        /* Set CONFIG_STM32U5_RNG in NuttX to enable the RCC */
3203
        #define WC_RNG_CR *((volatile uint32_t*)(STM32_RNG_CR))
3204
        #define WC_RNG_SR *((volatile uint32_t*)(STM32_RNG_SR))
3205
        #define WC_RNG_DR *((volatile uint32_t*)(STM32_RNG_DR))
3206
    #else
3207
        /* Comes from "stm32xxxx_hal.h" */
3208
        #define WC_RNG_CR RNG->CR
3209
        #define WC_RNG_SR RNG->SR
3210
        #define WC_RNG_DR RNG->DR
3211
    #endif
3212
3213
3214
    /* Generate a RNG seed using the hardware RNG on the STM32F427
3215
     * directly, following steps outlined in STM32F4 Reference
3216
     * Manual (Chapter 24) for STM32F4xx family. */
3217
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3218
    {
3219
        int ret;
3220
        word32 i;
3221
        (void)os;
3222
3223
        ret = wolfSSL_CryptHwMutexLock();
3224
        if (ret != 0) {
3225
            return ret;
3226
        }
3227
3228
    #ifndef STM32_NUTTX_RNG
3229
        /* enable RNG peripheral clock */
3230
        RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
3231
    #endif
3232
3233
        /* enable RNG interrupt, set IE bit in RNG->CR register */
3234
        WC_RNG_CR |= RNG_CR_IE;
3235
3236
        /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG,
3237
         * RNG_LFSR, and error detector */
3238
        WC_RNG_CR |= RNG_CR_RNGEN;
3239
3240
        /* verify no errors, make sure SEIS and CEIS bits are 0
3241
         * in RNG->SR register */
3242
        if (WC_RNG_SR & (RNG_SR_SECS | RNG_SR_CECS)) {
3243
            wolfSSL_CryptHwMutexUnLock();
3244
            return RNG_FAILURE_E;
3245
        }
3246
3247
        for (i = 0; i < sz; i++) {
3248
            /* wait until RNG number is ready */
3249
            while ((WC_RNG_SR & RNG_SR_DRDY) == 0) { }
3250
3251
            /* get value */
3252
            output[i] = WC_RNG_DR;
3253
        }
3254
3255
        wolfSSL_CryptHwMutexUnLock();
3256
3257
        return 0;
3258
    }
3259
3260
    #else
3261
3262
    /* Generate a RNG seed using the STM32 Standard Peripheral Library */
3263
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3264
    {
3265
        int ret;
3266
        word32 i;
3267
        (void)os;
3268
3269
        ret = wolfSSL_CryptHwMutexLock();
3270
        if (ret != 0) {
3271
            return ret;
3272
        }
3273
3274
        /* enable RNG clock source */
3275
        RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
3276
3277
        /* reset RNG */
3278
        RNG_DeInit();
3279
3280
        /* enable RNG peripheral */
3281
        RNG_Cmd(ENABLE);
3282
3283
        /* verify no errors with RNG_CLK or Seed */
3284
        if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET) {
3285
            wolfSSL_CryptHwMutexUnLock();
3286
            return RNG_FAILURE_E;
3287
        }
3288
3289
        for (i = 0; i < sz; i++) {
3290
            /* wait until RNG number is ready */
3291
            while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { }
3292
3293
            /* get value */
3294
            output[i] = RNG_GetRandomNumber();
3295
        }
3296
3297
        wolfSSL_CryptHwMutexUnLock();
3298
3299
        return 0;
3300
    }
3301
    #endif /* WOLFSSL_STM32_CUBEMX */
3302
3303
#elif defined(WOLFSSL_TIRTOS)
3304
    #warning "potential for not enough entropy, currently being used for testing"
3305
    #include <xdc/runtime/Timestamp.h>
3306
    #include <stdlib.h>
3307
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3308
    {
3309
        int i;
3310
        srand(xdc_runtime_Timestamp_get32());
3311
3312
        for (i = 0; i < sz; i++ ) {
3313
            output[i] = rand() % 256;
3314
            if ((i % 8) == 7) {
3315
                srand(xdc_runtime_Timestamp_get32());
3316
            }
3317
        }
3318
3319
        return 0;
3320
    }
3321
3322
#elif defined(WOLFSSL_PB)
3323
3324
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3325
    {
3326
        word32 i;
3327
        for (i = 0; i < sz; i++)
3328
            output[i] = UTL_Rand();
3329
3330
        (void)os;
3331
3332
        return 0;
3333
    }
3334
3335
#elif defined(WOLFSSL_NUCLEUS)
3336
#include "nucleus.h"
3337
#include "kernel/plus_common.h"
3338
3339
#warning "potential for not enough entropy, currently being used for testing"
3340
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3341
{
3342
    int i;
3343
    srand(NU_Get_Time_Stamp());
3344
3345
    for (i = 0; i < sz; i++ ) {
3346
        output[i] = rand() % 256;
3347
        if ((i % 8) == 7) {
3348
            srand(NU_Get_Time_Stamp());
3349
        }
3350
    }
3351
3352
    return 0;
3353
}
3354
#elif defined(WOLFSSL_DEOS) && !defined(CUSTOM_RAND_GENERATE)
3355
    #include "stdlib.h"
3356
3357
    #warning "potential for not enough entropy, currently being used for testing Deos"
3358
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3359
    {
3360
        int i;
3361
        int seed = XTIME(0);
3362
        (void)os;
3363
3364
        for (i = 0; i < sz; i++ ) {
3365
            output[i] = rand_r(&seed) % 256;
3366
            if ((i % 8) == 7) {
3367
                seed = XTIME(0);
3368
                rand_r(&seed);
3369
            }
3370
        }
3371
3372
        return 0;
3373
    }
3374
#elif defined(WOLFSSL_VXWORKS)
3375
    #ifdef WOLFSSL_VXWORKS_6_x
3376
        #include "stdlib.h"
3377
        #warning "potential for not enough entropy, currently being used for testing"
3378
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3379
        {
3380
            int i;
3381
            unsigned int seed = (unsigned int)XTIME(0);
3382
            (void)os;
3383
3384
            for (i = 0; i < sz; i++ ) {
3385
                output[i] = rand_r(&seed) % 256;
3386
                if ((i % 8) == 7) {
3387
                    seed = (unsigned int)XTIME(0);
3388
                    rand_r(&seed);
3389
                }
3390
            }
3391
3392
            return 0;
3393
        }
3394
    #else
3395
        #include <randomNumGen.h>
3396
        #include <tickLib.h>
3397
3398
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) {
3399
            STATUS                status   = ERROR;
3400
            RANDOM_NUM_GEN_STATUS r_status = RANDOM_NUM_GEN_ERROR;
3401
            _Vx_ticks_t           seed = 0;
3402
3403
            #ifdef VXWORKS_SIM
3404
                /* cannot generate true entropy with VxWorks simulator */
3405
                #warning "not enough entropy, simulator for testing only"
3406
                int i = 0;
3407
3408
                for (i = 0; i < 1000; i++) {
3409
                    randomAddTimeStamp();
3410
                }
3411
            #endif
3412
3413
            /*
3414
              wolfSSL can request 52 Bytes of random bytes. We need to add
3415
              buffer to the entropy pool to ensure we can get more than 32 Bytes.
3416
              Because VxWorks has entropy limits (ENTROPY_MIN and ENTROPY_MAX)
3417
              defined as 256 and 1024 bits, see randomSWNumGenLib.c.
3418
3419
              randStatus() can return the following status:
3420
              RANDOM_NUM_GEN_NO_ENTROPY when entropy is 0
3421
              RANDOM_NUM_GEN_ERROR, entropy is not initialized
3422
              RANDOM_NUM_GEN_NOT_ENOUGH_ENTROPY if entropy < 32 Bytes
3423
              RANDOM_NUM_GEN_ENOUGH_ENTROPY if entropy is between 32 and 128 Bytes
3424
              RANDOM_NUM_GEN_MAX_ENTROPY if entropy is greater than 128 Bytes
3425
            */
3426
3427
            do {
3428
                seed = tickGet();
3429
                status = randAdd(&seed, sizeof(_Vx_ticks_t), 2);
3430
                if (status == OK)
3431
                    r_status = randStatus();
3432
3433
            } while (r_status != RANDOM_NUM_GEN_MAX_ENTROPY &&
3434
                     r_status != RANDOM_NUM_GEN_ERROR && status == OK);
3435
3436
            if (r_status == RANDOM_NUM_GEN_ERROR)
3437
                return RNG_FAILURE_E;
3438
3439
            status = randBytes (output, sz);
3440
3441
            if (status == ERROR) {
3442
                return RNG_FAILURE_E;
3443
            }
3444
3445
            return 0;
3446
        }
3447
    #endif
3448
#elif defined(WOLFSSL_NRF51) || defined(WOLFSSL_NRF5x)
3449
    #include "app_error.h"
3450
    #include "nrf_drv_rng.h"
3451
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3452
    {
3453
        int remaining = sz, pos = 0;
3454
        word32 err_code;
3455
        byte available;
3456
        static byte initialized = 0;
3457
3458
        (void)os;
3459
3460
        /* Make sure RNG is running */
3461
        if (!initialized) {
3462
            err_code = nrf_drv_rng_init(NULL);
3463
            if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE
3464
            #ifdef NRF_ERROR_MODULE_ALREADY_INITIALIZED
3465
                && err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED
3466
            #endif
3467
            ) {
3468
                return -1;
3469
            }
3470
            initialized = 1;
3471
        }
3472
3473
        while (remaining > 0) {
3474
            int length;
3475
            available = 0;
3476
            nrf_drv_rng_bytes_available(&available); /* void func */
3477
            length = (remaining < available) ? remaining : available;
3478
            if (length > 0) {
3479
                err_code = nrf_drv_rng_rand(&output[pos], length);
3480
                if (err_code != NRF_SUCCESS) {
3481
                    break;
3482
                }
3483
                remaining -= length;
3484
                pos += length;
3485
            }
3486
        }
3487
3488
        return (err_code == NRF_SUCCESS) ? 0 : -1;
3489
    }
3490
3491
#elif defined(HAVE_WNR)
3492
3493
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3494
    {
3495
        if (os == NULL || output == NULL || wnr_ctx == NULL ||
3496
                wnr_timeout < 0) {
3497
            return BAD_FUNC_ARG;
3498
        }
3499
3500
        if (wnr_mutex_init == 0) {
3501
            WOLFSSL_MSG("netRandom context must be created before use");
3502
            return RNG_FAILURE_E;
3503
        }
3504
3505
        if (wc_LockMutex(&wnr_mutex) != 0) {
3506
            WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
3507
            return BAD_MUTEX_E;
3508
        }
3509
3510
        if (wnr_get_entropy(wnr_ctx, wnr_timeout, output, sz, sz) !=
3511
                WNR_ERROR_NONE)
3512
            return RNG_FAILURE_E;
3513
3514
        wc_UnLockMutex(&wnr_mutex);
3515
3516
        return 0;
3517
    }
3518
3519
#elif defined(INTIME_RTOS)
3520
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3521
    {
3522
        uint32_t randval;
3523
        word32 len;
3524
3525
        if (output == NULL) {
3526
            return BUFFER_E;
3527
        }
3528
3529
    #ifdef INTIMEVER
3530
        /* If INTIMEVER exists then it is INTIME RTOS v6 or later */
3531
        #define INTIME_RAND_FUNC arc4random
3532
        len = 4;
3533
    #else
3534
        /* v5 and older */
3535
        #define INTIME_RAND_FUNC rand
3536
        srand(time(0));
3537
        len = 2; /* don't use all 31 returned bits */
3538
    #endif
3539
3540
        while (sz > 0) {
3541
            if (sz < len)
3542
                len = sz;
3543
            randval = INTIME_RAND_FUNC();
3544
            XMEMCPY(output, &randval, len);
3545
            output += len;
3546
            sz -= len;
3547
        }
3548
        (void)os;
3549
3550
        return 0;
3551
    }
3552
3553
#elif defined(WOLFSSL_WICED)
3554
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3555
    {
3556
        int ret;
3557
        (void)os;
3558
3559
        if (output == NULL || UINT16_MAX < sz) {
3560
            return BUFFER_E;
3561
        }
3562
3563
        if ((ret = wiced_crypto_get_random((void*) output, sz) )
3564
                         != WICED_SUCCESS) {
3565
            return ret;
3566
        }
3567
3568
        return ret;
3569
    }
3570
3571
#elif defined(WOLFSSL_NETBURNER)
3572
    #warning using NetBurner pseudo random GetRandomByte for seed
3573
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3574
    {
3575
        word32 i;
3576
        (void)os;
3577
3578
        if (output == NULL) {
3579
            return BUFFER_E;
3580
        }
3581
3582
        for (i = 0; i < sz; i++) {
3583
            output[i] = GetRandomByte();
3584
3585
            /* check if was a valid random number */
3586
            if (!RandomValid())
3587
                return RNG_FAILURE_E;
3588
        }
3589
3590
        return 0;
3591
    }
3592
#elif defined(IDIRECT_DEV_RANDOM)
3593
3594
    extern int getRandom( int sz, unsigned char *output );
3595
3596
    int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3597
    {
3598
        int num_bytes_returned = 0;
3599
3600
        num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );
3601
3602
        return 0;
3603
    }
3604
3605
#elif defined(WOLFSSL_CAAM)
3606
3607
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
3608
3609
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3610
    {
3611
        unsigned int args[4] = {0};
3612
        CAAM_BUFFER buf[1];
3613
        int ret    = 0;
3614
        int times  = 1000, i; /* 1000 is an arbitrary number chosen */
3615
        word32 idx = 0;
3616
3617
        (void)os;
3618
3619
        if (output == NULL) {
3620
            return BUFFER_E;
3621
        }
3622
3623
        /* Check Waiting to make sure entropy is ready */
3624
        for (i = 0; i < times; i++) {
3625
            buf[0].BufferType = DataBuffer | LastBuffer;
3626
            buf[0].TheAddress = (CAAM_ADDRESS)(output + idx);
3627
            buf[0].Length     = ((sz - idx) < WC_CAAM_MAX_ENTROPY)?
3628
                                sz - idx : WC_CAAM_MAX_ENTROPY;
3629
3630
            args[0] = buf[0].Length;
3631
            ret = wc_caamAddAndWait(buf, 1, args, CAAM_ENTROPY);
3632
            if (ret == 0) {
3633
                idx += buf[0].Length;
3634
                if (idx == sz)
3635
                    break;
3636
            }
3637
3638
            /* driver could be waiting for entropy */
3639
            if (ret != WC_NO_ERR_TRACE(RAN_BLOCK_E) && ret != 0) {
3640
                return ret;
3641
            }
3642
#ifndef WOLFSSL_IMXRT1170_CAAM
3643
            usleep(100);
3644
#endif
3645
        }
3646
3647
        if (i == times && ret != 0) {
3648
             return RNG_FAILURE_E;
3649
        }
3650
        else { /* Success case */
3651
            ret = 0;
3652
        }
3653
3654
        return ret;
3655
    }
3656
3657
#elif defined(WOLFSSL_APACHE_MYNEWT)
3658
3659
    #include <stdlib.h>
3660
    #include "os/os_time.h"
3661
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3662
    {
3663
        int i;
3664
        srand(os_time_get());
3665
3666
        for (i = 0; i < sz; i++ ) {
3667
            output[i] = rand() % 256;
3668
            if ((i % 8) == 7) {
3669
                srand(os_time_get());
3670
            }
3671
        }
3672
3673
        return 0;
3674
    }
3675
3676
#elif defined(ARDUINO)
3677
3678
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3679
    {
3680
        int ret = 0;
3681
        word32 rand;
3682
        while (sz > 0) {
3683
            word32 len = sizeof(rand);
3684
            if (sz < len)
3685
                len = sz;
3686
        /* Get an Arduino framework random number */
3687
        #if defined(ARDUINO_SAMD_NANO_33_IOT) || \
3688
            defined(ARDUINO_ARCH_RP2040)
3689
            /* Known, tested boards working with random() */
3690
            rand = random();
3691
        #elif defined(ARDUINO_SAM_DUE)
3692
            /* See: https://github.com/avrxml/asf/tree/master/sam/utils/cmsis/sam3x/include */
3693
            #if defined(__SAM3A4C__)
3694
                #ifndef TRNG
3695
                    #define TRNG (0x400BC000U)
3696
                #endif
3697
            #elif defined(__SAM3A8C__)
3698
                #ifndef TRNG
3699
                    #define TRNG (0x400BC000U)
3700
                #endif
3701
            #elif defined(__SAM3X4C__)
3702
                #ifndef TRNG
3703
                    #define TRNG (0x400BC000U)
3704
                #endif
3705
            #elif defined(__SAM3X4E__)
3706
                #ifndef TRNG
3707
                    #define TRNG (0x400BC000U)
3708
                #endif
3709
            #elif defined(__SAM3X8C__)
3710
                #ifndef TRNG
3711
                    #define TRNG (0x400BC000U)
3712
                #endif
3713
            #elif defined(__SAM3X8E__)
3714
                /* This is the Arduino Due */
3715
                #ifndef TRNG
3716
                    #define TRNG (0x400BC000U)
3717
                #endif
3718
            #elif  defined(__SAM3A8H__)
3719
                #ifndef TRNG
3720
                    #define TRNG (0x400BC000U)
3721
                #endif
3722
            #else
3723
                #ifndef TRNG
3724
                    #error "Unknown TRNG for this device"
3725
                #endif
3726
            #endif
3727
3728
            srand(analogRead(0));
3729
            rand = trng_read_output_data(TRNG);
3730
        #elif defined(__STM32__)
3731
            /* TODO: confirm this is proper random number on Arduino STM32 */
3732
            #warning "Not yet tested on STM32 targets"
3733
            rand = random();
3734
        #else
3735
            /* TODO: Pull requests appreciated for new targets.
3736
             * Do *all* other Arduino boards support random()?
3737
             * Probably not 100%, but most will likely work: */
3738
            rand = random();
3739
        #endif
3740
3741
            XMEMCPY(output, &rand, len);
3742
            output += len;
3743
            sz -= len;
3744
        }
3745
3746
        return ret;
3747
    }
3748
3749
#elif defined(WOLFSSL_ESPIDF)
3750
3751
    /* Espressif */
3752
    #if defined(WOLFSSL_ESP32) || defined(WOLFSSL_ESPWROOM32SE)
3753
3754
        /* Espressif ESP32 */
3755
        #include <esp_system.h>
3756
        #if defined(CONFIG_IDF_TARGET_ESP32S2) || \
3757
            defined(CONFIG_IDF_TARGET_ESP32S3)
3758
            #include <esp_random.h>
3759
        #endif
3760
3761
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3762
        {
3763
            word32 rand;
3764
            while (sz > 0) {
3765
                word32 len = sizeof(rand);
3766
                if (sz < len)
3767
                    len = sz;
3768
                /* Get one random 32-bit word from hw RNG */
3769
                rand = esp_random( );
3770
                XMEMCPY(output, &rand, len);
3771
                output += len;
3772
                sz -= len;
3773
            }
3774
3775
            return 0;
3776
        }
3777
3778
    #elif defined(WOLFSSL_ESP8266)
3779
3780
        /* Espressif ESP8266 */
3781
        #include <esp_system.h>
3782
3783
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3784
        {
3785
    #if defined(DEBUG_WOLFSSL)
3786
            WOLFSSL_ENTER("ESP8266 Random");
3787
    #endif
3788
            word32 rand;
3789
            while (sz > 0) {
3790
                word32 len = sizeof(rand);
3791
                if (sz < len)
3792
                    len = sz;
3793
                /* Get one random 32-bit word from hw RNG */
3794
                rand = esp_random( );
3795
                XMEMCPY(output, &rand, len);
3796
                output += len;
3797
                sz -= len;
3798
            }
3799
3800
            return 0;
3801
        }
3802
    #endif /* end WOLFSSL_ESPIDF */
3803
3804
#elif defined(WOLFSSL_LINUXKM)
3805
3806
    /* When registering the kernel default DRBG with a native/intrinsic entropy
3807
     * source, fallback to get_random_bytes() isn't allowed because we replace
3808
     * it with our DRBG.
3809
     */
3810
3811
    #if defined(HAVE_ENTROPY_MEMUSE) && \
3812
        defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT)
3813
3814
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3815
    {
3816
        (void)os;
3817
        return wc_Entropy_Get(MAX_ENTROPY_BITS, output, sz);
3818
    }
3819
3820
    #elif (defined(HAVE_INTEL_RDSEED) || defined(HAVE_AMD_RDSEED)) && \
3821
        defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT)
3822
3823
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3824
    {
3825
        (void)os;
3826
        return wc_GenerateSeed_IntelRD(NULL, output, sz);
3827
    }
3828
3829
    #else /* !((HAVE_ENTROPY_MEMUSE || HAVE_*_RDSEED) && LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) */
3830
3831
    #include <linux/random.h>
3832
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3833
    {
3834
        (void)os;
3835
        int ret;
3836
3837
    #ifdef HAVE_ENTROPY_MEMUSE
3838
        ret = wc_Entropy_Get(MAX_ENTROPY_BITS, output, sz);
3839
        if (ret == 0) {
3840
            return 0;
3841
        }
3842
        #ifdef ENTROPY_MEMUSE_FORCE_FAILURE
3843
        /* Don't fallback to /dev/urandom. */
3844
        return ret;
3845
        #endif
3846
    #endif
3847
3848
    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_AMD_RDSEED)
3849
        if (IS_INTEL_RDSEED(intel_flags)) {
3850
            ret = wc_GenerateSeed_IntelRD(NULL, output, sz);
3851
        #ifndef FORCE_FAILURE_RDSEED
3852
            if (ret == 0)
3853
        #endif
3854
            {
3855
                return ret;
3856
            }
3857
        }
3858
    #endif /* HAVE_INTEL_RDSEED || HAVE_AMD_RDSEED */
3859
3860
        (void)ret;
3861
3862
        get_random_bytes(output, sz);
3863
        return 0;
3864
    }
3865
3866
    #endif /* !(HAVE_*_RDSEED && LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) */
3867
3868
#elif defined(WOLFSSL_RENESAS_TSIP)
3869
3870
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3871
    {
3872
        (void)os;
3873
        return wc_tsip_GenerateRandBlock(output, sz);
3874
    }
3875
3876
3877
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG)
3878
    #include "hal_data.h"
3879
3880
    #ifndef WOLFSSL_SCE_TRNG_HANDLE
3881
        #define WOLFSSL_SCE_TRNG_HANDLE g_sce_trng
3882
    #endif
3883
3884
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3885
    {
3886
        word32 ret;
3887
        word32 blocks;
3888
        word32 len = sz;
3889
3890
        ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->open(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl,
3891
                                                  WOLFSSL_SCE_TRNG_HANDLE.p_cfg);
3892
        if (ret != SSP_SUCCESS && ret != SSP_ERR_CRYPTO_ALREADY_OPEN) {
3893
            /* error opening TRNG driver */
3894
            return -1;
3895
        }
3896
3897
        blocks = sz / sizeof(word32);
3898
        if (blocks > 0) {
3899
            ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->read(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl,
3900
                                                       (word32*)output, blocks);
3901
            if (ret != SSP_SUCCESS) {
3902
                return -1;
3903
            }
3904
        }
3905
3906
        len = len - (blocks * sizeof(word32));
3907
        if (len > 0) {
3908
            word32 tmp;
3909
3910
            if (len > sizeof(word32)) {
3911
                return -1;
3912
            }
3913
            ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->read(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl,
3914
                                                      (word32*)&tmp, 1);
3915
            if (ret != SSP_SUCCESS) {
3916
                return -1;
3917
            }
3918
            XMEMCPY(output + (blocks * sizeof(word32)), (byte*)&tmp, len);
3919
        }
3920
3921
        ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->close(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl);
3922
        if (ret != SSP_SUCCESS) {
3923
            /* error opening TRNG driver */
3924
            return -1;
3925
        }
3926
        return 0;
3927
    }
3928
#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
3929
    /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
3930
     * extern int myRngFunc(byte* output, word32 sz);
3931
     */
3932
3933
#elif defined(__MICROBLAZE__)
3934
    #warning weak source of entropy
3935
    #define LPD_SCNTR_BASE_ADDRESS 0xFF250000
3936
3937
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3938
    {
3939
        word32* cnt;
3940
        word32 i;
3941
3942
        /* using current time with srand */
3943
        cnt = (word32*)LPD_SCNTR_BASE_ADDRESS;
3944
        srand(*cnt | *(cnt+1));
3945
3946
        for (i = 0; i < sz; i++)
3947
            output[i] = rand();
3948
3949
        (void)os;
3950
        return 0;
3951
    }
3952
3953
#elif defined(WOLFSSL_ZEPHYR)
3954
3955
    #include <version.h>
3956
3957
    #if KERNEL_VERSION_NUMBER >= 0x30500
3958
        #include <zephyr/random/random.h>
3959
    #else
3960
        #if KERNEL_VERSION_NUMBER >= 0x30100
3961
            #include <zephyr/random/rand32.h>
3962
        #else
3963
            #include <random/rand32.h>
3964
        #endif
3965
    #endif
3966
3967
    #ifndef _POSIX_C_SOURCE
3968
        #if KERNEL_VERSION_NUMBER >= 0x30100
3969
            #include <zephyr/posix/time.h>
3970
        #else
3971
            #include <posix/time.h>
3972
        #endif
3973
    #else
3974
        #include <time.h>
3975
    #endif
3976
3977
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3978
    {
3979
        sys_rand_get(output, sz);
3980
        return 0;
3981
    }
3982
3983
#elif defined(WOLFSSL_TELIT_M2MB)
3984
3985
        #include "stdlib.h"
3986
        static long get_timestamp(void) {
3987
            long myTime = 0;
3988
            INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
3989
            if (fd >= 0) {
3990
                M2MB_RTC_TIMEVAL_T timeval;
3991
                m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
3992
                myTime = timeval.msec;
3993
                m2mb_rtc_close(fd);
3994
            }
3995
            return myTime;
3996
        }
3997
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
3998
        {
3999
            int i;
4000
            srand(get_timestamp());
4001
            for (i = 0; i < sz; i++ ) {
4002
                output[i] = rand() % 256;
4003
                if ((i % 8) == 7) {
4004
                    srand(get_timestamp());
4005
                }
4006
            }
4007
            return 0;
4008
        }
4009
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_TRNG)
4010
     #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
4011
4012
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz){
4013
        int ret = 0;
4014
4015
        (void)os;
4016
4017
        if (output == NULL) {
4018
            return BUFFER_E;
4019
        }
4020
        ret = wolfSSL_CryptHwMutexLock();
4021
        if (ret == 0) {
4022
            ret = se050_get_random_number(sz, output);
4023
            wolfSSL_CryptHwMutexUnLock();
4024
        }
4025
        return ret;
4026
    }
4027
4028
#elif defined(DOLPHIN_EMULATOR) || defined (WOLFSSL_NDS)
4029
4030
        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4031
        {
4032
            word32 i;
4033
            (void)os;
4034
            srand(time(NULL));
4035
            for (i = 0; i < sz; i++)
4036
                output[i] = (byte)rand();
4037
            return 0;
4038
        }
4039
#elif defined(WOLFSSL_MAXQ108X) || defined(WOLFSSL_MAXQ1065)
4040
4041
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4042
    {
4043
        (void)os;
4044
4045
        return maxq10xx_random(output, sz);
4046
    }
4047
#elif defined(MAX3266X_RNG)
4048
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4049
    {
4050
        #ifdef WOLFSSL_MAX3266X
4051
        int status;
4052
        #endif /* WOLFSSL_MAX3266X */
4053
        static int initDone = 0;
4054
        (void)os;
4055
        if (initDone == 0) {
4056
            #ifdef WOLFSSL_MAX3266X
4057
            status = wolfSSL_HwRngMutexLock();
4058
            if (status != 0) {
4059
                return status;
4060
            }
4061
            #endif /* WOLFSSL_MAX3266X */
4062
            if(MXC_TRNG_HealthTest() != 0) {
4063
                #ifdef DEBUG_WOLFSSL
4064
                WOLFSSL_MSG("TRNG HW Health Test Failed");
4065
                #endif /* DEBUG_WOLFSSL */
4066
                #ifdef WOLFSSL_MAX3266X
4067
                wolfSSL_HwRngMutexUnLock();
4068
                #endif /* WOLFSSL_MAX3266X */
4069
                return WC_HW_E;
4070
            }
4071
            #ifdef WOLFSSL_MAX3266X
4072
            wolfSSL_HwRngMutexUnLock();
4073
            #endif /* WOLFSSL_MAX3266X */
4074
            initDone = 1;
4075
        }
4076
        return wc_MXC_TRNG_Random(output, sz);
4077
    }
4078
4079
#elif defined(CY_USING_HAL) && defined(COMPONENT_WOLFSSL)
4080
4081
    /* Infineon/Cypress HAL RNG implementation */
4082
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4083
    {
4084
        cyhal_trng_t obj;
4085
        cy_rslt_t result;
4086
        uint32_t val;
4087
        word32 i = 0;
4088
4089
        (void)os;
4090
4091
        result = cyhal_trng_init(&obj);
4092
        if (result == CY_RSLT_SUCCESS) {
4093
            while (i < sz) {
4094
                /* If not aligned or there is odd/remainder add single byte */
4095
                if( (i + sizeof(word32)) > sz ||
4096
                    ((wc_ptr_t)&output[i] % sizeof(word32)) != 0
4097
                ) {
4098
                    val = cyhal_trng_generate(&obj);
4099
                    output[i++] = (byte)val;
4100
                }
4101
                else {
4102
                    /* Use native 32 instruction */
4103
                    val = cyhal_trng_generate(&obj);
4104
                    *((uint32_t*)&output[i]) = val;
4105
                    i += sizeof(word32);
4106
                }
4107
            }
4108
            cyhal_trng_free(&obj);
4109
        }
4110
        return 0;
4111
    }
4112
4113
#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \
4114
      defined(WOLFSSL_IAR_ARM)  || defined(WOLFSSL_MDK_ARM) || \
4115
      defined(WOLFSSL_uITRON4)  || defined(WOLFSSL_uTKERNEL2) || \
4116
      defined(WOLFSSL_LPC43xx)  || defined(NO_STM32_RNG) || \
4117
      defined(MBED)             || defined(WOLFSSL_EMBOS) || \
4118
      defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \
4119
      defined(WOLFSSL_CONTIKI)  || defined(WOLFSSL_AZSPHERE)
4120
4121
    /* these platforms do not have a default random seed and
4122
       you'll need to implement your own wc_GenerateSeed or define via
4123
       CUSTOM_RAND_GENERATE_BLOCK */
4124
4125
    #define USE_TEST_GENSEED
4126
4127
#elif defined(NO_DEV_RANDOM)
4128
4129
    /* Allow bare-metal targets to use cryptoCb as seed provider */
4130
    #if defined(WOLF_CRYPTO_CB)
4131
4132
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4133
    {
4134
        int ret = WC_NO_ERR_TRACE(WC_HW_E);
4135
4136
        #ifndef WOLF_CRYPTO_CB_FIND
4137
        if (os->devId != INVALID_DEVID)
4138
        #endif
4139
        {
4140
            ret = wc_CryptoCb_RandomSeed(os, output, sz);
4141
            if (ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
4142
                ret = WC_HW_E;
4143
            }
4144
        }
4145
4146
        return ret;
4147
    }
4148
4149
    #else /* defined(WOLF_CRYPTO_CB)*/
4150
4151
    #error "you need to write an os specific wc_GenerateSeed() here"
4152
4153
    /*
4154
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4155
    {
4156
        return 0;
4157
    }
4158
    */
4159
4160
   #endif  /* !defined(WOLF_CRYPTO_CB) */
4161
4162
#else
4163
4164
    /* may block */
4165
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4166
102k
    {
4167
102k
        int ret = 0;
4168
4169
102k
        if (os == NULL) {
4170
0
            return BAD_FUNC_ARG;
4171
0
        }
4172
4173
102k
    #ifdef WOLF_CRYPTO_CB
4174
102k
        #ifndef WOLF_CRYPTO_CB_FIND
4175
102k
        if (os->devId != INVALID_DEVID)
4176
9
        #endif
4177
9
        {
4178
9
            ret = wc_CryptoCb_RandomSeed(os, output, sz);
4179
9
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4180
9
                return ret;
4181
            /* fall-through when unavailable */
4182
0
            ret = 0; /* reset error code */
4183
0
        }
4184
102k
    #endif
4185
4186
    #ifdef HAVE_ENTROPY_MEMUSE
4187
        ret = wc_Entropy_Get(MAX_ENTROPY_BITS, output, sz);
4188
        if (ret == 0) {
4189
            return 0;
4190
        }
4191
     #ifdef ENTROPY_MEMUSE_FORCE_FAILURE
4192
        /* Don't fallback to /dev/urandom. */
4193
        return ret;
4194
    #endif
4195
    #endif
4196
4197
    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_AMD_RDSEED)
4198
        if (IS_INTEL_RDSEED(intel_flags)) {
4199
             ret = wc_GenerateSeed_IntelRD(NULL, output, sz);
4200
             if (ret == 0) {
4201
                 /* success, we're done */
4202
                 return ret;
4203
             }
4204
        #ifdef FORCE_FAILURE_RDSEED
4205
             /* don't fallback to /dev/urandom */
4206
             return ret;
4207
        #else
4208
             /* reset error and fallback to using /dev/urandom */
4209
             ret = 0;
4210
        #endif
4211
        }
4212
    #endif /* HAVE_INTEL_RDSEED || HAVE_AMD_RDSEED */
4213
4214
102k
    #if defined(WOLFSSL_GETRANDOM) || defined(HAVE_GETRANDOM)
4215
102k
        {
4216
102k
            word32 grSz = sz;
4217
102k
            byte* grOutput = output;
4218
4219
205k
            while (grSz) {
4220
102k
                ssize_t len;
4221
4222
102k
                errno = 0;
4223
102k
                len = getrandom(grOutput, grSz, 0);
4224
102k
                if (len == -1) {
4225
0
                    if (errno == EINTR) {
4226
                        /* interrupted, call getrandom again */
4227
0
                        continue;
4228
0
                    }
4229
0
                    else {
4230
0
                        ret = READ_RAN_E;
4231
0
                    }
4232
0
                    break;
4233
0
                }
4234
4235
102k
                grSz     -= (word32)len;
4236
102k
                grOutput += len;
4237
102k
            }
4238
102k
            if (ret == 0)
4239
102k
                return ret;
4240
        #ifdef FORCE_FAILURE_GETRANDOM
4241
            /* don't fallback to /dev/urandom */
4242
            return ret;
4243
        #else
4244
            /* reset error and fallback to using /dev/urandom */
4245
0
            ret = 0;
4246
0
        #endif
4247
0
        }
4248
0
    #endif
4249
4250
0
#ifndef NO_FILESYSTEM
4251
0
    #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
4252
0
        os->fd = open("/dev/urandom", O_RDONLY);
4253
        #if defined(DEBUG_WOLFSSL)
4254
            WOLFSSL_MSG("opened /dev/urandom.");
4255
        #endif
4256
0
        if (os->fd == -1)
4257
0
    #endif
4258
0
        {
4259
            /* may still have /dev/random */
4260
0
            os->fd = open("/dev/random", O_RDONLY);
4261
    #if defined(DEBUG_WOLFSSL)
4262
            WOLFSSL_MSG("opened /dev/random.");
4263
    #endif
4264
0
            if (os->fd == -1)
4265
0
                return OPEN_RAN_E;
4266
0
        }
4267
    #if defined(DEBUG_WOLFSSL)
4268
        WOLFSSL_MSG("rnd read...");
4269
    #endif
4270
0
        while (sz) {
4271
0
            int len = (int)read(os->fd, output, sz);
4272
0
            if (len == -1) {
4273
0
                ret = READ_RAN_E;
4274
0
                break;
4275
0
            }
4276
4277
0
            sz     -= (word32)len;
4278
0
            output += len;
4279
4280
0
            if (sz) {
4281
    #if defined(BLOCKING) || defined(WC_RNG_BLOCKING)
4282
                sleep(0);             /* context switch */
4283
    #else
4284
0
                ret = RAN_BLOCK_E;
4285
0
                break;
4286
0
    #endif
4287
0
            }
4288
0
        }
4289
0
        close(os->fd);
4290
#else
4291
        ret = NOT_COMPILED_IN;
4292
#endif /* NO_FILESYSTEM */
4293
4294
0
        return ret;
4295
0
    }
4296
4297
#endif
4298
4299
#ifdef USE_TEST_GENSEED
4300
    #ifndef _MSC_VER
4301
        #warning "write a real random seed!!!!, just for testing now"
4302
    #else
4303
        #pragma message("Warning: write a real random seed!!!!, just for testing now")
4304
    #endif
4305
    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
4306
    {
4307
        word32 i;
4308
        for (i = 0; i < sz; i++ )
4309
            output[i] = (byte)i;
4310
4311
        (void)os;
4312
4313
        return 0;
4314
    }
4315
#endif
4316
/* End wc_GenerateSeed */
4317
4318
#if defined(CUSTOM_RAND_GENERATE_BLOCK) && defined(WOLFSSL_KCAPI)
4319
#include <fcntl.h>
4320
int wc_hwrng_generate_block(byte *output, word32 sz)
4321
{
4322
    int fd;
4323
    int ret = 0;
4324
    fd = open("/dev/hwrng", O_RDONLY);
4325
    if (fd == -1)
4326
        return OPEN_RAN_E;
4327
    while(sz)
4328
    {
4329
        int len = (int)read(fd, output, sz);
4330
        if (len == -1)
4331
        {
4332
            ret = READ_RAN_E;
4333
            break;
4334
        }
4335
        sz -= len;
4336
        output += len;
4337
    }
4338
    close(fd);
4339
    return ret;
4340
}
4341
#endif
4342
4343
#endif /* WC_NO_RNG */