Mercurial > dropbear
comparison libtomcrypt/src/prngs/fortuna.c @ 1435:f849a5ca2efc
update to libtomcrypt 1.17 (with Dropbear changes)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 24 Jun 2017 17:50:50 +0800 |
parents | 0cbe8f6dbf9e |
children | 6dba84798cd5 |
comparison
equal
deleted
inserted
replaced
1434:27b9ddb06b09 | 1435:f849a5ca2efc |
---|---|
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 * | 8 * |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | 9 * Tom St Denis, [email protected], http://libtom.org |
10 */ | 10 */ |
11 #include "tomcrypt.h" | 11 #include "tomcrypt.h" |
12 | 12 |
13 /** | 13 /** |
14 @file fortuna.c | 14 @file fortuna.c |
17 | 17 |
18 /* Implementation of Fortuna by Tom St Denis | 18 /* Implementation of Fortuna by Tom St Denis |
19 | 19 |
20 We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources" | 20 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 | 21 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 FORTUNA_WD calls to the read function */ | 22 we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */ |
23 | 23 |
24 #ifdef FORTUNA | 24 #ifdef LTC_FORTUNA |
25 | 25 |
26 /* requries SHA256 and AES */ | 26 /* requries LTC_SHA256 and AES */ |
27 #if !(defined(RIJNDAEL) && defined(SHA256)) | 27 #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256)) |
28 #error FORTUNA requires SHA256 and RIJNDAEL (AES) | 28 #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES) |
29 #endif | 29 #endif |
30 | 30 |
31 #ifndef FORTUNA_POOLS | 31 #ifndef LTC_FORTUNA_POOLS |
32 #warning FORTUNA_POOLS was not previously defined (old headers?) | 32 #warning LTC_FORTUNA_POOLS was not previously defined (old headers?) |
33 #define FORTUNA_POOLS 32 | 33 #define LTC_FORTUNA_POOLS 32 |
34 #endif | 34 #endif |
35 | 35 |
36 #if FORTUNA_POOLS < 4 || FORTUNA_POOLS > 32 | 36 #if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32 |
37 #error FORTUNA_POOLS must be in [4..32] | 37 #error LTC_FORTUNA_POOLS must be in [4..32] |
38 #endif | 38 #endif |
39 | 39 |
40 const struct ltc_prng_descriptor fortuna_desc = { | 40 const struct ltc_prng_descriptor fortuna_desc = { |
41 "fortuna", 1024, | 41 "fortuna", 1024, |
42 &fortuna_start, | 42 &fortuna_start, |
69 hash_state md; | 69 hash_state md; |
70 int err, x; | 70 int err, x; |
71 | 71 |
72 ++prng->fortuna.reset_cnt; | 72 ++prng->fortuna.reset_cnt; |
73 | 73 |
74 /* new K == SHA256(K || s) where s == SHA256(P0) || SHA256(P1) ... */ | 74 /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ |
75 sha256_init(&md); | 75 sha256_init(&md); |
76 if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { | 76 if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { |
77 sha256_done(&md, tmp); | 77 sha256_done(&md, tmp); |
78 return err; | 78 return err; |
79 } | 79 } |
80 | 80 |
81 for (x = 0; x < FORTUNA_POOLS; x++) { | 81 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
82 if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { | 82 if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { |
83 /* terminate this hash */ | 83 /* terminate this hash */ |
84 if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { | 84 if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { |
85 sha256_done(&md, tmp); | 85 sha256_done(&md, tmp); |
86 return err; | 86 return err; |
133 unsigned char tmp[MAXBLOCKSIZE]; | 133 unsigned char tmp[MAXBLOCKSIZE]; |
134 | 134 |
135 LTC_ARGCHK(prng != NULL); | 135 LTC_ARGCHK(prng != NULL); |
136 | 136 |
137 /* initialize the pools */ | 137 /* initialize the pools */ |
138 for (x = 0; x < 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); |
142 } | 142 } |
143 return err; | 143 return err; |
147 prng->fortuna.reset_cnt = 0; | 147 prng->fortuna.reset_cnt = 0; |
148 | 148 |
149 /* reset bufs */ | 149 /* reset bufs */ |
150 zeromem(prng->fortuna.K, 32); | 150 zeromem(prng->fortuna.K, 32); |
151 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { | 151 if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { |
152 for (x = 0; x < FORTUNA_POOLS; x++) { | 152 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
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); |
196 return err; | 196 return err; |
197 } | 197 } |
198 if (prng->fortuna.pool_idx == 0) { | 198 if (prng->fortuna.pool_idx == 0) { |
199 prng->fortuna.pool0_len += inlen; | 199 prng->fortuna.pool0_len += inlen; |
200 } | 200 } |
201 if (++(prng->fortuna.pool_idx) == FORTUNA_POOLS) { | 201 if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) { |
202 prng->fortuna.pool_idx = 0; | 202 prng->fortuna.pool_idx = 0; |
203 } | 203 } |
204 | 204 |
205 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); | 205 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
206 return CRYPT_OK; | 206 return CRYPT_OK; |
233 LTC_ARGCHK(prng != NULL); | 233 LTC_ARGCHK(prng != NULL); |
234 | 234 |
235 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); | 235 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); |
236 | 236 |
237 /* do we have to reseed? */ | 237 /* do we have to reseed? */ |
238 if (++prng->fortuna.wd == FORTUNA_WD || prng->fortuna.pool0_len >= 64) { | 238 if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) { |
239 if ((err = fortuna_reseed(prng)) != CRYPT_OK) { | 239 if ((err = fortuna_reseed(prng)) != CRYPT_OK) { |
240 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); | 240 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
241 return 0; | 241 return 0; |
242 } | 242 } |
243 } | 243 } |
288 | 288 |
289 LTC_ARGCHK(prng != NULL); | 289 LTC_ARGCHK(prng != NULL); |
290 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); | 290 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); |
291 | 291 |
292 /* terminate all the hashes */ | 292 /* terminate all the hashes */ |
293 for (x = 0; x < FORTUNA_POOLS; x++) { | 293 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
294 if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { | 294 if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { |
295 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); | 295 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
296 return err; | 296 return err; |
297 } | 297 } |
298 } | 298 } |
323 LTC_ARGCHK(prng != NULL); | 323 LTC_ARGCHK(prng != NULL); |
324 | 324 |
325 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); | 325 LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); |
326 | 326 |
327 /* we'll write bytes for s&g's */ | 327 /* we'll write bytes for s&g's */ |
328 if (*outlen < 32*FORTUNA_POOLS) { | 328 if (*outlen < 32*LTC_FORTUNA_POOLS) { |
329 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); | 329 LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
330 *outlen = 32*FORTUNA_POOLS; | 330 *outlen = 32*LTC_FORTUNA_POOLS; |
331 return CRYPT_BUFFER_OVERFLOW; | 331 return CRYPT_BUFFER_OVERFLOW; |
332 } | 332 } |
333 | 333 |
334 md = XMALLOC(sizeof(hash_state)); | 334 md = XMALLOC(sizeof(hash_state)); |
335 if (md == NULL) { | 335 if (md == NULL) { |
338 } | 338 } |
339 | 339 |
340 /* to emit the state we copy each pool, terminate it then hash it again so | 340 /* 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 | 341 * an attacker who sees the state can't determine the current state of the PRNG |
342 */ | 342 */ |
343 for (x = 0; x < FORTUNA_POOLS; x++) { | 343 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
344 /* copy the PRNG */ | 344 /* copy the PRNG */ |
345 XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); | 345 XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); |
346 | 346 |
347 /* terminate it */ | 347 /* terminate it */ |
348 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { | 348 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { |
358 } | 358 } |
359 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { | 359 if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { |
360 goto LBL_ERR; | 360 goto LBL_ERR; |
361 } | 361 } |
362 } | 362 } |
363 *outlen = 32*FORTUNA_POOLS; | 363 *outlen = 32*LTC_FORTUNA_POOLS; |
364 err = CRYPT_OK; | 364 err = CRYPT_OK; |
365 | 365 |
366 LBL_ERR: | 366 LBL_ERR: |
367 #ifdef LTC_CLEAN_STACK | 367 #ifdef LTC_CLEAN_STACK |
368 zeromem(md, sizeof(*md)); | 368 zeromem(md, sizeof(*md)); |
384 int err, x; | 384 int err, x; |
385 | 385 |
386 LTC_ARGCHK(in != NULL); | 386 LTC_ARGCHK(in != NULL); |
387 LTC_ARGCHK(prng != NULL); | 387 LTC_ARGCHK(prng != NULL); |
388 | 388 |
389 if (inlen != 32*FORTUNA_POOLS) { | 389 if (inlen != 32*LTC_FORTUNA_POOLS) { |
390 return CRYPT_INVALID_ARG; | 390 return CRYPT_INVALID_ARG; |
391 } | 391 } |
392 | 392 |
393 if ((err = fortuna_start(prng)) != CRYPT_OK) { | 393 if ((err = fortuna_start(prng)) != CRYPT_OK) { |
394 return err; | 394 return err; |
395 } | 395 } |
396 for (x = 0; x < FORTUNA_POOLS; x++) { | 396 for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
397 if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { | 397 if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { |
398 return err; | 398 return err; |
399 } | 399 } |
400 } | 400 } |
401 return err; | 401 return err; |
420 } | 420 } |
421 | 421 |
422 #endif | 422 #endif |
423 | 423 |
424 | 424 |
425 /* $Source: /cvs/libtom/libtomcrypt/src/prngs/fortuna.c,v $ */ | 425 /* $Source$ */ |
426 /* $Revision: 1.12 $ */ | 426 /* $Revision$ */ |
427 /* $Date: 2006/12/04 21:34:03 $ */ | 427 /* $Date$ */ |