SSL/TLS Library

Dependents:  

CyaSSL is SSL/TLS library for embedded systems.

wolfssl.com

Committer:
wolfSSL
Date:
Sun Apr 20 12:40:57 2014 +0000
Revision:
0:9d17e4342598
CyaSSL SSL/TLS Library 2.9.4;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:9d17e4342598 1 /* random.c
wolfSSL 0:9d17e4342598 2 *
wolfSSL 0:9d17e4342598 3 * Copyright (C) 2006-2013 wolfSSL Inc.
wolfSSL 0:9d17e4342598 4 *
wolfSSL 0:9d17e4342598 5 * This file is part of CyaSSL.
wolfSSL 0:9d17e4342598 6 *
wolfSSL 0:9d17e4342598 7 * CyaSSL is free software; you can redistribute it and/or modify
wolfSSL 0:9d17e4342598 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:9d17e4342598 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:9d17e4342598 10 * (at your option) any later version.
wolfSSL 0:9d17e4342598 11 *
wolfSSL 0:9d17e4342598 12 * CyaSSL is distributed in the hope that it will be useful,
wolfSSL 0:9d17e4342598 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:9d17e4342598 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:9d17e4342598 15 * GNU General Public License for more details.
wolfSSL 0:9d17e4342598 16 *
wolfSSL 0:9d17e4342598 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:9d17e4342598 18 * along with this program; if not, write to the Free Software
wolfSSL 0:9d17e4342598 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
wolfSSL 0:9d17e4342598 20 */
wolfSSL 0:9d17e4342598 21
wolfSSL 0:9d17e4342598 22 #ifdef HAVE_CONFIG_H
wolfSSL 0:9d17e4342598 23 #include <config.h>
wolfSSL 0:9d17e4342598 24 #endif
wolfSSL 0:9d17e4342598 25
wolfSSL 0:9d17e4342598 26 #include <cyassl/ctaocrypt/settings.h>
wolfSSL 0:9d17e4342598 27
wolfSSL 0:9d17e4342598 28 /* on HPUX 11 you may need to install /dev/random see
wolfSSL 0:9d17e4342598 29 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
wolfSSL 0:9d17e4342598 30
wolfSSL 0:9d17e4342598 31 */
wolfSSL 0:9d17e4342598 32
wolfSSL 0:9d17e4342598 33 #include <cyassl/ctaocrypt/random.h>
wolfSSL 0:9d17e4342598 34 #include <cyassl/ctaocrypt/error-crypt.h>
wolfSSL 0:9d17e4342598 35
wolfSSL 0:9d17e4342598 36 #ifdef NO_RC4
wolfSSL 0:9d17e4342598 37 #include <cyassl/ctaocrypt/sha256.h>
wolfSSL 0:9d17e4342598 38
wolfSSL 0:9d17e4342598 39 #ifdef NO_INLINE
wolfSSL 0:9d17e4342598 40 #include <cyassl/ctaocrypt/misc.h>
wolfSSL 0:9d17e4342598 41 #else
wolfSSL 0:9d17e4342598 42 #define MISC_DUMM_FUNC misc_dummy_random
wolfSSL 0:9d17e4342598 43 #include <ctaocrypt/src/misc.c>
wolfSSL 0:9d17e4342598 44 #endif
wolfSSL 0:9d17e4342598 45 #endif
wolfSSL 0:9d17e4342598 46
wolfSSL 0:9d17e4342598 47 #if defined(USE_WINDOWS_API)
wolfSSL 0:9d17e4342598 48 #ifndef _WIN32_WINNT
wolfSSL 0:9d17e4342598 49 #define _WIN32_WINNT 0x0400
wolfSSL 0:9d17e4342598 50 #endif
wolfSSL 0:9d17e4342598 51 #include <windows.h>
wolfSSL 0:9d17e4342598 52 #include <wincrypt.h>
wolfSSL 0:9d17e4342598 53 #else
wolfSSL 0:9d17e4342598 54 #if !defined(NO_DEV_RANDOM) && !defined(CYASSL_MDK_ARM) \
wolfSSL 0:9d17e4342598 55 && !defined(CYASSL_IAR_ARM)
wolfSSL 0:9d17e4342598 56 #include <fcntl.h>
wolfSSL 0:9d17e4342598 57 #ifndef EBSNET
wolfSSL 0:9d17e4342598 58 #include <unistd.h>
wolfSSL 0:9d17e4342598 59 #endif
wolfSSL 0:9d17e4342598 60 #else
wolfSSL 0:9d17e4342598 61 /* include headers that may be needed to get good seed */
wolfSSL 0:9d17e4342598 62 #endif
wolfSSL 0:9d17e4342598 63 #endif /* USE_WINDOWS_API */
wolfSSL 0:9d17e4342598 64
wolfSSL 0:9d17e4342598 65
wolfSSL 0:9d17e4342598 66 #ifdef NO_RC4
wolfSSL 0:9d17e4342598 67
wolfSSL 0:9d17e4342598 68 /* Start NIST DRBG code */
wolfSSL 0:9d17e4342598 69
wolfSSL 0:9d17e4342598 70 #define OUTPUT_BLOCK_LEN (256/8)
wolfSSL 0:9d17e4342598 71 #define MAX_REQUEST_LEN (0x1000)
wolfSSL 0:9d17e4342598 72 #define MAX_STRING_LEN (0x100000000)
wolfSSL 0:9d17e4342598 73 #define RESEED_MAX (0x100000000000LL)
wolfSSL 0:9d17e4342598 74 #define ENTROPY_SZ 256
wolfSSL 0:9d17e4342598 75
wolfSSL 0:9d17e4342598 76 #define DBRG_SUCCESS 0
wolfSSL 0:9d17e4342598 77 #define DBRG_ERROR 1
wolfSSL 0:9d17e4342598 78 #define DBRG_NEED_RESEED 2
wolfSSL 0:9d17e4342598 79
wolfSSL 0:9d17e4342598 80
wolfSSL 0:9d17e4342598 81 enum {
wolfSSL 0:9d17e4342598 82 dbrgInitC = 0,
wolfSSL 0:9d17e4342598 83 dbrgReseed = 1,
wolfSSL 0:9d17e4342598 84 dbrgGenerateW = 2,
wolfSSL 0:9d17e4342598 85 dbrgGenerateH = 3,
wolfSSL 0:9d17e4342598 86 dbrgInitV
wolfSSL 0:9d17e4342598 87 };
wolfSSL 0:9d17e4342598 88
wolfSSL 0:9d17e4342598 89
wolfSSL 0:9d17e4342598 90 static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, byte* inA, word32 inASz,
wolfSSL 0:9d17e4342598 91 byte* inB, word32 inBSz, byte* inC, word32 inCSz)
wolfSSL 0:9d17e4342598 92 {
wolfSSL 0:9d17e4342598 93 byte ctr;
wolfSSL 0:9d17e4342598 94 int i;
wolfSSL 0:9d17e4342598 95 int len;
wolfSSL 0:9d17e4342598 96 word32 bits = (outSz * 8); /* reverse byte order */
wolfSSL 0:9d17e4342598 97
wolfSSL 0:9d17e4342598 98 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 0:9d17e4342598 99 bits = ByteReverseWord32(bits);
wolfSSL 0:9d17e4342598 100 #endif
wolfSSL 0:9d17e4342598 101 len = (outSz / SHA256_DIGEST_SIZE)
wolfSSL 0:9d17e4342598 102 + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0);
wolfSSL 0:9d17e4342598 103
wolfSSL 0:9d17e4342598 104 for (i = 0, ctr = 1; i < len; i++, ctr++)
wolfSSL 0:9d17e4342598 105 {
wolfSSL 0:9d17e4342598 106 if (InitSha256(&rng->sha) != 0)
wolfSSL 0:9d17e4342598 107 return DBRG_ERROR;
wolfSSL 0:9d17e4342598 108 Sha256Update(&rng->sha, &ctr, sizeof(ctr));
wolfSSL 0:9d17e4342598 109 Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits));
wolfSSL 0:9d17e4342598 110 /* churning V is the only string that doesn't have
wolfSSL 0:9d17e4342598 111 * the type added */
wolfSSL 0:9d17e4342598 112 if (type != dbrgInitV)
wolfSSL 0:9d17e4342598 113 Sha256Update(&rng->sha, &type, sizeof(type));
wolfSSL 0:9d17e4342598 114 Sha256Update(&rng->sha, inA, inASz);
wolfSSL 0:9d17e4342598 115 if (inB != NULL && inBSz > 0)
wolfSSL 0:9d17e4342598 116 Sha256Update(&rng->sha, inB, inBSz);
wolfSSL 0:9d17e4342598 117 if (inC != NULL && inCSz > 0)
wolfSSL 0:9d17e4342598 118 Sha256Update(&rng->sha, inC, inCSz);
wolfSSL 0:9d17e4342598 119 Sha256Final(&rng->sha, rng->digest);
wolfSSL 0:9d17e4342598 120
wolfSSL 0:9d17e4342598 121 if (outSz > SHA256_DIGEST_SIZE) {
wolfSSL 0:9d17e4342598 122 XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE);
wolfSSL 0:9d17e4342598 123 outSz -= SHA256_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 124 out += SHA256_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 125 }
wolfSSL 0:9d17e4342598 126 else {
wolfSSL 0:9d17e4342598 127 XMEMCPY(out, rng->digest, outSz);
wolfSSL 0:9d17e4342598 128 }
wolfSSL 0:9d17e4342598 129 }
wolfSSL 0:9d17e4342598 130
wolfSSL 0:9d17e4342598 131 return DBRG_SUCCESS;
wolfSSL 0:9d17e4342598 132 }
wolfSSL 0:9d17e4342598 133
wolfSSL 0:9d17e4342598 134
wolfSSL 0:9d17e4342598 135 static int Hash_DBRG_Reseed(RNG* rng, byte* entropy, word32 entropySz)
wolfSSL 0:9d17e4342598 136 {
wolfSSL 0:9d17e4342598 137 byte seed[DBRG_SEED_LEN];
wolfSSL 0:9d17e4342598 138
wolfSSL 0:9d17e4342598 139 Hash_df(rng, seed, sizeof(seed), dbrgInitV, rng->V, sizeof(rng->V),
wolfSSL 0:9d17e4342598 140 entropy, entropySz, NULL, 0);
wolfSSL 0:9d17e4342598 141 XMEMCPY(rng->V, seed, sizeof(rng->V));
wolfSSL 0:9d17e4342598 142 XMEMSET(seed, 0, sizeof(seed));
wolfSSL 0:9d17e4342598 143
wolfSSL 0:9d17e4342598 144 Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, sizeof(rng->V),
wolfSSL 0:9d17e4342598 145 NULL, 0, NULL, 0);
wolfSSL 0:9d17e4342598 146 rng->reseed_ctr = 1;
wolfSSL 0:9d17e4342598 147 return 0;
wolfSSL 0:9d17e4342598 148 }
wolfSSL 0:9d17e4342598 149
wolfSSL 0:9d17e4342598 150 static INLINE void array_add_one(byte* data, word32 dataSz)
wolfSSL 0:9d17e4342598 151 {
wolfSSL 0:9d17e4342598 152 int i;
wolfSSL 0:9d17e4342598 153
wolfSSL 0:9d17e4342598 154 for (i = dataSz - 1; i >= 0; i--)
wolfSSL 0:9d17e4342598 155 {
wolfSSL 0:9d17e4342598 156 data[i]++;
wolfSSL 0:9d17e4342598 157 if (data[i] != 0) break;
wolfSSL 0:9d17e4342598 158 }
wolfSSL 0:9d17e4342598 159 }
wolfSSL 0:9d17e4342598 160
wolfSSL 0:9d17e4342598 161 static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V)
wolfSSL 0:9d17e4342598 162 {
wolfSSL 0:9d17e4342598 163 byte data[DBRG_SEED_LEN];
wolfSSL 0:9d17e4342598 164 int i, ret;
wolfSSL 0:9d17e4342598 165 int len = (outSz / SHA256_DIGEST_SIZE)
wolfSSL 0:9d17e4342598 166 + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0);
wolfSSL 0:9d17e4342598 167
wolfSSL 0:9d17e4342598 168 XMEMCPY(data, V, sizeof(data));
wolfSSL 0:9d17e4342598 169 for (i = 0; i < len; i++) {
wolfSSL 0:9d17e4342598 170 ret = InitSha256(&rng->sha);
wolfSSL 0:9d17e4342598 171 if (ret != 0) return ret;
wolfSSL 0:9d17e4342598 172 Sha256Update(&rng->sha, data, sizeof(data));
wolfSSL 0:9d17e4342598 173 Sha256Final(&rng->sha, rng->digest);
wolfSSL 0:9d17e4342598 174 if (outSz > SHA256_DIGEST_SIZE) {
wolfSSL 0:9d17e4342598 175 XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE);
wolfSSL 0:9d17e4342598 176 outSz -= SHA256_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 177 out += SHA256_DIGEST_SIZE;
wolfSSL 0:9d17e4342598 178 array_add_one(data, DBRG_SEED_LEN);
wolfSSL 0:9d17e4342598 179 }
wolfSSL 0:9d17e4342598 180 else {
wolfSSL 0:9d17e4342598 181 XMEMCPY(out, rng->digest, outSz);
wolfSSL 0:9d17e4342598 182 }
wolfSSL 0:9d17e4342598 183 }
wolfSSL 0:9d17e4342598 184 XMEMSET(data, 0, sizeof(data));
wolfSSL 0:9d17e4342598 185
wolfSSL 0:9d17e4342598 186 return 0;
wolfSSL 0:9d17e4342598 187 }
wolfSSL 0:9d17e4342598 188
wolfSSL 0:9d17e4342598 189
wolfSSL 0:9d17e4342598 190 static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen)
wolfSSL 0:9d17e4342598 191 {
wolfSSL 0:9d17e4342598 192 word16 carry = 0;
wolfSSL 0:9d17e4342598 193
wolfSSL 0:9d17e4342598 194 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
wolfSSL 0:9d17e4342598 195 int sIdx, dIdx;
wolfSSL 0:9d17e4342598 196
wolfSSL 0:9d17e4342598 197 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
wolfSSL 0:9d17e4342598 198 {
wolfSSL 0:9d17e4342598 199 carry += d[dIdx] + s[sIdx];
wolfSSL 0:9d17e4342598 200 d[dIdx] = carry;
wolfSSL 0:9d17e4342598 201 carry >>= 8;
wolfSSL 0:9d17e4342598 202 }
wolfSSL 0:9d17e4342598 203 if (dIdx > 0)
wolfSSL 0:9d17e4342598 204 d[dIdx] += carry;
wolfSSL 0:9d17e4342598 205 }
wolfSSL 0:9d17e4342598 206 }
wolfSSL 0:9d17e4342598 207
wolfSSL 0:9d17e4342598 208
wolfSSL 0:9d17e4342598 209 static int Hash_DBRG_Generate(RNG* rng, byte* out, word32 outSz)
wolfSSL 0:9d17e4342598 210 {
wolfSSL 0:9d17e4342598 211 int ret;
wolfSSL 0:9d17e4342598 212
wolfSSL 0:9d17e4342598 213 if (rng->reseed_ctr != RESEED_MAX) {
wolfSSL 0:9d17e4342598 214 byte type = dbrgGenerateH;
wolfSSL 0:9d17e4342598 215
wolfSSL 0:9d17e4342598 216 if (Hash_gen(rng, out, outSz, rng->V) != 0)
wolfSSL 0:9d17e4342598 217 return DBRG_ERROR;
wolfSSL 0:9d17e4342598 218 if (InitSha256(&rng->sha) != 0)
wolfSSL 0:9d17e4342598 219 return DBRG_ERROR;
wolfSSL 0:9d17e4342598 220 Sha256Update(&rng->sha, &type, sizeof(type));
wolfSSL 0:9d17e4342598 221 Sha256Update(&rng->sha, rng->V, sizeof(rng->V));
wolfSSL 0:9d17e4342598 222 Sha256Final(&rng->sha, rng->digest);
wolfSSL 0:9d17e4342598 223 array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest));
wolfSSL 0:9d17e4342598 224 array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C));
wolfSSL 0:9d17e4342598 225 array_add(rng->V, sizeof(rng->V),
wolfSSL 0:9d17e4342598 226 (byte*)&rng->reseed_ctr, sizeof(rng->reseed_ctr));
wolfSSL 0:9d17e4342598 227 rng->reseed_ctr++;
wolfSSL 0:9d17e4342598 228 ret = DBRG_SUCCESS;
wolfSSL 0:9d17e4342598 229 }
wolfSSL 0:9d17e4342598 230 else {
wolfSSL 0:9d17e4342598 231 ret = DBRG_NEED_RESEED;
wolfSSL 0:9d17e4342598 232 }
wolfSSL 0:9d17e4342598 233 return ret;
wolfSSL 0:9d17e4342598 234 }
wolfSSL 0:9d17e4342598 235
wolfSSL 0:9d17e4342598 236
wolfSSL 0:9d17e4342598 237 static void Hash_DBRG_Instantiate(RNG* rng, byte* seed, word32 seedSz)
wolfSSL 0:9d17e4342598 238 {
wolfSSL 0:9d17e4342598 239 XMEMSET(rng, 0, sizeof(*rng));
wolfSSL 0:9d17e4342598 240 Hash_df(rng, rng->V, sizeof(rng->V), dbrgInitV, seed, seedSz, NULL, 0, NULL, 0);
wolfSSL 0:9d17e4342598 241 Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, sizeof(rng->V),
wolfSSL 0:9d17e4342598 242 NULL, 0, NULL, 0);
wolfSSL 0:9d17e4342598 243 rng->reseed_ctr = 1;
wolfSSL 0:9d17e4342598 244 }
wolfSSL 0:9d17e4342598 245
wolfSSL 0:9d17e4342598 246
wolfSSL 0:9d17e4342598 247 static int Hash_DBRG_Uninstantiate(RNG* rng)
wolfSSL 0:9d17e4342598 248 {
wolfSSL 0:9d17e4342598 249 int result = DBRG_ERROR;
wolfSSL 0:9d17e4342598 250
wolfSSL 0:9d17e4342598 251 if (rng != NULL) {
wolfSSL 0:9d17e4342598 252 XMEMSET(rng, 0, sizeof(*rng));
wolfSSL 0:9d17e4342598 253 result = DBRG_SUCCESS;
wolfSSL 0:9d17e4342598 254 }
wolfSSL 0:9d17e4342598 255
wolfSSL 0:9d17e4342598 256 return result;
wolfSSL 0:9d17e4342598 257 }
wolfSSL 0:9d17e4342598 258
wolfSSL 0:9d17e4342598 259 /* End NIST DRBG Code */
wolfSSL 0:9d17e4342598 260
wolfSSL 0:9d17e4342598 261
wolfSSL 0:9d17e4342598 262
wolfSSL 0:9d17e4342598 263 /* Get seed and key cipher */
wolfSSL 0:9d17e4342598 264 int InitRng(RNG* rng)
wolfSSL 0:9d17e4342598 265 {
wolfSSL 0:9d17e4342598 266 byte entropy[ENTROPY_SZ];
wolfSSL 0:9d17e4342598 267 int ret = DBRG_ERROR;
wolfSSL 0:9d17e4342598 268
wolfSSL 0:9d17e4342598 269 if (GenerateSeed(&rng->seed, entropy, sizeof(entropy)) == 0) {
wolfSSL 0:9d17e4342598 270 Hash_DBRG_Instantiate(rng, entropy, sizeof(entropy));
wolfSSL 0:9d17e4342598 271 ret = DBRG_SUCCESS;
wolfSSL 0:9d17e4342598 272 }
wolfSSL 0:9d17e4342598 273 XMEMSET(entropy, 0, sizeof(entropy));
wolfSSL 0:9d17e4342598 274 return ret;
wolfSSL 0:9d17e4342598 275 }
wolfSSL 0:9d17e4342598 276
wolfSSL 0:9d17e4342598 277
wolfSSL 0:9d17e4342598 278 /* place a generated block in output */
wolfSSL 0:9d17e4342598 279 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 280 {
wolfSSL 0:9d17e4342598 281 int ret;
wolfSSL 0:9d17e4342598 282
wolfSSL 0:9d17e4342598 283 XMEMSET(output, 0, sz);
wolfSSL 0:9d17e4342598 284 ret = Hash_DBRG_Generate(rng, output, sz);
wolfSSL 0:9d17e4342598 285 if (ret == DBRG_NEED_RESEED) {
wolfSSL 0:9d17e4342598 286 byte entropy[ENTROPY_SZ];
wolfSSL 0:9d17e4342598 287 ret = GenerateSeed(&rng->seed, entropy, sizeof(entropy));
wolfSSL 0:9d17e4342598 288 if (ret == 0) {
wolfSSL 0:9d17e4342598 289 Hash_DBRG_Reseed(rng, entropy, sizeof(entropy));
wolfSSL 0:9d17e4342598 290 ret = Hash_DBRG_Generate(rng, output, sz);
wolfSSL 0:9d17e4342598 291 }
wolfSSL 0:9d17e4342598 292 else
wolfSSL 0:9d17e4342598 293 ret = DBRG_ERROR;
wolfSSL 0:9d17e4342598 294 XMEMSET(entropy, 0, sizeof(entropy));
wolfSSL 0:9d17e4342598 295 }
wolfSSL 0:9d17e4342598 296 }
wolfSSL 0:9d17e4342598 297
wolfSSL 0:9d17e4342598 298
wolfSSL 0:9d17e4342598 299 byte RNG_GenerateByte(RNG* rng)
wolfSSL 0:9d17e4342598 300 {
wolfSSL 0:9d17e4342598 301 byte b;
wolfSSL 0:9d17e4342598 302 RNG_GenerateBlock(rng, &b, 1);
wolfSSL 0:9d17e4342598 303
wolfSSL 0:9d17e4342598 304 return b;
wolfSSL 0:9d17e4342598 305 }
wolfSSL 0:9d17e4342598 306
wolfSSL 0:9d17e4342598 307
wolfSSL 0:9d17e4342598 308 void FreeRng(RNG* rng)
wolfSSL 0:9d17e4342598 309 {
wolfSSL 0:9d17e4342598 310 Hash_DBRG_Uninstantiate(rng);
wolfSSL 0:9d17e4342598 311 }
wolfSSL 0:9d17e4342598 312
wolfSSL 0:9d17e4342598 313 #else /* NO_RC4 */
wolfSSL 0:9d17e4342598 314
wolfSSL 0:9d17e4342598 315 /* Get seed and key cipher */
wolfSSL 0:9d17e4342598 316 int InitRng(RNG* rng)
wolfSSL 0:9d17e4342598 317 {
wolfSSL 0:9d17e4342598 318 byte key[32];
wolfSSL 0:9d17e4342598 319 byte junk[256];
wolfSSL 0:9d17e4342598 320 int ret;
wolfSSL 0:9d17e4342598 321
wolfSSL 0:9d17e4342598 322 #ifdef HAVE_CAVIUM
wolfSSL 0:9d17e4342598 323 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC)
wolfSSL 0:9d17e4342598 324 return 0;
wolfSSL 0:9d17e4342598 325 #endif
wolfSSL 0:9d17e4342598 326 ret = GenerateSeed(&rng->seed, key, sizeof(key));
wolfSSL 0:9d17e4342598 327
wolfSSL 0:9d17e4342598 328 if (ret == 0) {
wolfSSL 0:9d17e4342598 329 Arc4SetKey(&rng->cipher, key, sizeof(key));
wolfSSL 0:9d17e4342598 330 RNG_GenerateBlock(rng, junk, sizeof(junk)); /* rid initial state */
wolfSSL 0:9d17e4342598 331 }
wolfSSL 0:9d17e4342598 332
wolfSSL 0:9d17e4342598 333 return ret;
wolfSSL 0:9d17e4342598 334 }
wolfSSL 0:9d17e4342598 335
wolfSSL 0:9d17e4342598 336 #ifdef HAVE_CAVIUM
wolfSSL 0:9d17e4342598 337 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz);
wolfSSL 0:9d17e4342598 338 #endif
wolfSSL 0:9d17e4342598 339
wolfSSL 0:9d17e4342598 340 /* place a generated block in output */
wolfSSL 0:9d17e4342598 341 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 342 {
wolfSSL 0:9d17e4342598 343 #ifdef HAVE_CAVIUM
wolfSSL 0:9d17e4342598 344 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC)
wolfSSL 0:9d17e4342598 345 return CaviumRNG_GenerateBlock(rng, output, sz);
wolfSSL 0:9d17e4342598 346 #endif
wolfSSL 0:9d17e4342598 347 XMEMSET(output, 0, sz);
wolfSSL 0:9d17e4342598 348 Arc4Process(&rng->cipher, output, output, sz);
wolfSSL 0:9d17e4342598 349 }
wolfSSL 0:9d17e4342598 350
wolfSSL 0:9d17e4342598 351
wolfSSL 0:9d17e4342598 352 byte RNG_GenerateByte(RNG* rng)
wolfSSL 0:9d17e4342598 353 {
wolfSSL 0:9d17e4342598 354 byte b;
wolfSSL 0:9d17e4342598 355 RNG_GenerateBlock(rng, &b, 1);
wolfSSL 0:9d17e4342598 356
wolfSSL 0:9d17e4342598 357 return b;
wolfSSL 0:9d17e4342598 358 }
wolfSSL 0:9d17e4342598 359
wolfSSL 0:9d17e4342598 360
wolfSSL 0:9d17e4342598 361 #ifdef HAVE_CAVIUM
wolfSSL 0:9d17e4342598 362
wolfSSL 0:9d17e4342598 363 #include <cyassl/ctaocrypt/logging.h>
wolfSSL 0:9d17e4342598 364 #include "cavium_common.h"
wolfSSL 0:9d17e4342598 365
wolfSSL 0:9d17e4342598 366 /* Initiliaze RNG for use with Nitrox device */
wolfSSL 0:9d17e4342598 367 int InitRngCavium(RNG* rng, int devId)
wolfSSL 0:9d17e4342598 368 {
wolfSSL 0:9d17e4342598 369 if (rng == NULL)
wolfSSL 0:9d17e4342598 370 return -1;
wolfSSL 0:9d17e4342598 371
wolfSSL 0:9d17e4342598 372 rng->devId = devId;
wolfSSL 0:9d17e4342598 373 rng->magic = CYASSL_RNG_CAVIUM_MAGIC;
wolfSSL 0:9d17e4342598 374
wolfSSL 0:9d17e4342598 375 return 0;
wolfSSL 0:9d17e4342598 376 }
wolfSSL 0:9d17e4342598 377
wolfSSL 0:9d17e4342598 378
wolfSSL 0:9d17e4342598 379 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 380 {
wolfSSL 0:9d17e4342598 381 word offset = 0;
wolfSSL 0:9d17e4342598 382 word32 requestId;
wolfSSL 0:9d17e4342598 383
wolfSSL 0:9d17e4342598 384 while (sz > CYASSL_MAX_16BIT) {
wolfSSL 0:9d17e4342598 385 word16 slen = (word16)CYASSL_MAX_16BIT;
wolfSSL 0:9d17e4342598 386 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
wolfSSL 0:9d17e4342598 387 rng->devId) != 0) {
wolfSSL 0:9d17e4342598 388 CYASSL_MSG("Cavium RNG failed");
wolfSSL 0:9d17e4342598 389 }
wolfSSL 0:9d17e4342598 390 sz -= CYASSL_MAX_16BIT;
wolfSSL 0:9d17e4342598 391 offset += CYASSL_MAX_16BIT;
wolfSSL 0:9d17e4342598 392 }
wolfSSL 0:9d17e4342598 393 if (sz) {
wolfSSL 0:9d17e4342598 394 word16 slen = (word16)sz;
wolfSSL 0:9d17e4342598 395 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
wolfSSL 0:9d17e4342598 396 rng->devId) != 0) {
wolfSSL 0:9d17e4342598 397 CYASSL_MSG("Cavium RNG failed");
wolfSSL 0:9d17e4342598 398 }
wolfSSL 0:9d17e4342598 399 }
wolfSSL 0:9d17e4342598 400 }
wolfSSL 0:9d17e4342598 401
wolfSSL 0:9d17e4342598 402 #endif /* HAVE_CAVIUM */
wolfSSL 0:9d17e4342598 403
wolfSSL 0:9d17e4342598 404 #endif /* NO_RC4 */
wolfSSL 0:9d17e4342598 405
wolfSSL 0:9d17e4342598 406
wolfSSL 0:9d17e4342598 407 #if defined(USE_WINDOWS_API)
wolfSSL 0:9d17e4342598 408
wolfSSL 0:9d17e4342598 409
wolfSSL 0:9d17e4342598 410 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 411 {
wolfSSL 0:9d17e4342598 412 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
wolfSSL 0:9d17e4342598 413 CRYPT_VERIFYCONTEXT))
wolfSSL 0:9d17e4342598 414 return WINCRYPT_E;
wolfSSL 0:9d17e4342598 415
wolfSSL 0:9d17e4342598 416 if (!CryptGenRandom(os->handle, sz, output))
wolfSSL 0:9d17e4342598 417 return CRYPTGEN_E;
wolfSSL 0:9d17e4342598 418
wolfSSL 0:9d17e4342598 419 CryptReleaseContext(os->handle, 0);
wolfSSL 0:9d17e4342598 420
wolfSSL 0:9d17e4342598 421 return 0;
wolfSSL 0:9d17e4342598 422 }
wolfSSL 0:9d17e4342598 423
wolfSSL 0:9d17e4342598 424
wolfSSL 0:9d17e4342598 425 #elif defined(HAVE_RTP_SYS) || defined(EBSNET)
wolfSSL 0:9d17e4342598 426
wolfSSL 0:9d17e4342598 427 #include "rtprand.h" /* rtp_rand () */
wolfSSL 0:9d17e4342598 428 #include "rtptime.h" /* rtp_get_system_msec() */
wolfSSL 0:9d17e4342598 429
wolfSSL 0:9d17e4342598 430
wolfSSL 0:9d17e4342598 431 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 432 {
wolfSSL 0:9d17e4342598 433 int i;
wolfSSL 0:9d17e4342598 434 rtp_srand(rtp_get_system_msec());
wolfSSL 0:9d17e4342598 435
wolfSSL 0:9d17e4342598 436 for (i = 0; i < sz; i++ ) {
wolfSSL 0:9d17e4342598 437 output[i] = rtp_rand() % 256;
wolfSSL 0:9d17e4342598 438 if ( (i % 8) == 7)
wolfSSL 0:9d17e4342598 439 rtp_srand(rtp_get_system_msec());
wolfSSL 0:9d17e4342598 440 }
wolfSSL 0:9d17e4342598 441
wolfSSL 0:9d17e4342598 442 return 0;
wolfSSL 0:9d17e4342598 443 }
wolfSSL 0:9d17e4342598 444
wolfSSL 0:9d17e4342598 445
wolfSSL 0:9d17e4342598 446 #elif defined(MICRIUM)
wolfSSL 0:9d17e4342598 447
wolfSSL 0:9d17e4342598 448 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 449 {
wolfSSL 0:9d17e4342598 450 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
wolfSSL 0:9d17e4342598 451 NetSecure_InitSeed(output, sz);
wolfSSL 0:9d17e4342598 452 #endif
wolfSSL 0:9d17e4342598 453 return 0;
wolfSSL 0:9d17e4342598 454 }
wolfSSL 0:9d17e4342598 455
wolfSSL 0:9d17e4342598 456 #elif defined(MBED)
wolfSSL 0:9d17e4342598 457
wolfSSL 0:9d17e4342598 458 /* write a real one !!!, just for testing board */
wolfSSL 0:9d17e4342598 459 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 460 {
wolfSSL 0:9d17e4342598 461 int i;
wolfSSL 0:9d17e4342598 462 for (i = 0; i < sz; i++ )
wolfSSL 0:9d17e4342598 463 output[i] = i;
wolfSSL 0:9d17e4342598 464
wolfSSL 0:9d17e4342598 465 return 0;
wolfSSL 0:9d17e4342598 466 }
wolfSSL 0:9d17e4342598 467
wolfSSL 0:9d17e4342598 468 #elif defined(MICROCHIP_PIC32)
wolfSSL 0:9d17e4342598 469
wolfSSL 0:9d17e4342598 470 #ifdef MICROCHIP_MPLAB_HARMONY
wolfSSL 0:9d17e4342598 471 #define PIC32_SEED_COUNT _CP0_GET_COUNT
wolfSSL 0:9d17e4342598 472 #else
wolfSSL 0:9d17e4342598 473 #if !defined(CYASSL_MICROCHIP_PIC32MZ)
wolfSSL 0:9d17e4342598 474 #include <peripheral/timer.h>
wolfSSL 0:9d17e4342598 475 #endif
wolfSSL 0:9d17e4342598 476 #define PIC32_SEED_COUNT ReadCoreTimer
wolfSSL 0:9d17e4342598 477 #endif
wolfSSL 0:9d17e4342598 478 #ifdef CYASSL_MIC32MZ_RNG
wolfSSL 0:9d17e4342598 479 #include "xc.h"
wolfSSL 0:9d17e4342598 480 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 481 {
wolfSSL 0:9d17e4342598 482 int i ;
wolfSSL 0:9d17e4342598 483 byte rnd[8] ;
wolfSSL 0:9d17e4342598 484 word32 *rnd32 = (word32 *)rnd ;
wolfSSL 0:9d17e4342598 485 word32 size = sz ;
wolfSSL 0:9d17e4342598 486 byte* op = output ;
wolfSSL 0:9d17e4342598 487
wolfSSL 0:9d17e4342598 488 /* This part has to be replaced with better random seed */
wolfSSL 0:9d17e4342598 489 RNGNUMGEN1 = ReadCoreTimer();
wolfSSL 0:9d17e4342598 490 RNGPOLY1 = ReadCoreTimer();
wolfSSL 0:9d17e4342598 491 RNGPOLY2 = ReadCoreTimer();
wolfSSL 0:9d17e4342598 492 RNGNUMGEN2 = ReadCoreTimer();
wolfSSL 0:9d17e4342598 493 #ifdef DEBUG_CYASSL
wolfSSL 0:9d17e4342598 494 printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ;
wolfSSL 0:9d17e4342598 495 #endif
wolfSSL 0:9d17e4342598 496 RNGCONbits.PLEN = 0x40;
wolfSSL 0:9d17e4342598 497 RNGCONbits.PRNGEN = 1;
wolfSSL 0:9d17e4342598 498 for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
wolfSSL 0:9d17e4342598 499 volatile int x ;
wolfSSL 0:9d17e4342598 500 x = RNGNUMGEN1 ;
wolfSSL 0:9d17e4342598 501 x = RNGNUMGEN2 ;
wolfSSL 0:9d17e4342598 502 }
wolfSSL 0:9d17e4342598 503 do {
wolfSSL 0:9d17e4342598 504 rnd32[0] = RNGNUMGEN1;
wolfSSL 0:9d17e4342598 505 rnd32[1] = RNGNUMGEN2;
wolfSSL 0:9d17e4342598 506
wolfSSL 0:9d17e4342598 507 for(i=0; i<8; i++, op++) {
wolfSSL 0:9d17e4342598 508 *op = rnd[i] ;
wolfSSL 0:9d17e4342598 509 size -- ;
wolfSSL 0:9d17e4342598 510 if(size==0)break ;
wolfSSL 0:9d17e4342598 511 }
wolfSSL 0:9d17e4342598 512 } while(size) ;
wolfSSL 0:9d17e4342598 513 return 0;
wolfSSL 0:9d17e4342598 514 }
wolfSSL 0:9d17e4342598 515 #else /* CYASSL_MIC32MZ_RNG */
wolfSSL 0:9d17e4342598 516 /* uses the core timer, in nanoseconds to seed srand */
wolfSSL 0:9d17e4342598 517 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 518 {
wolfSSL 0:9d17e4342598 519 int i;
wolfSSL 0:9d17e4342598 520 srand(PIC32_SEED_COUNT() * 25);
wolfSSL 0:9d17e4342598 521
wolfSSL 0:9d17e4342598 522 for (i = 0; i < sz; i++ ) {
wolfSSL 0:9d17e4342598 523 output[i] = rand() % 256;
wolfSSL 0:9d17e4342598 524 if ( (i % 8) == 7)
wolfSSL 0:9d17e4342598 525 srand(PIC32_SEED_COUNT() * 25);
wolfSSL 0:9d17e4342598 526 }
wolfSSL 0:9d17e4342598 527 return 0;
wolfSSL 0:9d17e4342598 528 }
wolfSSL 0:9d17e4342598 529 #endif /* CYASSL_MIC32MZ_RNG */
wolfSSL 0:9d17e4342598 530
wolfSSL 0:9d17e4342598 531 #elif defined(FREESCALE_MQX)
wolfSSL 0:9d17e4342598 532
wolfSSL 0:9d17e4342598 533 #ifdef FREESCALE_K70_RNGA
wolfSSL 0:9d17e4342598 534 /*
wolfSSL 0:9d17e4342598 535 * Generates a RNG seed using the Random Number Generator Accelerator
wolfSSL 0:9d17e4342598 536 * on the Kinetis K70. Documentation located in Chapter 37 of
wolfSSL 0:9d17e4342598 537 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
wolfSSL 0:9d17e4342598 538 */
wolfSSL 0:9d17e4342598 539 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 540 {
wolfSSL 0:9d17e4342598 541 int i;
wolfSSL 0:9d17e4342598 542
wolfSSL 0:9d17e4342598 543 /* turn on RNGA module */
wolfSSL 0:9d17e4342598 544 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
wolfSSL 0:9d17e4342598 545
wolfSSL 0:9d17e4342598 546 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
wolfSSL 0:9d17e4342598 547 RNG_CR &= ~RNG_CR_SLP_MASK;
wolfSSL 0:9d17e4342598 548
wolfSSL 0:9d17e4342598 549 /* set HA bit to 1 - "security violations masked" */
wolfSSL 0:9d17e4342598 550 RNG_CR |= RNG_CR_HA_MASK;
wolfSSL 0:9d17e4342598 551
wolfSSL 0:9d17e4342598 552 /* set GO bit to 1 - "output register loaded with data" */
wolfSSL 0:9d17e4342598 553 RNG_CR |= RNG_CR_GO_MASK;
wolfSSL 0:9d17e4342598 554
wolfSSL 0:9d17e4342598 555 for (i = 0; i < sz; i++) {
wolfSSL 0:9d17e4342598 556
wolfSSL 0:9d17e4342598 557 /* wait for RNG FIFO to be full */
wolfSSL 0:9d17e4342598 558 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
wolfSSL 0:9d17e4342598 559
wolfSSL 0:9d17e4342598 560 /* get value */
wolfSSL 0:9d17e4342598 561 output[i] = RNG_OR;
wolfSSL 0:9d17e4342598 562 }
wolfSSL 0:9d17e4342598 563
wolfSSL 0:9d17e4342598 564 return 0;
wolfSSL 0:9d17e4342598 565 }
wolfSSL 0:9d17e4342598 566
wolfSSL 0:9d17e4342598 567 #elif defined(FREESCALE_K53_RNGB)
wolfSSL 0:9d17e4342598 568 /*
wolfSSL 0:9d17e4342598 569 * Generates a RNG seed using the Random Number Generator (RNGB)
wolfSSL 0:9d17e4342598 570 * on the Kinetis K53. Documentation located in Chapter 33 of
wolfSSL 0:9d17e4342598 571 * K53 Sub-Family Reference Manual (see note in the README for link).
wolfSSL 0:9d17e4342598 572 */
wolfSSL 0:9d17e4342598 573 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 574 {
wolfSSL 0:9d17e4342598 575 int i;
wolfSSL 0:9d17e4342598 576
wolfSSL 0:9d17e4342598 577 /* turn on RNGB module */
wolfSSL 0:9d17e4342598 578 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
wolfSSL 0:9d17e4342598 579
wolfSSL 0:9d17e4342598 580 /* reset RNGB */
wolfSSL 0:9d17e4342598 581 RNG_CMD |= RNG_CMD_SR_MASK;
wolfSSL 0:9d17e4342598 582
wolfSSL 0:9d17e4342598 583 /* FIFO generate interrupt, return all zeros on underflow,
wolfSSL 0:9d17e4342598 584 * set auto reseed */
wolfSSL 0:9d17e4342598 585 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
wolfSSL 0:9d17e4342598 586
wolfSSL 0:9d17e4342598 587 /* gen seed, clear interrupts, clear errors */
wolfSSL 0:9d17e4342598 588 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
wolfSSL 0:9d17e4342598 589
wolfSSL 0:9d17e4342598 590 /* wait for seeding to complete */
wolfSSL 0:9d17e4342598 591 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
wolfSSL 0:9d17e4342598 592
wolfSSL 0:9d17e4342598 593 for (i = 0; i < sz; i++) {
wolfSSL 0:9d17e4342598 594
wolfSSL 0:9d17e4342598 595 /* wait for a word to be available from FIFO */
wolfSSL 0:9d17e4342598 596 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
wolfSSL 0:9d17e4342598 597
wolfSSL 0:9d17e4342598 598 /* get value */
wolfSSL 0:9d17e4342598 599 output[i] = RNG_OUT;
wolfSSL 0:9d17e4342598 600 }
wolfSSL 0:9d17e4342598 601
wolfSSL 0:9d17e4342598 602 return 0;
wolfSSL 0:9d17e4342598 603 }
wolfSSL 0:9d17e4342598 604
wolfSSL 0:9d17e4342598 605 #else
wolfSSL 0:9d17e4342598 606 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 0:9d17e4342598 607
wolfSSL 0:9d17e4342598 608 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 609 {
wolfSSL 0:9d17e4342598 610 int i;
wolfSSL 0:9d17e4342598 611 for (i = 0; i < sz; i++ )
wolfSSL 0:9d17e4342598 612 output[i] = i;
wolfSSL 0:9d17e4342598 613
wolfSSL 0:9d17e4342598 614 return 0;
wolfSSL 0:9d17e4342598 615 }
wolfSSL 0:9d17e4342598 616 #endif /* FREESCALE_K70_RNGA */
wolfSSL 0:9d17e4342598 617
wolfSSL 0:9d17e4342598 618 #elif defined(CYASSL_SAFERTOS) || defined(CYASSL_LEANPSK) \
wolfSSL 0:9d17e4342598 619 || defined(CYASSL_IAR_ARM)
wolfSSL 0:9d17e4342598 620
wolfSSL 0:9d17e4342598 621 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 0:9d17e4342598 622
wolfSSL 0:9d17e4342598 623 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 624 {
wolfSSL 0:9d17e4342598 625 word32 i;
wolfSSL 0:9d17e4342598 626 for (i = 0; i < sz; i++ )
wolfSSL 0:9d17e4342598 627 output[i] = i;
wolfSSL 0:9d17e4342598 628
wolfSSL 0:9d17e4342598 629 (void)os;
wolfSSL 0:9d17e4342598 630
wolfSSL 0:9d17e4342598 631 return 0;
wolfSSL 0:9d17e4342598 632 }
wolfSSL 0:9d17e4342598 633
wolfSSL 0:9d17e4342598 634 #elif defined(STM32F2_RNG)
wolfSSL 0:9d17e4342598 635 #undef RNG
wolfSSL 0:9d17e4342598 636 #include "stm32f2xx_rng.h"
wolfSSL 0:9d17e4342598 637 #include "stm32f2xx_rcc.h"
wolfSSL 0:9d17e4342598 638 /*
wolfSSL 0:9d17e4342598 639 * Generate a RNG seed using the hardware random number generator
wolfSSL 0:9d17e4342598 640 * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
wolfSSL 0:9d17e4342598 641 * Library document (See note in README).
wolfSSL 0:9d17e4342598 642 */
wolfSSL 0:9d17e4342598 643 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 644 {
wolfSSL 0:9d17e4342598 645 int i;
wolfSSL 0:9d17e4342598 646
wolfSSL 0:9d17e4342598 647 /* enable RNG clock source */
wolfSSL 0:9d17e4342598 648 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
wolfSSL 0:9d17e4342598 649
wolfSSL 0:9d17e4342598 650 /* enable RNG peripheral */
wolfSSL 0:9d17e4342598 651 RNG_Cmd(ENABLE);
wolfSSL 0:9d17e4342598 652
wolfSSL 0:9d17e4342598 653 for (i = 0; i < sz; i++) {
wolfSSL 0:9d17e4342598 654 /* wait until RNG number is ready */
wolfSSL 0:9d17e4342598 655 while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
wolfSSL 0:9d17e4342598 656
wolfSSL 0:9d17e4342598 657 /* get value */
wolfSSL 0:9d17e4342598 658 output[i] = RNG_GetRandomNumber();
wolfSSL 0:9d17e4342598 659 }
wolfSSL 0:9d17e4342598 660
wolfSSL 0:9d17e4342598 661 return 0;
wolfSSL 0:9d17e4342598 662 }
wolfSSL 0:9d17e4342598 663 #elif defined(CYASSL_LPC43xx) || defined(CYASSL_STM32F2xx)
wolfSSL 0:9d17e4342598 664
wolfSSL 0:9d17e4342598 665 #warning "write a real random seed!!!!, just for testing now"
wolfSSL 0:9d17e4342598 666
wolfSSL 0:9d17e4342598 667 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 668 {
wolfSSL 0:9d17e4342598 669 int i;
wolfSSL 0:9d17e4342598 670
wolfSSL 0:9d17e4342598 671 for (i = 0; i < sz; i++ )
wolfSSL 0:9d17e4342598 672 output[i] = i;
wolfSSL 0:9d17e4342598 673
wolfSSL 0:9d17e4342598 674 return 0;
wolfSSL 0:9d17e4342598 675 }
wolfSSL 0:9d17e4342598 676
wolfSSL 0:9d17e4342598 677 #elif defined(CUSTOM_RAND_GENERATE)
wolfSSL 0:9d17e4342598 678
wolfSSL 0:9d17e4342598 679 /* Implement your own random generation function
wolfSSL 0:9d17e4342598 680 * word32 rand_gen(void);
wolfSSL 0:9d17e4342598 681 * #define CUSTOM_RAND_GENERATE rand_gen */
wolfSSL 0:9d17e4342598 682
wolfSSL 0:9d17e4342598 683 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 684 {
wolfSSL 0:9d17e4342598 685 int i;
wolfSSL 0:9d17e4342598 686
wolfSSL 0:9d17e4342598 687 for (i = 0; i < sz; i++ )
wolfSSL 0:9d17e4342598 688 output[i] = CUSTOM_RAND_GENERATE();
wolfSSL 0:9d17e4342598 689
wolfSSL 0:9d17e4342598 690 return 0;
wolfSSL 0:9d17e4342598 691 }
wolfSSL 0:9d17e4342598 692
wolfSSL 0:9d17e4342598 693 #elif defined(NO_DEV_RANDOM)
wolfSSL 0:9d17e4342598 694
wolfSSL 0:9d17e4342598 695 #error "you need to write an os specific GenerateSeed() here"
wolfSSL 0:9d17e4342598 696
wolfSSL 0:9d17e4342598 697 /*
wolfSSL 0:9d17e4342598 698 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 699 {
wolfSSL 0:9d17e4342598 700 return 0;
wolfSSL 0:9d17e4342598 701 }
wolfSSL 0:9d17e4342598 702 */
wolfSSL 0:9d17e4342598 703
wolfSSL 0:9d17e4342598 704
wolfSSL 0:9d17e4342598 705 #else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */
wolfSSL 0:9d17e4342598 706
wolfSSL 0:9d17e4342598 707
wolfSSL 0:9d17e4342598 708 /* may block */
wolfSSL 0:9d17e4342598 709 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
wolfSSL 0:9d17e4342598 710 {
wolfSSL 0:9d17e4342598 711 int ret = 0;
wolfSSL 0:9d17e4342598 712
wolfSSL 0:9d17e4342598 713 os->fd = open("/dev/urandom",O_RDONLY);
wolfSSL 0:9d17e4342598 714 if (os->fd == -1) {
wolfSSL 0:9d17e4342598 715 /* may still have /dev/random */
wolfSSL 0:9d17e4342598 716 os->fd = open("/dev/random",O_RDONLY);
wolfSSL 0:9d17e4342598 717 if (os->fd == -1)
wolfSSL 0:9d17e4342598 718 return OPEN_RAN_E;
wolfSSL 0:9d17e4342598 719 }
wolfSSL 0:9d17e4342598 720
wolfSSL 0:9d17e4342598 721 while (sz) {
wolfSSL 0:9d17e4342598 722 int len = (int)read(os->fd, output, sz);
wolfSSL 0:9d17e4342598 723 if (len == -1) {
wolfSSL 0:9d17e4342598 724 ret = READ_RAN_E;
wolfSSL 0:9d17e4342598 725 break;
wolfSSL 0:9d17e4342598 726 }
wolfSSL 0:9d17e4342598 727
wolfSSL 0:9d17e4342598 728 sz -= len;
wolfSSL 0:9d17e4342598 729 output += len;
wolfSSL 0:9d17e4342598 730
wolfSSL 0:9d17e4342598 731 if (sz) {
wolfSSL 0:9d17e4342598 732 #ifdef BLOCKING
wolfSSL 0:9d17e4342598 733 sleep(0); /* context switch */
wolfSSL 0:9d17e4342598 734 #else
wolfSSL 0:9d17e4342598 735 ret = RAN_BLOCK_E;
wolfSSL 0:9d17e4342598 736 break;
wolfSSL 0:9d17e4342598 737 #endif
wolfSSL 0:9d17e4342598 738 }
wolfSSL 0:9d17e4342598 739 }
wolfSSL 0:9d17e4342598 740 close(os->fd);
wolfSSL 0:9d17e4342598 741
wolfSSL 0:9d17e4342598 742 return ret;
wolfSSL 0:9d17e4342598 743 }
wolfSSL 0:9d17e4342598 744
wolfSSL 0:9d17e4342598 745 #endif /* USE_WINDOWS_API */
wolfSSL 0:9d17e4342598 746