A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Vanger
Date:
Mon Jan 19 21:45:42 2015 +0000
Revision:
0:b86d15c6ba29
Updated CyaSSL Library to 3.3.0. Changed Settings and functions to be implemented for mbed platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* random.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 */
Vanger 0:b86d15c6ba29 21
Vanger 0:b86d15c6ba29 22 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 23 #include <config.h>
Vanger 0:b86d15c6ba29 24 #endif
Vanger 0:b86d15c6ba29 25
Vanger 0:b86d15c6ba29 26 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 27
Vanger 0:b86d15c6ba29 28 /* on HPUX 11 you may need to install /dev/random see
Vanger 0:b86d15c6ba29 29 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
Vanger 0:b86d15c6ba29 30
Vanger 0:b86d15c6ba29 31 */
Vanger 0:b86d15c6ba29 32
Vanger 0:b86d15c6ba29 33 #ifdef HAVE_FIPS
Vanger 0:b86d15c6ba29 34 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
Vanger 0:b86d15c6ba29 35 #define FIPS_NO_WRAPPERS
Vanger 0:b86d15c6ba29 36 #endif
Vanger 0:b86d15c6ba29 37
Vanger 0:b86d15c6ba29 38 #include <cyassl/ctaocrypt/random.h>
Vanger 0:b86d15c6ba29 39 #include <cyassl/ctaocrypt/error-crypt.h>
Vanger 0:b86d15c6ba29 40
Vanger 0:b86d15c6ba29 41 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
Vanger 0:b86d15c6ba29 42
Vanger 0:b86d15c6ba29 43 #include <cyassl/ctaocrypt/sha256.h>
Vanger 0:b86d15c6ba29 44
Vanger 0:b86d15c6ba29 45 #ifdef NO_INLINE
Vanger 0:b86d15c6ba29 46 #include <cyassl/ctaocrypt/misc.h>
Vanger 0:b86d15c6ba29 47 #else
Vanger 0:b86d15c6ba29 48 #include <ctaocrypt/src/misc.c>
Vanger 0:b86d15c6ba29 49 #endif
Vanger 0:b86d15c6ba29 50 #endif /* HAVE_HASHDRBG || NO_RC4 */
Vanger 0:b86d15c6ba29 51
Vanger 0:b86d15c6ba29 52 #if defined(USE_WINDOWS_API)
Vanger 0:b86d15c6ba29 53 #ifndef _WIN32_WINNT
Vanger 0:b86d15c6ba29 54 #define _WIN32_WINNT 0x0400
Vanger 0:b86d15c6ba29 55 #endif
Vanger 0:b86d15c6ba29 56 #include <windows.h>
Vanger 0:b86d15c6ba29 57 #include <wincrypt.h>
Vanger 0:b86d15c6ba29 58 #else
Vanger 0:b86d15c6ba29 59 #if !defined(NO_DEV_RANDOM) && !defined(CYASSL_MDK_ARM) \
Vanger 0:b86d15c6ba29 60 && !defined(CYASSL_IAR_ARM)
Vanger 0:b86d15c6ba29 61 #include <fcntl.h>
Vanger 0:b86d15c6ba29 62 #ifndef EBSNET
Vanger 0:b86d15c6ba29 63 #include <unistd.h>
Vanger 0:b86d15c6ba29 64 #endif
Vanger 0:b86d15c6ba29 65 #else
Vanger 0:b86d15c6ba29 66 /* include headers that may be needed to get good seed */
Vanger 0:b86d15c6ba29 67 #endif
Vanger 0:b86d15c6ba29 68 #endif /* USE_WINDOWS_API */
Vanger 0:b86d15c6ba29 69
Vanger 0:b86d15c6ba29 70
Vanger 0:b86d15c6ba29 71 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73 /* Start NIST DRBG code */
Vanger 0:b86d15c6ba29 74
Vanger 0:b86d15c6ba29 75 #define OUTPUT_BLOCK_LEN (SHA256_DIGEST_SIZE)
Vanger 0:b86d15c6ba29 76 #define MAX_REQUEST_LEN (0x10000)
Vanger 0:b86d15c6ba29 77 #define RESEED_INTERVAL (1000000)
Vanger 0:b86d15c6ba29 78 #define SECURITY_STRENGTH (256)
Vanger 0:b86d15c6ba29 79 #define ENTROPY_SZ (SECURITY_STRENGTH/8)
Vanger 0:b86d15c6ba29 80 #define NONCE_SZ (ENTROPY_SZ/2)
Vanger 0:b86d15c6ba29 81 #define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
Vanger 0:b86d15c6ba29 82
Vanger 0:b86d15c6ba29 83 /* Internal return codes */
Vanger 0:b86d15c6ba29 84 #define DRBG_SUCCESS 0
Vanger 0:b86d15c6ba29 85 #define DRBG_ERROR 1
Vanger 0:b86d15c6ba29 86 #define DRBG_FAILURE 2
Vanger 0:b86d15c6ba29 87 #define DRBG_NEED_RESEED 3
Vanger 0:b86d15c6ba29 88 #define DRBG_CONT_FAILURE 4
Vanger 0:b86d15c6ba29 89
Vanger 0:b86d15c6ba29 90 /* RNG health states */
Vanger 0:b86d15c6ba29 91 #define DRBG_NOT_INIT 0
Vanger 0:b86d15c6ba29 92 #define DRBG_OK 1
Vanger 0:b86d15c6ba29 93 #define DRBG_FAILED 2
Vanger 0:b86d15c6ba29 94 #define DRBG_CONT_FAILED 3
Vanger 0:b86d15c6ba29 95
Vanger 0:b86d15c6ba29 96
Vanger 0:b86d15c6ba29 97 enum {
Vanger 0:b86d15c6ba29 98 drbgInitC = 0,
Vanger 0:b86d15c6ba29 99 drbgReseed = 1,
Vanger 0:b86d15c6ba29 100 drbgGenerateW = 2,
Vanger 0:b86d15c6ba29 101 drbgGenerateH = 3,
Vanger 0:b86d15c6ba29 102 drbgInitV
Vanger 0:b86d15c6ba29 103 };
Vanger 0:b86d15c6ba29 104
Vanger 0:b86d15c6ba29 105
Vanger 0:b86d15c6ba29 106 typedef struct DRBG {
Vanger 0:b86d15c6ba29 107 Sha256 sha;
Vanger 0:b86d15c6ba29 108 byte digest[SHA256_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 109 byte V[DRBG_SEED_LEN];
Vanger 0:b86d15c6ba29 110 byte C[DRBG_SEED_LEN];
Vanger 0:b86d15c6ba29 111 word32 reseedCtr;
Vanger 0:b86d15c6ba29 112 word32 lastBlock;
Vanger 0:b86d15c6ba29 113 byte matchCount;
Vanger 0:b86d15c6ba29 114 } DRBG;
Vanger 0:b86d15c6ba29 115
Vanger 0:b86d15c6ba29 116
Vanger 0:b86d15c6ba29 117 /* Hash Derivation Function */
Vanger 0:b86d15c6ba29 118 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
Vanger 0:b86d15c6ba29 119 static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
Vanger 0:b86d15c6ba29 120 const byte* inA, word32 inASz,
Vanger 0:b86d15c6ba29 121 const byte* inB, word32 inBSz)
Vanger 0:b86d15c6ba29 122 {
Vanger 0:b86d15c6ba29 123 byte ctr;
Vanger 0:b86d15c6ba29 124 int i;
Vanger 0:b86d15c6ba29 125 int len;
Vanger 0:b86d15c6ba29 126 word32 bits = (outSz * 8); /* reverse byte order */
Vanger 0:b86d15c6ba29 127
Vanger 0:b86d15c6ba29 128 #ifdef LITTLE_ENDIAN_ORDER
Vanger 0:b86d15c6ba29 129 bits = ByteReverseWord32(bits);
Vanger 0:b86d15c6ba29 130 #endif
Vanger 0:b86d15c6ba29 131 len = (outSz / OUTPUT_BLOCK_LEN)
Vanger 0:b86d15c6ba29 132 + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
Vanger 0:b86d15c6ba29 133
Vanger 0:b86d15c6ba29 134 for (i = 0, ctr = 1; i < len; i++, ctr++)
Vanger 0:b86d15c6ba29 135 {
Vanger 0:b86d15c6ba29 136 if (InitSha256(&drbg->sha) != 0)
Vanger 0:b86d15c6ba29 137 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 138
Vanger 0:b86d15c6ba29 139 if (Sha256Update(&drbg->sha, &ctr, sizeof(ctr)) != 0)
Vanger 0:b86d15c6ba29 140 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 141
Vanger 0:b86d15c6ba29 142 if (Sha256Update(&drbg->sha, (byte*)&bits, sizeof(bits)) != 0)
Vanger 0:b86d15c6ba29 143 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 144
Vanger 0:b86d15c6ba29 145 /* churning V is the only string that doesn't have
Vanger 0:b86d15c6ba29 146 * the type added */
Vanger 0:b86d15c6ba29 147 if (type != drbgInitV)
Vanger 0:b86d15c6ba29 148 if (Sha256Update(&drbg->sha, &type, sizeof(type)) != 0)
Vanger 0:b86d15c6ba29 149 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 150
Vanger 0:b86d15c6ba29 151 if (Sha256Update(&drbg->sha, inA, inASz) != 0)
Vanger 0:b86d15c6ba29 152 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 153
Vanger 0:b86d15c6ba29 154 if (inB != NULL && inBSz > 0)
Vanger 0:b86d15c6ba29 155 if (Sha256Update(&drbg->sha, inB, inBSz) != 0)
Vanger 0:b86d15c6ba29 156 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 157
Vanger 0:b86d15c6ba29 158 if (Sha256Final(&drbg->sha, drbg->digest) != 0)
Vanger 0:b86d15c6ba29 159 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 160
Vanger 0:b86d15c6ba29 161 if (outSz > OUTPUT_BLOCK_LEN) {
Vanger 0:b86d15c6ba29 162 XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN);
Vanger 0:b86d15c6ba29 163 outSz -= OUTPUT_BLOCK_LEN;
Vanger 0:b86d15c6ba29 164 out += OUTPUT_BLOCK_LEN;
Vanger 0:b86d15c6ba29 165 }
Vanger 0:b86d15c6ba29 166 else {
Vanger 0:b86d15c6ba29 167 XMEMCPY(out, drbg->digest, outSz);
Vanger 0:b86d15c6ba29 168 }
Vanger 0:b86d15c6ba29 169 }
Vanger 0:b86d15c6ba29 170
Vanger 0:b86d15c6ba29 171 return DRBG_SUCCESS;
Vanger 0:b86d15c6ba29 172 }
Vanger 0:b86d15c6ba29 173
Vanger 0:b86d15c6ba29 174
Vanger 0:b86d15c6ba29 175 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
Vanger 0:b86d15c6ba29 176 static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
Vanger 0:b86d15c6ba29 177 {
Vanger 0:b86d15c6ba29 178 byte seed[DRBG_SEED_LEN];
Vanger 0:b86d15c6ba29 179
Vanger 0:b86d15c6ba29 180 if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
Vanger 0:b86d15c6ba29 181 entropy, entropySz) != DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 182 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 183 }
Vanger 0:b86d15c6ba29 184
Vanger 0:b86d15c6ba29 185 XMEMCPY(drbg->V, seed, sizeof(drbg->V));
Vanger 0:b86d15c6ba29 186 XMEMSET(seed, 0, sizeof(seed));
Vanger 0:b86d15c6ba29 187
Vanger 0:b86d15c6ba29 188 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
Vanger 0:b86d15c6ba29 189 sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 190 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 191 }
Vanger 0:b86d15c6ba29 192
Vanger 0:b86d15c6ba29 193 drbg->reseedCtr = 1;
Vanger 0:b86d15c6ba29 194 drbg->lastBlock = 0;
Vanger 0:b86d15c6ba29 195 drbg->matchCount = 0;
Vanger 0:b86d15c6ba29 196 return DRBG_SUCCESS;
Vanger 0:b86d15c6ba29 197 }
Vanger 0:b86d15c6ba29 198
Vanger 0:b86d15c6ba29 199 static INLINE void array_add_one(byte* data, word32 dataSz)
Vanger 0:b86d15c6ba29 200 {
Vanger 0:b86d15c6ba29 201 int i;
Vanger 0:b86d15c6ba29 202
Vanger 0:b86d15c6ba29 203 for (i = dataSz - 1; i >= 0; i--)
Vanger 0:b86d15c6ba29 204 {
Vanger 0:b86d15c6ba29 205 data[i]++;
Vanger 0:b86d15c6ba29 206 if (data[i] != 0) break;
Vanger 0:b86d15c6ba29 207 }
Vanger 0:b86d15c6ba29 208 }
Vanger 0:b86d15c6ba29 209
Vanger 0:b86d15c6ba29 210
Vanger 0:b86d15c6ba29 211 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
Vanger 0:b86d15c6ba29 212 static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
Vanger 0:b86d15c6ba29 213 {
Vanger 0:b86d15c6ba29 214 byte data[DRBG_SEED_LEN];
Vanger 0:b86d15c6ba29 215 int i;
Vanger 0:b86d15c6ba29 216 int len;
Vanger 0:b86d15c6ba29 217 word32 checkBlock;
Vanger 0:b86d15c6ba29 218
Vanger 0:b86d15c6ba29 219 /* Special case: outSz is 0 and out is NULL. Generate a block to save for
Vanger 0:b86d15c6ba29 220 * the continuous test. */
Vanger 0:b86d15c6ba29 221
Vanger 0:b86d15c6ba29 222 if (outSz == 0) outSz = 1;
Vanger 0:b86d15c6ba29 223
Vanger 0:b86d15c6ba29 224 len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
Vanger 0:b86d15c6ba29 225
Vanger 0:b86d15c6ba29 226 XMEMCPY(data, V, sizeof(data));
Vanger 0:b86d15c6ba29 227 for (i = 0; i < len; i++) {
Vanger 0:b86d15c6ba29 228 if (InitSha256(&drbg->sha) != 0 ||
Vanger 0:b86d15c6ba29 229 Sha256Update(&drbg->sha, data, sizeof(data)) != 0 ||
Vanger 0:b86d15c6ba29 230 Sha256Final(&drbg->sha, drbg->digest) != 0) {
Vanger 0:b86d15c6ba29 231
Vanger 0:b86d15c6ba29 232 return DRBG_FAILURE;
Vanger 0:b86d15c6ba29 233 }
Vanger 0:b86d15c6ba29 234
Vanger 0:b86d15c6ba29 235 checkBlock = *(word32*)drbg->digest;
Vanger 0:b86d15c6ba29 236 if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
Vanger 0:b86d15c6ba29 237 if (drbg->matchCount == 1) {
Vanger 0:b86d15c6ba29 238 return DRBG_CONT_FAILURE;
Vanger 0:b86d15c6ba29 239 }
Vanger 0:b86d15c6ba29 240 else {
Vanger 0:b86d15c6ba29 241 if (i == len) {
Vanger 0:b86d15c6ba29 242 len++;
Vanger 0:b86d15c6ba29 243 }
Vanger 0:b86d15c6ba29 244 drbg->matchCount = 1;
Vanger 0:b86d15c6ba29 245 }
Vanger 0:b86d15c6ba29 246 }
Vanger 0:b86d15c6ba29 247 else {
Vanger 0:b86d15c6ba29 248 drbg->matchCount = 0;
Vanger 0:b86d15c6ba29 249 drbg->lastBlock = checkBlock;
Vanger 0:b86d15c6ba29 250 }
Vanger 0:b86d15c6ba29 251
Vanger 0:b86d15c6ba29 252 if (outSz >= OUTPUT_BLOCK_LEN) {
Vanger 0:b86d15c6ba29 253 XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN);
Vanger 0:b86d15c6ba29 254 outSz -= OUTPUT_BLOCK_LEN;
Vanger 0:b86d15c6ba29 255 out += OUTPUT_BLOCK_LEN;
Vanger 0:b86d15c6ba29 256 array_add_one(data, DRBG_SEED_LEN);
Vanger 0:b86d15c6ba29 257 }
Vanger 0:b86d15c6ba29 258 else if (out != NULL && outSz != 0) {
Vanger 0:b86d15c6ba29 259 XMEMCPY(out, drbg->digest, outSz);
Vanger 0:b86d15c6ba29 260 outSz = 0;
Vanger 0:b86d15c6ba29 261 }
Vanger 0:b86d15c6ba29 262 }
Vanger 0:b86d15c6ba29 263 XMEMSET(data, 0, sizeof(data));
Vanger 0:b86d15c6ba29 264
Vanger 0:b86d15c6ba29 265 return DRBG_SUCCESS;
Vanger 0:b86d15c6ba29 266 }
Vanger 0:b86d15c6ba29 267
Vanger 0:b86d15c6ba29 268
Vanger 0:b86d15c6ba29 269 static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
Vanger 0:b86d15c6ba29 270 {
Vanger 0:b86d15c6ba29 271 word16 carry = 0;
Vanger 0:b86d15c6ba29 272
Vanger 0:b86d15c6ba29 273 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
Vanger 0:b86d15c6ba29 274 int sIdx, dIdx;
Vanger 0:b86d15c6ba29 275
Vanger 0:b86d15c6ba29 276 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
Vanger 0:b86d15c6ba29 277 {
Vanger 0:b86d15c6ba29 278 carry += d[dIdx] + s[sIdx];
Vanger 0:b86d15c6ba29 279 d[dIdx] = carry;
Vanger 0:b86d15c6ba29 280 carry >>= 8;
Vanger 0:b86d15c6ba29 281 }
Vanger 0:b86d15c6ba29 282
Vanger 0:b86d15c6ba29 283 for (; carry != 0 && dIdx >= 0; dIdx--) {
Vanger 0:b86d15c6ba29 284 carry += d[dIdx];
Vanger 0:b86d15c6ba29 285 d[dIdx] = carry;
Vanger 0:b86d15c6ba29 286 carry >>= 8;
Vanger 0:b86d15c6ba29 287 }
Vanger 0:b86d15c6ba29 288 }
Vanger 0:b86d15c6ba29 289 }
Vanger 0:b86d15c6ba29 290
Vanger 0:b86d15c6ba29 291
Vanger 0:b86d15c6ba29 292 /* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
Vanger 0:b86d15c6ba29 293 static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
Vanger 0:b86d15c6ba29 294 {
Vanger 0:b86d15c6ba29 295 int ret = DRBG_NEED_RESEED;
Vanger 0:b86d15c6ba29 296
Vanger 0:b86d15c6ba29 297 if (drbg->reseedCtr != RESEED_INTERVAL) {
Vanger 0:b86d15c6ba29 298 byte type = drbgGenerateH;
Vanger 0:b86d15c6ba29 299 word32 reseedCtr = drbg->reseedCtr;
Vanger 0:b86d15c6ba29 300
Vanger 0:b86d15c6ba29 301 ret = Hash_gen(drbg, out, outSz, drbg->V);
Vanger 0:b86d15c6ba29 302 if (ret == DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 303 if (InitSha256(&drbg->sha) != 0 ||
Vanger 0:b86d15c6ba29 304 Sha256Update(&drbg->sha, &type, sizeof(type)) != 0 ||
Vanger 0:b86d15c6ba29 305 Sha256Update(&drbg->sha, drbg->V, sizeof(drbg->V)) != 0 ||
Vanger 0:b86d15c6ba29 306 Sha256Final(&drbg->sha, drbg->digest) != 0) {
Vanger 0:b86d15c6ba29 307
Vanger 0:b86d15c6ba29 308 ret = DRBG_FAILURE;
Vanger 0:b86d15c6ba29 309 }
Vanger 0:b86d15c6ba29 310 else {
Vanger 0:b86d15c6ba29 311 array_add(drbg->V, sizeof(drbg->V),
Vanger 0:b86d15c6ba29 312 drbg->digest, sizeof(drbg->digest));
Vanger 0:b86d15c6ba29 313 array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
Vanger 0:b86d15c6ba29 314 #ifdef LITTLE_ENDIAN_ORDER
Vanger 0:b86d15c6ba29 315 reseedCtr = ByteReverseWord32(reseedCtr);
Vanger 0:b86d15c6ba29 316 #endif
Vanger 0:b86d15c6ba29 317 array_add(drbg->V, sizeof(drbg->V),
Vanger 0:b86d15c6ba29 318 (byte*)&reseedCtr, sizeof(reseedCtr));
Vanger 0:b86d15c6ba29 319 ret = DRBG_SUCCESS;
Vanger 0:b86d15c6ba29 320 }
Vanger 0:b86d15c6ba29 321 drbg->reseedCtr++;
Vanger 0:b86d15c6ba29 322 }
Vanger 0:b86d15c6ba29 323 }
Vanger 0:b86d15c6ba29 324
Vanger 0:b86d15c6ba29 325 return ret;
Vanger 0:b86d15c6ba29 326 }
Vanger 0:b86d15c6ba29 327
Vanger 0:b86d15c6ba29 328
Vanger 0:b86d15c6ba29 329 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
Vanger 0:b86d15c6ba29 330 static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
Vanger 0:b86d15c6ba29 331 const byte* nonce, word32 nonceSz)
Vanger 0:b86d15c6ba29 332 {
Vanger 0:b86d15c6ba29 333 int ret = DRBG_FAILURE;
Vanger 0:b86d15c6ba29 334
Vanger 0:b86d15c6ba29 335 XMEMSET(drbg, 0, sizeof(DRBG));
Vanger 0:b86d15c6ba29 336
Vanger 0:b86d15c6ba29 337 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
Vanger 0:b86d15c6ba29 338 nonce, nonceSz) == DRBG_SUCCESS &&
Vanger 0:b86d15c6ba29 339 Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
Vanger 0:b86d15c6ba29 340 sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 341
Vanger 0:b86d15c6ba29 342 drbg->reseedCtr = 1;
Vanger 0:b86d15c6ba29 343 drbg->lastBlock = 0;
Vanger 0:b86d15c6ba29 344 drbg->matchCount = 0;
Vanger 0:b86d15c6ba29 345 ret = DRBG_SUCCESS;
Vanger 0:b86d15c6ba29 346 }
Vanger 0:b86d15c6ba29 347
Vanger 0:b86d15c6ba29 348 return ret;
Vanger 0:b86d15c6ba29 349 }
Vanger 0:b86d15c6ba29 350
Vanger 0:b86d15c6ba29 351
Vanger 0:b86d15c6ba29 352 /* Returns: DRBG_SUCCESS */
Vanger 0:b86d15c6ba29 353 static int Hash_DRBG_Uninstantiate(DRBG* drbg)
Vanger 0:b86d15c6ba29 354 {
Vanger 0:b86d15c6ba29 355 XMEMSET(drbg, 0, sizeof(DRBG));
Vanger 0:b86d15c6ba29 356
Vanger 0:b86d15c6ba29 357 return DRBG_SUCCESS;
Vanger 0:b86d15c6ba29 358 }
Vanger 0:b86d15c6ba29 359
Vanger 0:b86d15c6ba29 360 /* End NIST DRBG Code */
Vanger 0:b86d15c6ba29 361
Vanger 0:b86d15c6ba29 362
Vanger 0:b86d15c6ba29 363 /* Get seed and key cipher */
Vanger 0:b86d15c6ba29 364 int InitRng(RNG* rng)
Vanger 0:b86d15c6ba29 365 {
Vanger 0:b86d15c6ba29 366 int ret = BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 367
Vanger 0:b86d15c6ba29 368 if (rng != NULL) {
Vanger 0:b86d15c6ba29 369 byte entropy[ENTROPY_NONCE_SZ];
Vanger 0:b86d15c6ba29 370
Vanger 0:b86d15c6ba29 371 rng->drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
Vanger 0:b86d15c6ba29 372 if (rng->drbg == NULL) {
Vanger 0:b86d15c6ba29 373 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 374 }
Vanger 0:b86d15c6ba29 375 /* This doesn't use a separate nonce. The entropy input will be
Vanger 0:b86d15c6ba29 376 * the default size plus the size of the nonce making the seed
Vanger 0:b86d15c6ba29 377 * size. */
Vanger 0:b86d15c6ba29 378 else if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
Vanger 0:b86d15c6ba29 379 Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
Vanger 0:b86d15c6ba29 380 NULL, 0) == DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 381
Vanger 0:b86d15c6ba29 382 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
Vanger 0:b86d15c6ba29 383 }
Vanger 0:b86d15c6ba29 384 else
Vanger 0:b86d15c6ba29 385 ret = DRBG_FAILURE;
Vanger 0:b86d15c6ba29 386
Vanger 0:b86d15c6ba29 387 XMEMSET(entropy, 0, ENTROPY_NONCE_SZ);
Vanger 0:b86d15c6ba29 388
Vanger 0:b86d15c6ba29 389 if (ret == DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 390 rng->status = DRBG_OK;
Vanger 0:b86d15c6ba29 391 ret = 0;
Vanger 0:b86d15c6ba29 392 }
Vanger 0:b86d15c6ba29 393 else if (ret == DRBG_CONT_FAILURE) {
Vanger 0:b86d15c6ba29 394 rng->status = DRBG_CONT_FAILED;
Vanger 0:b86d15c6ba29 395 ret = DRBG_CONT_FIPS_E;
Vanger 0:b86d15c6ba29 396 }
Vanger 0:b86d15c6ba29 397 else if (ret == DRBG_FAILURE) {
Vanger 0:b86d15c6ba29 398 rng->status = DRBG_FAILED;
Vanger 0:b86d15c6ba29 399 ret = RNG_FAILURE_E;
Vanger 0:b86d15c6ba29 400 }
Vanger 0:b86d15c6ba29 401 else {
Vanger 0:b86d15c6ba29 402 rng->status = DRBG_FAILED;
Vanger 0:b86d15c6ba29 403 }
Vanger 0:b86d15c6ba29 404 }
Vanger 0:b86d15c6ba29 405
Vanger 0:b86d15c6ba29 406 return ret;
Vanger 0:b86d15c6ba29 407 }
Vanger 0:b86d15c6ba29 408
Vanger 0:b86d15c6ba29 409
Vanger 0:b86d15c6ba29 410 /* place a generated block in output */
Vanger 0:b86d15c6ba29 411 int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 412 {
Vanger 0:b86d15c6ba29 413 int ret;
Vanger 0:b86d15c6ba29 414
Vanger 0:b86d15c6ba29 415 if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN)
Vanger 0:b86d15c6ba29 416 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 417
Vanger 0:b86d15c6ba29 418 if (rng->status != DRBG_OK)
Vanger 0:b86d15c6ba29 419 return RNG_FAILURE_E;
Vanger 0:b86d15c6ba29 420
Vanger 0:b86d15c6ba29 421 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
Vanger 0:b86d15c6ba29 422
Vanger 0:b86d15c6ba29 423 if (ret == DRBG_NEED_RESEED) {
Vanger 0:b86d15c6ba29 424 byte entropy[ENTROPY_SZ];
Vanger 0:b86d15c6ba29 425
Vanger 0:b86d15c6ba29 426 if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
Vanger 0:b86d15c6ba29 427 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ) == DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 428
Vanger 0:b86d15c6ba29 429 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
Vanger 0:b86d15c6ba29 430 if (ret == DRBG_SUCCESS)
Vanger 0:b86d15c6ba29 431 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
Vanger 0:b86d15c6ba29 432 }
Vanger 0:b86d15c6ba29 433 else
Vanger 0:b86d15c6ba29 434 ret = DRBG_FAILURE;
Vanger 0:b86d15c6ba29 435
Vanger 0:b86d15c6ba29 436 XMEMSET(entropy, 0, ENTROPY_SZ);
Vanger 0:b86d15c6ba29 437 }
Vanger 0:b86d15c6ba29 438
Vanger 0:b86d15c6ba29 439 if (ret == DRBG_SUCCESS) {
Vanger 0:b86d15c6ba29 440 ret = 0;
Vanger 0:b86d15c6ba29 441 }
Vanger 0:b86d15c6ba29 442 else if (ret == DRBG_CONT_FAILURE) {
Vanger 0:b86d15c6ba29 443 ret = DRBG_CONT_FIPS_E;
Vanger 0:b86d15c6ba29 444 rng->status = DRBG_CONT_FAILED;
Vanger 0:b86d15c6ba29 445 }
Vanger 0:b86d15c6ba29 446 else {
Vanger 0:b86d15c6ba29 447 ret = RNG_FAILURE_E;
Vanger 0:b86d15c6ba29 448 rng->status = DRBG_FAILED;
Vanger 0:b86d15c6ba29 449 }
Vanger 0:b86d15c6ba29 450
Vanger 0:b86d15c6ba29 451 return ret;
Vanger 0:b86d15c6ba29 452 }
Vanger 0:b86d15c6ba29 453
Vanger 0:b86d15c6ba29 454
Vanger 0:b86d15c6ba29 455 int RNG_GenerateByte(RNG* rng, byte* b)
Vanger 0:b86d15c6ba29 456 {
Vanger 0:b86d15c6ba29 457 return RNG_GenerateBlock(rng, b, 1);
Vanger 0:b86d15c6ba29 458 }
Vanger 0:b86d15c6ba29 459
Vanger 0:b86d15c6ba29 460
Vanger 0:b86d15c6ba29 461 int FreeRng(RNG* rng)
Vanger 0:b86d15c6ba29 462 {
Vanger 0:b86d15c6ba29 463 int ret = BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 464
Vanger 0:b86d15c6ba29 465 if (rng != NULL) {
Vanger 0:b86d15c6ba29 466 if (Hash_DRBG_Uninstantiate(rng->drbg) == DRBG_SUCCESS)
Vanger 0:b86d15c6ba29 467 ret = 0;
Vanger 0:b86d15c6ba29 468 else
Vanger 0:b86d15c6ba29 469 ret = RNG_FAILURE_E;
Vanger 0:b86d15c6ba29 470
Vanger 0:b86d15c6ba29 471 XFREE(rng->drbg, NULL, DYNAMIC_TYPE_RNG);
Vanger 0:b86d15c6ba29 472 rng->drbg = NULL;
Vanger 0:b86d15c6ba29 473 rng->status = DRBG_NOT_INIT;
Vanger 0:b86d15c6ba29 474 }
Vanger 0:b86d15c6ba29 475
Vanger 0:b86d15c6ba29 476 return ret;
Vanger 0:b86d15c6ba29 477 }
Vanger 0:b86d15c6ba29 478
Vanger 0:b86d15c6ba29 479
Vanger 0:b86d15c6ba29 480 int RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
Vanger 0:b86d15c6ba29 481 const byte* entropyB, word32 entropyBSz,
Vanger 0:b86d15c6ba29 482 byte* output, word32 outputSz)
Vanger 0:b86d15c6ba29 483 {
Vanger 0:b86d15c6ba29 484 DRBG drbg;
Vanger 0:b86d15c6ba29 485
Vanger 0:b86d15c6ba29 486 if (entropyA == NULL || output == NULL)
Vanger 0:b86d15c6ba29 487 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 488
Vanger 0:b86d15c6ba29 489 if (reseed != 0 && entropyB == NULL)
Vanger 0:b86d15c6ba29 490 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 491
Vanger 0:b86d15c6ba29 492 if (outputSz != (SHA256_DIGEST_SIZE * 4))
Vanger 0:b86d15c6ba29 493 return -1;
Vanger 0:b86d15c6ba29 494
Vanger 0:b86d15c6ba29 495 if (Hash_DRBG_Instantiate(&drbg, entropyA, entropyASz, NULL, 0) != 0)
Vanger 0:b86d15c6ba29 496 return -1;
Vanger 0:b86d15c6ba29 497
Vanger 0:b86d15c6ba29 498 if (reseed) {
Vanger 0:b86d15c6ba29 499 if (Hash_DRBG_Reseed(&drbg, entropyB, entropyBSz) != 0) {
Vanger 0:b86d15c6ba29 500 Hash_DRBG_Uninstantiate(&drbg);
Vanger 0:b86d15c6ba29 501 return -1;
Vanger 0:b86d15c6ba29 502 }
Vanger 0:b86d15c6ba29 503 }
Vanger 0:b86d15c6ba29 504
Vanger 0:b86d15c6ba29 505 if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
Vanger 0:b86d15c6ba29 506 Hash_DRBG_Uninstantiate(&drbg);
Vanger 0:b86d15c6ba29 507 return -1;
Vanger 0:b86d15c6ba29 508 }
Vanger 0:b86d15c6ba29 509
Vanger 0:b86d15c6ba29 510 if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
Vanger 0:b86d15c6ba29 511 Hash_DRBG_Uninstantiate(&drbg);
Vanger 0:b86d15c6ba29 512 return -1;
Vanger 0:b86d15c6ba29 513 }
Vanger 0:b86d15c6ba29 514
Vanger 0:b86d15c6ba29 515 Hash_DRBG_Uninstantiate(&drbg);
Vanger 0:b86d15c6ba29 516
Vanger 0:b86d15c6ba29 517 return 0;
Vanger 0:b86d15c6ba29 518 }
Vanger 0:b86d15c6ba29 519
Vanger 0:b86d15c6ba29 520
Vanger 0:b86d15c6ba29 521 #else /* HAVE_HASHDRBG || NO_RC4 */
Vanger 0:b86d15c6ba29 522
Vanger 0:b86d15c6ba29 523 /* Get seed and key cipher */
Vanger 0:b86d15c6ba29 524 int InitRng(RNG* rng)
Vanger 0:b86d15c6ba29 525 {
Vanger 0:b86d15c6ba29 526 int ret;
Vanger 0:b86d15c6ba29 527 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 528 byte* key;
Vanger 0:b86d15c6ba29 529 byte* junk;
Vanger 0:b86d15c6ba29 530 #else
Vanger 0:b86d15c6ba29 531 byte key[32];
Vanger 0:b86d15c6ba29 532 byte junk[256];
Vanger 0:b86d15c6ba29 533 #endif
Vanger 0:b86d15c6ba29 534
Vanger 0:b86d15c6ba29 535 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 536 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC)
Vanger 0:b86d15c6ba29 537 return 0;
Vanger 0:b86d15c6ba29 538 #endif
Vanger 0:b86d15c6ba29 539
Vanger 0:b86d15c6ba29 540 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 541 key = (byte*)XMALLOC(32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 542 if (key == NULL)
Vanger 0:b86d15c6ba29 543 return MEMORY_E;
Vanger 0:b86d15c6ba29 544
Vanger 0:b86d15c6ba29 545 junk = (byte*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 546 if (junk == NULL) {
Vanger 0:b86d15c6ba29 547 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 548 return MEMORY_E;
Vanger 0:b86d15c6ba29 549 }
Vanger 0:b86d15c6ba29 550 #endif
Vanger 0:b86d15c6ba29 551
Vanger 0:b86d15c6ba29 552 ret = GenerateSeed(&rng->seed, key, 32);
Vanger 0:b86d15c6ba29 553
Vanger 0:b86d15c6ba29 554 if (ret == 0) {
Vanger 0:b86d15c6ba29 555 Arc4SetKey(&rng->cipher, key, sizeof(key));
Vanger 0:b86d15c6ba29 556
Vanger 0:b86d15c6ba29 557 ret = RNG_GenerateBlock(rng, junk, 256); /*rid initial state*/
Vanger 0:b86d15c6ba29 558 }
Vanger 0:b86d15c6ba29 559
Vanger 0:b86d15c6ba29 560 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 561 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 562 XFREE(junk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 563 #endif
Vanger 0:b86d15c6ba29 564
Vanger 0:b86d15c6ba29 565 return ret;
Vanger 0:b86d15c6ba29 566 }
Vanger 0:b86d15c6ba29 567
Vanger 0:b86d15c6ba29 568 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 569 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz);
Vanger 0:b86d15c6ba29 570 #endif
Vanger 0:b86d15c6ba29 571
Vanger 0:b86d15c6ba29 572 /* place a generated block in output */
Vanger 0:b86d15c6ba29 573 int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 574 {
Vanger 0:b86d15c6ba29 575 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 576 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC)
Vanger 0:b86d15c6ba29 577 return CaviumRNG_GenerateBlock(rng, output, sz);
Vanger 0:b86d15c6ba29 578 #endif
Vanger 0:b86d15c6ba29 579 XMEMSET(output, 0, sz);
Vanger 0:b86d15c6ba29 580 Arc4Process(&rng->cipher, output, output, sz);
Vanger 0:b86d15c6ba29 581
Vanger 0:b86d15c6ba29 582 return 0;
Vanger 0:b86d15c6ba29 583 }
Vanger 0:b86d15c6ba29 584
Vanger 0:b86d15c6ba29 585
Vanger 0:b86d15c6ba29 586 int RNG_GenerateByte(RNG* rng, byte* b)
Vanger 0:b86d15c6ba29 587 {
Vanger 0:b86d15c6ba29 588 return RNG_GenerateBlock(rng, b, 1);
Vanger 0:b86d15c6ba29 589 }
Vanger 0:b86d15c6ba29 590
Vanger 0:b86d15c6ba29 591
Vanger 0:b86d15c6ba29 592 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 593
Vanger 0:b86d15c6ba29 594 #include <cyassl/ctaocrypt/logging.h>
Vanger 0:b86d15c6ba29 595 #include "cavium_common.h"
Vanger 0:b86d15c6ba29 596
Vanger 0:b86d15c6ba29 597 /* Initiliaze RNG for use with Nitrox device */
Vanger 0:b86d15c6ba29 598 int InitRngCavium(RNG* rng, int devId)
Vanger 0:b86d15c6ba29 599 {
Vanger 0:b86d15c6ba29 600 if (rng == NULL)
Vanger 0:b86d15c6ba29 601 return -1;
Vanger 0:b86d15c6ba29 602
Vanger 0:b86d15c6ba29 603 rng->devId = devId;
Vanger 0:b86d15c6ba29 604 rng->magic = CYASSL_RNG_CAVIUM_MAGIC;
Vanger 0:b86d15c6ba29 605
Vanger 0:b86d15c6ba29 606 return 0;
Vanger 0:b86d15c6ba29 607 }
Vanger 0:b86d15c6ba29 608
Vanger 0:b86d15c6ba29 609
Vanger 0:b86d15c6ba29 610 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 611 {
Vanger 0:b86d15c6ba29 612 cyassl_word offset = 0;
Vanger 0:b86d15c6ba29 613 word32 requestId;
Vanger 0:b86d15c6ba29 614
Vanger 0:b86d15c6ba29 615 while (sz > CYASSL_MAX_16BIT) {
Vanger 0:b86d15c6ba29 616 word16 slen = (word16)CYASSL_MAX_16BIT;
Vanger 0:b86d15c6ba29 617 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
Vanger 0:b86d15c6ba29 618 rng->devId) != 0) {
Vanger 0:b86d15c6ba29 619 CYASSL_MSG("Cavium RNG failed");
Vanger 0:b86d15c6ba29 620 }
Vanger 0:b86d15c6ba29 621 sz -= CYASSL_MAX_16BIT;
Vanger 0:b86d15c6ba29 622 offset += CYASSL_MAX_16BIT;
Vanger 0:b86d15c6ba29 623 }
Vanger 0:b86d15c6ba29 624 if (sz) {
Vanger 0:b86d15c6ba29 625 word16 slen = (word16)sz;
Vanger 0:b86d15c6ba29 626 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
Vanger 0:b86d15c6ba29 627 rng->devId) != 0) {
Vanger 0:b86d15c6ba29 628 CYASSL_MSG("Cavium RNG failed");
Vanger 0:b86d15c6ba29 629 }
Vanger 0:b86d15c6ba29 630 }
Vanger 0:b86d15c6ba29 631 }
Vanger 0:b86d15c6ba29 632
Vanger 0:b86d15c6ba29 633 #endif /* HAVE_CAVIUM */
Vanger 0:b86d15c6ba29 634
Vanger 0:b86d15c6ba29 635 #endif /* HAVE_HASHDRBG || NO_RC4 */
Vanger 0:b86d15c6ba29 636
Vanger 0:b86d15c6ba29 637
Vanger 0:b86d15c6ba29 638 #if defined(USE_WINDOWS_API)
Vanger 0:b86d15c6ba29 639
Vanger 0:b86d15c6ba29 640
Vanger 0:b86d15c6ba29 641 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 642 {
Vanger 0:b86d15c6ba29 643 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
Vanger 0:b86d15c6ba29 644 CRYPT_VERIFYCONTEXT))
Vanger 0:b86d15c6ba29 645 return WINCRYPT_E;
Vanger 0:b86d15c6ba29 646
Vanger 0:b86d15c6ba29 647 if (!CryptGenRandom(os->handle, sz, output))
Vanger 0:b86d15c6ba29 648 return CRYPTGEN_E;
Vanger 0:b86d15c6ba29 649
Vanger 0:b86d15c6ba29 650 CryptReleaseContext(os->handle, 0);
Vanger 0:b86d15c6ba29 651
Vanger 0:b86d15c6ba29 652 return 0;
Vanger 0:b86d15c6ba29 653 }
Vanger 0:b86d15c6ba29 654
Vanger 0:b86d15c6ba29 655
Vanger 0:b86d15c6ba29 656 #elif defined(HAVE_RTP_SYS) || defined(EBSNET)
Vanger 0:b86d15c6ba29 657
Vanger 0:b86d15c6ba29 658 #include "rtprand.h" /* rtp_rand () */
Vanger 0:b86d15c6ba29 659 #include "rtptime.h" /* rtp_get_system_msec() */
Vanger 0:b86d15c6ba29 660
Vanger 0:b86d15c6ba29 661
Vanger 0:b86d15c6ba29 662 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 663 {
Vanger 0:b86d15c6ba29 664 int i;
Vanger 0:b86d15c6ba29 665 rtp_srand(rtp_get_system_msec());
Vanger 0:b86d15c6ba29 666
Vanger 0:b86d15c6ba29 667 for (i = 0; i < sz; i++ ) {
Vanger 0:b86d15c6ba29 668 output[i] = rtp_rand() % 256;
Vanger 0:b86d15c6ba29 669 if ( (i % 8) == 7)
Vanger 0:b86d15c6ba29 670 rtp_srand(rtp_get_system_msec());
Vanger 0:b86d15c6ba29 671 }
Vanger 0:b86d15c6ba29 672
Vanger 0:b86d15c6ba29 673 return 0;
Vanger 0:b86d15c6ba29 674 }
Vanger 0:b86d15c6ba29 675
Vanger 0:b86d15c6ba29 676
Vanger 0:b86d15c6ba29 677 #elif defined(MICRIUM)
Vanger 0:b86d15c6ba29 678
Vanger 0:b86d15c6ba29 679 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 680 {
Vanger 0:b86d15c6ba29 681 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
Vanger 0:b86d15c6ba29 682 NetSecure_InitSeed(output, sz);
Vanger 0:b86d15c6ba29 683 #endif
Vanger 0:b86d15c6ba29 684 return 0;
Vanger 0:b86d15c6ba29 685 }
Vanger 0:b86d15c6ba29 686
Vanger 0:b86d15c6ba29 687 #elif defined(MBED)
Vanger 0:b86d15c6ba29 688
Vanger 0:b86d15c6ba29 689 /* write a real one !!!, just for testing board */
Vanger 0:b86d15c6ba29 690 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 691 {
Vanger 0:b86d15c6ba29 692 int i;
Vanger 0:b86d15c6ba29 693 for (i = 0; i < sz; i++ )
Vanger 0:b86d15c6ba29 694 output[i] = i;
Vanger 0:b86d15c6ba29 695
Vanger 0:b86d15c6ba29 696 return 0;
Vanger 0:b86d15c6ba29 697 }
Vanger 0:b86d15c6ba29 698
Vanger 0:b86d15c6ba29 699 #elif defined(MICROCHIP_PIC32)
Vanger 0:b86d15c6ba29 700
Vanger 0:b86d15c6ba29 701 #ifdef MICROCHIP_MPLAB_HARMONY
Vanger 0:b86d15c6ba29 702 #define PIC32_SEED_COUNT _CP0_GET_COUNT
Vanger 0:b86d15c6ba29 703 #else
Vanger 0:b86d15c6ba29 704 #if !defined(CYASSL_MICROCHIP_PIC32MZ)
Vanger 0:b86d15c6ba29 705 #include <peripheral/timer.h>
Vanger 0:b86d15c6ba29 706 #endif
Vanger 0:b86d15c6ba29 707 #define PIC32_SEED_COUNT ReadCoreTimer
Vanger 0:b86d15c6ba29 708 #endif
Vanger 0:b86d15c6ba29 709 #ifdef CYASSL_MIC32MZ_RNG
Vanger 0:b86d15c6ba29 710 #include "xc.h"
Vanger 0:b86d15c6ba29 711 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 712 {
Vanger 0:b86d15c6ba29 713 int i ;
Vanger 0:b86d15c6ba29 714 byte rnd[8] ;
Vanger 0:b86d15c6ba29 715 word32 *rnd32 = (word32 *)rnd ;
Vanger 0:b86d15c6ba29 716 word32 size = sz ;
Vanger 0:b86d15c6ba29 717 byte* op = output ;
Vanger 0:b86d15c6ba29 718
Vanger 0:b86d15c6ba29 719 /* This part has to be replaced with better random seed */
Vanger 0:b86d15c6ba29 720 RNGNUMGEN1 = ReadCoreTimer();
Vanger 0:b86d15c6ba29 721 RNGPOLY1 = ReadCoreTimer();
Vanger 0:b86d15c6ba29 722 RNGPOLY2 = ReadCoreTimer();
Vanger 0:b86d15c6ba29 723 RNGNUMGEN2 = ReadCoreTimer();
Vanger 0:b86d15c6ba29 724 #ifdef DEBUG_CYASSL
Vanger 0:b86d15c6ba29 725 printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ;
Vanger 0:b86d15c6ba29 726 #endif
Vanger 0:b86d15c6ba29 727 RNGCONbits.PLEN = 0x40;
Vanger 0:b86d15c6ba29 728 RNGCONbits.PRNGEN = 1;
Vanger 0:b86d15c6ba29 729 for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
Vanger 0:b86d15c6ba29 730 volatile int x ;
Vanger 0:b86d15c6ba29 731 x = RNGNUMGEN1 ;
Vanger 0:b86d15c6ba29 732 x = RNGNUMGEN2 ;
Vanger 0:b86d15c6ba29 733 }
Vanger 0:b86d15c6ba29 734 do {
Vanger 0:b86d15c6ba29 735 rnd32[0] = RNGNUMGEN1;
Vanger 0:b86d15c6ba29 736 rnd32[1] = RNGNUMGEN2;
Vanger 0:b86d15c6ba29 737
Vanger 0:b86d15c6ba29 738 for(i=0; i<8; i++, op++) {
Vanger 0:b86d15c6ba29 739 *op = rnd[i] ;
Vanger 0:b86d15c6ba29 740 size -- ;
Vanger 0:b86d15c6ba29 741 if(size==0)break ;
Vanger 0:b86d15c6ba29 742 }
Vanger 0:b86d15c6ba29 743 } while(size) ;
Vanger 0:b86d15c6ba29 744 return 0;
Vanger 0:b86d15c6ba29 745 }
Vanger 0:b86d15c6ba29 746 #else /* CYASSL_MIC32MZ_RNG */
Vanger 0:b86d15c6ba29 747 /* uses the core timer, in nanoseconds to seed srand */
Vanger 0:b86d15c6ba29 748 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 749 {
Vanger 0:b86d15c6ba29 750 int i;
Vanger 0:b86d15c6ba29 751 srand(PIC32_SEED_COUNT() * 25);
Vanger 0:b86d15c6ba29 752
Vanger 0:b86d15c6ba29 753 for (i = 0; i < sz; i++ ) {
Vanger 0:b86d15c6ba29 754 output[i] = rand() % 256;
Vanger 0:b86d15c6ba29 755 if ( (i % 8) == 7)
Vanger 0:b86d15c6ba29 756 srand(PIC32_SEED_COUNT() * 25);
Vanger 0:b86d15c6ba29 757 }
Vanger 0:b86d15c6ba29 758 return 0;
Vanger 0:b86d15c6ba29 759 }
Vanger 0:b86d15c6ba29 760 #endif /* CYASSL_MIC32MZ_RNG */
Vanger 0:b86d15c6ba29 761
Vanger 0:b86d15c6ba29 762 #elif defined(FREESCALE_MQX)
Vanger 0:b86d15c6ba29 763
Vanger 0:b86d15c6ba29 764 #ifdef FREESCALE_K70_RNGA
Vanger 0:b86d15c6ba29 765 /*
Vanger 0:b86d15c6ba29 766 * Generates a RNG seed using the Random Number Generator Accelerator
Vanger 0:b86d15c6ba29 767 * on the Kinetis K70. Documentation located in Chapter 37 of
Vanger 0:b86d15c6ba29 768 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
Vanger 0:b86d15c6ba29 769 */
Vanger 0:b86d15c6ba29 770 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 771 {
Vanger 0:b86d15c6ba29 772 int i;
Vanger 0:b86d15c6ba29 773
Vanger 0:b86d15c6ba29 774 /* turn on RNGA module */
Vanger 0:b86d15c6ba29 775 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
Vanger 0:b86d15c6ba29 776
Vanger 0:b86d15c6ba29 777 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
Vanger 0:b86d15c6ba29 778 RNG_CR &= ~RNG_CR_SLP_MASK;
Vanger 0:b86d15c6ba29 779
Vanger 0:b86d15c6ba29 780 /* set HA bit to 1 - "security violations masked" */
Vanger 0:b86d15c6ba29 781 RNG_CR |= RNG_CR_HA_MASK;
Vanger 0:b86d15c6ba29 782
Vanger 0:b86d15c6ba29 783 /* set GO bit to 1 - "output register loaded with data" */
Vanger 0:b86d15c6ba29 784 RNG_CR |= RNG_CR_GO_MASK;
Vanger 0:b86d15c6ba29 785
Vanger 0:b86d15c6ba29 786 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 787
Vanger 0:b86d15c6ba29 788 /* wait for RNG FIFO to be full */
Vanger 0:b86d15c6ba29 789 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
Vanger 0:b86d15c6ba29 790
Vanger 0:b86d15c6ba29 791 /* get value */
Vanger 0:b86d15c6ba29 792 output[i] = RNG_OR;
Vanger 0:b86d15c6ba29 793 }
Vanger 0:b86d15c6ba29 794
Vanger 0:b86d15c6ba29 795 return 0;
Vanger 0:b86d15c6ba29 796 }
Vanger 0:b86d15c6ba29 797
Vanger 0:b86d15c6ba29 798 #elif defined(FREESCALE_K53_RNGB)
Vanger 0:b86d15c6ba29 799 /*
Vanger 0:b86d15c6ba29 800 * Generates a RNG seed using the Random Number Generator (RNGB)
Vanger 0:b86d15c6ba29 801 * on the Kinetis K53. Documentation located in Chapter 33 of
Vanger 0:b86d15c6ba29 802 * K53 Sub-Family Reference Manual (see note in the README for link).
Vanger 0:b86d15c6ba29 803 */
Vanger 0:b86d15c6ba29 804 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 805 {
Vanger 0:b86d15c6ba29 806 int i;
Vanger 0:b86d15c6ba29 807
Vanger 0:b86d15c6ba29 808 /* turn on RNGB module */
Vanger 0:b86d15c6ba29 809 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
Vanger 0:b86d15c6ba29 810
Vanger 0:b86d15c6ba29 811 /* reset RNGB */
Vanger 0:b86d15c6ba29 812 RNG_CMD |= RNG_CMD_SR_MASK;
Vanger 0:b86d15c6ba29 813
Vanger 0:b86d15c6ba29 814 /* FIFO generate interrupt, return all zeros on underflow,
Vanger 0:b86d15c6ba29 815 * set auto reseed */
Vanger 0:b86d15c6ba29 816 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
Vanger 0:b86d15c6ba29 817
Vanger 0:b86d15c6ba29 818 /* gen seed, clear interrupts, clear errors */
Vanger 0:b86d15c6ba29 819 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
Vanger 0:b86d15c6ba29 820
Vanger 0:b86d15c6ba29 821 /* wait for seeding to complete */
Vanger 0:b86d15c6ba29 822 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
Vanger 0:b86d15c6ba29 823
Vanger 0:b86d15c6ba29 824 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 825
Vanger 0:b86d15c6ba29 826 /* wait for a word to be available from FIFO */
Vanger 0:b86d15c6ba29 827 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
Vanger 0:b86d15c6ba29 828
Vanger 0:b86d15c6ba29 829 /* get value */
Vanger 0:b86d15c6ba29 830 output[i] = RNG_OUT;
Vanger 0:b86d15c6ba29 831 }
Vanger 0:b86d15c6ba29 832
Vanger 0:b86d15c6ba29 833 return 0;
Vanger 0:b86d15c6ba29 834 }
Vanger 0:b86d15c6ba29 835
Vanger 0:b86d15c6ba29 836 #else
Vanger 0:b86d15c6ba29 837 #warning "write a real random seed!!!!, just for testing now"
Vanger 0:b86d15c6ba29 838
Vanger 0:b86d15c6ba29 839 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 840 {
Vanger 0:b86d15c6ba29 841 int i;
Vanger 0:b86d15c6ba29 842 for (i = 0; i < sz; i++ )
Vanger 0:b86d15c6ba29 843 output[i] = i;
Vanger 0:b86d15c6ba29 844
Vanger 0:b86d15c6ba29 845 return 0;
Vanger 0:b86d15c6ba29 846 }
Vanger 0:b86d15c6ba29 847 #endif /* FREESCALE_K70_RNGA */
Vanger 0:b86d15c6ba29 848
Vanger 0:b86d15c6ba29 849 #elif defined(CYASSL_SAFERTOS) || defined(CYASSL_LEANPSK) \
Vanger 0:b86d15c6ba29 850 || defined(CYASSL_IAR_ARM) || defined(CYASSL_MDK_ARM)
Vanger 0:b86d15c6ba29 851
Vanger 0:b86d15c6ba29 852 #warning "write a real random seed!!!!, just for testing now"
Vanger 0:b86d15c6ba29 853
Vanger 0:b86d15c6ba29 854 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 855 {
Vanger 0:b86d15c6ba29 856 word32 i;
Vanger 0:b86d15c6ba29 857 for (i = 0; i < sz; i++ )
Vanger 0:b86d15c6ba29 858 output[i] = i;
Vanger 0:b86d15c6ba29 859
Vanger 0:b86d15c6ba29 860 (void)os;
Vanger 0:b86d15c6ba29 861
Vanger 0:b86d15c6ba29 862 return 0;
Vanger 0:b86d15c6ba29 863 }
Vanger 0:b86d15c6ba29 864
Vanger 0:b86d15c6ba29 865 #elif defined(STM32F2_RNG)
Vanger 0:b86d15c6ba29 866 #undef RNG
Vanger 0:b86d15c6ba29 867 #include "stm32f2xx_rng.h"
Vanger 0:b86d15c6ba29 868 #include "stm32f2xx_rcc.h"
Vanger 0:b86d15c6ba29 869 /*
Vanger 0:b86d15c6ba29 870 * Generate a RNG seed using the hardware random number generator
Vanger 0:b86d15c6ba29 871 * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
Vanger 0:b86d15c6ba29 872 * Library document (See note in README).
Vanger 0:b86d15c6ba29 873 */
Vanger 0:b86d15c6ba29 874 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 875 {
Vanger 0:b86d15c6ba29 876 int i;
Vanger 0:b86d15c6ba29 877
Vanger 0:b86d15c6ba29 878 /* enable RNG clock source */
Vanger 0:b86d15c6ba29 879 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
Vanger 0:b86d15c6ba29 880
Vanger 0:b86d15c6ba29 881 /* enable RNG peripheral */
Vanger 0:b86d15c6ba29 882 RNG_Cmd(ENABLE);
Vanger 0:b86d15c6ba29 883
Vanger 0:b86d15c6ba29 884 for (i = 0; i < sz; i++) {
Vanger 0:b86d15c6ba29 885 /* wait until RNG number is ready */
Vanger 0:b86d15c6ba29 886 while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
Vanger 0:b86d15c6ba29 887
Vanger 0:b86d15c6ba29 888 /* get value */
Vanger 0:b86d15c6ba29 889 output[i] = RNG_GetRandomNumber();
Vanger 0:b86d15c6ba29 890 }
Vanger 0:b86d15c6ba29 891
Vanger 0:b86d15c6ba29 892 return 0;
Vanger 0:b86d15c6ba29 893 }
Vanger 0:b86d15c6ba29 894 #elif defined(CYASSL_LPC43xx) || defined(CYASSL_STM32F2xx)
Vanger 0:b86d15c6ba29 895
Vanger 0:b86d15c6ba29 896 #warning "write a real random seed!!!!, just for testing now"
Vanger 0:b86d15c6ba29 897
Vanger 0:b86d15c6ba29 898 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 899 {
Vanger 0:b86d15c6ba29 900 int i;
Vanger 0:b86d15c6ba29 901
Vanger 0:b86d15c6ba29 902 for (i = 0; i < sz; i++ )
Vanger 0:b86d15c6ba29 903 output[i] = i;
Vanger 0:b86d15c6ba29 904
Vanger 0:b86d15c6ba29 905 return 0;
Vanger 0:b86d15c6ba29 906 }
Vanger 0:b86d15c6ba29 907
Vanger 0:b86d15c6ba29 908 #elif defined(CYASSL_TIRTOS)
Vanger 0:b86d15c6ba29 909
Vanger 0:b86d15c6ba29 910 #include <xdc/runtime/Timestamp.h>
Vanger 0:b86d15c6ba29 911 #include <stdlib.h>
Vanger 0:b86d15c6ba29 912 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 913 {
Vanger 0:b86d15c6ba29 914 int i;
Vanger 0:b86d15c6ba29 915 srand(xdc_runtime_Timestamp_get32());
Vanger 0:b86d15c6ba29 916
Vanger 0:b86d15c6ba29 917 for (i = 0; i < sz; i++ ) {
Vanger 0:b86d15c6ba29 918 output[i] = rand() % 256;
Vanger 0:b86d15c6ba29 919 if ((i % 8) == 7) {
Vanger 0:b86d15c6ba29 920 srand(xdc_runtime_Timestamp_get32());
Vanger 0:b86d15c6ba29 921 }
Vanger 0:b86d15c6ba29 922 }
Vanger 0:b86d15c6ba29 923
Vanger 0:b86d15c6ba29 924 return 0;
Vanger 0:b86d15c6ba29 925 }
Vanger 0:b86d15c6ba29 926
Vanger 0:b86d15c6ba29 927 #elif defined(CUSTOM_RAND_GENERATE)
Vanger 0:b86d15c6ba29 928
Vanger 0:b86d15c6ba29 929 /* Implement your own random generation function
Vanger 0:b86d15c6ba29 930 * word32 rand_gen(void);
Vanger 0:b86d15c6ba29 931 * #define CUSTOM_RAND_GENERATE rand_gen */
Vanger 0:b86d15c6ba29 932
Vanger 0:b86d15c6ba29 933 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 934 {
Vanger 0:b86d15c6ba29 935 int i;
Vanger 0:b86d15c6ba29 936
Vanger 0:b86d15c6ba29 937 for (i = 0; i < sz; i++ )
Vanger 0:b86d15c6ba29 938 output[i] = CUSTOM_RAND_GENERATE();
Vanger 0:b86d15c6ba29 939
Vanger 0:b86d15c6ba29 940 return 0;
Vanger 0:b86d15c6ba29 941 }
Vanger 0:b86d15c6ba29 942
Vanger 0:b86d15c6ba29 943 #elif defined(NO_DEV_RANDOM)
Vanger 0:b86d15c6ba29 944
Vanger 0:b86d15c6ba29 945 #error "you need to write an os specific GenerateSeed() here"
Vanger 0:b86d15c6ba29 946
Vanger 0:b86d15c6ba29 947 /*
Vanger 0:b86d15c6ba29 948 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 949 {
Vanger 0:b86d15c6ba29 950 return 0;
Vanger 0:b86d15c6ba29 951 }
Vanger 0:b86d15c6ba29 952 */
Vanger 0:b86d15c6ba29 953
Vanger 0:b86d15c6ba29 954
Vanger 0:b86d15c6ba29 955 #else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */
Vanger 0:b86d15c6ba29 956
Vanger 0:b86d15c6ba29 957
Vanger 0:b86d15c6ba29 958 /* may block */
Vanger 0:b86d15c6ba29 959 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
Vanger 0:b86d15c6ba29 960 {
Vanger 0:b86d15c6ba29 961 int ret = 0;
Vanger 0:b86d15c6ba29 962
Vanger 0:b86d15c6ba29 963 os->fd = open("/dev/urandom",O_RDONLY);
Vanger 0:b86d15c6ba29 964 if (os->fd == -1) {
Vanger 0:b86d15c6ba29 965 /* may still have /dev/random */
Vanger 0:b86d15c6ba29 966 os->fd = open("/dev/random",O_RDONLY);
Vanger 0:b86d15c6ba29 967 if (os->fd == -1)
Vanger 0:b86d15c6ba29 968 return OPEN_RAN_E;
Vanger 0:b86d15c6ba29 969 }
Vanger 0:b86d15c6ba29 970
Vanger 0:b86d15c6ba29 971 while (sz) {
Vanger 0:b86d15c6ba29 972 int len = (int)read(os->fd, output, sz);
Vanger 0:b86d15c6ba29 973 if (len == -1) {
Vanger 0:b86d15c6ba29 974 ret = READ_RAN_E;
Vanger 0:b86d15c6ba29 975 break;
Vanger 0:b86d15c6ba29 976 }
Vanger 0:b86d15c6ba29 977
Vanger 0:b86d15c6ba29 978 sz -= len;
Vanger 0:b86d15c6ba29 979 output += len;
Vanger 0:b86d15c6ba29 980
Vanger 0:b86d15c6ba29 981 if (sz) {
Vanger 0:b86d15c6ba29 982 #ifdef BLOCKING
Vanger 0:b86d15c6ba29 983 sleep(0); /* context switch */
Vanger 0:b86d15c6ba29 984 #else
Vanger 0:b86d15c6ba29 985 ret = RAN_BLOCK_E;
Vanger 0:b86d15c6ba29 986 break;
Vanger 0:b86d15c6ba29 987 #endif
Vanger 0:b86d15c6ba29 988 }
Vanger 0:b86d15c6ba29 989 }
Vanger 0:b86d15c6ba29 990 close(os->fd);
Vanger 0:b86d15c6ba29 991
Vanger 0:b86d15c6ba29 992 return ret;
Vanger 0:b86d15c6ba29 993 }
Vanger 0:b86d15c6ba29 994
Vanger 0:b86d15c6ba29 995 #endif /* USE_WINDOWS_API */
Vanger 0:b86d15c6ba29 996