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

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

Committer:
wolfSSL
Date:
Fri Jun 26 00:39:20 2015 +0000
Revision:
0:d92f9d21154c
wolfSSL 3.6.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:d92f9d21154c 1 /* random.c
wolfSSL 0:d92f9d21154c 2 *
wolfSSL 0:d92f9d21154c 3 * Copyright (C) 2006-2015 wolfSSL Inc.
wolfSSL 0:d92f9d21154c 4 *
wolfSSL 0:d92f9d21154c 5 * This file is part of wolfSSL. (formerly known as CyaSSL)
wolfSSL 0:d92f9d21154c 6 *
wolfSSL 0:d92f9d21154c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 0:d92f9d21154c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:d92f9d21154c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:d92f9d21154c 10 * (at your option) any later version.
wolfSSL 0:d92f9d21154c 11 *
wolfSSL 0:d92f9d21154c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 0:d92f9d21154c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:d92f9d21154c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:d92f9d21154c 15 * GNU General Public License for more details.
wolfSSL 0:d92f9d21154c 16 *
wolfSSL 0:d92f9d21154c 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:d92f9d21154c 18 * along with this program; if not, write to the Free Software
wolfSSL 0:d92f9d21154c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
wolfSSL 0:d92f9d21154c 20 */
wolfSSL 0:d92f9d21154c 21
wolfSSL 0:d92f9d21154c 22 #ifdef HAVE_CONFIG_H
wolfSSL 0:d92f9d21154c 23 #include <config.h>
wolfSSL 0:d92f9d21154c 24 #endif
wolfSSL 0:d92f9d21154c 25
wolfSSL 0:d92f9d21154c 26 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 0:d92f9d21154c 27
wolfSSL 0:d92f9d21154c 28 /* on HPUX 11 you may need to install /dev/random see
wolfSSL 0:d92f9d21154c 29 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
wolfSSL 0:d92f9d21154c 30
wolfSSL 0:d92f9d21154c 31 */
wolfSSL 0:d92f9d21154c 32
wolfSSL 0:d92f9d21154c 33 #include <wolfssl/wolfcrypt/random.h>
wolfSSL 0:d92f9d21154c 34
wolfSSL 0:d92f9d21154c 35 #ifdef HAVE_FIPS
wolfSSL 0:d92f9d21154c 36 int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
wolfSSL 0:d92f9d21154c 37 {
wolfSSL 0:d92f9d21154c 38 return GenerateSeed(os, seed, sz);
wolfSSL 0:d92f9d21154c 39 }
wolfSSL 0:d92f9d21154c 40
wolfSSL 0:d92f9d21154c 41 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 42 int wc_InitRngCavium(RNG* rng, int i)
wolfSSL 0:d92f9d21154c 43 {
wolfSSL 0:d92f9d21154c 44 return InitRngCavium(rng, i);
wolfSSL 0:d92f9d21154c 45 }
wolfSSL 0:d92f9d21154c 46 #endif
wolfSSL 0:d92f9d21154c 47
wolfSSL 0:d92f9d21154c 48
wolfSSL 0:d92f9d21154c 49 int wc_InitRng(RNG* rng)
wolfSSL 0:d92f9d21154c 50 {
wolfSSL 0:d92f9d21154c 51 return InitRng_fips(rng);
wolfSSL 0:d92f9d21154c 52 }
wolfSSL 0:d92f9d21154c 53
wolfSSL 0:d92f9d21154c 54
wolfSSL 0:d92f9d21154c 55 int wc_RNG_GenerateBlock(RNG* rng, byte* b, word32 sz)
wolfSSL 0:d92f9d21154c 56 {
wolfSSL 0:d92f9d21154c 57 return RNG_GenerateBlock_fips(rng, b, sz);
wolfSSL 0:d92f9d21154c 58 }
wolfSSL 0:d92f9d21154c 59
wolfSSL 0:d92f9d21154c 60
wolfSSL 0:d92f9d21154c 61 int wc_RNG_GenerateByte(RNG* rng, byte* b)
wolfSSL 0:d92f9d21154c 62 {
wolfSSL 0:d92f9d21154c 63 return RNG_GenerateByte(rng, b);
wolfSSL 0:d92f9d21154c 64 }
wolfSSL 0:d92f9d21154c 65
wolfSSL 0:d92f9d21154c 66 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
wolfSSL 0:d92f9d21154c 67
wolfSSL 0:d92f9d21154c 68 int wc_FreeRng(RNG* rng)
wolfSSL 0:d92f9d21154c 69 {
wolfSSL 0:d92f9d21154c 70 return FreeRng_fips(rng);
wolfSSL 0:d92f9d21154c 71 }
wolfSSL 0:d92f9d21154c 72
wolfSSL 0:d92f9d21154c 73
wolfSSL 0:d92f9d21154c 74 int wc_RNG_HealthTest(int reseed,
wolfSSL 0:d92f9d21154c 75 const byte* entropyA, word32 entropyASz,
wolfSSL 0:d92f9d21154c 76 const byte* entropyB, word32 entropyBSz,
wolfSSL 0:d92f9d21154c 77 byte* output, word32 outputSz)
wolfSSL 0:d92f9d21154c 78 {
wolfSSL 0:d92f9d21154c 79 return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
wolfSSL 0:d92f9d21154c 80 entropyB, entropyBSz, output, outputSz);
wolfSSL 0:d92f9d21154c 81 }
wolfSSL 0:d92f9d21154c 82 #endif /* HAVE_HASHDRBG || NO_RC4 */
wolfSSL 0:d92f9d21154c 83 #else /* else build without fips */
wolfSSL 0:d92f9d21154c 84 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 0:d92f9d21154c 85
wolfSSL 0:d92f9d21154c 86 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
wolfSSL 0:d92f9d21154c 87
wolfSSL 0:d92f9d21154c 88 #include <wolfssl/wolfcrypt/sha256.h>
wolfSSL 0:d92f9d21154c 89
wolfSSL 0:d92f9d21154c 90 #ifdef NO_INLINE
wolfSSL 0:d92f9d21154c 91 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 0:d92f9d21154c 92 #else
wolfSSL 0:d92f9d21154c 93 #include <wolfcrypt/src/misc.c>
wolfSSL 0:d92f9d21154c 94 #endif
wolfSSL 0:d92f9d21154c 95 #endif /* HAVE_HASHDRBG || NO_RC4 */
wolfSSL 0:d92f9d21154c 96
wolfSSL 0:d92f9d21154c 97 #if defined(USE_WINDOWS_API)
wolfSSL 0:d92f9d21154c 98 #ifndef _WIN32_WINNT
wolfSSL 0:d92f9d21154c 99 #define _WIN32_WINNT 0x0400
wolfSSL 0:d92f9d21154c 100 #endif
wolfSSL 0:d92f9d21154c 101 #include <windows.h>
wolfSSL 0:d92f9d21154c 102 #include <wincrypt.h>
wolfSSL 0:d92f9d21154c 103 #else
wolfSSL 0:d92f9d21154c 104 #if !defined(NO_DEV_RANDOM) && !defined(CUSTOM_RAND_GENERATE) && \
wolfSSL 0:d92f9d21154c 105 !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)
wolfSSL 0:d92f9d21154c 106 #include <fcntl.h>
wolfSSL 0:d92f9d21154c 107 #ifndef EBSNET
wolfSSL 0:d92f9d21154c 108 #include <unistd.h>
wolfSSL 0:d92f9d21154c 109 #endif
wolfSSL 0:d92f9d21154c 110 #else
wolfSSL 0:d92f9d21154c 111 /* include headers that may be needed to get good seed */
wolfSSL 0:d92f9d21154c 112 #endif
wolfSSL 0:d92f9d21154c 113 #endif /* USE_WINDOWS_API */
wolfSSL 0:d92f9d21154c 114
wolfSSL 0:d92f9d21154c 115 #ifdef HAVE_INTEL_RDGEN
wolfSSL 0:d92f9d21154c 116 static int wc_InitRng_IntelRD(void) ;
wolfSSL 0:d92f9d21154c 117 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
wolfSSL 0:d92f9d21154c 118 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) ;
wolfSSL 0:d92f9d21154c 119 #else
wolfSSL 0:d92f9d21154c 120 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) ;
wolfSSL 0:d92f9d21154c 121 #endif
wolfSSL 0:d92f9d21154c 122 static word32 cpuid_check = 0 ;
wolfSSL 0:d92f9d21154c 123 static word32 cpuid_flags = 0 ;
wolfSSL 0:d92f9d21154c 124 #define CPUID_RDRAND 0x4
wolfSSL 0:d92f9d21154c 125 #define CPUID_RDSEED 0x8
wolfSSL 0:d92f9d21154c 126 #define IS_INTEL_RDRAND (cpuid_flags&CPUID_RDRAND)
wolfSSL 0:d92f9d21154c 127 #define IS_INTEL_RDSEED (cpuid_flags&CPUID_RDSEED)
wolfSSL 0:d92f9d21154c 128 #endif
wolfSSL 0:d92f9d21154c 129
wolfSSL 0:d92f9d21154c 130 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
wolfSSL 0:d92f9d21154c 131
wolfSSL 0:d92f9d21154c 132 /* Start NIST DRBG code */
wolfSSL 0:d92f9d21154c 133
wolfSSL 0:d92f9d21154c 134 #define OUTPUT_BLOCK_LEN (SHA256_DIGEST_SIZE)
wolfSSL 0:d92f9d21154c 135 #define MAX_REQUEST_LEN (0x10000)
wolfSSL 0:d92f9d21154c 136 #define RESEED_INTERVAL (1000000)
wolfSSL 0:d92f9d21154c 137 #define SECURITY_STRENGTH (256)
wolfSSL 0:d92f9d21154c 138 #define ENTROPY_SZ (SECURITY_STRENGTH/8)
wolfSSL 0:d92f9d21154c 139 #define NONCE_SZ (ENTROPY_SZ/2)
wolfSSL 0:d92f9d21154c 140 #define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
wolfSSL 0:d92f9d21154c 141
wolfSSL 0:d92f9d21154c 142 /* Internal return codes */
wolfSSL 0:d92f9d21154c 143 #define DRBG_SUCCESS 0
wolfSSL 0:d92f9d21154c 144 #define DRBG_ERROR 1
wolfSSL 0:d92f9d21154c 145 #define DRBG_FAILURE 2
wolfSSL 0:d92f9d21154c 146 #define DRBG_NEED_RESEED 3
wolfSSL 0:d92f9d21154c 147 #define DRBG_CONT_FAILURE 4
wolfSSL 0:d92f9d21154c 148
wolfSSL 0:d92f9d21154c 149 /* RNG health states */
wolfSSL 0:d92f9d21154c 150 #define DRBG_NOT_INIT 0
wolfSSL 0:d92f9d21154c 151 #define DRBG_OK 1
wolfSSL 0:d92f9d21154c 152 #define DRBG_FAILED 2
wolfSSL 0:d92f9d21154c 153 #define DRBG_CONT_FAILED 3
wolfSSL 0:d92f9d21154c 154
wolfSSL 0:d92f9d21154c 155
wolfSSL 0:d92f9d21154c 156 enum {
wolfSSL 0:d92f9d21154c 157 drbgInitC = 0,
wolfSSL 0:d92f9d21154c 158 drbgReseed = 1,
wolfSSL 0:d92f9d21154c 159 drbgGenerateW = 2,
wolfSSL 0:d92f9d21154c 160 drbgGenerateH = 3,
wolfSSL 0:d92f9d21154c 161 drbgInitV
wolfSSL 0:d92f9d21154c 162 };
wolfSSL 0:d92f9d21154c 163
wolfSSL 0:d92f9d21154c 164
wolfSSL 0:d92f9d21154c 165 typedef struct DRBG {
wolfSSL 0:d92f9d21154c 166 word32 reseedCtr;
wolfSSL 0:d92f9d21154c 167 word32 lastBlock;
wolfSSL 0:d92f9d21154c 168 byte V[DRBG_SEED_LEN];
wolfSSL 0:d92f9d21154c 169 byte C[DRBG_SEED_LEN];
wolfSSL 0:d92f9d21154c 170 byte matchCount;
wolfSSL 0:d92f9d21154c 171 } DRBG;
wolfSSL 0:d92f9d21154c 172
wolfSSL 0:d92f9d21154c 173
wolfSSL 0:d92f9d21154c 174 static int wc_RNG_HealthTestLocal(int reseed);
wolfSSL 0:d92f9d21154c 175
wolfSSL 0:d92f9d21154c 176 /* Hash Derivation Function */
wolfSSL 0:d92f9d21154c 177 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 0:d92f9d21154c 178 static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
wolfSSL 0:d92f9d21154c 179 const byte* inA, word32 inASz,
wolfSSL 0:d92f9d21154c 180 const byte* inB, word32 inBSz)
wolfSSL 0:d92f9d21154c 181 {
wolfSSL 0:d92f9d21154c 182 byte ctr;
wolfSSL 0:d92f9d21154c 183 int i;
wolfSSL 0:d92f9d21154c 184 int len;
wolfSSL 0:d92f9d21154c 185 word32 bits = (outSz * 8); /* reverse byte order */
wolfSSL 0:d92f9d21154c 186 Sha256 sha;
wolfSSL 0:d92f9d21154c 187 byte digest[SHA256_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 188
wolfSSL 0:d92f9d21154c 189 (void)drbg;
wolfSSL 0:d92f9d21154c 190 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 0:d92f9d21154c 191 bits = ByteReverseWord32(bits);
wolfSSL 0:d92f9d21154c 192 #endif
wolfSSL 0:d92f9d21154c 193 len = (outSz / OUTPUT_BLOCK_LEN)
wolfSSL 0:d92f9d21154c 194 + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
wolfSSL 0:d92f9d21154c 195
wolfSSL 0:d92f9d21154c 196 for (i = 0, ctr = 1; i < len; i++, ctr++)
wolfSSL 0:d92f9d21154c 197 {
wolfSSL 0:d92f9d21154c 198 if (wc_InitSha256(&sha) != 0)
wolfSSL 0:d92f9d21154c 199 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 200
wolfSSL 0:d92f9d21154c 201 if (wc_Sha256Update(&sha, &ctr, sizeof(ctr)) != 0)
wolfSSL 0:d92f9d21154c 202 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 203
wolfSSL 0:d92f9d21154c 204 if (wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits)) != 0)
wolfSSL 0:d92f9d21154c 205 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 206
wolfSSL 0:d92f9d21154c 207 /* churning V is the only string that doesn't have the type added */
wolfSSL 0:d92f9d21154c 208 if (type != drbgInitV)
wolfSSL 0:d92f9d21154c 209 if (wc_Sha256Update(&sha, &type, sizeof(type)) != 0)
wolfSSL 0:d92f9d21154c 210 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 211
wolfSSL 0:d92f9d21154c 212 if (wc_Sha256Update(&sha, inA, inASz) != 0)
wolfSSL 0:d92f9d21154c 213 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 214
wolfSSL 0:d92f9d21154c 215 if (inB != NULL && inBSz > 0)
wolfSSL 0:d92f9d21154c 216 if (wc_Sha256Update(&sha, inB, inBSz) != 0)
wolfSSL 0:d92f9d21154c 217 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 218
wolfSSL 0:d92f9d21154c 219 if (wc_Sha256Final(&sha, digest) != 0)
wolfSSL 0:d92f9d21154c 220 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 221
wolfSSL 0:d92f9d21154c 222 if (outSz > OUTPUT_BLOCK_LEN) {
wolfSSL 0:d92f9d21154c 223 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
wolfSSL 0:d92f9d21154c 224 outSz -= OUTPUT_BLOCK_LEN;
wolfSSL 0:d92f9d21154c 225 out += OUTPUT_BLOCK_LEN;
wolfSSL 0:d92f9d21154c 226 }
wolfSSL 0:d92f9d21154c 227 else {
wolfSSL 0:d92f9d21154c 228 XMEMCPY(out, digest, outSz);
wolfSSL 0:d92f9d21154c 229 }
wolfSSL 0:d92f9d21154c 230 }
wolfSSL 0:d92f9d21154c 231 ForceZero(digest, sizeof(digest));
wolfSSL 0:d92f9d21154c 232
wolfSSL 0:d92f9d21154c 233 return DRBG_SUCCESS;
wolfSSL 0:d92f9d21154c 234 }
wolfSSL 0:d92f9d21154c 235
wolfSSL 0:d92f9d21154c 236
wolfSSL 0:d92f9d21154c 237 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 0:d92f9d21154c 238 static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
wolfSSL 0:d92f9d21154c 239 {
wolfSSL 0:d92f9d21154c 240 byte seed[DRBG_SEED_LEN];
wolfSSL 0:d92f9d21154c 241
wolfSSL 0:d92f9d21154c 242 if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
wolfSSL 0:d92f9d21154c 243 entropy, entropySz) != DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 244 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 245 }
wolfSSL 0:d92f9d21154c 246
wolfSSL 0:d92f9d21154c 247 XMEMCPY(drbg->V, seed, sizeof(drbg->V));
wolfSSL 0:d92f9d21154c 248 ForceZero(seed, sizeof(seed));
wolfSSL 0:d92f9d21154c 249
wolfSSL 0:d92f9d21154c 250 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
wolfSSL 0:d92f9d21154c 251 sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 252 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 253 }
wolfSSL 0:d92f9d21154c 254
wolfSSL 0:d92f9d21154c 255 drbg->reseedCtr = 1;
wolfSSL 0:d92f9d21154c 256 drbg->lastBlock = 0;
wolfSSL 0:d92f9d21154c 257 drbg->matchCount = 0;
wolfSSL 0:d92f9d21154c 258 return DRBG_SUCCESS;
wolfSSL 0:d92f9d21154c 259 }
wolfSSL 0:d92f9d21154c 260
wolfSSL 0:d92f9d21154c 261 static INLINE void array_add_one(byte* data, word32 dataSz)
wolfSSL 0:d92f9d21154c 262 {
wolfSSL 0:d92f9d21154c 263 int i;
wolfSSL 0:d92f9d21154c 264
wolfSSL 0:d92f9d21154c 265 for (i = dataSz - 1; i >= 0; i--)
wolfSSL 0:d92f9d21154c 266 {
wolfSSL 0:d92f9d21154c 267 data[i]++;
wolfSSL 0:d92f9d21154c 268 if (data[i] != 0) break;
wolfSSL 0:d92f9d21154c 269 }
wolfSSL 0:d92f9d21154c 270 }
wolfSSL 0:d92f9d21154c 271
wolfSSL 0:d92f9d21154c 272
wolfSSL 0:d92f9d21154c 273 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 0:d92f9d21154c 274 static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
wolfSSL 0:d92f9d21154c 275 {
wolfSSL 0:d92f9d21154c 276 byte data[DRBG_SEED_LEN];
wolfSSL 0:d92f9d21154c 277 int i;
wolfSSL 0:d92f9d21154c 278 int len;
wolfSSL 0:d92f9d21154c 279 word32 checkBlock;
wolfSSL 0:d92f9d21154c 280 Sha256 sha;
wolfSSL 0:d92f9d21154c 281 byte digest[SHA256_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 282
wolfSSL 0:d92f9d21154c 283 /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
wolfSSL 0:d92f9d21154c 284 * the continuous test. */
wolfSSL 0:d92f9d21154c 285
wolfSSL 0:d92f9d21154c 286 if (outSz == 0) outSz = 1;
wolfSSL 0:d92f9d21154c 287
wolfSSL 0:d92f9d21154c 288 len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
wolfSSL 0:d92f9d21154c 289
wolfSSL 0:d92f9d21154c 290 XMEMCPY(data, V, sizeof(data));
wolfSSL 0:d92f9d21154c 291 for (i = 0; i < len; i++) {
wolfSSL 0:d92f9d21154c 292 if (wc_InitSha256(&sha) != 0 ||
wolfSSL 0:d92f9d21154c 293 wc_Sha256Update(&sha, data, sizeof(data)) != 0 ||
wolfSSL 0:d92f9d21154c 294 wc_Sha256Final(&sha, digest) != 0) {
wolfSSL 0:d92f9d21154c 295
wolfSSL 0:d92f9d21154c 296 return DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 297 }
wolfSSL 0:d92f9d21154c 298
wolfSSL 0:d92f9d21154c 299 XMEMCPY(&checkBlock, digest, sizeof(word32));
wolfSSL 0:d92f9d21154c 300 if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
wolfSSL 0:d92f9d21154c 301 if (drbg->matchCount == 1) {
wolfSSL 0:d92f9d21154c 302 return DRBG_CONT_FAILURE;
wolfSSL 0:d92f9d21154c 303 }
wolfSSL 0:d92f9d21154c 304 else {
wolfSSL 0:d92f9d21154c 305 if (i == len) {
wolfSSL 0:d92f9d21154c 306 len++;
wolfSSL 0:d92f9d21154c 307 }
wolfSSL 0:d92f9d21154c 308 drbg->matchCount = 1;
wolfSSL 0:d92f9d21154c 309 }
wolfSSL 0:d92f9d21154c 310 }
wolfSSL 0:d92f9d21154c 311 else {
wolfSSL 0:d92f9d21154c 312 drbg->matchCount = 0;
wolfSSL 0:d92f9d21154c 313 drbg->lastBlock = checkBlock;
wolfSSL 0:d92f9d21154c 314 }
wolfSSL 0:d92f9d21154c 315
wolfSSL 0:d92f9d21154c 316 if (outSz >= OUTPUT_BLOCK_LEN) {
wolfSSL 0:d92f9d21154c 317 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
wolfSSL 0:d92f9d21154c 318 outSz -= OUTPUT_BLOCK_LEN;
wolfSSL 0:d92f9d21154c 319 out += OUTPUT_BLOCK_LEN;
wolfSSL 0:d92f9d21154c 320 array_add_one(data, DRBG_SEED_LEN);
wolfSSL 0:d92f9d21154c 321 }
wolfSSL 0:d92f9d21154c 322 else if (out != NULL && outSz != 0) {
wolfSSL 0:d92f9d21154c 323 XMEMCPY(out, digest, outSz);
wolfSSL 0:d92f9d21154c 324 outSz = 0;
wolfSSL 0:d92f9d21154c 325 }
wolfSSL 0:d92f9d21154c 326 }
wolfSSL 0:d92f9d21154c 327 ForceZero(data, sizeof(data));
wolfSSL 0:d92f9d21154c 328
wolfSSL 0:d92f9d21154c 329 return DRBG_SUCCESS;
wolfSSL 0:d92f9d21154c 330 }
wolfSSL 0:d92f9d21154c 331
wolfSSL 0:d92f9d21154c 332
wolfSSL 0:d92f9d21154c 333 static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
wolfSSL 0:d92f9d21154c 334 {
wolfSSL 0:d92f9d21154c 335 word16 carry = 0;
wolfSSL 0:d92f9d21154c 336
wolfSSL 0:d92f9d21154c 337 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
wolfSSL 0:d92f9d21154c 338 int sIdx, dIdx;
wolfSSL 0:d92f9d21154c 339
wolfSSL 0:d92f9d21154c 340 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
wolfSSL 0:d92f9d21154c 341 {
wolfSSL 0:d92f9d21154c 342 carry += d[dIdx] + s[sIdx];
wolfSSL 0:d92f9d21154c 343 d[dIdx] = (byte)carry;
wolfSSL 0:d92f9d21154c 344 carry >>= 8;
wolfSSL 0:d92f9d21154c 345 }
wolfSSL 0:d92f9d21154c 346
wolfSSL 0:d92f9d21154c 347 for (; carry != 0 && dIdx >= 0; dIdx--) {
wolfSSL 0:d92f9d21154c 348 carry += d[dIdx];
wolfSSL 0:d92f9d21154c 349 d[dIdx] = (byte)carry;
wolfSSL 0:d92f9d21154c 350 carry >>= 8;
wolfSSL 0:d92f9d21154c 351 }
wolfSSL 0:d92f9d21154c 352 }
wolfSSL 0:d92f9d21154c 353 }
wolfSSL 0:d92f9d21154c 354
wolfSSL 0:d92f9d21154c 355
wolfSSL 0:d92f9d21154c 356 /* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
wolfSSL 0:d92f9d21154c 357 static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
wolfSSL 0:d92f9d21154c 358 {
wolfSSL 0:d92f9d21154c 359 int ret = DRBG_NEED_RESEED;
wolfSSL 0:d92f9d21154c 360 Sha256 sha;
wolfSSL 0:d92f9d21154c 361 byte digest[SHA256_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 362
wolfSSL 0:d92f9d21154c 363 if (drbg->reseedCtr != RESEED_INTERVAL) {
wolfSSL 0:d92f9d21154c 364 byte type = drbgGenerateH;
wolfSSL 0:d92f9d21154c 365 word32 reseedCtr = drbg->reseedCtr;
wolfSSL 0:d92f9d21154c 366
wolfSSL 0:d92f9d21154c 367 ret = Hash_gen(drbg, out, outSz, drbg->V);
wolfSSL 0:d92f9d21154c 368 if (ret == DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 369 if (wc_InitSha256(&sha) != 0 ||
wolfSSL 0:d92f9d21154c 370 wc_Sha256Update(&sha, &type, sizeof(type)) != 0 ||
wolfSSL 0:d92f9d21154c 371 wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V)) != 0 ||
wolfSSL 0:d92f9d21154c 372 wc_Sha256Final(&sha, digest) != 0) {
wolfSSL 0:d92f9d21154c 373
wolfSSL 0:d92f9d21154c 374 ret = DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 375 }
wolfSSL 0:d92f9d21154c 376 else {
wolfSSL 0:d92f9d21154c 377 array_add(drbg->V, sizeof(drbg->V), digest, sizeof(digest));
wolfSSL 0:d92f9d21154c 378 array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
wolfSSL 0:d92f9d21154c 379 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 0:d92f9d21154c 380 reseedCtr = ByteReverseWord32(reseedCtr);
wolfSSL 0:d92f9d21154c 381 #endif
wolfSSL 0:d92f9d21154c 382 array_add(drbg->V, sizeof(drbg->V),
wolfSSL 0:d92f9d21154c 383 (byte*)&reseedCtr, sizeof(reseedCtr));
wolfSSL 0:d92f9d21154c 384 ret = DRBG_SUCCESS;
wolfSSL 0:d92f9d21154c 385 }
wolfSSL 0:d92f9d21154c 386 drbg->reseedCtr++;
wolfSSL 0:d92f9d21154c 387 }
wolfSSL 0:d92f9d21154c 388 }
wolfSSL 0:d92f9d21154c 389 ForceZero(digest, sizeof(digest));
wolfSSL 0:d92f9d21154c 390
wolfSSL 0:d92f9d21154c 391 return ret;
wolfSSL 0:d92f9d21154c 392 }
wolfSSL 0:d92f9d21154c 393
wolfSSL 0:d92f9d21154c 394
wolfSSL 0:d92f9d21154c 395 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 0:d92f9d21154c 396 static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
wolfSSL 0:d92f9d21154c 397 const byte* nonce, word32 nonceSz)
wolfSSL 0:d92f9d21154c 398 {
wolfSSL 0:d92f9d21154c 399 int ret = DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 400
wolfSSL 0:d92f9d21154c 401 XMEMSET(drbg, 0, sizeof(DRBG));
wolfSSL 0:d92f9d21154c 402
wolfSSL 0:d92f9d21154c 403 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
wolfSSL 0:d92f9d21154c 404 nonce, nonceSz) == DRBG_SUCCESS &&
wolfSSL 0:d92f9d21154c 405 Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
wolfSSL 0:d92f9d21154c 406 sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 407
wolfSSL 0:d92f9d21154c 408 drbg->reseedCtr = 1;
wolfSSL 0:d92f9d21154c 409 drbg->lastBlock = 0;
wolfSSL 0:d92f9d21154c 410 drbg->matchCount = 0;
wolfSSL 0:d92f9d21154c 411 ret = DRBG_SUCCESS;
wolfSSL 0:d92f9d21154c 412 }
wolfSSL 0:d92f9d21154c 413
wolfSSL 0:d92f9d21154c 414 return ret;
wolfSSL 0:d92f9d21154c 415 }
wolfSSL 0:d92f9d21154c 416
wolfSSL 0:d92f9d21154c 417
wolfSSL 0:d92f9d21154c 418 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
wolfSSL 0:d92f9d21154c 419 static int Hash_DRBG_Uninstantiate(DRBG* drbg)
wolfSSL 0:d92f9d21154c 420 {
wolfSSL 0:d92f9d21154c 421 word32 i;
wolfSSL 0:d92f9d21154c 422 int compareSum = 0;
wolfSSL 0:d92f9d21154c 423 byte* compareDrbg = (byte*)drbg;
wolfSSL 0:d92f9d21154c 424
wolfSSL 0:d92f9d21154c 425 ForceZero(drbg, sizeof(DRBG));
wolfSSL 0:d92f9d21154c 426
wolfSSL 0:d92f9d21154c 427 for (i = 0; i < sizeof(DRBG); i++)
wolfSSL 0:d92f9d21154c 428 compareSum |= compareDrbg[i] ^ 0;
wolfSSL 0:d92f9d21154c 429
wolfSSL 0:d92f9d21154c 430 return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 431 }
wolfSSL 0:d92f9d21154c 432
wolfSSL 0:d92f9d21154c 433 /* End NIST DRBG Code */
wolfSSL 0:d92f9d21154c 434
wolfSSL 0:d92f9d21154c 435
wolfSSL 0:d92f9d21154c 436 /* Get seed and key cipher */
wolfSSL 0:d92f9d21154c 437 int wc_InitRng(RNG* rng)
wolfSSL 0:d92f9d21154c 438 {
wolfSSL 0:d92f9d21154c 439 int ret = BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 440
wolfSSL 0:d92f9d21154c 441 if (rng != NULL) {
wolfSSL 0:d92f9d21154c 442 if (wc_RNG_HealthTestLocal(0) == 0) {
wolfSSL 0:d92f9d21154c 443 byte entropy[ENTROPY_NONCE_SZ];
wolfSSL 0:d92f9d21154c 444
wolfSSL 0:d92f9d21154c 445 rng->drbg =
wolfSSL 0:d92f9d21154c 446 (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
wolfSSL 0:d92f9d21154c 447 if (rng->drbg == NULL) {
wolfSSL 0:d92f9d21154c 448 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 449 }
wolfSSL 0:d92f9d21154c 450 /* This doesn't use a separate nonce. The entropy input will be
wolfSSL 0:d92f9d21154c 451 * the default size plus the size of the nonce making the seed
wolfSSL 0:d92f9d21154c 452 * size. */
wolfSSL 0:d92f9d21154c 453 else if (wc_GenerateSeed(&rng->seed,
wolfSSL 0:d92f9d21154c 454 entropy, ENTROPY_NONCE_SZ) == 0 &&
wolfSSL 0:d92f9d21154c 455 Hash_DRBG_Instantiate(rng->drbg,
wolfSSL 0:d92f9d21154c 456 entropy, ENTROPY_NONCE_SZ, NULL, 0) == DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 457
wolfSSL 0:d92f9d21154c 458 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
wolfSSL 0:d92f9d21154c 459 }
wolfSSL 0:d92f9d21154c 460 else
wolfSSL 0:d92f9d21154c 461 ret = DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 462
wolfSSL 0:d92f9d21154c 463 ForceZero(entropy, ENTROPY_NONCE_SZ);
wolfSSL 0:d92f9d21154c 464 }
wolfSSL 0:d92f9d21154c 465 else
wolfSSL 0:d92f9d21154c 466 ret = DRBG_CONT_FAILURE;
wolfSSL 0:d92f9d21154c 467
wolfSSL 0:d92f9d21154c 468 if (ret == DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 469 rng->status = DRBG_OK;
wolfSSL 0:d92f9d21154c 470 ret = 0;
wolfSSL 0:d92f9d21154c 471 }
wolfSSL 0:d92f9d21154c 472 else if (ret == DRBG_CONT_FAILURE) {
wolfSSL 0:d92f9d21154c 473 rng->status = DRBG_CONT_FAILED;
wolfSSL 0:d92f9d21154c 474 ret = DRBG_CONT_FIPS_E;
wolfSSL 0:d92f9d21154c 475 }
wolfSSL 0:d92f9d21154c 476 else if (ret == DRBG_FAILURE) {
wolfSSL 0:d92f9d21154c 477 rng->status = DRBG_FAILED;
wolfSSL 0:d92f9d21154c 478 ret = RNG_FAILURE_E;
wolfSSL 0:d92f9d21154c 479 }
wolfSSL 0:d92f9d21154c 480 else {
wolfSSL 0:d92f9d21154c 481 rng->status = DRBG_FAILED;
wolfSSL 0:d92f9d21154c 482 }
wolfSSL 0:d92f9d21154c 483 }
wolfSSL 0:d92f9d21154c 484
wolfSSL 0:d92f9d21154c 485 return ret;
wolfSSL 0:d92f9d21154c 486 }
wolfSSL 0:d92f9d21154c 487
wolfSSL 0:d92f9d21154c 488
wolfSSL 0:d92f9d21154c 489 /* place a generated block in output */
wolfSSL 0:d92f9d21154c 490 int wc_RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 491 {
wolfSSL 0:d92f9d21154c 492 int ret;
wolfSSL 0:d92f9d21154c 493
wolfSSL 0:d92f9d21154c 494 if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN)
wolfSSL 0:d92f9d21154c 495 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 496
wolfSSL 0:d92f9d21154c 497 if (rng->status != DRBG_OK)
wolfSSL 0:d92f9d21154c 498 return RNG_FAILURE_E;
wolfSSL 0:d92f9d21154c 499
wolfSSL 0:d92f9d21154c 500 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
wolfSSL 0:d92f9d21154c 501
wolfSSL 0:d92f9d21154c 502 if (ret == DRBG_NEED_RESEED) {
wolfSSL 0:d92f9d21154c 503 if (wc_RNG_HealthTestLocal(1) == 0) {
wolfSSL 0:d92f9d21154c 504 byte entropy[ENTROPY_SZ];
wolfSSL 0:d92f9d21154c 505
wolfSSL 0:d92f9d21154c 506 if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
wolfSSL 0:d92f9d21154c 507 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
wolfSSL 0:d92f9d21154c 508 == DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 509
wolfSSL 0:d92f9d21154c 510 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
wolfSSL 0:d92f9d21154c 511 if (ret == DRBG_SUCCESS)
wolfSSL 0:d92f9d21154c 512 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
wolfSSL 0:d92f9d21154c 513 }
wolfSSL 0:d92f9d21154c 514 else
wolfSSL 0:d92f9d21154c 515 ret = DRBG_FAILURE;
wolfSSL 0:d92f9d21154c 516
wolfSSL 0:d92f9d21154c 517 ForceZero(entropy, ENTROPY_SZ);
wolfSSL 0:d92f9d21154c 518 }
wolfSSL 0:d92f9d21154c 519 else
wolfSSL 0:d92f9d21154c 520 ret = DRBG_CONT_FAILURE;
wolfSSL 0:d92f9d21154c 521 }
wolfSSL 0:d92f9d21154c 522
wolfSSL 0:d92f9d21154c 523 if (ret == DRBG_SUCCESS) {
wolfSSL 0:d92f9d21154c 524 ret = 0;
wolfSSL 0:d92f9d21154c 525 }
wolfSSL 0:d92f9d21154c 526 else if (ret == DRBG_CONT_FAILURE) {
wolfSSL 0:d92f9d21154c 527 ret = DRBG_CONT_FIPS_E;
wolfSSL 0:d92f9d21154c 528 rng->status = DRBG_CONT_FAILED;
wolfSSL 0:d92f9d21154c 529 }
wolfSSL 0:d92f9d21154c 530 else {
wolfSSL 0:d92f9d21154c 531 ret = RNG_FAILURE_E;
wolfSSL 0:d92f9d21154c 532 rng->status = DRBG_FAILED;
wolfSSL 0:d92f9d21154c 533 }
wolfSSL 0:d92f9d21154c 534
wolfSSL 0:d92f9d21154c 535 return ret;
wolfSSL 0:d92f9d21154c 536 }
wolfSSL 0:d92f9d21154c 537
wolfSSL 0:d92f9d21154c 538
wolfSSL 0:d92f9d21154c 539 int wc_RNG_GenerateByte(RNG* rng, byte* b)
wolfSSL 0:d92f9d21154c 540 {
wolfSSL 0:d92f9d21154c 541 return wc_RNG_GenerateBlock(rng, b, 1);
wolfSSL 0:d92f9d21154c 542 }
wolfSSL 0:d92f9d21154c 543
wolfSSL 0:d92f9d21154c 544
wolfSSL 0:d92f9d21154c 545 int wc_FreeRng(RNG* rng)
wolfSSL 0:d92f9d21154c 546 {
wolfSSL 0:d92f9d21154c 547 int ret = BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 548
wolfSSL 0:d92f9d21154c 549 if (rng != NULL) {
wolfSSL 0:d92f9d21154c 550 if (rng->drbg != NULL) {
wolfSSL 0:d92f9d21154c 551 if (Hash_DRBG_Uninstantiate(rng->drbg) == DRBG_SUCCESS)
wolfSSL 0:d92f9d21154c 552 ret = 0;
wolfSSL 0:d92f9d21154c 553 else
wolfSSL 0:d92f9d21154c 554 ret = RNG_FAILURE_E;
wolfSSL 0:d92f9d21154c 555
wolfSSL 0:d92f9d21154c 556 XFREE(rng->drbg, NULL, DYNAMIC_TYPE_RNG);
wolfSSL 0:d92f9d21154c 557 rng->drbg = NULL;
wolfSSL 0:d92f9d21154c 558 }
wolfSSL 0:d92f9d21154c 559
wolfSSL 0:d92f9d21154c 560 rng->status = DRBG_NOT_INIT;
wolfSSL 0:d92f9d21154c 561 }
wolfSSL 0:d92f9d21154c 562
wolfSSL 0:d92f9d21154c 563 return ret;
wolfSSL 0:d92f9d21154c 564 }
wolfSSL 0:d92f9d21154c 565
wolfSSL 0:d92f9d21154c 566
wolfSSL 0:d92f9d21154c 567 int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
wolfSSL 0:d92f9d21154c 568 const byte* entropyB, word32 entropyBSz,
wolfSSL 0:d92f9d21154c 569 byte* output, word32 outputSz)
wolfSSL 0:d92f9d21154c 570 {
wolfSSL 0:d92f9d21154c 571 DRBG drbg;
wolfSSL 0:d92f9d21154c 572
wolfSSL 0:d92f9d21154c 573 if (entropyA == NULL || output == NULL)
wolfSSL 0:d92f9d21154c 574 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 575
wolfSSL 0:d92f9d21154c 576 if (reseed != 0 && entropyB == NULL)
wolfSSL 0:d92f9d21154c 577 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 578
wolfSSL 0:d92f9d21154c 579 if (outputSz != (SHA256_DIGEST_SIZE * 4))
wolfSSL 0:d92f9d21154c 580 return -1;
wolfSSL 0:d92f9d21154c 581
wolfSSL 0:d92f9d21154c 582 if (Hash_DRBG_Instantiate(&drbg, entropyA, entropyASz, NULL, 0) != 0)
wolfSSL 0:d92f9d21154c 583 return -1;
wolfSSL 0:d92f9d21154c 584
wolfSSL 0:d92f9d21154c 585 if (reseed) {
wolfSSL 0:d92f9d21154c 586 if (Hash_DRBG_Reseed(&drbg, entropyB, entropyBSz) != 0) {
wolfSSL 0:d92f9d21154c 587 Hash_DRBG_Uninstantiate(&drbg);
wolfSSL 0:d92f9d21154c 588 return -1;
wolfSSL 0:d92f9d21154c 589 }
wolfSSL 0:d92f9d21154c 590 }
wolfSSL 0:d92f9d21154c 591
wolfSSL 0:d92f9d21154c 592 if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
wolfSSL 0:d92f9d21154c 593 Hash_DRBG_Uninstantiate(&drbg);
wolfSSL 0:d92f9d21154c 594 return -1;
wolfSSL 0:d92f9d21154c 595 }
wolfSSL 0:d92f9d21154c 596
wolfSSL 0:d92f9d21154c 597 if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
wolfSSL 0:d92f9d21154c 598 Hash_DRBG_Uninstantiate(&drbg);
wolfSSL 0:d92f9d21154c 599 return -1;
wolfSSL 0:d92f9d21154c 600 }
wolfSSL 0:d92f9d21154c 601
wolfSSL 0:d92f9d21154c 602 if (Hash_DRBG_Uninstantiate(&drbg) != 0) {
wolfSSL 0:d92f9d21154c 603 return -1;
wolfSSL 0:d92f9d21154c 604 }
wolfSSL 0:d92f9d21154c 605
wolfSSL 0:d92f9d21154c 606 return 0;
wolfSSL 0:d92f9d21154c 607 }
wolfSSL 0:d92f9d21154c 608
wolfSSL 0:d92f9d21154c 609
wolfSSL 0:d92f9d21154c 610 const byte entropyA[] = {
wolfSSL 0:d92f9d21154c 611 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
wolfSSL 0:d92f9d21154c 612 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
wolfSSL 0:d92f9d21154c 613 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
wolfSSL 0:d92f9d21154c 614 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
wolfSSL 0:d92f9d21154c 615 };
wolfSSL 0:d92f9d21154c 616
wolfSSL 0:d92f9d21154c 617 const byte reseedEntropyA[] = {
wolfSSL 0:d92f9d21154c 618 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
wolfSSL 0:d92f9d21154c 619 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
wolfSSL 0:d92f9d21154c 620 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
wolfSSL 0:d92f9d21154c 621 };
wolfSSL 0:d92f9d21154c 622
wolfSSL 0:d92f9d21154c 623 const byte outputA[] = {
wolfSSL 0:d92f9d21154c 624 0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
wolfSSL 0:d92f9d21154c 625 0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
wolfSSL 0:d92f9d21154c 626 0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
wolfSSL 0:d92f9d21154c 627 0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
wolfSSL 0:d92f9d21154c 628 0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
wolfSSL 0:d92f9d21154c 629 0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
wolfSSL 0:d92f9d21154c 630 0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
wolfSSL 0:d92f9d21154c 631 0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
wolfSSL 0:d92f9d21154c 632 0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
wolfSSL 0:d92f9d21154c 633 0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
wolfSSL 0:d92f9d21154c 634 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
wolfSSL 0:d92f9d21154c 635 };
wolfSSL 0:d92f9d21154c 636
wolfSSL 0:d92f9d21154c 637 const byte entropyB[] = {
wolfSSL 0:d92f9d21154c 638 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
wolfSSL 0:d92f9d21154c 639 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
wolfSSL 0:d92f9d21154c 640 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
wolfSSL 0:d92f9d21154c 641 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
wolfSSL 0:d92f9d21154c 642 };
wolfSSL 0:d92f9d21154c 643
wolfSSL 0:d92f9d21154c 644 const byte outputB[] = {
wolfSSL 0:d92f9d21154c 645 0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
wolfSSL 0:d92f9d21154c 646 0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
wolfSSL 0:d92f9d21154c 647 0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
wolfSSL 0:d92f9d21154c 648 0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
wolfSSL 0:d92f9d21154c 649 0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
wolfSSL 0:d92f9d21154c 650 0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
wolfSSL 0:d92f9d21154c 651 0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
wolfSSL 0:d92f9d21154c 652 0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
wolfSSL 0:d92f9d21154c 653 0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
wolfSSL 0:d92f9d21154c 654 0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
wolfSSL 0:d92f9d21154c 655 0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
wolfSSL 0:d92f9d21154c 656 };
wolfSSL 0:d92f9d21154c 657
wolfSSL 0:d92f9d21154c 658
wolfSSL 0:d92f9d21154c 659 static int wc_RNG_HealthTestLocal(int reseed)
wolfSSL 0:d92f9d21154c 660 {
wolfSSL 0:d92f9d21154c 661 int ret = 0;
wolfSSL 0:d92f9d21154c 662 byte check[SHA256_DIGEST_SIZE * 4];
wolfSSL 0:d92f9d21154c 663
wolfSSL 0:d92f9d21154c 664 if (reseed) {
wolfSSL 0:d92f9d21154c 665 ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
wolfSSL 0:d92f9d21154c 666 reseedEntropyA, sizeof(reseedEntropyA),
wolfSSL 0:d92f9d21154c 667 check, sizeof(check));
wolfSSL 0:d92f9d21154c 668 if (ret == 0) {
wolfSSL 0:d92f9d21154c 669 if (ConstantCompare(check, outputA, sizeof(check)) != 0)
wolfSSL 0:d92f9d21154c 670 ret = -1;
wolfSSL 0:d92f9d21154c 671 }
wolfSSL 0:d92f9d21154c 672 }
wolfSSL 0:d92f9d21154c 673 else {
wolfSSL 0:d92f9d21154c 674 ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
wolfSSL 0:d92f9d21154c 675 NULL, 0,
wolfSSL 0:d92f9d21154c 676 check, sizeof(check));
wolfSSL 0:d92f9d21154c 677 if (ret == 0) {
wolfSSL 0:d92f9d21154c 678 if (ConstantCompare(check, outputB, sizeof(check)) != 0)
wolfSSL 0:d92f9d21154c 679 ret = -1;
wolfSSL 0:d92f9d21154c 680 }
wolfSSL 0:d92f9d21154c 681 }
wolfSSL 0:d92f9d21154c 682
wolfSSL 0:d92f9d21154c 683 return ret;
wolfSSL 0:d92f9d21154c 684 }
wolfSSL 0:d92f9d21154c 685
wolfSSL 0:d92f9d21154c 686
wolfSSL 0:d92f9d21154c 687 #else /* HAVE_HASHDRBG || NO_RC4 */
wolfSSL 0:d92f9d21154c 688
wolfSSL 0:d92f9d21154c 689 /* Get seed and key cipher */
wolfSSL 0:d92f9d21154c 690 int wc_InitRng(RNG* rng)
wolfSSL 0:d92f9d21154c 691 {
wolfSSL 0:d92f9d21154c 692 int ret;
wolfSSL 0:d92f9d21154c 693 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 694 byte* key;
wolfSSL 0:d92f9d21154c 695 byte* junk;
wolfSSL 0:d92f9d21154c 696 #else
wolfSSL 0:d92f9d21154c 697 byte key[32];
wolfSSL 0:d92f9d21154c 698 byte junk[256];
wolfSSL 0:d92f9d21154c 699 #endif
wolfSSL 0:d92f9d21154c 700
wolfSSL 0:d92f9d21154c 701 #ifdef HAVE_INTEL_RDGEN
wolfSSL 0:d92f9d21154c 702 wc_InitRng_IntelRD() ;
wolfSSL 0:d92f9d21154c 703 if(IS_INTEL_RDRAND)return 0 ;
wolfSSL 0:d92f9d21154c 704 #endif
wolfSSL 0:d92f9d21154c 705 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 706 if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC)
wolfSSL 0:d92f9d21154c 707 return 0;
wolfSSL 0:d92f9d21154c 708 #endif
wolfSSL 0:d92f9d21154c 709
wolfSSL 0:d92f9d21154c 710 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 711 key = (byte*)XMALLOC(32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 712 if (key == NULL)
wolfSSL 0:d92f9d21154c 713 return MEMORY_E;
wolfSSL 0:d92f9d21154c 714
wolfSSL 0:d92f9d21154c 715 junk = (byte*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 716 if (junk == NULL) {
wolfSSL 0:d92f9d21154c 717 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 718 return MEMORY_E;
wolfSSL 0:d92f9d21154c 719 }
wolfSSL 0:d92f9d21154c 720 #endif
wolfSSL 0:d92f9d21154c 721
wolfSSL 0:d92f9d21154c 722 ret = wc_GenerateSeed(&rng->seed, key, 32);
wolfSSL 0:d92f9d21154c 723
wolfSSL 0:d92f9d21154c 724 if (ret == 0) {
wolfSSL 0:d92f9d21154c 725 wc_Arc4SetKey(&rng->cipher, key, sizeof(key));
wolfSSL 0:d92f9d21154c 726
wolfSSL 0:d92f9d21154c 727 ret = wc_RNG_GenerateBlock(rng, junk, 256); /*rid initial state*/
wolfSSL 0:d92f9d21154c 728 }
wolfSSL 0:d92f9d21154c 729
wolfSSL 0:d92f9d21154c 730 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 731 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 732 XFREE(junk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 733 #endif
wolfSSL 0:d92f9d21154c 734
wolfSSL 0:d92f9d21154c 735 return ret;
wolfSSL 0:d92f9d21154c 736 }
wolfSSL 0:d92f9d21154c 737
wolfSSL 0:d92f9d21154c 738 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 739 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz);
wolfSSL 0:d92f9d21154c 740 #endif
wolfSSL 0:d92f9d21154c 741
wolfSSL 0:d92f9d21154c 742 /* place a generated block in output */
wolfSSL 0:d92f9d21154c 743 int wc_RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 744 {
wolfSSL 0:d92f9d21154c 745 #ifdef HAVE_INTEL_RDGEN
wolfSSL 0:d92f9d21154c 746 if(IS_INTEL_RDRAND)
wolfSSL 0:d92f9d21154c 747 return wc_GenerateRand_IntelRD(NULL, output, sz) ;
wolfSSL 0:d92f9d21154c 748 #endif
wolfSSL 0:d92f9d21154c 749 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 750 if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC)
wolfSSL 0:d92f9d21154c 751 return CaviumRNG_GenerateBlock(rng, output, sz);
wolfSSL 0:d92f9d21154c 752 #endif
wolfSSL 0:d92f9d21154c 753 XMEMSET(output, 0, sz);
wolfSSL 0:d92f9d21154c 754 wc_Arc4Process(&rng->cipher, output, output, sz);
wolfSSL 0:d92f9d21154c 755
wolfSSL 0:d92f9d21154c 756 return 0;
wolfSSL 0:d92f9d21154c 757 }
wolfSSL 0:d92f9d21154c 758
wolfSSL 0:d92f9d21154c 759
wolfSSL 0:d92f9d21154c 760 int wc_RNG_GenerateByte(RNG* rng, byte* b)
wolfSSL 0:d92f9d21154c 761 {
wolfSSL 0:d92f9d21154c 762 return wc_RNG_GenerateBlock(rng, b, 1);
wolfSSL 0:d92f9d21154c 763 }
wolfSSL 0:d92f9d21154c 764
wolfSSL 0:d92f9d21154c 765
wolfSSL 0:d92f9d21154c 766 int wc_FreeRng(RNG* rng)
wolfSSL 0:d92f9d21154c 767 {
wolfSSL 0:d92f9d21154c 768 (void)rng;
wolfSSL 0:d92f9d21154c 769 return 0;
wolfSSL 0:d92f9d21154c 770 }
wolfSSL 0:d92f9d21154c 771
wolfSSL 0:d92f9d21154c 772
wolfSSL 0:d92f9d21154c 773 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 774
wolfSSL 0:d92f9d21154c 775 #include <wolfssl/ctaocrypt/logging.h>
wolfSSL 0:d92f9d21154c 776 #include "cavium_common.h"
wolfSSL 0:d92f9d21154c 777
wolfSSL 0:d92f9d21154c 778 /* Initiliaze RNG for use with Nitrox device */
wolfSSL 0:d92f9d21154c 779 int wc_InitRngCavium(RNG* rng, int devId)
wolfSSL 0:d92f9d21154c 780 {
wolfSSL 0:d92f9d21154c 781 if (rng == NULL)
wolfSSL 0:d92f9d21154c 782 return -1;
wolfSSL 0:d92f9d21154c 783
wolfSSL 0:d92f9d21154c 784 rng->devId = devId;
wolfSSL 0:d92f9d21154c 785 rng->magic = WOLFSSL_RNG_CAVIUM_MAGIC;
wolfSSL 0:d92f9d21154c 786
wolfSSL 0:d92f9d21154c 787 return 0;
wolfSSL 0:d92f9d21154c 788 }
wolfSSL 0:d92f9d21154c 789
wolfSSL 0:d92f9d21154c 790
wolfSSL 0:d92f9d21154c 791 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 792 {
wolfSSL 0:d92f9d21154c 793 wolfssl_word offset = 0;
wolfSSL 0:d92f9d21154c 794 word32 requestId;
wolfSSL 0:d92f9d21154c 795
wolfSSL 0:d92f9d21154c 796 while (sz > WOLFSSL_MAX_16BIT) {
wolfSSL 0:d92f9d21154c 797 word16 slen = (word16)WOLFSSL_MAX_16BIT;
wolfSSL 0:d92f9d21154c 798 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
wolfSSL 0:d92f9d21154c 799 rng->devId) != 0) {
wolfSSL 0:d92f9d21154c 800 WOLFSSL_MSG("Cavium RNG failed");
wolfSSL 0:d92f9d21154c 801 }
wolfSSL 0:d92f9d21154c 802 sz -= WOLFSSL_MAX_16BIT;
wolfSSL 0:d92f9d21154c 803 offset += WOLFSSL_MAX_16BIT;
wolfSSL 0:d92f9d21154c 804 }
wolfSSL 0:d92f9d21154c 805 if (sz) {
wolfSSL 0:d92f9d21154c 806 word16 slen = (word16)sz;
wolfSSL 0:d92f9d21154c 807 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
wolfSSL 0:d92f9d21154c 808 rng->devId) != 0) {
wolfSSL 0:d92f9d21154c 809 WOLFSSL_MSG("Cavium RNG failed");
wolfSSL 0:d92f9d21154c 810 }
wolfSSL 0:d92f9d21154c 811 }
wolfSSL 0:d92f9d21154c 812 }
wolfSSL 0:d92f9d21154c 813
wolfSSL 0:d92f9d21154c 814 #endif /* HAVE_CAVIUM */
wolfSSL 0:d92f9d21154c 815
wolfSSL 0:d92f9d21154c 816 #endif /* HAVE_HASHDRBG || NO_RC4 */
wolfSSL 0:d92f9d21154c 817
wolfSSL 0:d92f9d21154c 818
wolfSSL 0:d92f9d21154c 819 #if defined(HAVE_INTEL_RDGEN)
wolfSSL 0:d92f9d21154c 820
wolfSSL 0:d92f9d21154c 821 #ifndef _MSC_VER
wolfSSL 0:d92f9d21154c 822 #define cpuid(reg, leaf, sub)\
wolfSSL 0:d92f9d21154c 823 __asm__ __volatile__ ("cpuid":\
wolfSSL 0:d92f9d21154c 824 "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
wolfSSL 0:d92f9d21154c 825 "a" (leaf), "c"(sub));
wolfSSL 0:d92f9d21154c 826
wolfSSL 0:d92f9d21154c 827 #define XASM_LINK(f) asm(f)
wolfSSL 0:d92f9d21154c 828 #else
wolfSSL 0:d92f9d21154c 829
wolfSSL 0:d92f9d21154c 830 #include <intrin.h>
wolfSSL 0:d92f9d21154c 831 #define cpuid(a,b) __cpuid((int*)a,b)
wolfSSL 0:d92f9d21154c 832
wolfSSL 0:d92f9d21154c 833 #define XASM_LINK(f)
wolfSSL 0:d92f9d21154c 834
wolfSSL 0:d92f9d21154c 835 #endif /* _MSC_VER */
wolfSSL 0:d92f9d21154c 836
wolfSSL 0:d92f9d21154c 837 #define EAX 0
wolfSSL 0:d92f9d21154c 838 #define EBX 1
wolfSSL 0:d92f9d21154c 839 #define ECX 2
wolfSSL 0:d92f9d21154c 840 #define EDX 3
wolfSSL 0:d92f9d21154c 841
wolfSSL 0:d92f9d21154c 842 static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) {
wolfSSL 0:d92f9d21154c 843 int got_intel_cpu=0;
wolfSSL 0:d92f9d21154c 844 unsigned int reg[5];
wolfSSL 0:d92f9d21154c 845
wolfSSL 0:d92f9d21154c 846 reg[4] = '\0' ;
wolfSSL 0:d92f9d21154c 847 cpuid(reg, 0, 0);
wolfSSL 0:d92f9d21154c 848 if(memcmp((char *)&(reg[EBX]), "Genu", 4) == 0 &&
wolfSSL 0:d92f9d21154c 849 memcmp((char *)&(reg[EDX]), "ineI", 4) == 0 &&
wolfSSL 0:d92f9d21154c 850 memcmp((char *)&(reg[ECX]), "ntel", 4) == 0) {
wolfSSL 0:d92f9d21154c 851 got_intel_cpu = 1;
wolfSSL 0:d92f9d21154c 852 }
wolfSSL 0:d92f9d21154c 853 if (got_intel_cpu) {
wolfSSL 0:d92f9d21154c 854 cpuid(reg, leaf, sub);
wolfSSL 0:d92f9d21154c 855 return((reg[num]>>bit)&0x1) ;
wolfSSL 0:d92f9d21154c 856 }
wolfSSL 0:d92f9d21154c 857 return 0 ;
wolfSSL 0:d92f9d21154c 858 }
wolfSSL 0:d92f9d21154c 859
wolfSSL 0:d92f9d21154c 860 static int wc_InitRng_IntelRD()
wolfSSL 0:d92f9d21154c 861 {
wolfSSL 0:d92f9d21154c 862 if(cpuid_check==0) {
wolfSSL 0:d92f9d21154c 863 if(cpuid_flag(1, 0, ECX, 30)){ cpuid_flags |= CPUID_RDRAND ;}
wolfSSL 0:d92f9d21154c 864 if(cpuid_flag(7, 0, EBX, 18)){ cpuid_flags |= CPUID_RDSEED ;}
wolfSSL 0:d92f9d21154c 865 cpuid_check = 1 ;
wolfSSL 0:d92f9d21154c 866 }
wolfSSL 0:d92f9d21154c 867 return 1 ;
wolfSSL 0:d92f9d21154c 868 }
wolfSSL 0:d92f9d21154c 869
wolfSSL 0:d92f9d21154c 870 #define INTELRD_RETRY 10
wolfSSL 0:d92f9d21154c 871
wolfSSL 0:d92f9d21154c 872 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
wolfSSL 0:d92f9d21154c 873
wolfSSL 0:d92f9d21154c 874 /* return 0 on success */
wolfSSL 0:d92f9d21154c 875 static inline int IntelRDseed32(unsigned int *seed)
wolfSSL 0:d92f9d21154c 876 {
wolfSSL 0:d92f9d21154c 877 int rdseed; unsigned char ok ;
wolfSSL 0:d92f9d21154c 878
wolfSSL 0:d92f9d21154c 879 __asm__ volatile("rdseed %0; setc %1":"=r"(rdseed), "=qm"(ok));
wolfSSL 0:d92f9d21154c 880 if(ok){
wolfSSL 0:d92f9d21154c 881 *seed = rdseed ;
wolfSSL 0:d92f9d21154c 882 return 0 ;
wolfSSL 0:d92f9d21154c 883 } else
wolfSSL 0:d92f9d21154c 884 return 1;
wolfSSL 0:d92f9d21154c 885 }
wolfSSL 0:d92f9d21154c 886
wolfSSL 0:d92f9d21154c 887 /* return 0 on success */
wolfSSL 0:d92f9d21154c 888 static inline int IntelRDseed32_r(unsigned int *rnd)
wolfSSL 0:d92f9d21154c 889 {
wolfSSL 0:d92f9d21154c 890 int i ;
wolfSSL 0:d92f9d21154c 891 for(i=0; i<INTELRD_RETRY;i++) {
wolfSSL 0:d92f9d21154c 892 if(IntelRDseed32(rnd) == 0) return 0 ;
wolfSSL 0:d92f9d21154c 893 }
wolfSSL 0:d92f9d21154c 894 return 1 ;
wolfSSL 0:d92f9d21154c 895 }
wolfSSL 0:d92f9d21154c 896
wolfSSL 0:d92f9d21154c 897 /* return 0 on success */
wolfSSL 0:d92f9d21154c 898 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 899 {
wolfSSL 0:d92f9d21154c 900 (void) os ;
wolfSSL 0:d92f9d21154c 901 int ret ;
wolfSSL 0:d92f9d21154c 902 unsigned int rndTmp ;
wolfSSL 0:d92f9d21154c 903
wolfSSL 0:d92f9d21154c 904 for( ; sz/4 > 0; sz-=4, output+=4) {
wolfSSL 0:d92f9d21154c 905 if(IS_INTEL_RDSEED)ret = IntelRDseed32_r((word32 *)output) ;
wolfSSL 0:d92f9d21154c 906 else return 1 ;
wolfSSL 0:d92f9d21154c 907 if(ret)
wolfSSL 0:d92f9d21154c 908 return 1 ;
wolfSSL 0:d92f9d21154c 909 }
wolfSSL 0:d92f9d21154c 910 if(sz == 0)return 0 ;
wolfSSL 0:d92f9d21154c 911
wolfSSL 0:d92f9d21154c 912 if(IS_INTEL_RDSEED)ret = IntelRDseed32_r(&rndTmp) ;
wolfSSL 0:d92f9d21154c 913 else return 1 ;
wolfSSL 0:d92f9d21154c 914 if(ret)
wolfSSL 0:d92f9d21154c 915 return 1 ;
wolfSSL 0:d92f9d21154c 916 XMEMCPY(output, &rndTmp, sz) ;
wolfSSL 0:d92f9d21154c 917 return 0;
wolfSSL 0:d92f9d21154c 918 }
wolfSSL 0:d92f9d21154c 919
wolfSSL 0:d92f9d21154c 920 #else
wolfSSL 0:d92f9d21154c 921
wolfSSL 0:d92f9d21154c 922 /* return 0 on success */
wolfSSL 0:d92f9d21154c 923 static inline int IntelRDrand32(unsigned int *rnd)
wolfSSL 0:d92f9d21154c 924 {
wolfSSL 0:d92f9d21154c 925 int rdrand; unsigned char ok ;
wolfSSL 0:d92f9d21154c 926 __asm__ volatile("rdrand %0; setc %1":"=r"(rdrand), "=qm"(ok));
wolfSSL 0:d92f9d21154c 927 if(ok){
wolfSSL 0:d92f9d21154c 928 *rnd = rdrand;
wolfSSL 0:d92f9d21154c 929 return 0 ;
wolfSSL 0:d92f9d21154c 930 } else
wolfSSL 0:d92f9d21154c 931 return 1;
wolfSSL 0:d92f9d21154c 932 }
wolfSSL 0:d92f9d21154c 933
wolfSSL 0:d92f9d21154c 934 /* return 0 on success */
wolfSSL 0:d92f9d21154c 935 static inline int IntelRDrand32_r(unsigned int *rnd)
wolfSSL 0:d92f9d21154c 936 {
wolfSSL 0:d92f9d21154c 937 int i ;
wolfSSL 0:d92f9d21154c 938 for(i=0; i<INTELRD_RETRY;i++) {
wolfSSL 0:d92f9d21154c 939 if(IntelRDrand32(rnd) == 0) return 0 ;
wolfSSL 0:d92f9d21154c 940 }
wolfSSL 0:d92f9d21154c 941 return 1 ;
wolfSSL 0:d92f9d21154c 942 }
wolfSSL 0:d92f9d21154c 943
wolfSSL 0:d92f9d21154c 944 /* return 0 on success */
wolfSSL 0:d92f9d21154c 945 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 946 {
wolfSSL 0:d92f9d21154c 947 (void) os ;
wolfSSL 0:d92f9d21154c 948 int ret ;
wolfSSL 0:d92f9d21154c 949 unsigned int rndTmp;
wolfSSL 0:d92f9d21154c 950
wolfSSL 0:d92f9d21154c 951 for( ; sz/4 > 0; sz-=4, output+=4) {
wolfSSL 0:d92f9d21154c 952 if(IS_INTEL_RDRAND)ret = IntelRDrand32_r((word32 *)output);
wolfSSL 0:d92f9d21154c 953 else return 1 ;
wolfSSL 0:d92f9d21154c 954 if(ret)
wolfSSL 0:d92f9d21154c 955 return 1 ;
wolfSSL 0:d92f9d21154c 956 }
wolfSSL 0:d92f9d21154c 957 if(sz == 0)return 0 ;
wolfSSL 0:d92f9d21154c 958
wolfSSL 0:d92f9d21154c 959 if(IS_INTEL_RDRAND)ret = IntelRDrand32_r(&rndTmp);
wolfSSL 0:d92f9d21154c 960 else return 1 ;
wolfSSL 0:d92f9d21154c 961 if(ret)
wolfSSL 0:d92f9d21154c 962 return 1 ;
wolfSSL 0:d92f9d21154c 963 XMEMCPY(output, &rndTmp, sz) ;
wolfSSL 0:d92f9d21154c 964 return 0;
wolfSSL 0:d92f9d21154c 965 }
wolfSSL 0:d92f9d21154c 966 #endif /* defined(HAVE_HASHDRBG) || defined(NO_RC4) */
wolfSSL 0:d92f9d21154c 967
wolfSSL 0:d92f9d21154c 968 #endif /* HAVE_INTEL_RDGEN */
wolfSSL 0:d92f9d21154c 969
wolfSSL 0:d92f9d21154c 970
wolfSSL 0:d92f9d21154c 971 #if defined(USE_WINDOWS_API)
wolfSSL 0:d92f9d21154c 972
wolfSSL 0:d92f9d21154c 973
wolfSSL 0:d92f9d21154c 974 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 975 {
wolfSSL 0:d92f9d21154c 976 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
wolfSSL 0:d92f9d21154c 977 CRYPT_VERIFYCONTEXT))
wolfSSL 0:d92f9d21154c 978 return WINCRYPT_E;
wolfSSL 0:d92f9d21154c 979
wolfSSL 0:d92f9d21154c 980 if (!CryptGenRandom(os->handle, sz, output))
wolfSSL 0:d92f9d21154c 981 return CRYPTGEN_E;
wolfSSL 0:d92f9d21154c 982
wolfSSL 0:d92f9d21154c 983 CryptReleaseContext(os->handle, 0);
wolfSSL 0:d92f9d21154c 984
wolfSSL 0:d92f9d21154c 985 return 0;
wolfSSL 0:d92f9d21154c 986 }
wolfSSL 0:d92f9d21154c 987
wolfSSL 0:d92f9d21154c 988
wolfSSL 0:d92f9d21154c 989 #elif defined(HAVE_RTP_SYS) || defined(EBSNET)
wolfSSL 0:d92f9d21154c 990
wolfSSL 0:d92f9d21154c 991 #include "rtprand.h" /* rtp_rand () */
wolfSSL 0:d92f9d21154c 992 #include "rtptime.h" /* rtp_get_system_msec() */
wolfSSL 0:d92f9d21154c 993
wolfSSL 0:d92f9d21154c 994
wolfSSL 0:d92f9d21154c 995 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 996 {
wolfSSL 0:d92f9d21154c 997 int i;
wolfSSL 0:d92f9d21154c 998 rtp_srand(rtp_get_system_msec());
wolfSSL 0:d92f9d21154c 999
wolfSSL 0:d92f9d21154c 1000 for (i = 0; i < sz; i++ ) {
wolfSSL 0:d92f9d21154c 1001 output[i] = rtp_rand() % 256;
wolfSSL 0:d92f9d21154c 1002 if ( (i % 8) == 7)
wolfSSL 0:d92f9d21154c 1003 rtp_srand(rtp_get_system_msec());
wolfSSL 0:d92f9d21154c 1004 }
wolfSSL 0:d92f9d21154c 1005
wolfSSL 0:d92f9d21154c 1006 return 0;
wolfSSL 0:d92f9d21154c 1007 }
wolfSSL 0:d92f9d21154c 1008
wolfSSL 0:d92f9d21154c 1009
wolfSSL 0:d92f9d21154c 1010 #elif defined(MICRIUM)
wolfSSL 0:d92f9d21154c 1011
wolfSSL 0:d92f9d21154c 1012 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1013 {
wolfSSL 0:d92f9d21154c 1014 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
wolfSSL 0:d92f9d21154c 1015 NetSecure_InitSeed(output, sz);
wolfSSL 0:d92f9d21154c 1016 #endif
wolfSSL 0:d92f9d21154c 1017 return 0;
wolfSSL 0:d92f9d21154c 1018 }
wolfSSL 0:d92f9d21154c 1019
wolfSSL 0:d92f9d21154c 1020 #elif defined(MBED)
wolfSSL 0:d92f9d21154c 1021
wolfSSL 0:d92f9d21154c 1022 /* write a real one !!!, just for testing board */
wolfSSL 0:d92f9d21154c 1023 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1024 {
wolfSSL 0:d92f9d21154c 1025 int i;
wolfSSL 0:d92f9d21154c 1026 for (i = 0; i < sz; i++ )
wolfSSL 0:d92f9d21154c 1027 output[i] = i;
wolfSSL 0:d92f9d21154c 1028
wolfSSL 0:d92f9d21154c 1029 return 0;
wolfSSL 0:d92f9d21154c 1030 }
wolfSSL 0:d92f9d21154c 1031
wolfSSL 0:d92f9d21154c 1032 #elif defined(MICROCHIP_PIC32)
wolfSSL 0:d92f9d21154c 1033
wolfSSL 0:d92f9d21154c 1034 #ifdef MICROCHIP_MPLAB_HARMONY
wolfSSL 0:d92f9d21154c 1035 #define PIC32_SEED_COUNT _CP0_GET_COUNT
wolfSSL 0:d92f9d21154c 1036 #else
wolfSSL 0:d92f9d21154c 1037 #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
wolfSSL 0:d92f9d21154c 1038 #include <peripheral/timer.h>
wolfSSL 0:d92f9d21154c 1039 #endif
wolfSSL 0:d92f9d21154c 1040 #define PIC32_SEED_COUNT ReadCoreTimer
wolfSSL 0:d92f9d21154c 1041 #endif
wolfSSL 0:d92f9d21154c 1042 #ifdef WOLFSSL_MIC32MZ_RNG
wolfSSL 0:d92f9d21154c 1043 #include "xc.h"
wolfSSL 0:d92f9d21154c 1044 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1045 {
wolfSSL 0:d92f9d21154c 1046 int i ;
wolfSSL 0:d92f9d21154c 1047 byte rnd[8] ;
wolfSSL 0:d92f9d21154c 1048 word32 *rnd32 = (word32 *)rnd ;
wolfSSL 0:d92f9d21154c 1049 word32 size = sz ;
wolfSSL 0:d92f9d21154c 1050 byte* op = output ;
wolfSSL 0:d92f9d21154c 1051
wolfSSL 0:d92f9d21154c 1052 /* This part has to be replaced with better random seed */
wolfSSL 0:d92f9d21154c 1053 RNGNUMGEN1 = ReadCoreTimer();
wolfSSL 0:d92f9d21154c 1054 RNGPOLY1 = ReadCoreTimer();
wolfSSL 0:d92f9d21154c 1055 RNGPOLY2 = ReadCoreTimer();
wolfSSL 0:d92f9d21154c 1056 RNGNUMGEN2 = ReadCoreTimer();
wolfSSL 0:d92f9d21154c 1057 #ifdef DEBUG_WOLFSSL
wolfSSL 0:d92f9d21154c 1058 printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ;
wolfSSL 0:d92f9d21154c 1059 #endif
wolfSSL 0:d92f9d21154c 1060 RNGCONbits.PLEN = 0x40;
wolfSSL 0:d92f9d21154c 1061 RNGCONbits.PRNGEN = 1;
wolfSSL 0:d92f9d21154c 1062 for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
wolfSSL 0:d92f9d21154c 1063 volatile int x ;
wolfSSL 0:d92f9d21154c 1064 x = RNGNUMGEN1 ;
wolfSSL 0:d92f9d21154c 1065 x = RNGNUMGEN2 ;
wolfSSL 0:d92f9d21154c 1066 }
wolfSSL 0:d92f9d21154c 1067 do {
wolfSSL 0:d92f9d21154c 1068 rnd32[0] = RNGNUMGEN1;
wolfSSL 0:d92f9d21154c 1069 rnd32[1] = RNGNUMGEN2;
wolfSSL 0:d92f9d21154c 1070
wolfSSL 0:d92f9d21154c 1071 for(i=0; i<8; i++, op++) {
wolfSSL 0:d92f9d21154c 1072 *op = rnd[i] ;
wolfSSL 0:d92f9d21154c 1073 size -- ;
wolfSSL 0:d92f9d21154c 1074 if(size==0)break ;
wolfSSL 0:d92f9d21154c 1075 }
wolfSSL 0:d92f9d21154c 1076 } while(size) ;
wolfSSL 0:d92f9d21154c 1077 return 0;
wolfSSL 0:d92f9d21154c 1078 }
wolfSSL 0:d92f9d21154c 1079 #else /* WOLFSSL_MIC32MZ_RNG */
wolfSSL 0:d92f9d21154c 1080 /* uses the core timer, in nanoseconds to seed srand */
wolfSSL 0:d92f9d21154c 1081 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1082 {
wolfSSL 0:d92f9d21154c 1083 int i;
wolfSSL 0:d92f9d21154c 1084 srand(PIC32_SEED_COUNT() * 25);
wolfSSL 0:d92f9d21154c 1085
wolfSSL 0:d92f9d21154c 1086 for (i = 0; i < sz; i++ ) {
wolfSSL 0:d92f9d21154c 1087 output[i] = rand() % 256;
wolfSSL 0:d92f9d21154c 1088 if ( (i % 8) == 7)
wolfSSL 0:d92f9d21154c 1089 srand(PIC32_SEED_COUNT() * 25);
wolfSSL 0:d92f9d21154c 1090 }
wolfSSL 0:d92f9d21154c 1091 return 0;
wolfSSL 0:d92f9d21154c 1092 }
wolfSSL 0:d92f9d21154c 1093 #endif /* WOLFSSL_MIC32MZ_RNG */
wolfSSL 0:d92f9d21154c 1094
wolfSSL 0:d92f9d21154c 1095 #elif defined(FREESCALE_MQX)
wolfSSL 0:d92f9d21154c 1096
wolfSSL 0:d92f9d21154c 1097 #ifdef FREESCALE_K70_RNGA
wolfSSL 0:d92f9d21154c 1098 /*
wolfSSL 0:d92f9d21154c 1099 * wc_Generates a RNG seed using the Random Number Generator Accelerator
wolfSSL 0:d92f9d21154c 1100 * on the Kinetis K70. Documentation located in Chapter 37 of
wolfSSL 0:d92f9d21154c 1101 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
wolfSSL 0:d92f9d21154c 1102 */
wolfSSL 0:d92f9d21154c 1103 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1104 {
wolfSSL 0:d92f9d21154c 1105 int i;
wolfSSL 0:d92f9d21154c 1106
wolfSSL 0:d92f9d21154c 1107 /* turn on RNGA module */
wolfSSL 0:d92f9d21154c 1108 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
wolfSSL 0:d92f9d21154c 1109
wolfSSL 0:d92f9d21154c 1110 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
wolfSSL 0:d92f9d21154c 1111 RNG_CR &= ~RNG_CR_SLP_MASK;
wolfSSL 0:d92f9d21154c 1112
wolfSSL 0:d92f9d21154c 1113 /* set HA bit to 1 - "security violations masked" */
wolfSSL 0:d92f9d21154c 1114 RNG_CR |= RNG_CR_HA_MASK;
wolfSSL 0:d92f9d21154c 1115
wolfSSL 0:d92f9d21154c 1116 /* set GO bit to 1 - "output register loaded with data" */
wolfSSL 0:d92f9d21154c 1117 RNG_CR |= RNG_CR_GO_MASK;
wolfSSL 0:d92f9d21154c 1118
wolfSSL 0:d92f9d21154c 1119 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 1120
wolfSSL 0:d92f9d21154c 1121 /* wait for RNG FIFO to be full */
wolfSSL 0:d92f9d21154c 1122 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
wolfSSL 0:d92f9d21154c 1123
wolfSSL 0:d92f9d21154c 1124 /* get value */
wolfSSL 0:d92f9d21154c 1125 output[i] = RNG_OR;
wolfSSL 0:d92f9d21154c 1126 }
wolfSSL 0:d92f9d21154c 1127
wolfSSL 0:d92f9d21154c 1128 return 0;
wolfSSL 0:d92f9d21154c 1129 }
wolfSSL 0:d92f9d21154c 1130
wolfSSL 0:d92f9d21154c 1131 #elif defined(FREESCALE_K53_RNGB)
wolfSSL 0:d92f9d21154c 1132 /*
wolfSSL 0:d92f9d21154c 1133 * wc_Generates a RNG seed using the Random Number Generator (RNGB)
wolfSSL 0:d92f9d21154c 1134 * on the Kinetis K53. Documentation located in Chapter 33 of
wolfSSL 0:d92f9d21154c 1135 * K53 Sub-Family Reference Manual (see note in the README for link).
wolfSSL 0:d92f9d21154c 1136 */
wolfSSL 0:d92f9d21154c 1137 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1138 {
wolfSSL 0:d92f9d21154c 1139 int i;
wolfSSL 0:d92f9d21154c 1140
wolfSSL 0:d92f9d21154c 1141 /* turn on RNGB module */
wolfSSL 0:d92f9d21154c 1142 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
wolfSSL 0:d92f9d21154c 1143
wolfSSL 0:d92f9d21154c 1144 /* reset RNGB */
wolfSSL 0:d92f9d21154c 1145 RNG_CMD |= RNG_CMD_SR_MASK;
wolfSSL 0:d92f9d21154c 1146
wolfSSL 0:d92f9d21154c 1147 /* FIFO generate interrupt, return all zeros on underflow,
wolfSSL 0:d92f9d21154c 1148 * set auto reseed */
wolfSSL 0:d92f9d21154c 1149 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
wolfSSL 0:d92f9d21154c 1150
wolfSSL 0:d92f9d21154c 1151 /* gen seed, clear interrupts, clear errors */
wolfSSL 0:d92f9d21154c 1152 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
wolfSSL 0:d92f9d21154c 1153
wolfSSL 0:d92f9d21154c 1154 /* wait for seeding to complete */
wolfSSL 0:d92f9d21154c 1155 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
wolfSSL 0:d92f9d21154c 1156
wolfSSL 0:d92f9d21154c 1157 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 1158
wolfSSL 0:d92f9d21154c 1159 /* wait for a word to be available from FIFO */
wolfSSL 0:d92f9d21154c 1160 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
wolfSSL 0:d92f9d21154c 1161
wolfSSL 0:d92f9d21154c 1162 /* get value */
wolfSSL 0:d92f9d21154c 1163 output[i] = RNG_OUT;
wolfSSL 0:d92f9d21154c 1164 }
wolfSSL 0:d92f9d21154c 1165
wolfSSL 0:d92f9d21154c 1166 return 0;
wolfSSL 0:d92f9d21154c 1167 }
wolfSSL 0:d92f9d21154c 1168
wolfSSL 0:d92f9d21154c 1169 #else
wolfSSL 0:d92f9d21154c 1170 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 0:d92f9d21154c 1171
wolfSSL 0:d92f9d21154c 1172 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1173 {
wolfSSL 0:d92f9d21154c 1174 int i;
wolfSSL 0:d92f9d21154c 1175 for (i = 0; i < sz; i++ )
wolfSSL 0:d92f9d21154c 1176 output[i] = i;
wolfSSL 0:d92f9d21154c 1177
wolfSSL 0:d92f9d21154c 1178 return 0;
wolfSSL 0:d92f9d21154c 1179 }
wolfSSL 0:d92f9d21154c 1180 #endif /* FREESCALE_K70_RNGA */
wolfSSL 0:d92f9d21154c 1181
wolfSSL 0:d92f9d21154c 1182 #elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) \
wolfSSL 0:d92f9d21154c 1183 || defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_MDK_ARM) \
wolfSSL 0:d92f9d21154c 1184 || defined(WOLFSSL_uITRON4) || defined(WOLFSSL_uTKERNEL2)
wolfSSL 0:d92f9d21154c 1185
wolfSSL 0:d92f9d21154c 1186 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 0:d92f9d21154c 1187
wolfSSL 0:d92f9d21154c 1188 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1189 {
wolfSSL 0:d92f9d21154c 1190 word32 i;
wolfSSL 0:d92f9d21154c 1191 for (i = 0; i < sz; i++ )
wolfSSL 0:d92f9d21154c 1192 output[i] = i;
wolfSSL 0:d92f9d21154c 1193
wolfSSL 0:d92f9d21154c 1194 (void)os;
wolfSSL 0:d92f9d21154c 1195
wolfSSL 0:d92f9d21154c 1196 return 0;
wolfSSL 0:d92f9d21154c 1197 }
wolfSSL 0:d92f9d21154c 1198
wolfSSL 0:d92f9d21154c 1199 #elif defined(STM32F2_RNG)
wolfSSL 0:d92f9d21154c 1200 #undef RNG
wolfSSL 0:d92f9d21154c 1201 #include "stm32f2xx_rng.h"
wolfSSL 0:d92f9d21154c 1202 #include "stm32f2xx_rcc.h"
wolfSSL 0:d92f9d21154c 1203 /*
wolfSSL 0:d92f9d21154c 1204 * wc_Generate a RNG seed using the hardware random number generator
wolfSSL 0:d92f9d21154c 1205 * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
wolfSSL 0:d92f9d21154c 1206 * Library document (See note in README).
wolfSSL 0:d92f9d21154c 1207 */
wolfSSL 0:d92f9d21154c 1208 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1209 {
wolfSSL 0:d92f9d21154c 1210 int i;
wolfSSL 0:d92f9d21154c 1211
wolfSSL 0:d92f9d21154c 1212 /* enable RNG clock source */
wolfSSL 0:d92f9d21154c 1213 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
wolfSSL 0:d92f9d21154c 1214
wolfSSL 0:d92f9d21154c 1215 /* enable RNG peripheral */
wolfSSL 0:d92f9d21154c 1216 RNG_Cmd(ENABLE);
wolfSSL 0:d92f9d21154c 1217
wolfSSL 0:d92f9d21154c 1218 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 1219 /* wait until RNG number is ready */
wolfSSL 0:d92f9d21154c 1220 while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
wolfSSL 0:d92f9d21154c 1221
wolfSSL 0:d92f9d21154c 1222 /* get value */
wolfSSL 0:d92f9d21154c 1223 output[i] = RNG_GetRandomNumber();
wolfSSL 0:d92f9d21154c 1224 }
wolfSSL 0:d92f9d21154c 1225
wolfSSL 0:d92f9d21154c 1226 return 0;
wolfSSL 0:d92f9d21154c 1227 }
wolfSSL 0:d92f9d21154c 1228 #elif defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx)
wolfSSL 0:d92f9d21154c 1229
wolfSSL 0:d92f9d21154c 1230 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 0:d92f9d21154c 1231
wolfSSL 0:d92f9d21154c 1232 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1233 {
wolfSSL 0:d92f9d21154c 1234 int i;
wolfSSL 0:d92f9d21154c 1235
wolfSSL 0:d92f9d21154c 1236 for (i = 0; i < sz; i++ )
wolfSSL 0:d92f9d21154c 1237 output[i] = i;
wolfSSL 0:d92f9d21154c 1238
wolfSSL 0:d92f9d21154c 1239 return 0;
wolfSSL 0:d92f9d21154c 1240 }
wolfSSL 0:d92f9d21154c 1241
wolfSSL 0:d92f9d21154c 1242 #elif defined(WOLFSSL_TIRTOS)
wolfSSL 0:d92f9d21154c 1243
wolfSSL 0:d92f9d21154c 1244 #include <xdc/runtime/Timestamp.h>
wolfSSL 0:d92f9d21154c 1245 #include <stdlib.h>
wolfSSL 0:d92f9d21154c 1246 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1247 {
wolfSSL 0:d92f9d21154c 1248 int i;
wolfSSL 0:d92f9d21154c 1249 srand(xdc_runtime_Timestamp_get32());
wolfSSL 0:d92f9d21154c 1250
wolfSSL 0:d92f9d21154c 1251 for (i = 0; i < sz; i++ ) {
wolfSSL 0:d92f9d21154c 1252 output[i] = rand() % 256;
wolfSSL 0:d92f9d21154c 1253 if ((i % 8) == 7) {
wolfSSL 0:d92f9d21154c 1254 srand(xdc_runtime_Timestamp_get32());
wolfSSL 0:d92f9d21154c 1255 }
wolfSSL 0:d92f9d21154c 1256 }
wolfSSL 0:d92f9d21154c 1257
wolfSSL 0:d92f9d21154c 1258 return 0;
wolfSSL 0:d92f9d21154c 1259 }
wolfSSL 0:d92f9d21154c 1260
wolfSSL 0:d92f9d21154c 1261 #elif defined(CUSTOM_RAND_GENERATE)
wolfSSL 0:d92f9d21154c 1262
wolfSSL 0:d92f9d21154c 1263 /* Implement your own random generation function
wolfSSL 0:d92f9d21154c 1264 * word32 rand_gen(void);
wolfSSL 0:d92f9d21154c 1265 * #define CUSTOM_RAND_GENERATE rand_gen */
wolfSSL 0:d92f9d21154c 1266
wolfSSL 0:d92f9d21154c 1267 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1268 {
wolfSSL 0:d92f9d21154c 1269 word32 i;
wolfSSL 0:d92f9d21154c 1270
wolfSSL 0:d92f9d21154c 1271 (void)os;
wolfSSL 0:d92f9d21154c 1272
wolfSSL 0:d92f9d21154c 1273 for (i = 0; i < sz; i++ )
wolfSSL 0:d92f9d21154c 1274 output[i] = CUSTOM_RAND_GENERATE();
wolfSSL 0:d92f9d21154c 1275
wolfSSL 0:d92f9d21154c 1276 return 0;
wolfSSL 0:d92f9d21154c 1277 }
wolfSSL 0:d92f9d21154c 1278
wolfSSL 0:d92f9d21154c 1279 #elif defined(NO_DEV_RANDOM)
wolfSSL 0:d92f9d21154c 1280
wolfSSL 0:d92f9d21154c 1281 #error "you need to write an os specific wc_GenerateSeed() here"
wolfSSL 0:d92f9d21154c 1282
wolfSSL 0:d92f9d21154c 1283 /*
wolfSSL 0:d92f9d21154c 1284 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1285 {
wolfSSL 0:d92f9d21154c 1286 return 0;
wolfSSL 0:d92f9d21154c 1287 }
wolfSSL 0:d92f9d21154c 1288 */
wolfSSL 0:d92f9d21154c 1289
wolfSSL 0:d92f9d21154c 1290
wolfSSL 0:d92f9d21154c 1291 #else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */
wolfSSL 0:d92f9d21154c 1292
wolfSSL 0:d92f9d21154c 1293 /* may block */
wolfSSL 0:d92f9d21154c 1294 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:d92f9d21154c 1295 {
wolfSSL 0:d92f9d21154c 1296 int ret = 0;
wolfSSL 0:d92f9d21154c 1297
wolfSSL 0:d92f9d21154c 1298
wolfSSL 0:d92f9d21154c 1299 #if defined(HAVE_INTEL_RDGEN) && (defined(HAVE_HASHDRBG) || defined(NO_RC4))
wolfSSL 0:d92f9d21154c 1300 wc_InitRng_IntelRD() ; /* set cpuid_flags if not yet */
wolfSSL 0:d92f9d21154c 1301 if(IS_INTEL_RDSEED)
wolfSSL 0:d92f9d21154c 1302 return wc_GenerateSeed_IntelRD(NULL, output, sz) ;
wolfSSL 0:d92f9d21154c 1303 #endif
wolfSSL 0:d92f9d21154c 1304
wolfSSL 0:d92f9d21154c 1305 os->fd = open("/dev/urandom",O_RDONLY);
wolfSSL 0:d92f9d21154c 1306 if (os->fd == -1) {
wolfSSL 0:d92f9d21154c 1307 /* may still have /dev/random */
wolfSSL 0:d92f9d21154c 1308 os->fd = open("/dev/random",O_RDONLY);
wolfSSL 0:d92f9d21154c 1309 if (os->fd == -1)
wolfSSL 0:d92f9d21154c 1310 return OPEN_RAN_E;
wolfSSL 0:d92f9d21154c 1311 }
wolfSSL 0:d92f9d21154c 1312
wolfSSL 0:d92f9d21154c 1313 while (sz) {
wolfSSL 0:d92f9d21154c 1314 int len = (int)read(os->fd, output, sz);
wolfSSL 0:d92f9d21154c 1315 if (len == -1) {
wolfSSL 0:d92f9d21154c 1316 ret = READ_RAN_E;
wolfSSL 0:d92f9d21154c 1317 break;
wolfSSL 0:d92f9d21154c 1318 }
wolfSSL 0:d92f9d21154c 1319
wolfSSL 0:d92f9d21154c 1320 sz -= len;
wolfSSL 0:d92f9d21154c 1321 output += len;
wolfSSL 0:d92f9d21154c 1322
wolfSSL 0:d92f9d21154c 1323 if (sz) {
wolfSSL 0:d92f9d21154c 1324 #ifdef BLOCKING
wolfSSL 0:d92f9d21154c 1325 sleep(0); /* context switch */
wolfSSL 0:d92f9d21154c 1326 #else
wolfSSL 0:d92f9d21154c 1327 ret = RAN_BLOCK_E;
wolfSSL 0:d92f9d21154c 1328 break;
wolfSSL 0:d92f9d21154c 1329 #endif
wolfSSL 0:d92f9d21154c 1330 }
wolfSSL 0:d92f9d21154c 1331 }
wolfSSL 0:d92f9d21154c 1332 close(os->fd);
wolfSSL 0:d92f9d21154c 1333
wolfSSL 0:d92f9d21154c 1334 return ret;
wolfSSL 0:d92f9d21154c 1335 }
wolfSSL 0:d92f9d21154c 1336
wolfSSL 0:d92f9d21154c 1337 #endif /* USE_WINDOWS_API */
wolfSSL 0:d92f9d21154c 1338 #endif /* HAVE_FIPS */
wolfSSL 0:d92f9d21154c 1339
wolfSSL 0:d92f9d21154c 1340