wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
Parent:
11:cee25a834751
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

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