cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

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