comparison libtomcrypt/src/prngs/fortuna.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children e9dba7abd939
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
3 * LibTomCrypt is a library that provides various cryptographic 3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtom.org
10 */ 8 */
11 #include "tomcrypt.h" 9 #include "tomcrypt.h"
12 10
13 /** 11 /**
14 @file fortuna.c 12 @file fortuna.c
15 Fortuna PRNG, Tom St Denis 13 Fortuna PRNG, Tom St Denis
16 */ 14 */
17 15
18 /* Implementation of Fortuna by Tom St Denis 16 /* Implementation of Fortuna by Tom St Denis
19 17
20 We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources" 18 We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources"
21 in the AddEntropy function are fixed to 0. Second since no reliable timer is provided 19 in the AddEntropy function are fixed to 0. Second since no reliable timer is provided
22 we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */ 20 we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */
23 21
24 #ifdef LTC_FORTUNA 22 #ifdef LTC_FORTUNA
25 23
26 /* requries LTC_SHA256 and AES */ 24 /* requries LTC_SHA256 and AES */
27 #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256)) 25 #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256))
28 #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES) 26 #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES)
29 #endif 27 #endif
36 #if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32 34 #if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32
37 #error LTC_FORTUNA_POOLS must be in [4..32] 35 #error LTC_FORTUNA_POOLS must be in [4..32]
38 #endif 36 #endif
39 37
40 const struct ltc_prng_descriptor fortuna_desc = { 38 const struct ltc_prng_descriptor fortuna_desc = {
41 "fortuna", 1024, 39 "fortuna",
40 (32 * LTC_FORTUNA_POOLS), /* default: 1024 */
42 &fortuna_start, 41 &fortuna_start,
43 &fortuna_add_entropy, 42 &fortuna_add_entropy,
44 &fortuna_ready, 43 &fortuna_ready,
45 &fortuna_read, 44 &fortuna_read,
46 &fortuna_done, 45 &fortuna_done,
48 &fortuna_import, 47 &fortuna_import,
49 &fortuna_test 48 &fortuna_test
50 }; 49 };
51 50
52 /* update the IV */ 51 /* update the IV */
53 static void fortuna_update_iv(prng_state *prng) 52 static void _fortuna_update_iv(prng_state *prng)
54 { 53 {
55 int x; 54 int x;
56 unsigned char *IV; 55 unsigned char *IV;
57 /* update IV */ 56 /* update IV */
58 IV = prng->fortuna.IV; 57 IV = prng->fortuna.IV;
61 if (IV[x] != 0) break; 60 if (IV[x] != 0) break;
62 } 61 }
63 } 62 }
64 63
65 /* reseed the PRNG */ 64 /* reseed the PRNG */
66 static int fortuna_reseed(prng_state *prng) 65 static int _fortuna_reseed(prng_state *prng)
67 { 66 {
68 unsigned char tmp[MAXBLOCKSIZE]; 67 unsigned char tmp[MAXBLOCKSIZE];
69 hash_state md; 68 hash_state md;
70 int err, x; 69 int err, x;
71 70
77 sha256_done(&md, tmp); 76 sha256_done(&md, tmp);
78 return err; 77 return err;
79 } 78 }
80 79
81 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 80 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
82 if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { 81 if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) {
83 /* terminate this hash */ 82 /* terminate this hash */
84 if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { 83 if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) {
85 sha256_done(&md, tmp); 84 sha256_done(&md, tmp);
86 return err; 85 return err;
87 } 86 }
88 /* add it to the string */ 87 /* add it to the string */
89 if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) { 88 if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) {
90 sha256_done(&md, tmp); 89 sha256_done(&md, tmp);
91 return err; 90 return err;
100 } 99 }
101 } 100 }
102 101
103 /* finish key */ 102 /* finish key */
104 if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { 103 if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) {
105 return err; 104 return err;
106 } 105 }
107 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { 106 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) {
108 return err; 107 return err;
109 } 108 }
110 fortuna_update_iv(prng); 109 _fortuna_update_iv(prng);
111 110
112 /* reset pool len */ 111 /* reset pool len */
113 prng->fortuna.pool0_len = 0; 112 prng->fortuna.pool0_len = 0;
114 prng->fortuna.wd = 0; 113 prng->fortuna.wd = 0;
115 114
124 123
125 /** 124 /**
126 Start the PRNG 125 Start the PRNG
127 @param prng [out] The PRNG state to initialize 126 @param prng [out] The PRNG state to initialize
128 @return CRYPT_OK if successful 127 @return CRYPT_OK if successful
129 */ 128 */
130 int fortuna_start(prng_state *prng) 129 int fortuna_start(prng_state *prng)
131 { 130 {
132 int err, x, y; 131 int err, x, y;
133 unsigned char tmp[MAXBLOCKSIZE]; 132 unsigned char tmp[MAXBLOCKSIZE];
134 133
135 LTC_ARGCHK(prng != NULL); 134 LTC_ARGCHK(prng != NULL);
136 135 prng->ready = 0;
136
137 /* initialize the pools */ 137 /* initialize the pools */
138 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 138 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
139 if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { 139 if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) {
140 for (y = 0; y < x; y++) { 140 for (y = 0; y < x; y++) {
141 sha256_done(&prng->fortuna.pool[y], tmp); 141 sha256_done(&prng->fortuna.pool[y], tmp);
153 sha256_done(&prng->fortuna.pool[x], tmp); 153 sha256_done(&prng->fortuna.pool[x], tmp);
154 } 154 }
155 return err; 155 return err;
156 } 156 }
157 zeromem(prng->fortuna.IV, 16); 157 zeromem(prng->fortuna.IV, 16);
158 158
159 LTC_MUTEX_INIT(&prng->fortuna.prng_lock) 159 LTC_MUTEX_INIT(&prng->lock)
160 160
161 return CRYPT_OK; 161 return CRYPT_OK;
162 } 162 }
163 163
164 /** 164 /**
165 Add entropy to the PRNG state 165 Add entropy to the PRNG state
166 @param in The data to add 166 @param in The data to add
167 @param inlen Length of the data to add 167 @param inlen Length of the data to add
168 @param prng PRNG state to update 168 @param prng PRNG state to update
169 @return CRYPT_OK if successful 169 @return CRYPT_OK if successful
170 */ 170 */
171 int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) 171 int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
172 { 172 {
173 unsigned char tmp[2]; 173 unsigned char tmp[2];
174 int err; 174 int err;
175 175
176 LTC_ARGCHK(in != NULL);
177 LTC_ARGCHK(prng != NULL); 176 LTC_ARGCHK(prng != NULL);
178 177 LTC_ARGCHK(in != NULL);
179 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); 178 LTC_ARGCHK(inlen > 0);
180 179
181 /* ensure inlen <= 32 */ 180 /* ensure inlen <= 32 */
182 if (inlen > 32) { 181 if (inlen > 32) {
183 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 182 inlen = 32;
184 return CRYPT_INVALID_ARG;
185 } 183 }
186 184
187 /* add s || length(in) || in to pool[pool_idx] */ 185 /* add s || length(in) || in to pool[pool_idx] */
188 tmp[0] = 0; 186 tmp[0] = 0;
189 tmp[1] = (unsigned char)inlen; 187 tmp[1] = (unsigned char)inlen;
188
189 LTC_MUTEX_LOCK(&prng->lock);
190 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) { 190 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) {
191 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 191 goto LBL_UNLOCK;
192 return err;
193 } 192 }
194 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) { 193 if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) {
195 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 194 goto LBL_UNLOCK;
196 return err;
197 } 195 }
198 if (prng->fortuna.pool_idx == 0) { 196 if (prng->fortuna.pool_idx == 0) {
199 prng->fortuna.pool0_len += inlen; 197 prng->fortuna.pool0_len += inlen;
200 } 198 }
201 if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) { 199 if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) {
202 prng->fortuna.pool_idx = 0; 200 prng->fortuna.pool_idx = 0;
203 } 201 }
204 202 err = CRYPT_OK; /* success */
205 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 203
206 return CRYPT_OK; 204 LBL_UNLOCK:
205 LTC_MUTEX_UNLOCK(&prng->lock);
206 return err;
207 } 207 }
208 208
209 /** 209 /**
210 Make the PRNG ready to read from 210 Make the PRNG ready to read from
211 @param prng The PRNG to make active 211 @param prng The PRNG to make active
212 @return CRYPT_OK if successful 212 @return CRYPT_OK if successful
213 */ 213 */
214 int fortuna_ready(prng_state *prng) 214 int fortuna_ready(prng_state *prng)
215 { 215 {
216 return fortuna_reseed(prng); 216 int err;
217 LTC_ARGCHK(prng != NULL);
218
219 LTC_MUTEX_LOCK(&prng->lock);
220 err = _fortuna_reseed(prng);
221 prng->ready = (err == CRYPT_OK) ? 1 : 0;
222
223 LTC_MUTEX_UNLOCK(&prng->lock);
224 return err;
217 } 225 }
218 226
219 /** 227 /**
220 Read from the PRNG 228 Read from the PRNG
221 @param out Destination 229 @param out Destination
222 @param outlen Length of output 230 @param outlen Length of output
223 @param prng The active PRNG to read from 231 @param prng The active PRNG to read from
224 @return Number of octets read 232 @return Number of octets read
225 */ 233 */
226 unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng) 234 unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng)
227 { 235 {
228 unsigned char tmp[16]; 236 unsigned char tmp[16];
229 int err; 237 unsigned long tlen = 0;
230 unsigned long tlen; 238
231 239 if (outlen == 0 || prng == NULL || out == NULL) return 0;
232 LTC_ARGCHK(out != NULL); 240
233 LTC_ARGCHK(prng != NULL); 241 LTC_MUTEX_LOCK(&prng->lock);
234 242
235 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); 243 if (!prng->ready) {
244 goto LBL_UNLOCK;
245 }
236 246
237 /* do we have to reseed? */ 247 /* do we have to reseed? */
238 if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) { 248 if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) {
239 if ((err = fortuna_reseed(prng)) != CRYPT_OK) { 249 if (_fortuna_reseed(prng) != CRYPT_OK) {
240 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 250 goto LBL_UNLOCK;
241 return 0;
242 } 251 }
243 } 252 }
244 253
245 /* now generate the blocks required */ 254 /* now generate the blocks required */
246 tlen = outlen; 255 tlen = outlen;
249 while (outlen >= 16) { 258 while (outlen >= 16) {
250 /* encrypt the IV and store it */ 259 /* encrypt the IV and store it */
251 rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey); 260 rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey);
252 out += 16; 261 out += 16;
253 outlen -= 16; 262 outlen -= 16;
254 fortuna_update_iv(prng); 263 _fortuna_update_iv(prng);
255 } 264 }
256 265
257 /* left over bytes? */ 266 /* left over bytes? */
258 if (outlen > 0) { 267 if (outlen > 0) {
259 rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey); 268 rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey);
260 XMEMCPY(out, tmp, outlen); 269 XMEMCPY(out, tmp, outlen);
261 fortuna_update_iv(prng); 270 _fortuna_update_iv(prng);
262 } 271 }
263 272
264 /* generate new key */ 273 /* generate new key */
265 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); fortuna_update_iv(prng); 274 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey);
266 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); fortuna_update_iv(prng); 275 _fortuna_update_iv(prng);
267 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { 276
268 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 277 rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey);
269 return 0; 278 _fortuna_update_iv(prng);
270 } 279
271 280 if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) {
281 tlen = 0;
282 }
283
284 LBL_UNLOCK:
272 #ifdef LTC_CLEAN_STACK 285 #ifdef LTC_CLEAN_STACK
273 zeromem(tmp, sizeof(tmp)); 286 zeromem(tmp, sizeof(tmp));
274 #endif 287 #endif
275 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 288 LTC_MUTEX_UNLOCK(&prng->lock);
276 return tlen; 289 return tlen;
277 } 290 }
278 291
279 /** 292 /**
280 Terminate the PRNG 293 Terminate the PRNG
281 @param prng The PRNG to terminate 294 @param prng The PRNG to terminate
282 @return CRYPT_OK if successful 295 @return CRYPT_OK if successful
283 */ 296 */
284 int fortuna_done(prng_state *prng) 297 int fortuna_done(prng_state *prng)
285 { 298 {
286 int err, x; 299 int err, x;
287 unsigned char tmp[32]; 300 unsigned char tmp[32];
288 301
289 LTC_ARGCHK(prng != NULL); 302 LTC_ARGCHK(prng != NULL);
290 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); 303
304 LTC_MUTEX_LOCK(&prng->lock);
305 prng->ready = 0;
291 306
292 /* terminate all the hashes */ 307 /* terminate all the hashes */
293 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 308 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
294 if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { 309 if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) {
295 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 310 goto LBL_UNLOCK;
296 return err;
297 } 311 }
298 } 312 }
299 /* call cipher done when we invent one ;-) */ 313 /* call cipher done when we invent one ;-) */
300 314 err = CRYPT_OK; /* success */
315
316 LBL_UNLOCK:
301 #ifdef LTC_CLEAN_STACK 317 #ifdef LTC_CLEAN_STACK
302 zeromem(tmp, sizeof(tmp)); 318 zeromem(tmp, sizeof(tmp));
303 #endif 319 #endif
304 320 LTC_MUTEX_UNLOCK(&prng->lock);
305 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 321 LTC_MUTEX_DESTROY(&prng->lock);
306 return CRYPT_OK; 322 return err;
307 } 323 }
308 324
309 /** 325 /**
310 Export the PRNG state 326 Export the PRNG state
311 @param out [out] Destination 327 @param out [out] Destination
312 @param outlen [in/out] Max size and resulting size of the state 328 @param outlen [in/out] Max size and resulting size of the state
313 @param prng The PRNG to export 329 @param prng The PRNG to export
314 @return CRYPT_OK if successful 330 @return CRYPT_OK if successful
315 */ 331 */
316 int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) 332 int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
317 { 333 {
318 int x, err; 334 int x, err;
319 hash_state *md; 335 hash_state *md;
336 unsigned long len = fortuna_desc.export_size;
320 337
321 LTC_ARGCHK(out != NULL); 338 LTC_ARGCHK(out != NULL);
322 LTC_ARGCHK(outlen != NULL); 339 LTC_ARGCHK(outlen != NULL);
323 LTC_ARGCHK(prng != NULL); 340 LTC_ARGCHK(prng != NULL);
324 341
325 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); 342 LTC_MUTEX_LOCK(&prng->lock);
343
344 if (!prng->ready) {
345 err = CRYPT_ERROR;
346 goto LBL_UNLOCK;
347 }
326 348
327 /* we'll write bytes for s&g's */ 349 /* we'll write bytes for s&g's */
328 if (*outlen < 32*LTC_FORTUNA_POOLS) { 350 if (*outlen < len) {
329 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 351 *outlen = len;
330 *outlen = 32*LTC_FORTUNA_POOLS; 352 err = CRYPT_BUFFER_OVERFLOW;
331 return CRYPT_BUFFER_OVERFLOW; 353 goto LBL_UNLOCK;
332 } 354 }
333 355
334 md = XMALLOC(sizeof(hash_state)); 356 md = XMALLOC(sizeof(hash_state));
335 if (md == NULL) { 357 if (md == NULL) {
336 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 358 err = CRYPT_MEM;
337 return CRYPT_MEM; 359 goto LBL_UNLOCK;
338 } 360 }
339 361
340 /* to emit the state we copy each pool, terminate it then hash it again so 362 /* to emit the state we copy each pool, terminate it then hash it again so
341 * an attacker who sees the state can't determine the current state of the PRNG 363 * an attacker who sees the state can't determine the current state of the PRNG
342 */ 364 */
343 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 365 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
344 /* copy the PRNG */ 366 /* copy the PRNG */
345 XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); 367 XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md));
346 368
347 /* terminate it */ 369 /* terminate it */
358 } 380 }
359 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { 381 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) {
360 goto LBL_ERR; 382 goto LBL_ERR;
361 } 383 }
362 } 384 }
363 *outlen = 32*LTC_FORTUNA_POOLS; 385 *outlen = len;
364 err = CRYPT_OK; 386 err = CRYPT_OK;
365 387
366 LBL_ERR: 388 LBL_ERR:
367 #ifdef LTC_CLEAN_STACK 389 #ifdef LTC_CLEAN_STACK
368 zeromem(md, sizeof(*md)); 390 zeromem(md, sizeof(*md));
369 #endif 391 #endif
370 XFREE(md); 392 XFREE(md);
371 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); 393 LBL_UNLOCK:
394 LTC_MUTEX_UNLOCK(&prng->lock);
372 return err; 395 return err;
373 } 396 }
374 397
375 /** 398 /**
376 Import a PRNG state 399 Import a PRNG state
377 @param in The PRNG state 400 @param in The PRNG state
378 @param inlen Size of the state 401 @param inlen Size of the state
379 @param prng The PRNG to import 402 @param prng The PRNG to import
380 @return CRYPT_OK if successful 403 @return CRYPT_OK if successful
381 */ 404 */
382 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) 405 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
383 { 406 {
384 int err, x; 407 int err, x;
385 408
386 LTC_ARGCHK(in != NULL); 409 LTC_ARGCHK(in != NULL);
387 LTC_ARGCHK(prng != NULL); 410 LTC_ARGCHK(prng != NULL);
388 411
389 if (inlen != 32*LTC_FORTUNA_POOLS) { 412 if (inlen < (unsigned long)fortuna_desc.export_size) {
390 return CRYPT_INVALID_ARG; 413 return CRYPT_INVALID_ARG;
391 } 414 }
392 415
393 if ((err = fortuna_start(prng)) != CRYPT_OK) { 416 if ((err = fortuna_start(prng)) != CRYPT_OK) {
394 return err; 417 return err;
396 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 419 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
397 if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { 420 if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) {
398 return err; 421 return err;
399 } 422 }
400 } 423 }
401 return err; 424 return CRYPT_OK;
402 } 425 }
403 426
404 /** 427 /**
405 PRNG self-test 428 PRNG self-test
406 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled 429 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
407 */ 430 */
408 int fortuna_test(void) 431 int fortuna_test(void)
409 { 432 {
410 #ifndef LTC_TEST 433 #ifndef LTC_TEST
411 return CRYPT_NOP; 434 return CRYPT_NOP;
412 #else 435 #else
420 } 443 }
421 444
422 #endif 445 #endif
423 446
424 447
425 /* $Source$ */ 448 /* ref: $Format:%D$ */
426 /* $Revision$ */ 449 /* git commit: $Format:%H$ */
427 /* $Date$ */ 450 /* commit time: $Format:%ai$ */