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$ */