wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

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