Coverage Report

Created: 2025-11-16 07:15

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