Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Sat Aug 18 22:20:43 2018 +0000
Revision:
15:117db924cf7c
Child:
16:048e5e270a58
wolfSSL 3.15.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* random.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 15:117db924cf7c 3 * Copyright (C) 2006-2017 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 24 #include <config.h>
wolfSSL 15:117db924cf7c 25 #endif
wolfSSL 15:117db924cf7c 26
wolfSSL 15:117db924cf7c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 28 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 29
wolfSSL 15:117db924cf7c 30 /* on HPUX 11 you may need to install /dev/random see
wolfSSL 15:117db924cf7c 31 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
wolfSSL 15:117db924cf7c 32
wolfSSL 15:117db924cf7c 33 */
wolfSSL 15:117db924cf7c 34
wolfSSL 15:117db924cf7c 35 #if defined(HAVE_FIPS) && \
wolfSSL 15:117db924cf7c 36 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
wolfSSL 15:117db924cf7c 37
wolfSSL 15:117db924cf7c 38 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
wolfSSL 15:117db924cf7c 39 #define FIPS_NO_WRAPPERS
wolfSSL 15:117db924cf7c 40
wolfSSL 15:117db924cf7c 41 #ifdef USE_WINDOWS_API
wolfSSL 15:117db924cf7c 42 #pragma code_seg(".fipsA$c")
wolfSSL 15:117db924cf7c 43 #pragma const_seg(".fipsB$c")
wolfSSL 15:117db924cf7c 44 #endif
wolfSSL 15:117db924cf7c 45 #endif
wolfSSL 15:117db924cf7c 46
wolfSSL 15:117db924cf7c 47
wolfSSL 15:117db924cf7c 48 #include <wolfssl/wolfcrypt/random.h>
wolfSSL 15:117db924cf7c 49 #include <wolfssl/wolfcrypt/cpuid.h>
wolfSSL 15:117db924cf7c 50
wolfSSL 15:117db924cf7c 51
wolfSSL 15:117db924cf7c 52 /* If building for old FIPS. */
wolfSSL 15:117db924cf7c 53 #if defined(HAVE_FIPS) && \
wolfSSL 15:117db924cf7c 54 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
wolfSSL 15:117db924cf7c 55
wolfSSL 15:117db924cf7c 56 int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
wolfSSL 15:117db924cf7c 57 {
wolfSSL 15:117db924cf7c 58 return GenerateSeed(os, seed, sz);
wolfSSL 15:117db924cf7c 59 }
wolfSSL 15:117db924cf7c 60
wolfSSL 15:117db924cf7c 61 int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
wolfSSL 15:117db924cf7c 62 {
wolfSSL 15:117db924cf7c 63 (void)heap;
wolfSSL 15:117db924cf7c 64 (void)devId;
wolfSSL 15:117db924cf7c 65 return InitRng_fips(rng);
wolfSSL 15:117db924cf7c 66 }
wolfSSL 15:117db924cf7c 67
wolfSSL 15:117db924cf7c 68 int wc_InitRng(WC_RNG* rng)
wolfSSL 15:117db924cf7c 69 {
wolfSSL 15:117db924cf7c 70 return InitRng_fips(rng);
wolfSSL 15:117db924cf7c 71 }
wolfSSL 15:117db924cf7c 72
wolfSSL 15:117db924cf7c 73
wolfSSL 15:117db924cf7c 74 int wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz)
wolfSSL 15:117db924cf7c 75 {
wolfSSL 15:117db924cf7c 76 return RNG_GenerateBlock_fips(rng, b, sz);
wolfSSL 15:117db924cf7c 77 }
wolfSSL 15:117db924cf7c 78
wolfSSL 15:117db924cf7c 79
wolfSSL 15:117db924cf7c 80 int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
wolfSSL 15:117db924cf7c 81 {
wolfSSL 15:117db924cf7c 82 return RNG_GenerateByte(rng, b);
wolfSSL 15:117db924cf7c 83 }
wolfSSL 15:117db924cf7c 84
wolfSSL 15:117db924cf7c 85 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 86
wolfSSL 15:117db924cf7c 87 int wc_FreeRng(WC_RNG* rng)
wolfSSL 15:117db924cf7c 88 {
wolfSSL 15:117db924cf7c 89 return FreeRng_fips(rng);
wolfSSL 15:117db924cf7c 90 }
wolfSSL 15:117db924cf7c 91
wolfSSL 15:117db924cf7c 92 int wc_RNG_HealthTest(int reseed,
wolfSSL 15:117db924cf7c 93 const byte* entropyA, word32 entropyASz,
wolfSSL 15:117db924cf7c 94 const byte* entropyB, word32 entropyBSz,
wolfSSL 15:117db924cf7c 95 byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 96 {
wolfSSL 15:117db924cf7c 97 return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
wolfSSL 15:117db924cf7c 98 entropyB, entropyBSz, output, outputSz);
wolfSSL 15:117db924cf7c 99 }
wolfSSL 15:117db924cf7c 100 #endif /* HAVE_HASHDRBG */
wolfSSL 15:117db924cf7c 101
wolfSSL 15:117db924cf7c 102 #else /* else build without fips, or for new fips */
wolfSSL 15:117db924cf7c 103
wolfSSL 15:117db924cf7c 104 #ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */
wolfSSL 15:117db924cf7c 105
wolfSSL 15:117db924cf7c 106 #include <wolfssl/wolfcrypt/sha256.h>
wolfSSL 15:117db924cf7c 107
wolfSSL 15:117db924cf7c 108 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 109 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 110 #else
wolfSSL 15:117db924cf7c 111 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 112 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 113 #endif
wolfSSL 15:117db924cf7c 114
wolfSSL 15:117db924cf7c 115 #if defined(WOLFSSL_SGX)
wolfSSL 15:117db924cf7c 116 #include <sgx_trts.h>
wolfSSL 15:117db924cf7c 117 #elif defined(USE_WINDOWS_API)
wolfSSL 15:117db924cf7c 118 #ifndef _WIN32_WINNT
wolfSSL 15:117db924cf7c 119 #define _WIN32_WINNT 0x0400
wolfSSL 15:117db924cf7c 120 #endif
wolfSSL 15:117db924cf7c 121 #include <windows.h>
wolfSSL 15:117db924cf7c 122 #include <wincrypt.h>
wolfSSL 15:117db924cf7c 123 #elif defined(HAVE_WNR)
wolfSSL 15:117db924cf7c 124 #include <wnr.h>
wolfSSL 15:117db924cf7c 125 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 15:117db924cf7c 126 wolfSSL_Mutex wnr_mutex; /* global netRandom mutex */
wolfSSL 15:117db924cf7c 127 int wnr_timeout = 0; /* entropy timeout, mililseconds */
wolfSSL 15:117db924cf7c 128 int wnr_mutex_init = 0; /* flag for mutex init */
wolfSSL 15:117db924cf7c 129 wnr_context* wnr_ctx; /* global netRandom context */
wolfSSL 15:117db924cf7c 130 #elif defined(FREESCALE_KSDK_2_0_TRNG)
wolfSSL 15:117db924cf7c 131 #include "fsl_trng.h"
wolfSSL 15:117db924cf7c 132 #elif defined(FREESCALE_KSDK_2_0_RNGA)
wolfSSL 15:117db924cf7c 133 #include "fsl_rnga.h"
wolfSSL 15:117db924cf7c 134
wolfSSL 15:117db924cf7c 135 #elif defined(NO_DEV_RANDOM)
wolfSSL 15:117db924cf7c 136 #elif defined(CUSTOM_RAND_GENERATE)
wolfSSL 15:117db924cf7c 137 #elif defined(CUSTOM_RAND_GENERATE_BLOCK)
wolfSSL 15:117db924cf7c 138 #elif defined(CUSTOM_RAND_GENERATE_SEED)
wolfSSL 15:117db924cf7c 139 #elif defined(WOLFSSL_GENSEED_FORTEST)
wolfSSL 15:117db924cf7c 140 #elif defined(WOLFSSL_MDK_ARM)
wolfSSL 15:117db924cf7c 141 #elif defined(WOLFSSL_IAR_ARM)
wolfSSL 15:117db924cf7c 142 #elif defined(WOLFSSL_ROWLEY_ARM)
wolfSSL 15:117db924cf7c 143 #elif defined(WOLFSSL_EMBOS)
wolfSSL 15:117db924cf7c 144 #elif defined(MICRIUM)
wolfSSL 15:117db924cf7c 145 #elif defined(WOLFSSL_NUCLEUS)
wolfSSL 15:117db924cf7c 146 #elif defined(WOLFSSL_PB)
wolfSSL 15:117db924cf7c 147 #else
wolfSSL 15:117db924cf7c 148 /* include headers that may be needed to get good seed */
wolfSSL 15:117db924cf7c 149 #include <fcntl.h>
wolfSSL 15:117db924cf7c 150 #ifndef EBSNET
wolfSSL 15:117db924cf7c 151 #include <unistd.h>
wolfSSL 15:117db924cf7c 152 #endif
wolfSSL 15:117db924cf7c 153 #endif
wolfSSL 15:117db924cf7c 154
wolfSSL 15:117db924cf7c 155
wolfSSL 15:117db924cf7c 156 #if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)
wolfSSL 15:117db924cf7c 157 static word32 intel_flags = 0;
wolfSSL 15:117db924cf7c 158 static void wc_InitRng_IntelRD(void)
wolfSSL 15:117db924cf7c 159 {
wolfSSL 15:117db924cf7c 160 intel_flags = cpuid_get_flags();
wolfSSL 15:117db924cf7c 161 }
wolfSSL 15:117db924cf7c 162 #ifdef HAVE_INTEL_RDSEED
wolfSSL 15:117db924cf7c 163 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz);
wolfSSL 15:117db924cf7c 164 #endif
wolfSSL 15:117db924cf7c 165 #ifdef HAVE_INTEL_RDRAND
wolfSSL 15:117db924cf7c 166 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);
wolfSSL 15:117db924cf7c 167 #endif
wolfSSL 15:117db924cf7c 168
wolfSSL 15:117db924cf7c 169 #ifdef USE_WINDOWS_API
wolfSSL 15:117db924cf7c 170 #include <immintrin.h>
wolfSSL 15:117db924cf7c 171 #endif /* USE_WINDOWS_API */
wolfSSL 15:117db924cf7c 172 #endif
wolfSSL 15:117db924cf7c 173
wolfSSL 15:117db924cf7c 174 /* Start NIST DRBG code */
wolfSSL 15:117db924cf7c 175 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 176
wolfSSL 15:117db924cf7c 177 #define OUTPUT_BLOCK_LEN (WC_SHA256_DIGEST_SIZE)
wolfSSL 15:117db924cf7c 178 #define MAX_REQUEST_LEN (0x10000)
wolfSSL 15:117db924cf7c 179 #define RESEED_INTERVAL WC_RESEED_INTERVAL
wolfSSL 15:117db924cf7c 180 #define SECURITY_STRENGTH (2048)
wolfSSL 15:117db924cf7c 181 #define ENTROPY_SZ (SECURITY_STRENGTH/8)
wolfSSL 15:117db924cf7c 182 #define MAX_ENTROPY_SZ (ENTROPY_SZ + ENTROPY_SZ/2)
wolfSSL 15:117db924cf7c 183
wolfSSL 15:117db924cf7c 184 /* Internal return codes */
wolfSSL 15:117db924cf7c 185 #define DRBG_SUCCESS 0
wolfSSL 15:117db924cf7c 186 #define DRBG_FAILURE 1
wolfSSL 15:117db924cf7c 187 #define DRBG_NEED_RESEED 2
wolfSSL 15:117db924cf7c 188 #define DRBG_CONT_FAILURE 3
wolfSSL 15:117db924cf7c 189
wolfSSL 15:117db924cf7c 190 /* RNG health states */
wolfSSL 15:117db924cf7c 191 #define DRBG_NOT_INIT 0
wolfSSL 15:117db924cf7c 192 #define DRBG_OK 1
wolfSSL 15:117db924cf7c 193 #define DRBG_FAILED 2
wolfSSL 15:117db924cf7c 194 #define DRBG_CONT_FAILED 3
wolfSSL 15:117db924cf7c 195
wolfSSL 15:117db924cf7c 196 #define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4)
wolfSSL 15:117db924cf7c 197
wolfSSL 15:117db924cf7c 198 /* Verify max gen block len */
wolfSSL 15:117db924cf7c 199 #if RNG_MAX_BLOCK_LEN > MAX_REQUEST_LEN
wolfSSL 15:117db924cf7c 200 #error RNG_MAX_BLOCK_LEN is larger than NIST DBRG max request length
wolfSSL 15:117db924cf7c 201 #endif
wolfSSL 15:117db924cf7c 202
wolfSSL 15:117db924cf7c 203 enum {
wolfSSL 15:117db924cf7c 204 drbgInitC = 0,
wolfSSL 15:117db924cf7c 205 drbgReseed = 1,
wolfSSL 15:117db924cf7c 206 drbgGenerateW = 2,
wolfSSL 15:117db924cf7c 207 drbgGenerateH = 3,
wolfSSL 15:117db924cf7c 208 drbgInitV
wolfSSL 15:117db924cf7c 209 };
wolfSSL 15:117db924cf7c 210
wolfSSL 15:117db924cf7c 211
wolfSSL 15:117db924cf7c 212 typedef struct DRBG {
wolfSSL 15:117db924cf7c 213 word32 reseedCtr;
wolfSSL 15:117db924cf7c 214 word32 lastBlock;
wolfSSL 15:117db924cf7c 215 byte V[DRBG_SEED_LEN];
wolfSSL 15:117db924cf7c 216 byte C[DRBG_SEED_LEN];
wolfSSL 15:117db924cf7c 217 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 218 void* heap;
wolfSSL 15:117db924cf7c 219 int devId;
wolfSSL 15:117db924cf7c 220 #endif
wolfSSL 15:117db924cf7c 221 byte matchCount;
wolfSSL 15:117db924cf7c 222 #ifdef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 223 wc_Sha256 sha256;
wolfSSL 15:117db924cf7c 224 #endif
wolfSSL 15:117db924cf7c 225 } DRBG;
wolfSSL 15:117db924cf7c 226
wolfSSL 15:117db924cf7c 227
wolfSSL 15:117db924cf7c 228 static int wc_RNG_HealthTestLocal(int reseed);
wolfSSL 15:117db924cf7c 229
wolfSSL 15:117db924cf7c 230 /* Hash Derivation Function */
wolfSSL 15:117db924cf7c 231 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 15:117db924cf7c 232 static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
wolfSSL 15:117db924cf7c 233 const byte* inA, word32 inASz,
wolfSSL 15:117db924cf7c 234 const byte* inB, word32 inBSz)
wolfSSL 15:117db924cf7c 235 {
wolfSSL 15:117db924cf7c 236 int ret = DRBG_FAILURE;
wolfSSL 15:117db924cf7c 237 byte ctr;
wolfSSL 15:117db924cf7c 238 int i;
wolfSSL 15:117db924cf7c 239 int len;
wolfSSL 15:117db924cf7c 240 word32 bits = (outSz * 8); /* reverse byte order */
wolfSSL 15:117db924cf7c 241 #ifdef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 242 wc_Sha256* sha = &drbg->sha256;
wolfSSL 15:117db924cf7c 243 #else
wolfSSL 15:117db924cf7c 244 wc_Sha256 sha[1];
wolfSSL 15:117db924cf7c 245 #endif
wolfSSL 15:117db924cf7c 246 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
wolfSSL 15:117db924cf7c 247
wolfSSL 15:117db924cf7c 248 (void)drbg;
wolfSSL 15:117db924cf7c 249 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 250 if (digest == NULL)
wolfSSL 15:117db924cf7c 251 return DRBG_FAILURE;
wolfSSL 15:117db924cf7c 252 #endif
wolfSSL 15:117db924cf7c 253
wolfSSL 15:117db924cf7c 254 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 255 bits = ByteReverseWord32(bits);
wolfSSL 15:117db924cf7c 256 #endif
wolfSSL 15:117db924cf7c 257 len = (outSz / OUTPUT_BLOCK_LEN)
wolfSSL 15:117db924cf7c 258 + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
wolfSSL 15:117db924cf7c 259
wolfSSL 15:117db924cf7c 260 for (i = 0, ctr = 1; i < len; i++, ctr++) {
wolfSSL 15:117db924cf7c 261 #ifndef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 262 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 263 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
wolfSSL 15:117db924cf7c 264 #else
wolfSSL 15:117db924cf7c 265 ret = wc_InitSha256(sha);
wolfSSL 15:117db924cf7c 266 #endif
wolfSSL 15:117db924cf7c 267 if (ret != 0)
wolfSSL 15:117db924cf7c 268 break;
wolfSSL 15:117db924cf7c 269
wolfSSL 15:117db924cf7c 270 if (ret == 0)
wolfSSL 15:117db924cf7c 271 #endif
wolfSSL 15:117db924cf7c 272 ret = wc_Sha256Update(sha, &ctr, sizeof(ctr));
wolfSSL 15:117db924cf7c 273 if (ret == 0)
wolfSSL 15:117db924cf7c 274 ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits));
wolfSSL 15:117db924cf7c 275
wolfSSL 15:117db924cf7c 276 if (ret == 0) {
wolfSSL 15:117db924cf7c 277 /* churning V is the only string that doesn't have the type added */
wolfSSL 15:117db924cf7c 278 if (type != drbgInitV)
wolfSSL 15:117db924cf7c 279 ret = wc_Sha256Update(sha, &type, sizeof(type));
wolfSSL 15:117db924cf7c 280 }
wolfSSL 15:117db924cf7c 281 if (ret == 0)
wolfSSL 15:117db924cf7c 282 ret = wc_Sha256Update(sha, inA, inASz);
wolfSSL 15:117db924cf7c 283 if (ret == 0) {
wolfSSL 15:117db924cf7c 284 if (inB != NULL && inBSz > 0)
wolfSSL 15:117db924cf7c 285 ret = wc_Sha256Update(sha, inB, inBSz);
wolfSSL 15:117db924cf7c 286 }
wolfSSL 15:117db924cf7c 287 if (ret == 0)
wolfSSL 15:117db924cf7c 288 ret = wc_Sha256Final(sha, digest);
wolfSSL 15:117db924cf7c 289
wolfSSL 15:117db924cf7c 290 #ifndef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 291 wc_Sha256Free(sha);
wolfSSL 15:117db924cf7c 292 #endif
wolfSSL 15:117db924cf7c 293 if (ret == 0) {
wolfSSL 15:117db924cf7c 294 if (outSz > OUTPUT_BLOCK_LEN) {
wolfSSL 15:117db924cf7c 295 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
wolfSSL 15:117db924cf7c 296 outSz -= OUTPUT_BLOCK_LEN;
wolfSSL 15:117db924cf7c 297 out += OUTPUT_BLOCK_LEN;
wolfSSL 15:117db924cf7c 298 }
wolfSSL 15:117db924cf7c 299 else {
wolfSSL 15:117db924cf7c 300 XMEMCPY(out, digest, outSz);
wolfSSL 15:117db924cf7c 301 }
wolfSSL 15:117db924cf7c 302 }
wolfSSL 15:117db924cf7c 303 }
wolfSSL 15:117db924cf7c 304
wolfSSL 15:117db924cf7c 305 ForceZero(digest, WC_SHA256_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 306
wolfSSL 15:117db924cf7c 307 FREE_VAR(digest, drbg->heap);
wolfSSL 15:117db924cf7c 308
wolfSSL 15:117db924cf7c 309 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
wolfSSL 15:117db924cf7c 310 }
wolfSSL 15:117db924cf7c 311
wolfSSL 15:117db924cf7c 312 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 15:117db924cf7c 313 static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
wolfSSL 15:117db924cf7c 314 {
wolfSSL 15:117db924cf7c 315 byte seed[DRBG_SEED_LEN];
wolfSSL 15:117db924cf7c 316
wolfSSL 15:117db924cf7c 317 if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
wolfSSL 15:117db924cf7c 318 entropy, entropySz) != DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 319 return DRBG_FAILURE;
wolfSSL 15:117db924cf7c 320 }
wolfSSL 15:117db924cf7c 321
wolfSSL 15:117db924cf7c 322 XMEMCPY(drbg->V, seed, sizeof(drbg->V));
wolfSSL 15:117db924cf7c 323 ForceZero(seed, sizeof(seed));
wolfSSL 15:117db924cf7c 324
wolfSSL 15:117db924cf7c 325 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
wolfSSL 15:117db924cf7c 326 sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 327 return DRBG_FAILURE;
wolfSSL 15:117db924cf7c 328 }
wolfSSL 15:117db924cf7c 329
wolfSSL 15:117db924cf7c 330 drbg->reseedCtr = 1;
wolfSSL 15:117db924cf7c 331 drbg->lastBlock = 0;
wolfSSL 15:117db924cf7c 332 drbg->matchCount = 0;
wolfSSL 15:117db924cf7c 333 return DRBG_SUCCESS;
wolfSSL 15:117db924cf7c 334 }
wolfSSL 15:117db924cf7c 335
wolfSSL 15:117db924cf7c 336 /* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
wolfSSL 15:117db924cf7c 337 int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, word32 entropySz)
wolfSSL 15:117db924cf7c 338 {
wolfSSL 15:117db924cf7c 339 if (rng == NULL || entropy == NULL) {
wolfSSL 15:117db924cf7c 340 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 341 }
wolfSSL 15:117db924cf7c 342
wolfSSL 15:117db924cf7c 343 return Hash_DRBG_Reseed(rng->drbg, entropy, entropySz);
wolfSSL 15:117db924cf7c 344 }
wolfSSL 15:117db924cf7c 345
wolfSSL 15:117db924cf7c 346 static WC_INLINE void array_add_one(byte* data, word32 dataSz)
wolfSSL 15:117db924cf7c 347 {
wolfSSL 15:117db924cf7c 348 int i;
wolfSSL 15:117db924cf7c 349
wolfSSL 15:117db924cf7c 350 for (i = dataSz - 1; i >= 0; i--)
wolfSSL 15:117db924cf7c 351 {
wolfSSL 15:117db924cf7c 352 data[i]++;
wolfSSL 15:117db924cf7c 353 if (data[i] != 0) break;
wolfSSL 15:117db924cf7c 354 }
wolfSSL 15:117db924cf7c 355 }
wolfSSL 15:117db924cf7c 356
wolfSSL 15:117db924cf7c 357 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 15:117db924cf7c 358 static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
wolfSSL 15:117db924cf7c 359 {
wolfSSL 15:117db924cf7c 360 int ret = DRBG_FAILURE;
wolfSSL 15:117db924cf7c 361 byte data[DRBG_SEED_LEN];
wolfSSL 15:117db924cf7c 362 int i;
wolfSSL 15:117db924cf7c 363 int len;
wolfSSL 15:117db924cf7c 364 word32 checkBlock;
wolfSSL 15:117db924cf7c 365 #ifdef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 366 wc_Sha256* sha = &drbg->sha256;
wolfSSL 15:117db924cf7c 367 #else
wolfSSL 15:117db924cf7c 368 wc_Sha256 sha[1];
wolfSSL 15:117db924cf7c 369 #endif
wolfSSL 15:117db924cf7c 370 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
wolfSSL 15:117db924cf7c 371
wolfSSL 15:117db924cf7c 372 /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
wolfSSL 15:117db924cf7c 373 * the continuous test. */
wolfSSL 15:117db924cf7c 374
wolfSSL 15:117db924cf7c 375 if (outSz == 0) outSz = 1;
wolfSSL 15:117db924cf7c 376
wolfSSL 15:117db924cf7c 377 len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
wolfSSL 15:117db924cf7c 378
wolfSSL 15:117db924cf7c 379 XMEMCPY(data, V, sizeof(data));
wolfSSL 15:117db924cf7c 380 for (i = 0; i < len; i++) {
wolfSSL 15:117db924cf7c 381 #ifndef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 382 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 383 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
wolfSSL 15:117db924cf7c 384 #else
wolfSSL 15:117db924cf7c 385 ret = wc_InitSha256(sha);
wolfSSL 15:117db924cf7c 386 #endif
wolfSSL 15:117db924cf7c 387 if (ret == 0)
wolfSSL 15:117db924cf7c 388 #endif
wolfSSL 15:117db924cf7c 389 ret = wc_Sha256Update(sha, data, sizeof(data));
wolfSSL 15:117db924cf7c 390 if (ret == 0)
wolfSSL 15:117db924cf7c 391 ret = wc_Sha256Final(sha, digest);
wolfSSL 15:117db924cf7c 392 #ifndef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 393 wc_Sha256Free(sha);
wolfSSL 15:117db924cf7c 394 #endif
wolfSSL 15:117db924cf7c 395
wolfSSL 15:117db924cf7c 396 if (ret == 0) {
wolfSSL 15:117db924cf7c 397 XMEMCPY(&checkBlock, digest, sizeof(word32));
wolfSSL 15:117db924cf7c 398 if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
wolfSSL 15:117db924cf7c 399 if (drbg->matchCount == 1) {
wolfSSL 15:117db924cf7c 400 return DRBG_CONT_FAILURE;
wolfSSL 15:117db924cf7c 401 }
wolfSSL 15:117db924cf7c 402 else {
wolfSSL 15:117db924cf7c 403 if (i == len) {
wolfSSL 15:117db924cf7c 404 len++;
wolfSSL 15:117db924cf7c 405 }
wolfSSL 15:117db924cf7c 406 drbg->matchCount = 1;
wolfSSL 15:117db924cf7c 407 }
wolfSSL 15:117db924cf7c 408 }
wolfSSL 15:117db924cf7c 409 else {
wolfSSL 15:117db924cf7c 410 drbg->matchCount = 0;
wolfSSL 15:117db924cf7c 411 drbg->lastBlock = checkBlock;
wolfSSL 15:117db924cf7c 412 }
wolfSSL 15:117db924cf7c 413
wolfSSL 15:117db924cf7c 414 if (out != NULL && outSz != 0) {
wolfSSL 15:117db924cf7c 415 if (outSz >= OUTPUT_BLOCK_LEN) {
wolfSSL 15:117db924cf7c 416 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
wolfSSL 15:117db924cf7c 417 outSz -= OUTPUT_BLOCK_LEN;
wolfSSL 15:117db924cf7c 418 out += OUTPUT_BLOCK_LEN;
wolfSSL 15:117db924cf7c 419 array_add_one(data, DRBG_SEED_LEN);
wolfSSL 15:117db924cf7c 420 }
wolfSSL 15:117db924cf7c 421 else {
wolfSSL 15:117db924cf7c 422 XMEMCPY(out, digest, outSz);
wolfSSL 15:117db924cf7c 423 outSz = 0;
wolfSSL 15:117db924cf7c 424 }
wolfSSL 15:117db924cf7c 425 }
wolfSSL 15:117db924cf7c 426 }
wolfSSL 15:117db924cf7c 427 }
wolfSSL 15:117db924cf7c 428 ForceZero(data, sizeof(data));
wolfSSL 15:117db924cf7c 429
wolfSSL 15:117db924cf7c 430 FREE_VAR(digest, drbg->heap);
wolfSSL 15:117db924cf7c 431
wolfSSL 15:117db924cf7c 432 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
wolfSSL 15:117db924cf7c 433 }
wolfSSL 15:117db924cf7c 434
wolfSSL 15:117db924cf7c 435 static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
wolfSSL 15:117db924cf7c 436 {
wolfSSL 15:117db924cf7c 437 word16 carry = 0;
wolfSSL 15:117db924cf7c 438
wolfSSL 15:117db924cf7c 439 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
wolfSSL 15:117db924cf7c 440 int sIdx, dIdx;
wolfSSL 15:117db924cf7c 441
wolfSSL 15:117db924cf7c 442 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
wolfSSL 15:117db924cf7c 443 {
wolfSSL 15:117db924cf7c 444 carry += d[dIdx] + s[sIdx];
wolfSSL 15:117db924cf7c 445 d[dIdx] = (byte)carry;
wolfSSL 15:117db924cf7c 446 carry >>= 8;
wolfSSL 15:117db924cf7c 447 }
wolfSSL 15:117db924cf7c 448
wolfSSL 15:117db924cf7c 449 for (; carry != 0 && dIdx >= 0; dIdx--) {
wolfSSL 15:117db924cf7c 450 carry += d[dIdx];
wolfSSL 15:117db924cf7c 451 d[dIdx] = (byte)carry;
wolfSSL 15:117db924cf7c 452 carry >>= 8;
wolfSSL 15:117db924cf7c 453 }
wolfSSL 15:117db924cf7c 454 }
wolfSSL 15:117db924cf7c 455 }
wolfSSL 15:117db924cf7c 456
wolfSSL 15:117db924cf7c 457 /* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
wolfSSL 15:117db924cf7c 458 static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
wolfSSL 15:117db924cf7c 459 {
wolfSSL 15:117db924cf7c 460 int ret;
wolfSSL 15:117db924cf7c 461 #ifdef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 462 wc_Sha256* sha = &drbg->sha256;
wolfSSL 15:117db924cf7c 463 #else
wolfSSL 15:117db924cf7c 464 wc_Sha256 sha[1];
wolfSSL 15:117db924cf7c 465 #endif
wolfSSL 15:117db924cf7c 466 byte type;
wolfSSL 15:117db924cf7c 467 word32 reseedCtr;
wolfSSL 15:117db924cf7c 468
wolfSSL 15:117db924cf7c 469 if (drbg->reseedCtr == RESEED_INTERVAL) {
wolfSSL 15:117db924cf7c 470 return DRBG_NEED_RESEED;
wolfSSL 15:117db924cf7c 471 } else {
wolfSSL 15:117db924cf7c 472 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
wolfSSL 15:117db924cf7c 473 type = drbgGenerateH;
wolfSSL 15:117db924cf7c 474 reseedCtr = drbg->reseedCtr;
wolfSSL 15:117db924cf7c 475
wolfSSL 15:117db924cf7c 476 ret = Hash_gen(drbg, out, outSz, drbg->V);
wolfSSL 15:117db924cf7c 477 if (ret == DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 478 #ifndef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 479 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 480 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
wolfSSL 15:117db924cf7c 481 #else
wolfSSL 15:117db924cf7c 482 ret = wc_InitSha256(sha);
wolfSSL 15:117db924cf7c 483 #endif
wolfSSL 15:117db924cf7c 484 if (ret == 0)
wolfSSL 15:117db924cf7c 485 #endif
wolfSSL 15:117db924cf7c 486 ret = wc_Sha256Update(sha, &type, sizeof(type));
wolfSSL 15:117db924cf7c 487 if (ret == 0)
wolfSSL 15:117db924cf7c 488 ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));
wolfSSL 15:117db924cf7c 489 if (ret == 0)
wolfSSL 15:117db924cf7c 490 ret = wc_Sha256Final(sha, digest);
wolfSSL 15:117db924cf7c 491
wolfSSL 15:117db924cf7c 492 #ifndef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 493 wc_Sha256Free(sha);
wolfSSL 15:117db924cf7c 494 #endif
wolfSSL 15:117db924cf7c 495
wolfSSL 15:117db924cf7c 496 if (ret == 0) {
wolfSSL 15:117db924cf7c 497 array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 498 array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
wolfSSL 15:117db924cf7c 499 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 500 reseedCtr = ByteReverseWord32(reseedCtr);
wolfSSL 15:117db924cf7c 501 #endif
wolfSSL 15:117db924cf7c 502 array_add(drbg->V, sizeof(drbg->V),
wolfSSL 15:117db924cf7c 503 (byte*)&reseedCtr, sizeof(reseedCtr));
wolfSSL 15:117db924cf7c 504 ret = DRBG_SUCCESS;
wolfSSL 15:117db924cf7c 505 }
wolfSSL 15:117db924cf7c 506 drbg->reseedCtr++;
wolfSSL 15:117db924cf7c 507 }
wolfSSL 15:117db924cf7c 508 ForceZero(digest, WC_SHA256_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 509 FREE_VAR(digest, drbg->heap);
wolfSSL 15:117db924cf7c 510 }
wolfSSL 15:117db924cf7c 511
wolfSSL 15:117db924cf7c 512 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
wolfSSL 15:117db924cf7c 513 }
wolfSSL 15:117db924cf7c 514
wolfSSL 15:117db924cf7c 515 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 15:117db924cf7c 516 static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
wolfSSL 15:117db924cf7c 517 const byte* nonce, word32 nonceSz,
wolfSSL 15:117db924cf7c 518 void* heap, int devId)
wolfSSL 15:117db924cf7c 519 {
wolfSSL 15:117db924cf7c 520 int ret = DRBG_FAILURE;
wolfSSL 15:117db924cf7c 521
wolfSSL 15:117db924cf7c 522 XMEMSET(drbg, 0, sizeof(DRBG));
wolfSSL 15:117db924cf7c 523 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 524 drbg->heap = heap;
wolfSSL 15:117db924cf7c 525 drbg->devId = devId;
wolfSSL 15:117db924cf7c 526 #else
wolfSSL 15:117db924cf7c 527 (void)heap;
wolfSSL 15:117db924cf7c 528 (void)devId;
wolfSSL 15:117db924cf7c 529 #endif
wolfSSL 15:117db924cf7c 530
wolfSSL 15:117db924cf7c 531 #ifdef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 532 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 533 ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId);
wolfSSL 15:117db924cf7c 534 #else
wolfSSL 15:117db924cf7c 535 ret = wc_InitSha256(&drbg->sha256);
wolfSSL 15:117db924cf7c 536 #endif
wolfSSL 15:117db924cf7c 537 if (ret != 0)
wolfSSL 15:117db924cf7c 538 return ret;
wolfSSL 15:117db924cf7c 539 #endif
wolfSSL 15:117db924cf7c 540
wolfSSL 15:117db924cf7c 541 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
wolfSSL 15:117db924cf7c 542 nonce, nonceSz) == DRBG_SUCCESS &&
wolfSSL 15:117db924cf7c 543 Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
wolfSSL 15:117db924cf7c 544 sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 545
wolfSSL 15:117db924cf7c 546 drbg->reseedCtr = 1;
wolfSSL 15:117db924cf7c 547 drbg->lastBlock = 0;
wolfSSL 15:117db924cf7c 548 drbg->matchCount = 0;
wolfSSL 15:117db924cf7c 549 ret = DRBG_SUCCESS;
wolfSSL 15:117db924cf7c 550 }
wolfSSL 15:117db924cf7c 551
wolfSSL 15:117db924cf7c 552 return ret;
wolfSSL 15:117db924cf7c 553 }
wolfSSL 15:117db924cf7c 554
wolfSSL 15:117db924cf7c 555 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 15:117db924cf7c 556 static int Hash_DRBG_Uninstantiate(DRBG* drbg)
wolfSSL 15:117db924cf7c 557 {
wolfSSL 15:117db924cf7c 558 word32 i;
wolfSSL 15:117db924cf7c 559 int compareSum = 0;
wolfSSL 15:117db924cf7c 560 byte* compareDrbg = (byte*)drbg;
wolfSSL 15:117db924cf7c 561
wolfSSL 15:117db924cf7c 562 #ifdef WOLFSSL_SMALL_STACK_CACHE
wolfSSL 15:117db924cf7c 563 wc_Sha256Free(&drbg->sha256);
wolfSSL 15:117db924cf7c 564 #endif
wolfSSL 15:117db924cf7c 565
wolfSSL 15:117db924cf7c 566 ForceZero(drbg, sizeof(DRBG));
wolfSSL 15:117db924cf7c 567
wolfSSL 15:117db924cf7c 568 for (i = 0; i < sizeof(DRBG); i++)
wolfSSL 15:117db924cf7c 569 compareSum |= compareDrbg[i] ^ 0;
wolfSSL 15:117db924cf7c 570
wolfSSL 15:117db924cf7c 571 return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
wolfSSL 15:117db924cf7c 572 }
wolfSSL 15:117db924cf7c 573 #endif /* HAVE_HASHDRBG */
wolfSSL 15:117db924cf7c 574 /* End NIST DRBG Code */
wolfSSL 15:117db924cf7c 575
wolfSSL 15:117db924cf7c 576
wolfSSL 15:117db924cf7c 577 static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
wolfSSL 15:117db924cf7c 578 void* heap, int devId)
wolfSSL 15:117db924cf7c 579 {
wolfSSL 15:117db924cf7c 580 int ret = RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 581 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 582 word32 entropySz = ENTROPY_SZ;
wolfSSL 15:117db924cf7c 583 #endif
wolfSSL 15:117db924cf7c 584
wolfSSL 15:117db924cf7c 585 (void)nonce;
wolfSSL 15:117db924cf7c 586 (void)nonceSz;
wolfSSL 15:117db924cf7c 587
wolfSSL 15:117db924cf7c 588 if (rng == NULL)
wolfSSL 15:117db924cf7c 589 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 590 if (nonce == NULL && nonceSz != 0)
wolfSSL 15:117db924cf7c 591 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 592
wolfSSL 15:117db924cf7c 593 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 15:117db924cf7c 594 rng->heap = (void*)WOLFSSL_HEAP_TEST;
wolfSSL 15:117db924cf7c 595 (void)heap;
wolfSSL 15:117db924cf7c 596 #else
wolfSSL 15:117db924cf7c 597 rng->heap = heap;
wolfSSL 15:117db924cf7c 598 #endif
wolfSSL 15:117db924cf7c 599 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 600 rng->devId = devId;
wolfSSL 15:117db924cf7c 601 #else
wolfSSL 15:117db924cf7c 602 (void)devId;
wolfSSL 15:117db924cf7c 603 #endif
wolfSSL 15:117db924cf7c 604
wolfSSL 15:117db924cf7c 605 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 606 /* init the DBRG to known values */
wolfSSL 15:117db924cf7c 607 rng->drbg = NULL;
wolfSSL 15:117db924cf7c 608 rng->status = DRBG_NOT_INIT;
wolfSSL 15:117db924cf7c 609 #endif
wolfSSL 15:117db924cf7c 610
wolfSSL 15:117db924cf7c 611 #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
wolfSSL 15:117db924cf7c 612 /* init the intel RD seed and/or rand */
wolfSSL 15:117db924cf7c 613 wc_InitRng_IntelRD();
wolfSSL 15:117db924cf7c 614 #endif
wolfSSL 15:117db924cf7c 615
wolfSSL 15:117db924cf7c 616 /* configure async RNG source if available */
wolfSSL 15:117db924cf7c 617 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 618 ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG,
wolfSSL 15:117db924cf7c 619 rng->heap, rng->devId);
wolfSSL 15:117db924cf7c 620 if (ret != 0)
wolfSSL 15:117db924cf7c 621 return ret;
wolfSSL 15:117db924cf7c 622 #endif
wolfSSL 15:117db924cf7c 623
wolfSSL 15:117db924cf7c 624 #ifdef HAVE_INTEL_RDRAND
wolfSSL 15:117db924cf7c 625 /* if CPU supports RDRAND, use it directly and by-pass DRBG init */
wolfSSL 15:117db924cf7c 626 if (IS_INTEL_RDRAND(intel_flags))
wolfSSL 15:117db924cf7c 627 return 0;
wolfSSL 15:117db924cf7c 628 #endif
wolfSSL 15:117db924cf7c 629
wolfSSL 15:117db924cf7c 630 #ifdef CUSTOM_RAND_GENERATE_BLOCK
wolfSSL 15:117db924cf7c 631 ret = 0; /* success */
wolfSSL 15:117db924cf7c 632 #else
wolfSSL 15:117db924cf7c 633 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 634 if (nonceSz == 0)
wolfSSL 15:117db924cf7c 635 entropySz = MAX_ENTROPY_SZ;
wolfSSL 15:117db924cf7c 636
wolfSSL 15:117db924cf7c 637 if (wc_RNG_HealthTestLocal(0) == 0) {
wolfSSL 15:117db924cf7c 638 DECLARE_VAR(entropy, byte, MAX_ENTROPY_SZ, rng->heap);
wolfSSL 15:117db924cf7c 639
wolfSSL 15:117db924cf7c 640 rng->drbg =
wolfSSL 15:117db924cf7c 641 (struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,
wolfSSL 15:117db924cf7c 642 DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 643 if (rng->drbg == NULL) {
wolfSSL 15:117db924cf7c 644 ret = MEMORY_E;
wolfSSL 15:117db924cf7c 645 }
wolfSSL 15:117db924cf7c 646 else if (wc_GenerateSeed(&rng->seed, entropy, entropySz) == 0 &&
wolfSSL 15:117db924cf7c 647 Hash_DRBG_Instantiate(rng->drbg, entropy, entropySz,
wolfSSL 15:117db924cf7c 648 nonce, nonceSz, rng->heap, devId) == DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 649 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
wolfSSL 15:117db924cf7c 650 }
wolfSSL 15:117db924cf7c 651 else
wolfSSL 15:117db924cf7c 652 ret = DRBG_FAILURE;
wolfSSL 15:117db924cf7c 653
wolfSSL 15:117db924cf7c 654 ForceZero(entropy, entropySz);
wolfSSL 15:117db924cf7c 655 FREE_VAR(entropy, rng->heap);
wolfSSL 15:117db924cf7c 656 }
wolfSSL 15:117db924cf7c 657 else
wolfSSL 15:117db924cf7c 658 ret = DRBG_CONT_FAILURE;
wolfSSL 15:117db924cf7c 659
wolfSSL 15:117db924cf7c 660 if (ret == DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 661 rng->status = DRBG_OK;
wolfSSL 15:117db924cf7c 662 ret = 0;
wolfSSL 15:117db924cf7c 663 }
wolfSSL 15:117db924cf7c 664 else if (ret == DRBG_CONT_FAILURE) {
wolfSSL 15:117db924cf7c 665 rng->status = DRBG_CONT_FAILED;
wolfSSL 15:117db924cf7c 666 ret = DRBG_CONT_FIPS_E;
wolfSSL 15:117db924cf7c 667 }
wolfSSL 15:117db924cf7c 668 else if (ret == DRBG_FAILURE) {
wolfSSL 15:117db924cf7c 669 rng->status = DRBG_FAILED;
wolfSSL 15:117db924cf7c 670 ret = RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 671 }
wolfSSL 15:117db924cf7c 672 else {
wolfSSL 15:117db924cf7c 673 rng->status = DRBG_FAILED;
wolfSSL 15:117db924cf7c 674 }
wolfSSL 15:117db924cf7c 675 #endif /* HAVE_HASHDRBG */
wolfSSL 15:117db924cf7c 676 #endif /* CUSTOM_RAND_GENERATE_BLOCK */
wolfSSL 15:117db924cf7c 677
wolfSSL 15:117db924cf7c 678 return ret;
wolfSSL 15:117db924cf7c 679 }
wolfSSL 15:117db924cf7c 680
wolfSSL 15:117db924cf7c 681
wolfSSL 15:117db924cf7c 682 int wc_InitRng(WC_RNG* rng)
wolfSSL 15:117db924cf7c 683 {
wolfSSL 15:117db924cf7c 684 return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);
wolfSSL 15:117db924cf7c 685 }
wolfSSL 15:117db924cf7c 686
wolfSSL 15:117db924cf7c 687
wolfSSL 15:117db924cf7c 688 int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
wolfSSL 15:117db924cf7c 689 {
wolfSSL 15:117db924cf7c 690 return _InitRng(rng, NULL, 0, heap, devId);
wolfSSL 15:117db924cf7c 691 }
wolfSSL 15:117db924cf7c 692
wolfSSL 15:117db924cf7c 693
wolfSSL 15:117db924cf7c 694 int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)
wolfSSL 15:117db924cf7c 695 {
wolfSSL 15:117db924cf7c 696 return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);
wolfSSL 15:117db924cf7c 697 }
wolfSSL 15:117db924cf7c 698
wolfSSL 15:117db924cf7c 699
wolfSSL 15:117db924cf7c 700 int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
wolfSSL 15:117db924cf7c 701 void* heap, int devId)
wolfSSL 15:117db924cf7c 702 {
wolfSSL 15:117db924cf7c 703 return _InitRng(rng, nonce, nonceSz, heap, devId);
wolfSSL 15:117db924cf7c 704 }
wolfSSL 15:117db924cf7c 705
wolfSSL 15:117db924cf7c 706
wolfSSL 15:117db924cf7c 707 /* place a generated block in output */
wolfSSL 15:117db924cf7c 708 int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 709 {
wolfSSL 15:117db924cf7c 710 int ret;
wolfSSL 15:117db924cf7c 711
wolfSSL 15:117db924cf7c 712 if (rng == NULL || output == NULL)
wolfSSL 15:117db924cf7c 713 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 714
wolfSSL 15:117db924cf7c 715 #ifdef HAVE_INTEL_RDRAND
wolfSSL 15:117db924cf7c 716 if (IS_INTEL_RDRAND(intel_flags))
wolfSSL 15:117db924cf7c 717 return wc_GenerateRand_IntelRD(NULL, output, sz);
wolfSSL 15:117db924cf7c 718 #endif
wolfSSL 15:117db924cf7c 719
wolfSSL 15:117db924cf7c 720 #if defined(WOLFSSL_ASYNC_CRYPT)
wolfSSL 15:117db924cf7c 721 if (rng->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) {
wolfSSL 15:117db924cf7c 722 /* these are blocking */
wolfSSL 15:117db924cf7c 723 #ifdef HAVE_CAVIUM
wolfSSL 15:117db924cf7c 724 return NitroxRngGenerateBlock(rng, output, sz);
wolfSSL 15:117db924cf7c 725 #elif defined(HAVE_INTEL_QA)
wolfSSL 15:117db924cf7c 726 return IntelQaDrbg(&rng->asyncDev, output, sz);
wolfSSL 15:117db924cf7c 727 #else
wolfSSL 15:117db924cf7c 728 /* simulator not supported */
wolfSSL 15:117db924cf7c 729 #endif
wolfSSL 15:117db924cf7c 730 }
wolfSSL 15:117db924cf7c 731 #endif
wolfSSL 15:117db924cf7c 732
wolfSSL 15:117db924cf7c 733 #ifdef CUSTOM_RAND_GENERATE_BLOCK
wolfSSL 15:117db924cf7c 734 XMEMSET(output, 0, sz);
wolfSSL 15:117db924cf7c 735 ret = CUSTOM_RAND_GENERATE_BLOCK(output, sz);
wolfSSL 15:117db924cf7c 736 #else
wolfSSL 15:117db924cf7c 737
wolfSSL 15:117db924cf7c 738 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 739 if (sz > RNG_MAX_BLOCK_LEN)
wolfSSL 15:117db924cf7c 740 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 741
wolfSSL 15:117db924cf7c 742 if (rng->status != DRBG_OK)
wolfSSL 15:117db924cf7c 743 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 744
wolfSSL 15:117db924cf7c 745 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
wolfSSL 15:117db924cf7c 746 if (ret == DRBG_NEED_RESEED) {
wolfSSL 15:117db924cf7c 747 if (wc_RNG_HealthTestLocal(1) == 0) {
wolfSSL 15:117db924cf7c 748 byte entropy[ENTROPY_SZ];
wolfSSL 15:117db924cf7c 749
wolfSSL 15:117db924cf7c 750 if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
wolfSSL 15:117db924cf7c 751 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
wolfSSL 15:117db924cf7c 752 == DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 753
wolfSSL 15:117db924cf7c 754 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
wolfSSL 15:117db924cf7c 755 if (ret == DRBG_SUCCESS)
wolfSSL 15:117db924cf7c 756 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
wolfSSL 15:117db924cf7c 757 }
wolfSSL 15:117db924cf7c 758 else
wolfSSL 15:117db924cf7c 759 ret = DRBG_FAILURE;
wolfSSL 15:117db924cf7c 760
wolfSSL 15:117db924cf7c 761 ForceZero(entropy, ENTROPY_SZ);
wolfSSL 15:117db924cf7c 762 }
wolfSSL 15:117db924cf7c 763 else
wolfSSL 15:117db924cf7c 764 ret = DRBG_CONT_FAILURE;
wolfSSL 15:117db924cf7c 765 }
wolfSSL 15:117db924cf7c 766
wolfSSL 15:117db924cf7c 767 if (ret == DRBG_SUCCESS) {
wolfSSL 15:117db924cf7c 768 ret = 0;
wolfSSL 15:117db924cf7c 769 }
wolfSSL 15:117db924cf7c 770 else if (ret == DRBG_CONT_FAILURE) {
wolfSSL 15:117db924cf7c 771 ret = DRBG_CONT_FIPS_E;
wolfSSL 15:117db924cf7c 772 rng->status = DRBG_CONT_FAILED;
wolfSSL 15:117db924cf7c 773 }
wolfSSL 15:117db924cf7c 774 else {
wolfSSL 15:117db924cf7c 775 ret = RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 776 rng->status = DRBG_FAILED;
wolfSSL 15:117db924cf7c 777 }
wolfSSL 15:117db924cf7c 778 #else
wolfSSL 15:117db924cf7c 779
wolfSSL 15:117db924cf7c 780 /* if we get here then there is an RNG configuration error */
wolfSSL 15:117db924cf7c 781 ret = RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 782
wolfSSL 15:117db924cf7c 783 #endif /* HAVE_HASHDRBG */
wolfSSL 15:117db924cf7c 784 #endif /* CUSTOM_RAND_GENERATE_BLOCK */
wolfSSL 15:117db924cf7c 785
wolfSSL 15:117db924cf7c 786 return ret;
wolfSSL 15:117db924cf7c 787 }
wolfSSL 15:117db924cf7c 788
wolfSSL 15:117db924cf7c 789
wolfSSL 15:117db924cf7c 790 int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
wolfSSL 15:117db924cf7c 791 {
wolfSSL 15:117db924cf7c 792 return wc_RNG_GenerateBlock(rng, b, 1);
wolfSSL 15:117db924cf7c 793 }
wolfSSL 15:117db924cf7c 794
wolfSSL 15:117db924cf7c 795
wolfSSL 15:117db924cf7c 796 int wc_FreeRng(WC_RNG* rng)
wolfSSL 15:117db924cf7c 797 {
wolfSSL 15:117db924cf7c 798 int ret = 0;
wolfSSL 15:117db924cf7c 799
wolfSSL 15:117db924cf7c 800 if (rng == NULL)
wolfSSL 15:117db924cf7c 801 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 802
wolfSSL 15:117db924cf7c 803 #if defined(WOLFSSL_ASYNC_CRYPT)
wolfSSL 15:117db924cf7c 804 wolfAsync_DevCtxFree(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG);
wolfSSL 15:117db924cf7c 805 #endif
wolfSSL 15:117db924cf7c 806
wolfSSL 15:117db924cf7c 807 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 808 if (rng->drbg != NULL) {
wolfSSL 15:117db924cf7c 809 if (Hash_DRBG_Uninstantiate(rng->drbg) != DRBG_SUCCESS)
wolfSSL 15:117db924cf7c 810 ret = RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 811
wolfSSL 15:117db924cf7c 812 XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 813 rng->drbg = NULL;
wolfSSL 15:117db924cf7c 814 }
wolfSSL 15:117db924cf7c 815
wolfSSL 15:117db924cf7c 816 rng->status = DRBG_NOT_INIT;
wolfSSL 15:117db924cf7c 817 #endif /* HAVE_HASHDRBG */
wolfSSL 15:117db924cf7c 818
wolfSSL 15:117db924cf7c 819 return ret;
wolfSSL 15:117db924cf7c 820 }
wolfSSL 15:117db924cf7c 821
wolfSSL 15:117db924cf7c 822 #ifdef HAVE_HASHDRBG
wolfSSL 15:117db924cf7c 823 int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
wolfSSL 15:117db924cf7c 824 const byte* entropyB, word32 entropyBSz,
wolfSSL 15:117db924cf7c 825 byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 826 {
wolfSSL 15:117db924cf7c 827 return wc_RNG_HealthTest_ex(reseed, NULL, 0,
wolfSSL 15:117db924cf7c 828 entropyA, entropyASz,
wolfSSL 15:117db924cf7c 829 entropyB, entropyBSz,
wolfSSL 15:117db924cf7c 830 output, outputSz,
wolfSSL 15:117db924cf7c 831 NULL, INVALID_DEVID);
wolfSSL 15:117db924cf7c 832 }
wolfSSL 15:117db924cf7c 833
wolfSSL 15:117db924cf7c 834
wolfSSL 15:117db924cf7c 835 int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
wolfSSL 15:117db924cf7c 836 const byte* entropyA, word32 entropyASz,
wolfSSL 15:117db924cf7c 837 const byte* entropyB, word32 entropyBSz,
wolfSSL 15:117db924cf7c 838 byte* output, word32 outputSz,
wolfSSL 15:117db924cf7c 839 void* heap, int devId)
wolfSSL 15:117db924cf7c 840 {
wolfSSL 15:117db924cf7c 841 int ret = -1;
wolfSSL 15:117db924cf7c 842 DRBG* drbg;
wolfSSL 15:117db924cf7c 843 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 844 DRBG drbg_var;
wolfSSL 15:117db924cf7c 845 #endif
wolfSSL 15:117db924cf7c 846
wolfSSL 15:117db924cf7c 847 if (entropyA == NULL || output == NULL) {
wolfSSL 15:117db924cf7c 848 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 849 }
wolfSSL 15:117db924cf7c 850
wolfSSL 15:117db924cf7c 851 if (reseed != 0 && entropyB == NULL) {
wolfSSL 15:117db924cf7c 852 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 853 }
wolfSSL 15:117db924cf7c 854
wolfSSL 15:117db924cf7c 855 if (outputSz != RNG_HEALTH_TEST_CHECK_SIZE) {
wolfSSL 15:117db924cf7c 856 return ret;
wolfSSL 15:117db924cf7c 857 }
wolfSSL 15:117db924cf7c 858
wolfSSL 15:117db924cf7c 859 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 860 drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 861 if (drbg == NULL) {
wolfSSL 15:117db924cf7c 862 return MEMORY_E;
wolfSSL 15:117db924cf7c 863 }
wolfSSL 15:117db924cf7c 864 #else
wolfSSL 15:117db924cf7c 865 drbg = &drbg_var;
wolfSSL 15:117db924cf7c 866 #endif
wolfSSL 15:117db924cf7c 867
wolfSSL 15:117db924cf7c 868 if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, nonce, nonceSz,
wolfSSL 15:117db924cf7c 869 heap, devId) != 0) {
wolfSSL 15:117db924cf7c 870 goto exit_rng_ht;
wolfSSL 15:117db924cf7c 871 }
wolfSSL 15:117db924cf7c 872
wolfSSL 15:117db924cf7c 873 if (reseed) {
wolfSSL 15:117db924cf7c 874 if (Hash_DRBG_Reseed(drbg, entropyB, entropyBSz) != 0) {
wolfSSL 15:117db924cf7c 875 goto exit_rng_ht;
wolfSSL 15:117db924cf7c 876 }
wolfSSL 15:117db924cf7c 877 }
wolfSSL 15:117db924cf7c 878
wolfSSL 15:117db924cf7c 879 if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
wolfSSL 15:117db924cf7c 880 goto exit_rng_ht;
wolfSSL 15:117db924cf7c 881 }
wolfSSL 15:117db924cf7c 882
wolfSSL 15:117db924cf7c 883 if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
wolfSSL 15:117db924cf7c 884 goto exit_rng_ht;
wolfSSL 15:117db924cf7c 885 }
wolfSSL 15:117db924cf7c 886
wolfSSL 15:117db924cf7c 887 /* Mark success */
wolfSSL 15:117db924cf7c 888 ret = 0;
wolfSSL 15:117db924cf7c 889
wolfSSL 15:117db924cf7c 890 exit_rng_ht:
wolfSSL 15:117db924cf7c 891
wolfSSL 15:117db924cf7c 892 /* This is safe to call even if Hash_DRBG_Instantiate fails */
wolfSSL 15:117db924cf7c 893 if (Hash_DRBG_Uninstantiate(drbg) != 0) {
wolfSSL 15:117db924cf7c 894 ret = -1;
wolfSSL 15:117db924cf7c 895 }
wolfSSL 15:117db924cf7c 896
wolfSSL 15:117db924cf7c 897 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 898 XFREE(drbg, NULL, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 899 #endif
wolfSSL 15:117db924cf7c 900
wolfSSL 15:117db924cf7c 901 return ret;
wolfSSL 15:117db924cf7c 902 }
wolfSSL 15:117db924cf7c 903
wolfSSL 15:117db924cf7c 904
wolfSSL 15:117db924cf7c 905 const byte entropyA[] = {
wolfSSL 15:117db924cf7c 906 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
wolfSSL 15:117db924cf7c 907 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
wolfSSL 15:117db924cf7c 908 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
wolfSSL 15:117db924cf7c 909 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
wolfSSL 15:117db924cf7c 910 };
wolfSSL 15:117db924cf7c 911
wolfSSL 15:117db924cf7c 912 const byte reseedEntropyA[] = {
wolfSSL 15:117db924cf7c 913 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
wolfSSL 15:117db924cf7c 914 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
wolfSSL 15:117db924cf7c 915 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
wolfSSL 15:117db924cf7c 916 };
wolfSSL 15:117db924cf7c 917
wolfSSL 15:117db924cf7c 918 const byte outputA[] = {
wolfSSL 15:117db924cf7c 919 0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
wolfSSL 15:117db924cf7c 920 0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
wolfSSL 15:117db924cf7c 921 0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
wolfSSL 15:117db924cf7c 922 0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
wolfSSL 15:117db924cf7c 923 0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
wolfSSL 15:117db924cf7c 924 0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
wolfSSL 15:117db924cf7c 925 0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
wolfSSL 15:117db924cf7c 926 0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
wolfSSL 15:117db924cf7c 927 0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
wolfSSL 15:117db924cf7c 928 0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
wolfSSL 15:117db924cf7c 929 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
wolfSSL 15:117db924cf7c 930 };
wolfSSL 15:117db924cf7c 931
wolfSSL 15:117db924cf7c 932 const byte entropyB[] = {
wolfSSL 15:117db924cf7c 933 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
wolfSSL 15:117db924cf7c 934 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
wolfSSL 15:117db924cf7c 935 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
wolfSSL 15:117db924cf7c 936 0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,
wolfSSL 15:117db924cf7c 937 0xdb, 0xcb, 0xcc, 0x2e
wolfSSL 15:117db924cf7c 938 };
wolfSSL 15:117db924cf7c 939
wolfSSL 15:117db924cf7c 940 const byte outputB[] = {
wolfSSL 15:117db924cf7c 941 0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
wolfSSL 15:117db924cf7c 942 0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
wolfSSL 15:117db924cf7c 943 0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
wolfSSL 15:117db924cf7c 944 0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
wolfSSL 15:117db924cf7c 945 0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
wolfSSL 15:117db924cf7c 946 0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
wolfSSL 15:117db924cf7c 947 0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
wolfSSL 15:117db924cf7c 948 0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
wolfSSL 15:117db924cf7c 949 0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
wolfSSL 15:117db924cf7c 950 0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
wolfSSL 15:117db924cf7c 951 0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
wolfSSL 15:117db924cf7c 952 };
wolfSSL 15:117db924cf7c 953
wolfSSL 15:117db924cf7c 954
wolfSSL 15:117db924cf7c 955 static int wc_RNG_HealthTestLocal(int reseed)
wolfSSL 15:117db924cf7c 956 {
wolfSSL 15:117db924cf7c 957 int ret = 0;
wolfSSL 15:117db924cf7c 958 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 959 byte* check;
wolfSSL 15:117db924cf7c 960 #else
wolfSSL 15:117db924cf7c 961 byte check[RNG_HEALTH_TEST_CHECK_SIZE];
wolfSSL 15:117db924cf7c 962 #endif
wolfSSL 15:117db924cf7c 963
wolfSSL 15:117db924cf7c 964 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 965 check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, NULL,
wolfSSL 15:117db924cf7c 966 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 967 if (check == NULL) {
wolfSSL 15:117db924cf7c 968 return MEMORY_E;
wolfSSL 15:117db924cf7c 969 }
wolfSSL 15:117db924cf7c 970 #endif
wolfSSL 15:117db924cf7c 971
wolfSSL 15:117db924cf7c 972 if (reseed) {
wolfSSL 15:117db924cf7c 973 ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
wolfSSL 15:117db924cf7c 974 reseedEntropyA, sizeof(reseedEntropyA),
wolfSSL 15:117db924cf7c 975 check, RNG_HEALTH_TEST_CHECK_SIZE);
wolfSSL 15:117db924cf7c 976 if (ret == 0) {
wolfSSL 15:117db924cf7c 977 if (ConstantCompare(check, outputA,
wolfSSL 15:117db924cf7c 978 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
wolfSSL 15:117db924cf7c 979 ret = -1;
wolfSSL 15:117db924cf7c 980 }
wolfSSL 15:117db924cf7c 981 }
wolfSSL 15:117db924cf7c 982 else {
wolfSSL 15:117db924cf7c 983 ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
wolfSSL 15:117db924cf7c 984 NULL, 0,
wolfSSL 15:117db924cf7c 985 check, RNG_HEALTH_TEST_CHECK_SIZE);
wolfSSL 15:117db924cf7c 986 if (ret == 0) {
wolfSSL 15:117db924cf7c 987 if (ConstantCompare(check, outputB,
wolfSSL 15:117db924cf7c 988 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
wolfSSL 15:117db924cf7c 989 ret = -1;
wolfSSL 15:117db924cf7c 990 }
wolfSSL 15:117db924cf7c 991
wolfSSL 15:117db924cf7c 992 /* The previous test cases use a large seed instead of a seed and nonce.
wolfSSL 15:117db924cf7c 993 * entropyB is actually from a test case with a seed and nonce, and
wolfSSL 15:117db924cf7c 994 * just concatenates them. The pivot point between seed and nonce is
wolfSSL 15:117db924cf7c 995 * byte 32, feed them into the health test separately. */
wolfSSL 15:117db924cf7c 996 if (ret == 0) {
wolfSSL 15:117db924cf7c 997 ret = wc_RNG_HealthTest_ex(0,
wolfSSL 15:117db924cf7c 998 entropyB + 32, sizeof(entropyB) - 32,
wolfSSL 15:117db924cf7c 999 entropyB, 32,
wolfSSL 15:117db924cf7c 1000 NULL, 0,
wolfSSL 15:117db924cf7c 1001 check, RNG_HEALTH_TEST_CHECK_SIZE,
wolfSSL 15:117db924cf7c 1002 NULL, INVALID_DEVID);
wolfSSL 15:117db924cf7c 1003 if (ret == 0) {
wolfSSL 15:117db924cf7c 1004 if (ConstantCompare(check, outputB, sizeof(outputB)) != 0)
wolfSSL 15:117db924cf7c 1005 ret = -1;
wolfSSL 15:117db924cf7c 1006 }
wolfSSL 15:117db924cf7c 1007 }
wolfSSL 15:117db924cf7c 1008 }
wolfSSL 15:117db924cf7c 1009
wolfSSL 15:117db924cf7c 1010 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1011 XFREE(check, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1012 #endif
wolfSSL 15:117db924cf7c 1013
wolfSSL 15:117db924cf7c 1014 return ret;
wolfSSL 15:117db924cf7c 1015 }
wolfSSL 15:117db924cf7c 1016
wolfSSL 15:117db924cf7c 1017 #endif /* HAVE_HASHDRBG */
wolfSSL 15:117db924cf7c 1018
wolfSSL 15:117db924cf7c 1019
wolfSSL 15:117db924cf7c 1020 #ifdef HAVE_WNR
wolfSSL 15:117db924cf7c 1021
wolfSSL 15:117db924cf7c 1022 /*
wolfSSL 15:117db924cf7c 1023 * Init global Whitewood netRandom context
wolfSSL 15:117db924cf7c 1024 * Returns 0 on success, negative on error
wolfSSL 15:117db924cf7c 1025 */
wolfSSL 15:117db924cf7c 1026 int wc_InitNetRandom(const char* configFile, wnr_hmac_key hmac_cb, int timeout)
wolfSSL 15:117db924cf7c 1027 {
wolfSSL 15:117db924cf7c 1028 if (configFile == NULL || timeout < 0)
wolfSSL 15:117db924cf7c 1029 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1030
wolfSSL 15:117db924cf7c 1031 if (wnr_mutex_init > 0) {
wolfSSL 15:117db924cf7c 1032 WOLFSSL_MSG("netRandom context already created, skipping");
wolfSSL 15:117db924cf7c 1033 return 0;
wolfSSL 15:117db924cf7c 1034 }
wolfSSL 15:117db924cf7c 1035
wolfSSL 15:117db924cf7c 1036 if (wc_InitMutex(&wnr_mutex) != 0) {
wolfSSL 15:117db924cf7c 1037 WOLFSSL_MSG("Bad Init Mutex wnr_mutex");
wolfSSL 15:117db924cf7c 1038 return BAD_MUTEX_E;
wolfSSL 15:117db924cf7c 1039 }
wolfSSL 15:117db924cf7c 1040 wnr_mutex_init = 1;
wolfSSL 15:117db924cf7c 1041
wolfSSL 15:117db924cf7c 1042 if (wc_LockMutex(&wnr_mutex) != 0) {
wolfSSL 15:117db924cf7c 1043 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
wolfSSL 15:117db924cf7c 1044 return BAD_MUTEX_E;
wolfSSL 15:117db924cf7c 1045 }
wolfSSL 15:117db924cf7c 1046
wolfSSL 15:117db924cf7c 1047 /* store entropy timeout */
wolfSSL 15:117db924cf7c 1048 wnr_timeout = timeout;
wolfSSL 15:117db924cf7c 1049
wolfSSL 15:117db924cf7c 1050 /* create global wnr_context struct */
wolfSSL 15:117db924cf7c 1051 if (wnr_create(&wnr_ctx) != WNR_ERROR_NONE) {
wolfSSL 15:117db924cf7c 1052 WOLFSSL_MSG("Error creating global netRandom context");
wolfSSL 15:117db924cf7c 1053 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1054 }
wolfSSL 15:117db924cf7c 1055
wolfSSL 15:117db924cf7c 1056 /* load config file */
wolfSSL 15:117db924cf7c 1057 if (wnr_config_loadf(wnr_ctx, (char*)configFile) != WNR_ERROR_NONE) {
wolfSSL 15:117db924cf7c 1058 WOLFSSL_MSG("Error loading config file into netRandom context");
wolfSSL 15:117db924cf7c 1059 wnr_destroy(wnr_ctx);
wolfSSL 15:117db924cf7c 1060 wnr_ctx = NULL;
wolfSSL 15:117db924cf7c 1061 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1062 }
wolfSSL 15:117db924cf7c 1063
wolfSSL 15:117db924cf7c 1064 /* create/init polling mechanism */
wolfSSL 15:117db924cf7c 1065 if (wnr_poll_create() != WNR_ERROR_NONE) {
wolfSSL 15:117db924cf7c 1066 printf("ERROR: wnr_poll_create() failed\n");
wolfSSL 15:117db924cf7c 1067 WOLFSSL_MSG("Error initializing netRandom polling mechanism");
wolfSSL 15:117db924cf7c 1068 wnr_destroy(wnr_ctx);
wolfSSL 15:117db924cf7c 1069 wnr_ctx = NULL;
wolfSSL 15:117db924cf7c 1070 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1071 }
wolfSSL 15:117db924cf7c 1072
wolfSSL 15:117db924cf7c 1073 /* validate config, set HMAC callback (optional) */
wolfSSL 15:117db924cf7c 1074 if (wnr_setup(wnr_ctx, hmac_cb) != WNR_ERROR_NONE) {
wolfSSL 15:117db924cf7c 1075 WOLFSSL_MSG("Error setting up netRandom context");
wolfSSL 15:117db924cf7c 1076 wnr_destroy(wnr_ctx);
wolfSSL 15:117db924cf7c 1077 wnr_ctx = NULL;
wolfSSL 15:117db924cf7c 1078 wnr_poll_destroy();
wolfSSL 15:117db924cf7c 1079 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1080 }
wolfSSL 15:117db924cf7c 1081
wolfSSL 15:117db924cf7c 1082 wc_UnLockMutex(&wnr_mutex);
wolfSSL 15:117db924cf7c 1083
wolfSSL 15:117db924cf7c 1084 return 0;
wolfSSL 15:117db924cf7c 1085 }
wolfSSL 15:117db924cf7c 1086
wolfSSL 15:117db924cf7c 1087 /*
wolfSSL 15:117db924cf7c 1088 * Free global Whitewood netRandom context
wolfSSL 15:117db924cf7c 1089 * Returns 0 on success, negative on error
wolfSSL 15:117db924cf7c 1090 */
wolfSSL 15:117db924cf7c 1091 int wc_FreeNetRandom(void)
wolfSSL 15:117db924cf7c 1092 {
wolfSSL 15:117db924cf7c 1093 if (wnr_mutex_init > 0) {
wolfSSL 15:117db924cf7c 1094
wolfSSL 15:117db924cf7c 1095 if (wc_LockMutex(&wnr_mutex) != 0) {
wolfSSL 15:117db924cf7c 1096 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
wolfSSL 15:117db924cf7c 1097 return BAD_MUTEX_E;
wolfSSL 15:117db924cf7c 1098 }
wolfSSL 15:117db924cf7c 1099
wolfSSL 15:117db924cf7c 1100 if (wnr_ctx != NULL) {
wolfSSL 15:117db924cf7c 1101 wnr_destroy(wnr_ctx);
wolfSSL 15:117db924cf7c 1102 wnr_ctx = NULL;
wolfSSL 15:117db924cf7c 1103 }
wolfSSL 15:117db924cf7c 1104 wnr_poll_destroy();
wolfSSL 15:117db924cf7c 1105
wolfSSL 15:117db924cf7c 1106 wc_UnLockMutex(&wnr_mutex);
wolfSSL 15:117db924cf7c 1107
wolfSSL 15:117db924cf7c 1108 wc_FreeMutex(&wnr_mutex);
wolfSSL 15:117db924cf7c 1109 wnr_mutex_init = 0;
wolfSSL 15:117db924cf7c 1110 }
wolfSSL 15:117db924cf7c 1111
wolfSSL 15:117db924cf7c 1112 return 0;
wolfSSL 15:117db924cf7c 1113 }
wolfSSL 15:117db924cf7c 1114
wolfSSL 15:117db924cf7c 1115 #endif /* HAVE_WNR */
wolfSSL 15:117db924cf7c 1116
wolfSSL 15:117db924cf7c 1117
wolfSSL 15:117db924cf7c 1118 #if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)
wolfSSL 15:117db924cf7c 1119
wolfSSL 15:117db924cf7c 1120 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 1121 /* need more retries if multiple cores */
wolfSSL 15:117db924cf7c 1122 #define INTELRD_RETRY (32 * 8)
wolfSSL 15:117db924cf7c 1123 #else
wolfSSL 15:117db924cf7c 1124 #define INTELRD_RETRY 32
wolfSSL 15:117db924cf7c 1125 #endif
wolfSSL 15:117db924cf7c 1126
wolfSSL 15:117db924cf7c 1127 #ifdef HAVE_INTEL_RDSEED
wolfSSL 15:117db924cf7c 1128
wolfSSL 15:117db924cf7c 1129 #ifndef USE_WINDOWS_API
wolfSSL 15:117db924cf7c 1130
wolfSSL 15:117db924cf7c 1131 /* return 0 on success */
wolfSSL 15:117db924cf7c 1132 static WC_INLINE int IntelRDseed64(word64* seed)
wolfSSL 15:117db924cf7c 1133 {
wolfSSL 15:117db924cf7c 1134 unsigned char ok;
wolfSSL 15:117db924cf7c 1135
wolfSSL 15:117db924cf7c 1136 __asm__ volatile("rdseed %0; setc %1":"=r"(*seed), "=qm"(ok));
wolfSSL 15:117db924cf7c 1137 return (ok) ? 0 : -1;
wolfSSL 15:117db924cf7c 1138 }
wolfSSL 15:117db924cf7c 1139
wolfSSL 15:117db924cf7c 1140 #else /* USE_WINDOWS_API */
wolfSSL 15:117db924cf7c 1141 /* The compiler Visual Studio uses does not allow inline assembly.
wolfSSL 15:117db924cf7c 1142 * It does allow for Intel intrinsic functions. */
wolfSSL 15:117db924cf7c 1143
wolfSSL 15:117db924cf7c 1144 /* return 0 on success */
wolfSSL 15:117db924cf7c 1145 static WC_INLINE int IntelRDseed64(word64* seed)
wolfSSL 15:117db924cf7c 1146 {
wolfSSL 15:117db924cf7c 1147 int ok;
wolfSSL 15:117db924cf7c 1148
wolfSSL 15:117db924cf7c 1149 ok = _rdseed64_step(seed);
wolfSSL 15:117db924cf7c 1150 return (ok) ? 0 : -1;
wolfSSL 15:117db924cf7c 1151 }
wolfSSL 15:117db924cf7c 1152
wolfSSL 15:117db924cf7c 1153 #endif /* USE_WINDOWS_API */
wolfSSL 15:117db924cf7c 1154
wolfSSL 15:117db924cf7c 1155 /* return 0 on success */
wolfSSL 15:117db924cf7c 1156 static WC_INLINE int IntelRDseed64_r(word64* rnd)
wolfSSL 15:117db924cf7c 1157 {
wolfSSL 15:117db924cf7c 1158 int i;
wolfSSL 15:117db924cf7c 1159 for (i = 0; i < INTELRD_RETRY; i++) {
wolfSSL 15:117db924cf7c 1160 if (IntelRDseed64(rnd) == 0)
wolfSSL 15:117db924cf7c 1161 return 0;
wolfSSL 15:117db924cf7c 1162 }
wolfSSL 15:117db924cf7c 1163 return -1;
wolfSSL 15:117db924cf7c 1164 }
wolfSSL 15:117db924cf7c 1165
wolfSSL 15:117db924cf7c 1166 /* return 0 on success */
wolfSSL 15:117db924cf7c 1167 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1168 {
wolfSSL 15:117db924cf7c 1169 int ret;
wolfSSL 15:117db924cf7c 1170 word64 rndTmp;
wolfSSL 15:117db924cf7c 1171
wolfSSL 15:117db924cf7c 1172 (void)os;
wolfSSL 15:117db924cf7c 1173
wolfSSL 15:117db924cf7c 1174 if (!IS_INTEL_RDSEED(intel_flags))
wolfSSL 15:117db924cf7c 1175 return -1;
wolfSSL 15:117db924cf7c 1176
wolfSSL 15:117db924cf7c 1177 for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
wolfSSL 15:117db924cf7c 1178 output += sizeof(word64)) {
wolfSSL 15:117db924cf7c 1179 ret = IntelRDseed64_r((word64*)output);
wolfSSL 15:117db924cf7c 1180 if (ret != 0)
wolfSSL 15:117db924cf7c 1181 return ret;
wolfSSL 15:117db924cf7c 1182 }
wolfSSL 15:117db924cf7c 1183 if (sz == 0)
wolfSSL 15:117db924cf7c 1184 return 0;
wolfSSL 15:117db924cf7c 1185
wolfSSL 15:117db924cf7c 1186 /* handle unaligned remainder */
wolfSSL 15:117db924cf7c 1187 ret = IntelRDseed64_r(&rndTmp);
wolfSSL 15:117db924cf7c 1188 if (ret != 0)
wolfSSL 15:117db924cf7c 1189 return ret;
wolfSSL 15:117db924cf7c 1190
wolfSSL 15:117db924cf7c 1191 XMEMCPY(output, &rndTmp, sz);
wolfSSL 15:117db924cf7c 1192 ForceZero(&rndTmp, sizeof(rndTmp));
wolfSSL 15:117db924cf7c 1193
wolfSSL 15:117db924cf7c 1194 return 0;
wolfSSL 15:117db924cf7c 1195 }
wolfSSL 15:117db924cf7c 1196
wolfSSL 15:117db924cf7c 1197 #endif /* HAVE_INTEL_RDSEED */
wolfSSL 15:117db924cf7c 1198
wolfSSL 15:117db924cf7c 1199 #ifdef HAVE_INTEL_RDRAND
wolfSSL 15:117db924cf7c 1200
wolfSSL 15:117db924cf7c 1201 #ifndef USE_WINDOWS_API
wolfSSL 15:117db924cf7c 1202
wolfSSL 15:117db924cf7c 1203 /* return 0 on success */
wolfSSL 15:117db924cf7c 1204 static WC_INLINE int IntelRDrand64(word64 *rnd)
wolfSSL 15:117db924cf7c 1205 {
wolfSSL 15:117db924cf7c 1206 unsigned char ok;
wolfSSL 15:117db924cf7c 1207
wolfSSL 15:117db924cf7c 1208 __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok));
wolfSSL 15:117db924cf7c 1209
wolfSSL 15:117db924cf7c 1210 return (ok) ? 0 : -1;
wolfSSL 15:117db924cf7c 1211 }
wolfSSL 15:117db924cf7c 1212
wolfSSL 15:117db924cf7c 1213 #else /* USE_WINDOWS_API */
wolfSSL 15:117db924cf7c 1214 /* The compiler Visual Studio uses does not allow inline assembly.
wolfSSL 15:117db924cf7c 1215 * It does allow for Intel intrinsic functions. */
wolfSSL 15:117db924cf7c 1216
wolfSSL 15:117db924cf7c 1217 /* return 0 on success */
wolfSSL 15:117db924cf7c 1218 static WC_INLINE int IntelRDrand64(word64 *rnd)
wolfSSL 15:117db924cf7c 1219 {
wolfSSL 15:117db924cf7c 1220 int ok;
wolfSSL 15:117db924cf7c 1221
wolfSSL 15:117db924cf7c 1222 ok = _rdrand64_step(rnd);
wolfSSL 15:117db924cf7c 1223
wolfSSL 15:117db924cf7c 1224 return (ok) ? 0 : -1;
wolfSSL 15:117db924cf7c 1225 }
wolfSSL 15:117db924cf7c 1226
wolfSSL 15:117db924cf7c 1227 #endif /* USE_WINDOWS_API */
wolfSSL 15:117db924cf7c 1228
wolfSSL 15:117db924cf7c 1229 /* return 0 on success */
wolfSSL 15:117db924cf7c 1230 static WC_INLINE int IntelRDrand64_r(word64 *rnd)
wolfSSL 15:117db924cf7c 1231 {
wolfSSL 15:117db924cf7c 1232 int i;
wolfSSL 15:117db924cf7c 1233 for (i = 0; i < INTELRD_RETRY; i++) {
wolfSSL 15:117db924cf7c 1234 if (IntelRDrand64(rnd) == 0)
wolfSSL 15:117db924cf7c 1235 return 0;
wolfSSL 15:117db924cf7c 1236 }
wolfSSL 15:117db924cf7c 1237 return -1;
wolfSSL 15:117db924cf7c 1238 }
wolfSSL 15:117db924cf7c 1239
wolfSSL 15:117db924cf7c 1240 /* return 0 on success */
wolfSSL 15:117db924cf7c 1241 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1242 {
wolfSSL 15:117db924cf7c 1243 int ret;
wolfSSL 15:117db924cf7c 1244 word64 rndTmp;
wolfSSL 15:117db924cf7c 1245
wolfSSL 15:117db924cf7c 1246 (void)os;
wolfSSL 15:117db924cf7c 1247
wolfSSL 15:117db924cf7c 1248 if (!IS_INTEL_RDRAND(intel_flags))
wolfSSL 15:117db924cf7c 1249 return -1;
wolfSSL 15:117db924cf7c 1250
wolfSSL 15:117db924cf7c 1251 for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
wolfSSL 15:117db924cf7c 1252 output += sizeof(word64)) {
wolfSSL 15:117db924cf7c 1253 ret = IntelRDrand64_r((word64 *)output);
wolfSSL 15:117db924cf7c 1254 if (ret != 0)
wolfSSL 15:117db924cf7c 1255 return ret;
wolfSSL 15:117db924cf7c 1256 }
wolfSSL 15:117db924cf7c 1257 if (sz == 0)
wolfSSL 15:117db924cf7c 1258 return 0;
wolfSSL 15:117db924cf7c 1259
wolfSSL 15:117db924cf7c 1260 /* handle unaligned remainder */
wolfSSL 15:117db924cf7c 1261 ret = IntelRDrand64_r(&rndTmp);
wolfSSL 15:117db924cf7c 1262 if (ret != 0)
wolfSSL 15:117db924cf7c 1263 return ret;
wolfSSL 15:117db924cf7c 1264
wolfSSL 15:117db924cf7c 1265 XMEMCPY(output, &rndTmp, sz);
wolfSSL 15:117db924cf7c 1266
wolfSSL 15:117db924cf7c 1267 return 0;
wolfSSL 15:117db924cf7c 1268 }
wolfSSL 15:117db924cf7c 1269
wolfSSL 15:117db924cf7c 1270 #endif /* HAVE_INTEL_RDRAND */
wolfSSL 15:117db924cf7c 1271 #endif /* HAVE_INTEL_RDRAND || HAVE_INTEL_RDSEED */
wolfSSL 15:117db924cf7c 1272
wolfSSL 15:117db924cf7c 1273
wolfSSL 15:117db924cf7c 1274 /* Begin wc_GenerateSeed Implementations */
wolfSSL 15:117db924cf7c 1275 #if defined(CUSTOM_RAND_GENERATE_SEED)
wolfSSL 15:117db924cf7c 1276
wolfSSL 15:117db924cf7c 1277 /* Implement your own random generation function
wolfSSL 15:117db924cf7c 1278 * Return 0 to indicate success
wolfSSL 15:117db924cf7c 1279 * int rand_gen_seed(byte* output, word32 sz);
wolfSSL 15:117db924cf7c 1280 * #define CUSTOM_RAND_GENERATE_SEED rand_gen_seed */
wolfSSL 15:117db924cf7c 1281
wolfSSL 15:117db924cf7c 1282 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1283 {
wolfSSL 15:117db924cf7c 1284 (void)os; /* Suppress unused arg warning */
wolfSSL 15:117db924cf7c 1285 return CUSTOM_RAND_GENERATE_SEED(output, sz);
wolfSSL 15:117db924cf7c 1286 }
wolfSSL 15:117db924cf7c 1287
wolfSSL 15:117db924cf7c 1288 #elif defined(CUSTOM_RAND_GENERATE_SEED_OS)
wolfSSL 15:117db924cf7c 1289
wolfSSL 15:117db924cf7c 1290 /* Implement your own random generation function,
wolfSSL 15:117db924cf7c 1291 * which includes OS_Seed.
wolfSSL 15:117db924cf7c 1292 * Return 0 to indicate success
wolfSSL 15:117db924cf7c 1293 * int rand_gen_seed(OS_Seed* os, byte* output, word32 sz);
wolfSSL 15:117db924cf7c 1294 * #define CUSTOM_RAND_GENERATE_SEED_OS rand_gen_seed */
wolfSSL 15:117db924cf7c 1295
wolfSSL 15:117db924cf7c 1296 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1297 {
wolfSSL 15:117db924cf7c 1298 return CUSTOM_RAND_GENERATE_SEED_OS(os, output, sz);
wolfSSL 15:117db924cf7c 1299 }
wolfSSL 15:117db924cf7c 1300
wolfSSL 15:117db924cf7c 1301 #elif defined(CUSTOM_RAND_GENERATE)
wolfSSL 15:117db924cf7c 1302
wolfSSL 15:117db924cf7c 1303 /* Implement your own random generation function
wolfSSL 15:117db924cf7c 1304 * word32 rand_gen(void);
wolfSSL 15:117db924cf7c 1305 * #define CUSTOM_RAND_GENERATE rand_gen */
wolfSSL 15:117db924cf7c 1306
wolfSSL 15:117db924cf7c 1307 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1308 {
wolfSSL 15:117db924cf7c 1309 word32 i = 0;
wolfSSL 15:117db924cf7c 1310
wolfSSL 15:117db924cf7c 1311 (void)os;
wolfSSL 15:117db924cf7c 1312
wolfSSL 15:117db924cf7c 1313 while (i < sz)
wolfSSL 15:117db924cf7c 1314 {
wolfSSL 15:117db924cf7c 1315 /* If not aligned or there is odd/remainder */
wolfSSL 15:117db924cf7c 1316 if( (i + sizeof(CUSTOM_RAND_TYPE)) > sz ||
wolfSSL 15:117db924cf7c 1317 ((wolfssl_word)&output[i] % sizeof(CUSTOM_RAND_TYPE)) != 0
wolfSSL 15:117db924cf7c 1318 ) {
wolfSSL 15:117db924cf7c 1319 /* Single byte at a time */
wolfSSL 15:117db924cf7c 1320 output[i++] = (byte)CUSTOM_RAND_GENERATE();
wolfSSL 15:117db924cf7c 1321 }
wolfSSL 15:117db924cf7c 1322 else {
wolfSSL 15:117db924cf7c 1323 /* Use native 8, 16, 32 or 64 copy instruction */
wolfSSL 15:117db924cf7c 1324 *((CUSTOM_RAND_TYPE*)&output[i]) = CUSTOM_RAND_GENERATE();
wolfSSL 15:117db924cf7c 1325 i += sizeof(CUSTOM_RAND_TYPE);
wolfSSL 15:117db924cf7c 1326 }
wolfSSL 15:117db924cf7c 1327 }
wolfSSL 15:117db924cf7c 1328
wolfSSL 15:117db924cf7c 1329 return 0;
wolfSSL 15:117db924cf7c 1330 }
wolfSSL 15:117db924cf7c 1331
wolfSSL 15:117db924cf7c 1332 #elif defined(WOLFSSL_SGX)
wolfSSL 15:117db924cf7c 1333
wolfSSL 15:117db924cf7c 1334 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1335 {
wolfSSL 15:117db924cf7c 1336 int ret = !SGX_SUCCESS;
wolfSSL 15:117db924cf7c 1337 int i, read_max = 10;
wolfSSL 15:117db924cf7c 1338
wolfSSL 15:117db924cf7c 1339 for (i = 0; i < read_max && ret != SGX_SUCCESS; i++) {
wolfSSL 15:117db924cf7c 1340 ret = sgx_read_rand(output, sz);
wolfSSL 15:117db924cf7c 1341 }
wolfSSL 15:117db924cf7c 1342
wolfSSL 15:117db924cf7c 1343 (void)os;
wolfSSL 15:117db924cf7c 1344 return (ret == SGX_SUCCESS) ? 0 : 1;
wolfSSL 15:117db924cf7c 1345 }
wolfSSL 15:117db924cf7c 1346
wolfSSL 15:117db924cf7c 1347 #elif defined(USE_WINDOWS_API)
wolfSSL 15:117db924cf7c 1348
wolfSSL 15:117db924cf7c 1349 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1350 {
wolfSSL 15:117db924cf7c 1351 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
wolfSSL 15:117db924cf7c 1352 CRYPT_VERIFYCONTEXT))
wolfSSL 15:117db924cf7c 1353 return WINCRYPT_E;
wolfSSL 15:117db924cf7c 1354
wolfSSL 15:117db924cf7c 1355 if (!CryptGenRandom(os->handle, sz, output))
wolfSSL 15:117db924cf7c 1356 return CRYPTGEN_E;
wolfSSL 15:117db924cf7c 1357
wolfSSL 15:117db924cf7c 1358 CryptReleaseContext(os->handle, 0);
wolfSSL 15:117db924cf7c 1359
wolfSSL 15:117db924cf7c 1360 return 0;
wolfSSL 15:117db924cf7c 1361 }
wolfSSL 15:117db924cf7c 1362
wolfSSL 15:117db924cf7c 1363
wolfSSL 15:117db924cf7c 1364 #elif defined(HAVE_RTP_SYS) || defined(EBSNET)
wolfSSL 15:117db924cf7c 1365
wolfSSL 15:117db924cf7c 1366 #include "rtprand.h" /* rtp_rand () */
wolfSSL 15:117db924cf7c 1367 #include "rtptime.h" /* rtp_get_system_msec() */
wolfSSL 15:117db924cf7c 1368
wolfSSL 15:117db924cf7c 1369
wolfSSL 15:117db924cf7c 1370 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1371 {
wolfSSL 15:117db924cf7c 1372 int i;
wolfSSL 15:117db924cf7c 1373 rtp_srand(rtp_get_system_msec());
wolfSSL 15:117db924cf7c 1374
wolfSSL 15:117db924cf7c 1375 for (i = 0; i < sz; i++ ) {
wolfSSL 15:117db924cf7c 1376 output[i] = rtp_rand() % 256;
wolfSSL 15:117db924cf7c 1377 if ( (i % 8) == 7)
wolfSSL 15:117db924cf7c 1378 rtp_srand(rtp_get_system_msec());
wolfSSL 15:117db924cf7c 1379 }
wolfSSL 15:117db924cf7c 1380
wolfSSL 15:117db924cf7c 1381 return 0;
wolfSSL 15:117db924cf7c 1382 }
wolfSSL 15:117db924cf7c 1383
wolfSSL 15:117db924cf7c 1384
wolfSSL 15:117db924cf7c 1385 #elif defined(MICROCHIP_PIC32)
wolfSSL 15:117db924cf7c 1386
wolfSSL 15:117db924cf7c 1387 #ifdef MICROCHIP_MPLAB_HARMONY
wolfSSL 15:117db924cf7c 1388 #define PIC32_SEED_COUNT _CP0_GET_COUNT
wolfSSL 15:117db924cf7c 1389 #else
wolfSSL 15:117db924cf7c 1390 #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
wolfSSL 15:117db924cf7c 1391 #include <peripheral/timer.h>
wolfSSL 15:117db924cf7c 1392 #endif
wolfSSL 15:117db924cf7c 1393 extern word32 ReadCoreTimer(void);
wolfSSL 15:117db924cf7c 1394 #define PIC32_SEED_COUNT ReadCoreTimer
wolfSSL 15:117db924cf7c 1395 #endif
wolfSSL 15:117db924cf7c 1396
wolfSSL 15:117db924cf7c 1397 #ifdef WOLFSSL_PIC32MZ_RNG
wolfSSL 15:117db924cf7c 1398 #include "xc.h"
wolfSSL 15:117db924cf7c 1399 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1400 {
wolfSSL 15:117db924cf7c 1401 int i;
wolfSSL 15:117db924cf7c 1402 byte rnd[8];
wolfSSL 15:117db924cf7c 1403 word32 *rnd32 = (word32 *)rnd;
wolfSSL 15:117db924cf7c 1404 word32 size = sz;
wolfSSL 15:117db924cf7c 1405 byte* op = output;
wolfSSL 15:117db924cf7c 1406
wolfSSL 15:117db924cf7c 1407 #if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C'))
wolfSSL 15:117db924cf7c 1408 RNGNUMGEN1 = _CP0_GET_COUNT();
wolfSSL 15:117db924cf7c 1409 RNGPOLY1 = _CP0_GET_COUNT();
wolfSSL 15:117db924cf7c 1410 RNGPOLY2 = _CP0_GET_COUNT();
wolfSSL 15:117db924cf7c 1411 RNGNUMGEN2 = _CP0_GET_COUNT();
wolfSSL 15:117db924cf7c 1412 #else
wolfSSL 15:117db924cf7c 1413 // All others can be seeded from the TRNG
wolfSSL 15:117db924cf7c 1414 RNGCONbits.TRNGMODE = 1;
wolfSSL 15:117db924cf7c 1415 RNGCONbits.TRNGEN = 1;
wolfSSL 15:117db924cf7c 1416 while (RNGCNT < 64);
wolfSSL 15:117db924cf7c 1417 RNGCONbits.LOAD = 1;
wolfSSL 15:117db924cf7c 1418 while (RNGCONbits.LOAD == 1);
wolfSSL 15:117db924cf7c 1419 while (RNGCNT < 64);
wolfSSL 15:117db924cf7c 1420 RNGPOLY2 = RNGSEED2;
wolfSSL 15:117db924cf7c 1421 RNGPOLY1 = RNGSEED1;
wolfSSL 15:117db924cf7c 1422 #endif
wolfSSL 15:117db924cf7c 1423
wolfSSL 15:117db924cf7c 1424 RNGCONbits.PLEN = 0x40;
wolfSSL 15:117db924cf7c 1425 RNGCONbits.PRNGEN = 1;
wolfSSL 15:117db924cf7c 1426 for (i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
wolfSSL 15:117db924cf7c 1427 volatile int x;
wolfSSL 15:117db924cf7c 1428 x = RNGNUMGEN1;
wolfSSL 15:117db924cf7c 1429 x = RNGNUMGEN2;
wolfSSL 15:117db924cf7c 1430 (void)x;
wolfSSL 15:117db924cf7c 1431 }
wolfSSL 15:117db924cf7c 1432 do {
wolfSSL 15:117db924cf7c 1433 rnd32[0] = RNGNUMGEN1;
wolfSSL 15:117db924cf7c 1434 rnd32[1] = RNGNUMGEN2;
wolfSSL 15:117db924cf7c 1435
wolfSSL 15:117db924cf7c 1436 for(i=0; i<8; i++, op++) {
wolfSSL 15:117db924cf7c 1437 *op = rnd[i];
wolfSSL 15:117db924cf7c 1438 size --;
wolfSSL 15:117db924cf7c 1439 if(size==0)break;
wolfSSL 15:117db924cf7c 1440 }
wolfSSL 15:117db924cf7c 1441 } while(size);
wolfSSL 15:117db924cf7c 1442 return 0;
wolfSSL 15:117db924cf7c 1443 }
wolfSSL 15:117db924cf7c 1444 #else /* WOLFSSL_PIC32MZ_RNG */
wolfSSL 15:117db924cf7c 1445 /* uses the core timer, in nanoseconds to seed srand */
wolfSSL 15:117db924cf7c 1446 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1447 {
wolfSSL 15:117db924cf7c 1448 int i;
wolfSSL 15:117db924cf7c 1449 srand(PIC32_SEED_COUNT() * 25);
wolfSSL 15:117db924cf7c 1450
wolfSSL 15:117db924cf7c 1451 for (i = 0; i < sz; i++ ) {
wolfSSL 15:117db924cf7c 1452 output[i] = rand() % 256;
wolfSSL 15:117db924cf7c 1453 if ( (i % 8) == 7)
wolfSSL 15:117db924cf7c 1454 srand(PIC32_SEED_COUNT() * 25);
wolfSSL 15:117db924cf7c 1455 }
wolfSSL 15:117db924cf7c 1456 return 0;
wolfSSL 15:117db924cf7c 1457 }
wolfSSL 15:117db924cf7c 1458 #endif /* WOLFSSL_PIC32MZ_RNG */
wolfSSL 15:117db924cf7c 1459
wolfSSL 15:117db924cf7c 1460 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \
wolfSSL 15:117db924cf7c 1461 defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
wolfSSL 15:117db924cf7c 1462
wolfSSL 15:117db924cf7c 1463 #if defined(FREESCALE_K70_RNGA) || defined(FREESCALE_RNGA)
wolfSSL 15:117db924cf7c 1464 /*
wolfSSL 15:117db924cf7c 1465 * wc_Generates a RNG seed using the Random Number Generator Accelerator
wolfSSL 15:117db924cf7c 1466 * on the Kinetis K70. Documentation located in Chapter 37 of
wolfSSL 15:117db924cf7c 1467 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
wolfSSL 15:117db924cf7c 1468 */
wolfSSL 15:117db924cf7c 1469 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1470 {
wolfSSL 15:117db924cf7c 1471 word32 i;
wolfSSL 15:117db924cf7c 1472
wolfSSL 15:117db924cf7c 1473 /* turn on RNGA module */
wolfSSL 15:117db924cf7c 1474 #if defined(SIM_SCGC3_RNGA_MASK)
wolfSSL 15:117db924cf7c 1475 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
wolfSSL 15:117db924cf7c 1476 #endif
wolfSSL 15:117db924cf7c 1477 #if defined(SIM_SCGC6_RNGA_MASK)
wolfSSL 15:117db924cf7c 1478 /* additionally needed for at least K64F */
wolfSSL 15:117db924cf7c 1479 SIM_SCGC6 |= SIM_SCGC6_RNGA_MASK;
wolfSSL 15:117db924cf7c 1480 #endif
wolfSSL 15:117db924cf7c 1481
wolfSSL 15:117db924cf7c 1482 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
wolfSSL 15:117db924cf7c 1483 RNG_CR &= ~RNG_CR_SLP_MASK;
wolfSSL 15:117db924cf7c 1484
wolfSSL 15:117db924cf7c 1485 /* set HA bit to 1 - "security violations masked" */
wolfSSL 15:117db924cf7c 1486 RNG_CR |= RNG_CR_HA_MASK;
wolfSSL 15:117db924cf7c 1487
wolfSSL 15:117db924cf7c 1488 /* set GO bit to 1 - "output register loaded with data" */
wolfSSL 15:117db924cf7c 1489 RNG_CR |= RNG_CR_GO_MASK;
wolfSSL 15:117db924cf7c 1490
wolfSSL 15:117db924cf7c 1491 for (i = 0; i < sz; i++) {
wolfSSL 15:117db924cf7c 1492
wolfSSL 15:117db924cf7c 1493 /* wait for RNG FIFO to be full */
wolfSSL 15:117db924cf7c 1494 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
wolfSSL 15:117db924cf7c 1495
wolfSSL 15:117db924cf7c 1496 /* get value */
wolfSSL 15:117db924cf7c 1497 output[i] = RNG_OR;
wolfSSL 15:117db924cf7c 1498 }
wolfSSL 15:117db924cf7c 1499
wolfSSL 15:117db924cf7c 1500 return 0;
wolfSSL 15:117db924cf7c 1501 }
wolfSSL 15:117db924cf7c 1502
wolfSSL 15:117db924cf7c 1503 #elif defined(FREESCALE_K53_RNGB) || defined(FREESCALE_RNGB)
wolfSSL 15:117db924cf7c 1504 /*
wolfSSL 15:117db924cf7c 1505 * wc_Generates a RNG seed using the Random Number Generator (RNGB)
wolfSSL 15:117db924cf7c 1506 * on the Kinetis K53. Documentation located in Chapter 33 of
wolfSSL 15:117db924cf7c 1507 * K53 Sub-Family Reference Manual (see note in the README for link).
wolfSSL 15:117db924cf7c 1508 */
wolfSSL 15:117db924cf7c 1509 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1510 {
wolfSSL 15:117db924cf7c 1511 int i;
wolfSSL 15:117db924cf7c 1512
wolfSSL 15:117db924cf7c 1513 /* turn on RNGB module */
wolfSSL 15:117db924cf7c 1514 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
wolfSSL 15:117db924cf7c 1515
wolfSSL 15:117db924cf7c 1516 /* reset RNGB */
wolfSSL 15:117db924cf7c 1517 RNG_CMD |= RNG_CMD_SR_MASK;
wolfSSL 15:117db924cf7c 1518
wolfSSL 15:117db924cf7c 1519 /* FIFO generate interrupt, return all zeros on underflow,
wolfSSL 15:117db924cf7c 1520 * set auto reseed */
wolfSSL 15:117db924cf7c 1521 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
wolfSSL 15:117db924cf7c 1522
wolfSSL 15:117db924cf7c 1523 /* gen seed, clear interrupts, clear errors */
wolfSSL 15:117db924cf7c 1524 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
wolfSSL 15:117db924cf7c 1525
wolfSSL 15:117db924cf7c 1526 /* wait for seeding to complete */
wolfSSL 15:117db924cf7c 1527 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
wolfSSL 15:117db924cf7c 1528
wolfSSL 15:117db924cf7c 1529 for (i = 0; i < sz; i++) {
wolfSSL 15:117db924cf7c 1530
wolfSSL 15:117db924cf7c 1531 /* wait for a word to be available from FIFO */
wolfSSL 15:117db924cf7c 1532 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
wolfSSL 15:117db924cf7c 1533
wolfSSL 15:117db924cf7c 1534 /* get value */
wolfSSL 15:117db924cf7c 1535 output[i] = RNG_OUT;
wolfSSL 15:117db924cf7c 1536 }
wolfSSL 15:117db924cf7c 1537
wolfSSL 15:117db924cf7c 1538 return 0;
wolfSSL 15:117db924cf7c 1539 }
wolfSSL 15:117db924cf7c 1540
wolfSSL 15:117db924cf7c 1541 #elif defined(FREESCALE_KSDK_2_0_TRNG)
wolfSSL 15:117db924cf7c 1542
wolfSSL 15:117db924cf7c 1543 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1544 {
wolfSSL 15:117db924cf7c 1545 status_t status;
wolfSSL 15:117db924cf7c 1546 status = TRNG_GetRandomData(TRNG0, output, sz);
wolfSSL 15:117db924cf7c 1547 if (status == kStatus_Success)
wolfSSL 15:117db924cf7c 1548 {
wolfSSL 15:117db924cf7c 1549 return(0);
wolfSSL 15:117db924cf7c 1550 }
wolfSSL 15:117db924cf7c 1551 else
wolfSSL 15:117db924cf7c 1552 {
wolfSSL 15:117db924cf7c 1553 return RAN_BLOCK_E;
wolfSSL 15:117db924cf7c 1554 }
wolfSSL 15:117db924cf7c 1555 }
wolfSSL 15:117db924cf7c 1556
wolfSSL 15:117db924cf7c 1557 #elif defined(FREESCALE_KSDK_2_0_RNGA)
wolfSSL 15:117db924cf7c 1558
wolfSSL 15:117db924cf7c 1559 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1560 {
wolfSSL 15:117db924cf7c 1561 status_t status;
wolfSSL 15:117db924cf7c 1562 status = RNGA_GetRandomData(RNG, output, sz);
wolfSSL 15:117db924cf7c 1563 if (status == kStatus_Success)
wolfSSL 15:117db924cf7c 1564 {
wolfSSL 15:117db924cf7c 1565 return(0);
wolfSSL 15:117db924cf7c 1566 }
wolfSSL 15:117db924cf7c 1567 else
wolfSSL 15:117db924cf7c 1568 {
wolfSSL 15:117db924cf7c 1569 return RAN_BLOCK_E;
wolfSSL 15:117db924cf7c 1570 }
wolfSSL 15:117db924cf7c 1571 }
wolfSSL 15:117db924cf7c 1572
wolfSSL 15:117db924cf7c 1573
wolfSSL 15:117db924cf7c 1574 #elif defined(FREESCALE_RNGA)
wolfSSL 15:117db924cf7c 1575
wolfSSL 15:117db924cf7c 1576 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1577 {
wolfSSL 15:117db924cf7c 1578 RNGA_DRV_GetRandomData(RNGA_INSTANCE, output, sz);
wolfSSL 15:117db924cf7c 1579 return 0;
wolfSSL 15:117db924cf7c 1580 }
wolfSSL 15:117db924cf7c 1581
wolfSSL 15:117db924cf7c 1582 #else
wolfSSL 15:117db924cf7c 1583 #define USE_TEST_GENSEED
wolfSSL 15:117db924cf7c 1584 #endif /* FREESCALE_K70_RNGA */
wolfSSL 15:117db924cf7c 1585
wolfSSL 15:117db924cf7c 1586 #elif defined(STM32_RNG)
wolfSSL 15:117db924cf7c 1587 /* Generate a RNG seed using the hardware random number generator
wolfSSL 15:117db924cf7c 1588 * on the STM32F2/F4/F7. */
wolfSSL 15:117db924cf7c 1589
wolfSSL 15:117db924cf7c 1590 #ifdef WOLFSSL_STM32_CUBEMX
wolfSSL 15:117db924cf7c 1591 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1592 {
wolfSSL 15:117db924cf7c 1593 RNG_HandleTypeDef hrng;
wolfSSL 15:117db924cf7c 1594 int i;
wolfSSL 15:117db924cf7c 1595 (void)os;
wolfSSL 15:117db924cf7c 1596
wolfSSL 15:117db924cf7c 1597 /* enable RNG clock source */
wolfSSL 15:117db924cf7c 1598 __HAL_RCC_RNG_CLK_ENABLE();
wolfSSL 15:117db924cf7c 1599
wolfSSL 15:117db924cf7c 1600 /* enable RNG peripheral */
wolfSSL 15:117db924cf7c 1601 hrng.Instance = RNG;
wolfSSL 15:117db924cf7c 1602 HAL_RNG_Init(&hrng);
wolfSSL 15:117db924cf7c 1603
wolfSSL 15:117db924cf7c 1604 for (i = 0; i < (int)sz; i++) {
wolfSSL 15:117db924cf7c 1605 /* get value */
wolfSSL 15:117db924cf7c 1606 output[i] = (byte)HAL_RNG_GetRandomNumber(&hrng);
wolfSSL 15:117db924cf7c 1607 }
wolfSSL 15:117db924cf7c 1608
wolfSSL 15:117db924cf7c 1609 return 0;
wolfSSL 15:117db924cf7c 1610 }
wolfSSL 15:117db924cf7c 1611 #elif defined(WOLFSSL_STM32F427_RNG)
wolfSSL 15:117db924cf7c 1612
wolfSSL 15:117db924cf7c 1613 /* Generate a RNG seed using the hardware RNG on the STM32F427
wolfSSL 15:117db924cf7c 1614 * directly, following steps outlined in STM32F4 Reference
wolfSSL 15:117db924cf7c 1615 * Manual (Chapter 24) for STM32F4xx family. */
wolfSSL 15:117db924cf7c 1616 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1617 {
wolfSSL 15:117db924cf7c 1618 int i;
wolfSSL 15:117db924cf7c 1619 (void)os;
wolfSSL 15:117db924cf7c 1620
wolfSSL 15:117db924cf7c 1621 /* enable RNG interrupt, set IE bit in RNG->CR register */
wolfSSL 15:117db924cf7c 1622 RNG->CR |= RNG_CR_IE;
wolfSSL 15:117db924cf7c 1623
wolfSSL 15:117db924cf7c 1624 /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG,
wolfSSL 15:117db924cf7c 1625 * RNG_LFSR, and error detector */
wolfSSL 15:117db924cf7c 1626 RNG->CR |= RNG_CR_RNGEN;
wolfSSL 15:117db924cf7c 1627
wolfSSL 15:117db924cf7c 1628 /* verify no errors, make sure SEIS and CEIS bits are 0
wolfSSL 15:117db924cf7c 1629 * in RNG->SR register */
wolfSSL 15:117db924cf7c 1630 if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS))
wolfSSL 15:117db924cf7c 1631 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1632
wolfSSL 15:117db924cf7c 1633 for (i = 0; i < (int)sz; i++) {
wolfSSL 15:117db924cf7c 1634 /* wait until RNG number is ready */
wolfSSL 15:117db924cf7c 1635 while ((RNG->SR & RNG_SR_DRDY) == 0) { }
wolfSSL 15:117db924cf7c 1636
wolfSSL 15:117db924cf7c 1637 /* get value */
wolfSSL 15:117db924cf7c 1638 output[i] = RNG->DR;
wolfSSL 15:117db924cf7c 1639 }
wolfSSL 15:117db924cf7c 1640
wolfSSL 15:117db924cf7c 1641 return 0;
wolfSSL 15:117db924cf7c 1642 }
wolfSSL 15:117db924cf7c 1643
wolfSSL 15:117db924cf7c 1644 #else
wolfSSL 15:117db924cf7c 1645
wolfSSL 15:117db924cf7c 1646 /* Generate a RNG seed using the STM32 Standard Peripheral Library */
wolfSSL 15:117db924cf7c 1647 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1648 {
wolfSSL 15:117db924cf7c 1649 int i;
wolfSSL 15:117db924cf7c 1650 (void)os;
wolfSSL 15:117db924cf7c 1651
wolfSSL 15:117db924cf7c 1652 /* enable RNG clock source */
wolfSSL 15:117db924cf7c 1653 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
wolfSSL 15:117db924cf7c 1654
wolfSSL 15:117db924cf7c 1655 /* reset RNG */
wolfSSL 15:117db924cf7c 1656 RNG_DeInit();
wolfSSL 15:117db924cf7c 1657
wolfSSL 15:117db924cf7c 1658 /* enable RNG peripheral */
wolfSSL 15:117db924cf7c 1659 RNG_Cmd(ENABLE);
wolfSSL 15:117db924cf7c 1660
wolfSSL 15:117db924cf7c 1661 /* verify no errors with RNG_CLK or Seed */
wolfSSL 15:117db924cf7c 1662 if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET)
wolfSSL 15:117db924cf7c 1663 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1664
wolfSSL 15:117db924cf7c 1665 for (i = 0; i < (int)sz; i++) {
wolfSSL 15:117db924cf7c 1666 /* wait until RNG number is ready */
wolfSSL 15:117db924cf7c 1667 while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { }
wolfSSL 15:117db924cf7c 1668
wolfSSL 15:117db924cf7c 1669 /* get value */
wolfSSL 15:117db924cf7c 1670 output[i] = RNG_GetRandomNumber();
wolfSSL 15:117db924cf7c 1671 }
wolfSSL 15:117db924cf7c 1672
wolfSSL 15:117db924cf7c 1673 return 0;
wolfSSL 15:117db924cf7c 1674 }
wolfSSL 15:117db924cf7c 1675 #endif /* WOLFSSL_STM32_CUBEMX */
wolfSSL 15:117db924cf7c 1676
wolfSSL 15:117db924cf7c 1677 #elif defined(WOLFSSL_TIRTOS)
wolfSSL 15:117db924cf7c 1678
wolfSSL 15:117db924cf7c 1679 #include <xdc/runtime/Timestamp.h>
wolfSSL 15:117db924cf7c 1680 #include <stdlib.h>
wolfSSL 15:117db924cf7c 1681 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1682 {
wolfSSL 15:117db924cf7c 1683 int i;
wolfSSL 15:117db924cf7c 1684 srand(xdc_runtime_Timestamp_get32());
wolfSSL 15:117db924cf7c 1685
wolfSSL 15:117db924cf7c 1686 for (i = 0; i < sz; i++ ) {
wolfSSL 15:117db924cf7c 1687 output[i] = rand() % 256;
wolfSSL 15:117db924cf7c 1688 if ((i % 8) == 7) {
wolfSSL 15:117db924cf7c 1689 srand(xdc_runtime_Timestamp_get32());
wolfSSL 15:117db924cf7c 1690 }
wolfSSL 15:117db924cf7c 1691 }
wolfSSL 15:117db924cf7c 1692
wolfSSL 15:117db924cf7c 1693 return 0;
wolfSSL 15:117db924cf7c 1694 }
wolfSSL 15:117db924cf7c 1695
wolfSSL 15:117db924cf7c 1696 #elif defined(WOLFSSL_PB)
wolfSSL 15:117db924cf7c 1697
wolfSSL 15:117db924cf7c 1698 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1699 {
wolfSSL 15:117db924cf7c 1700 word32 i;
wolfSSL 15:117db924cf7c 1701 for (i = 0; i < sz; i++)
wolfSSL 15:117db924cf7c 1702 output[i] = UTL_Rand();
wolfSSL 15:117db924cf7c 1703
wolfSSL 15:117db924cf7c 1704 (void)os;
wolfSSL 15:117db924cf7c 1705
wolfSSL 15:117db924cf7c 1706 return 0;
wolfSSL 15:117db924cf7c 1707 }
wolfSSL 15:117db924cf7c 1708
wolfSSL 15:117db924cf7c 1709 #elif defined(WOLFSSL_NUCLEUS)
wolfSSL 15:117db924cf7c 1710 #include "nucleus.h"
wolfSSL 15:117db924cf7c 1711 #include "kernel/plus_common.h"
wolfSSL 15:117db924cf7c 1712
wolfSSL 15:117db924cf7c 1713 #warning "potential for not enough entropy, currently being used for testing"
wolfSSL 15:117db924cf7c 1714 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1715 {
wolfSSL 15:117db924cf7c 1716 int i;
wolfSSL 15:117db924cf7c 1717 srand(NU_Get_Time_Stamp());
wolfSSL 15:117db924cf7c 1718
wolfSSL 15:117db924cf7c 1719 for (i = 0; i < sz; i++ ) {
wolfSSL 15:117db924cf7c 1720 output[i] = rand() % 256;
wolfSSL 15:117db924cf7c 1721 if ((i % 8) == 7) {
wolfSSL 15:117db924cf7c 1722 srand(NU_Get_Time_Stamp());
wolfSSL 15:117db924cf7c 1723 }
wolfSSL 15:117db924cf7c 1724 }
wolfSSL 15:117db924cf7c 1725
wolfSSL 15:117db924cf7c 1726 return 0;
wolfSSL 15:117db924cf7c 1727 }
wolfSSL 15:117db924cf7c 1728 #elif defined(WOLFSSL_VXWORKS)
wolfSSL 15:117db924cf7c 1729
wolfSSL 15:117db924cf7c 1730 #include <randomNumGen.h>
wolfSSL 15:117db924cf7c 1731
wolfSSL 15:117db924cf7c 1732 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) {
wolfSSL 15:117db924cf7c 1733 STATUS status;
wolfSSL 15:117db924cf7c 1734
wolfSSL 15:117db924cf7c 1735 #ifdef VXWORKS_SIM
wolfSSL 15:117db924cf7c 1736 /* cannot generate true entropy with VxWorks simulator */
wolfSSL 15:117db924cf7c 1737 #warning "not enough entropy, simulator for testing only"
wolfSSL 15:117db924cf7c 1738 int i = 0;
wolfSSL 15:117db924cf7c 1739
wolfSSL 15:117db924cf7c 1740 for (i = 0; i < 1000; i++) {
wolfSSL 15:117db924cf7c 1741 randomAddTimeStamp();
wolfSSL 15:117db924cf7c 1742 }
wolfSSL 15:117db924cf7c 1743 #endif
wolfSSL 15:117db924cf7c 1744
wolfSSL 15:117db924cf7c 1745 status = randBytes (output, sz);
wolfSSL 15:117db924cf7c 1746 if (status == ERROR) {
wolfSSL 15:117db924cf7c 1747 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1748 }
wolfSSL 15:117db924cf7c 1749
wolfSSL 15:117db924cf7c 1750 return 0;
wolfSSL 15:117db924cf7c 1751 }
wolfSSL 15:117db924cf7c 1752
wolfSSL 15:117db924cf7c 1753 #elif defined(WOLFSSL_NRF51)
wolfSSL 15:117db924cf7c 1754 #include "app_error.h"
wolfSSL 15:117db924cf7c 1755 #include "nrf_drv_rng.h"
wolfSSL 15:117db924cf7c 1756 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1757 {
wolfSSL 15:117db924cf7c 1758 int remaining = sz, length, pos = 0;
wolfSSL 15:117db924cf7c 1759 uint8_t available;
wolfSSL 15:117db924cf7c 1760 uint32_t err_code;
wolfSSL 15:117db924cf7c 1761
wolfSSL 15:117db924cf7c 1762 (void)os;
wolfSSL 15:117db924cf7c 1763
wolfSSL 15:117db924cf7c 1764 /* Make sure RNG is running */
wolfSSL 15:117db924cf7c 1765 err_code = nrf_drv_rng_init(NULL);
wolfSSL 15:117db924cf7c 1766 if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
wolfSSL 15:117db924cf7c 1767 return -1;
wolfSSL 15:117db924cf7c 1768 }
wolfSSL 15:117db924cf7c 1769
wolfSSL 15:117db924cf7c 1770 while (remaining > 0) {
wolfSSL 15:117db924cf7c 1771 err_code = nrf_drv_rng_bytes_available(&available);
wolfSSL 15:117db924cf7c 1772 if (err_code == NRF_SUCCESS) {
wolfSSL 15:117db924cf7c 1773 length = (remaining < available) ? remaining : available;
wolfSSL 15:117db924cf7c 1774 if (length > 0) {
wolfSSL 15:117db924cf7c 1775 err_code = nrf_drv_rng_rand(&output[pos], length);
wolfSSL 15:117db924cf7c 1776 remaining -= length;
wolfSSL 15:117db924cf7c 1777 pos += length;
wolfSSL 15:117db924cf7c 1778 }
wolfSSL 15:117db924cf7c 1779 }
wolfSSL 15:117db924cf7c 1780
wolfSSL 15:117db924cf7c 1781 if (err_code != NRF_SUCCESS) {
wolfSSL 15:117db924cf7c 1782 break;
wolfSSL 15:117db924cf7c 1783 }
wolfSSL 15:117db924cf7c 1784 }
wolfSSL 15:117db924cf7c 1785
wolfSSL 15:117db924cf7c 1786 return (err_code == NRF_SUCCESS) ? 0 : -1;
wolfSSL 15:117db924cf7c 1787 }
wolfSSL 15:117db924cf7c 1788
wolfSSL 15:117db924cf7c 1789 #elif defined(HAVE_WNR)
wolfSSL 15:117db924cf7c 1790
wolfSSL 15:117db924cf7c 1791 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1792 {
wolfSSL 15:117db924cf7c 1793 if (os == NULL || output == NULL || wnr_ctx == NULL ||
wolfSSL 15:117db924cf7c 1794 wnr_timeout < 0) {
wolfSSL 15:117db924cf7c 1795 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1796 }
wolfSSL 15:117db924cf7c 1797
wolfSSL 15:117db924cf7c 1798 if (wnr_mutex_init == 0) {
wolfSSL 15:117db924cf7c 1799 WOLFSSL_MSG("netRandom context must be created before use");
wolfSSL 15:117db924cf7c 1800 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1801 }
wolfSSL 15:117db924cf7c 1802
wolfSSL 15:117db924cf7c 1803 if (wc_LockMutex(&wnr_mutex) != 0) {
wolfSSL 15:117db924cf7c 1804 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex\n");
wolfSSL 15:117db924cf7c 1805 return BAD_MUTEX_E;
wolfSSL 15:117db924cf7c 1806 }
wolfSSL 15:117db924cf7c 1807
wolfSSL 15:117db924cf7c 1808 if (wnr_get_entropy(wnr_ctx, wnr_timeout, output, sz, sz) !=
wolfSSL 15:117db924cf7c 1809 WNR_ERROR_NONE)
wolfSSL 15:117db924cf7c 1810 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1811
wolfSSL 15:117db924cf7c 1812 wc_UnLockMutex(&wnr_mutex);
wolfSSL 15:117db924cf7c 1813
wolfSSL 15:117db924cf7c 1814 return 0;
wolfSSL 15:117db924cf7c 1815 }
wolfSSL 15:117db924cf7c 1816
wolfSSL 15:117db924cf7c 1817 #elif defined(WOLFSSL_ATMEL)
wolfSSL 15:117db924cf7c 1818 #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
wolfSSL 15:117db924cf7c 1819
wolfSSL 15:117db924cf7c 1820 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1821 {
wolfSSL 15:117db924cf7c 1822 int ret = 0;
wolfSSL 15:117db924cf7c 1823
wolfSSL 15:117db924cf7c 1824 (void)os;
wolfSSL 15:117db924cf7c 1825 if (output == NULL) {
wolfSSL 15:117db924cf7c 1826 return BUFFER_E;
wolfSSL 15:117db924cf7c 1827 }
wolfSSL 15:117db924cf7c 1828
wolfSSL 15:117db924cf7c 1829 ret = atmel_get_random_number(sz, output);
wolfSSL 15:117db924cf7c 1830
wolfSSL 15:117db924cf7c 1831 return ret;
wolfSSL 15:117db924cf7c 1832 }
wolfSSL 15:117db924cf7c 1833
wolfSSL 15:117db924cf7c 1834 #elif defined(INTIME_RTOS)
wolfSSL 15:117db924cf7c 1835 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1836 {
wolfSSL 15:117db924cf7c 1837 int ret = 0;
wolfSSL 15:117db924cf7c 1838
wolfSSL 15:117db924cf7c 1839 (void)os;
wolfSSL 15:117db924cf7c 1840
wolfSSL 15:117db924cf7c 1841 if (output == NULL) {
wolfSSL 15:117db924cf7c 1842 return BUFFER_E;
wolfSSL 15:117db924cf7c 1843 }
wolfSSL 15:117db924cf7c 1844
wolfSSL 15:117db924cf7c 1845 /* Note: Investigate better solution */
wolfSSL 15:117db924cf7c 1846 /* no return to check */
wolfSSL 15:117db924cf7c 1847 arc4random_buf(output, sz);
wolfSSL 15:117db924cf7c 1848
wolfSSL 15:117db924cf7c 1849 return ret;
wolfSSL 15:117db924cf7c 1850 }
wolfSSL 15:117db924cf7c 1851
wolfSSL 15:117db924cf7c 1852 #elif defined(IDIRECT_DEV_RANDOM)
wolfSSL 15:117db924cf7c 1853
wolfSSL 15:117db924cf7c 1854 extern int getRandom( int sz, unsigned char *output );
wolfSSL 15:117db924cf7c 1855
wolfSSL 15:117db924cf7c 1856 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1857 {
wolfSSL 15:117db924cf7c 1858 int num_bytes_returned = 0;
wolfSSL 15:117db924cf7c 1859
wolfSSL 15:117db924cf7c 1860 num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );
wolfSSL 15:117db924cf7c 1861
wolfSSL 15:117db924cf7c 1862 return 0;
wolfSSL 15:117db924cf7c 1863 }
wolfSSL 15:117db924cf7c 1864
wolfSSL 15:117db924cf7c 1865 #elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG))
wolfSSL 15:117db924cf7c 1866
wolfSSL 15:117db924cf7c 1867 #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
wolfSSL 15:117db924cf7c 1868 #include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
wolfSSL 15:117db924cf7c 1869
wolfSSL 15:117db924cf7c 1870 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1871 {
wolfSSL 15:117db924cf7c 1872 Buffer buf[1];
wolfSSL 15:117db924cf7c 1873 int ret = 0;
wolfSSL 15:117db924cf7c 1874 int times = 1000, i;
wolfSSL 15:117db924cf7c 1875
wolfSSL 15:117db924cf7c 1876 (void)os;
wolfSSL 15:117db924cf7c 1877
wolfSSL 15:117db924cf7c 1878 if (output == NULL) {
wolfSSL 15:117db924cf7c 1879 return BUFFER_E;
wolfSSL 15:117db924cf7c 1880 }
wolfSSL 15:117db924cf7c 1881
wolfSSL 15:117db924cf7c 1882 buf[0].BufferType = DataBuffer | LastBuffer;
wolfSSL 15:117db924cf7c 1883 buf[0].TheAddress = (Address)output;
wolfSSL 15:117db924cf7c 1884 buf[0].Length = sz;
wolfSSL 15:117db924cf7c 1885
wolfSSL 15:117db924cf7c 1886 /* Check Waiting to make sure entropy is ready */
wolfSSL 15:117db924cf7c 1887 for (i = 0; i < times; i++) {
wolfSSL 15:117db924cf7c 1888 ret = wc_caamAddAndWait(buf, NULL, CAAM_ENTROPY);
wolfSSL 15:117db924cf7c 1889 if (ret == Success) {
wolfSSL 15:117db924cf7c 1890 break;
wolfSSL 15:117db924cf7c 1891 }
wolfSSL 15:117db924cf7c 1892
wolfSSL 15:117db924cf7c 1893 /* driver could be waiting for entropy */
wolfSSL 15:117db924cf7c 1894 if (ret != RAN_BLOCK_E) {
wolfSSL 15:117db924cf7c 1895 return ret;
wolfSSL 15:117db924cf7c 1896 }
wolfSSL 15:117db924cf7c 1897 usleep(100);
wolfSSL 15:117db924cf7c 1898 }
wolfSSL 15:117db924cf7c 1899
wolfSSL 15:117db924cf7c 1900 if (i == times && ret != Success) {
wolfSSL 15:117db924cf7c 1901 return RNG_FAILURE_E;
wolfSSL 15:117db924cf7c 1902 }
wolfSSL 15:117db924cf7c 1903 else { /* Success case */
wolfSSL 15:117db924cf7c 1904 ret = 0;
wolfSSL 15:117db924cf7c 1905 }
wolfSSL 15:117db924cf7c 1906
wolfSSL 15:117db924cf7c 1907 return ret;
wolfSSL 15:117db924cf7c 1908 }
wolfSSL 15:117db924cf7c 1909
wolfSSL 15:117db924cf7c 1910 #elif defined(CUSTOM_RAND_GENERATE_BLOCK)
wolfSSL 15:117db924cf7c 1911 /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
wolfSSL 15:117db924cf7c 1912 * extern int myRngFunc(byte* output, word32 sz);
wolfSSL 15:117db924cf7c 1913 */
wolfSSL 15:117db924cf7c 1914
wolfSSL 15:117db924cf7c 1915 #elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \
wolfSSL 15:117db924cf7c 1916 defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_MDK_ARM) || \
wolfSSL 15:117db924cf7c 1917 defined(WOLFSSL_uITRON4) || defined(WOLFSSL_uTKERNEL2) || \
wolfSSL 15:117db924cf7c 1918 defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || \
wolfSSL 15:117db924cf7c 1919 defined(MBED) || defined(WOLFSSL_EMBOS) || \
wolfSSL 15:117db924cf7c 1920 defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS)
wolfSSL 15:117db924cf7c 1921
wolfSSL 15:117db924cf7c 1922 /* these platforms do not have a default random seed and
wolfSSL 15:117db924cf7c 1923 you'll need to implement your own wc_GenerateSeed or define via
wolfSSL 15:117db924cf7c 1924 CUSTOM_RAND_GENERATE_BLOCK */
wolfSSL 15:117db924cf7c 1925
wolfSSL 15:117db924cf7c 1926 #define USE_TEST_GENSEED
wolfSSL 15:117db924cf7c 1927
wolfSSL 15:117db924cf7c 1928 #elif defined(NO_DEV_RANDOM)
wolfSSL 15:117db924cf7c 1929
wolfSSL 15:117db924cf7c 1930 #error "you need to write an os specific wc_GenerateSeed() here"
wolfSSL 15:117db924cf7c 1931
wolfSSL 15:117db924cf7c 1932 /*
wolfSSL 15:117db924cf7c 1933 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1934 {
wolfSSL 15:117db924cf7c 1935 return 0;
wolfSSL 15:117db924cf7c 1936 }
wolfSSL 15:117db924cf7c 1937 */
wolfSSL 15:117db924cf7c 1938
wolfSSL 15:117db924cf7c 1939 #else
wolfSSL 15:117db924cf7c 1940
wolfSSL 15:117db924cf7c 1941 /* may block */
wolfSSL 15:117db924cf7c 1942 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 1943 {
wolfSSL 15:117db924cf7c 1944 int ret = 0;
wolfSSL 15:117db924cf7c 1945
wolfSSL 15:117db924cf7c 1946 #ifdef HAVE_INTEL_RDSEED
wolfSSL 15:117db924cf7c 1947 if (IS_INTEL_RDSEED(intel_flags)) {
wolfSSL 15:117db924cf7c 1948 ret = wc_GenerateSeed_IntelRD(NULL, output, sz);
wolfSSL 15:117db924cf7c 1949 if (ret == 0) {
wolfSSL 15:117db924cf7c 1950 /* success, we're done */
wolfSSL 15:117db924cf7c 1951 return ret;
wolfSSL 15:117db924cf7c 1952 }
wolfSSL 15:117db924cf7c 1953 #ifdef FORCE_FAILURE_RDSEED
wolfSSL 15:117db924cf7c 1954 /* don't fallback to /dev/urandom */
wolfSSL 15:117db924cf7c 1955 return ret;
wolfSSL 15:117db924cf7c 1956 #else
wolfSSL 15:117db924cf7c 1957 /* reset error and fallback to using /dev/urandom */
wolfSSL 15:117db924cf7c 1958 ret = 0;
wolfSSL 15:117db924cf7c 1959 #endif
wolfSSL 15:117db924cf7c 1960 }
wolfSSL 15:117db924cf7c 1961 #endif /* HAVE_INTEL_RDSEED */
wolfSSL 15:117db924cf7c 1962
wolfSSL 15:117db924cf7c 1963 #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
wolfSSL 15:117db924cf7c 1964 os->fd = open("/dev/urandom", O_RDONLY);
wolfSSL 15:117db924cf7c 1965 if (os->fd == -1)
wolfSSL 15:117db924cf7c 1966 #endif
wolfSSL 15:117db924cf7c 1967 {
wolfSSL 15:117db924cf7c 1968 /* may still have /dev/random */
wolfSSL 15:117db924cf7c 1969 os->fd = open("/dev/random", O_RDONLY);
wolfSSL 15:117db924cf7c 1970 if (os->fd == -1)
wolfSSL 15:117db924cf7c 1971 return OPEN_RAN_E;
wolfSSL 15:117db924cf7c 1972 }
wolfSSL 15:117db924cf7c 1973
wolfSSL 15:117db924cf7c 1974 while (sz) {
wolfSSL 15:117db924cf7c 1975 int len = (int)read(os->fd, output, sz);
wolfSSL 15:117db924cf7c 1976 if (len == -1) {
wolfSSL 15:117db924cf7c 1977 ret = READ_RAN_E;
wolfSSL 15:117db924cf7c 1978 break;
wolfSSL 15:117db924cf7c 1979 }
wolfSSL 15:117db924cf7c 1980
wolfSSL 15:117db924cf7c 1981 sz -= len;
wolfSSL 15:117db924cf7c 1982 output += len;
wolfSSL 15:117db924cf7c 1983
wolfSSL 15:117db924cf7c 1984 if (sz) {
wolfSSL 15:117db924cf7c 1985 #if defined(BLOCKING) || defined(WC_RNG_BLOCKING)
wolfSSL 15:117db924cf7c 1986 sleep(0); /* context switch */
wolfSSL 15:117db924cf7c 1987 #else
wolfSSL 15:117db924cf7c 1988 ret = RAN_BLOCK_E;
wolfSSL 15:117db924cf7c 1989 break;
wolfSSL 15:117db924cf7c 1990 #endif
wolfSSL 15:117db924cf7c 1991 }
wolfSSL 15:117db924cf7c 1992 }
wolfSSL 15:117db924cf7c 1993 close(os->fd);
wolfSSL 15:117db924cf7c 1994
wolfSSL 15:117db924cf7c 1995 return ret;
wolfSSL 15:117db924cf7c 1996 }
wolfSSL 15:117db924cf7c 1997
wolfSSL 15:117db924cf7c 1998 #endif
wolfSSL 15:117db924cf7c 1999
wolfSSL 15:117db924cf7c 2000 #ifdef USE_TEST_GENSEED
wolfSSL 15:117db924cf7c 2001 #ifndef _MSC_VER
wolfSSL 15:117db924cf7c 2002 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 15:117db924cf7c 2003 #else
wolfSSL 15:117db924cf7c 2004 #pragma message("Warning: write a real random seed!!!!, just for testing now")
wolfSSL 15:117db924cf7c 2005 #endif
wolfSSL 15:117db924cf7c 2006
wolfSSL 15:117db924cf7c 2007 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 15:117db924cf7c 2008 {
wolfSSL 15:117db924cf7c 2009 word32 i;
wolfSSL 15:117db924cf7c 2010 for (i = 0; i < sz; i++ )
wolfSSL 15:117db924cf7c 2011 output[i] = i;
wolfSSL 15:117db924cf7c 2012
wolfSSL 15:117db924cf7c 2013 (void)os;
wolfSSL 15:117db924cf7c 2014
wolfSSL 15:117db924cf7c 2015 return 0;
wolfSSL 15:117db924cf7c 2016 }
wolfSSL 15:117db924cf7c 2017 #endif
wolfSSL 15:117db924cf7c 2018
wolfSSL 15:117db924cf7c 2019 /* End wc_GenerateSeed */
wolfSSL 15:117db924cf7c 2020
wolfSSL 15:117db924cf7c 2021 #endif /* WC_NO_RNG */
wolfSSL 15:117db924cf7c 2022 #endif /* HAVE_FIPS */
wolfSSL 15:117db924cf7c 2023