Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
sPymbed
Date:
Tue Nov 19 14:32:16 2019 +0000
Revision:
16:048e5e270a58
Parent:
15:117db924cf7c
working ssl

Who changed what in which revision?

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