diff options
Diffstat (limited to 'src/ltc/prngs/fortuna.c')
-rw-r--r-- | src/ltc/prngs/fortuna.c | 124 |
1 files changed, 64 insertions, 60 deletions
diff --git a/src/ltc/prngs/fortuna.c b/src/ltc/prngs/fortuna.c index 340cd037..ab56defc 100644 --- a/src/ltc/prngs/fortuna.c +++ b/src/ltc/prngs/fortuna.c @@ -6,12 +6,16 @@ * The library is free for all purposes without any express * guarantee it works. */ -#include "tomcrypt.h" +#include "tomcrypt_private.h" +#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED #if defined(_WIN32) #include <windows.h> +#elif defined(LTC_CLOCK_GETTIME) + #include <time.h> /* struct timespec + clock_gettime */ #else - #include <sys/time.h> + #include <sys/time.h> /* struct timeval + gettimeofday */ +#endif #endif /** @@ -60,7 +64,7 @@ static void _fortuna_update_iv(prng_state *prng) int x; unsigned char *IV; /* update IV */ - IV = prng->fortuna.IV; + IV = prng->u.fortuna.IV; for (x = 0; x < 16; x++) { IV[x] = (IV[x] + 1) & 255; if (IV[x] != 0) break; @@ -103,27 +107,27 @@ static int _fortuna_reseed(prng_state *prng) int err, x; #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED - unsigned long now = _fortuna_current_time(); - if (now == prng->fortuna.wd) + ulong64 now = _fortuna_current_time(); + if (now == prng->u.fortuna.wd) return CRYPT_OK; #else - if (++prng->fortuna.wd < LTC_FORTUNA_WD) + if (++prng->u.fortuna.wd < LTC_FORTUNA_WD) return CRYPT_OK; #endif /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ sha256_init(&md); - if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { + if ((err = sha256_process(&md, prng->u.fortuna.K, 32)) != CRYPT_OK) { sha256_done(&md, tmp); return err; } - reset_cnt = prng->fortuna.reset_cnt + 1; + reset_cnt = prng->u.fortuna.reset_cnt + 1; for (x = 0; x < LTC_FORTUNA_POOLS; x++) { if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) { /* terminate this hash */ - if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { + if ((err = sha256_done(&prng->u.fortuna.pool[x], tmp)) != CRYPT_OK) { sha256_done(&md, tmp); return err; } @@ -133,7 +137,7 @@ static int _fortuna_reseed(prng_state *prng) return err; } /* reset this pool */ - if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + if ((err = sha256_init(&prng->u.fortuna.pool[x])) != CRYPT_OK) { sha256_done(&md, tmp); return err; } @@ -143,22 +147,22 @@ static int _fortuna_reseed(prng_state *prng) } /* finish key */ - if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { + if ((err = sha256_done(&md, prng->u.fortuna.K)) != CRYPT_OK) { return err; } - if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + if ((err = rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) { return err; } _fortuna_update_iv(prng); /* reset/update internals */ - prng->fortuna.pool0_len = 0; + prng->u.fortuna.pool0_len = 0; #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED - prng->fortuna.wd = now; + prng->u.fortuna.wd = now; #else - prng->fortuna.wd = 0; + prng->u.fortuna.wd = 0; #endif - prng->fortuna.reset_cnt = reset_cnt; + prng->u.fortuna.reset_cnt = reset_cnt; #ifdef LTC_CLEAN_STACK @@ -183,10 +187,10 @@ int fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state unsigned char tmp[MAXBLOCKSIZE]; hash_state md; - LTC_MUTEX_LOCK(&prng->fortuna.lock); + LTC_MUTEX_LOCK(&prng->lock); /* new K = LTC_SHA256(K || in) */ sha256_init(&md); - if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { + if ((err = sha256_process(&md, prng->u.fortuna.K, 32)) != CRYPT_OK) { sha256_done(&md, tmp); goto LBL_UNLOCK; } @@ -195,13 +199,13 @@ int fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state goto LBL_UNLOCK; } /* finish key */ - if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { + if ((err = sha256_done(&md, prng->u.fortuna.K)) != CRYPT_OK) { goto LBL_UNLOCK; } _fortuna_update_iv(prng); LBL_UNLOCK: - LTC_MUTEX_UNLOCK(&prng->fortuna.lock); + LTC_MUTEX_UNLOCK(&prng->lock); #ifdef LTC_CLEAN_STACK zeromem(&md, sizeof(md)); #endif @@ -220,31 +224,31 @@ int fortuna_start(prng_state *prng) unsigned char tmp[MAXBLOCKSIZE]; LTC_ARGCHK(prng != NULL); - prng->fortuna.ready = 0; + prng->ready = 0; /* initialize the pools */ for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + if ((err = sha256_init(&prng->u.fortuna.pool[x])) != CRYPT_OK) { for (y = 0; y < x; y++) { - sha256_done(&prng->fortuna.pool[y], tmp); + sha256_done(&prng->u.fortuna.pool[y], tmp); } return err; } } - prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0; - prng->fortuna.reset_cnt = 0; + prng->u.fortuna.pool_idx = prng->u.fortuna.pool0_len = prng->u.fortuna.wd = 0; + prng->u.fortuna.reset_cnt = 0; /* reset bufs */ - zeromem(prng->fortuna.K, 32); - if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + zeromem(prng->u.fortuna.K, 32); + if ((err = rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) { for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - sha256_done(&prng->fortuna.pool[x], tmp); + sha256_done(&prng->u.fortuna.pool[x], tmp); } return err; } - zeromem(prng->fortuna.IV, 16); + zeromem(prng->u.fortuna.IV, 16); - LTC_MUTEX_INIT(&prng->fortuna.lock) + LTC_MUTEX_INIT(&prng->lock) return CRYPT_OK; } @@ -263,14 +267,14 @@ static int _fortuna_add(unsigned long source, unsigned long pool, const unsigned tmp[0] = (unsigned char)source; tmp[1] = (unsigned char)inlen; - if ((err = sha256_process(&prng->fortuna.pool[pool], tmp, 2)) != CRYPT_OK) { + if ((err = sha256_process(&prng->u.fortuna.pool[pool], tmp, 2)) != CRYPT_OK) { return err; } - if ((err = sha256_process(&prng->fortuna.pool[pool], in, inlen)) != CRYPT_OK) { + if ((err = sha256_process(&prng->u.fortuna.pool[pool], in, inlen)) != CRYPT_OK) { return err; } if (pool == 0) { - prng->fortuna.pool0_len += inlen; + prng->u.fortuna.pool0_len += inlen; } return CRYPT_OK; /* success */ } @@ -294,11 +298,11 @@ int fortuna_add_random_event(unsigned long source, unsigned long pool, const uns LTC_ARGCHK(source <= 255); LTC_ARGCHK(pool < LTC_FORTUNA_POOLS); - LTC_MUTEX_LOCK(&prng->fortuna.lock); + LTC_MUTEX_LOCK(&prng->lock); err = _fortuna_add(source, pool, in, inlen, prng); - LTC_MUTEX_UNLOCK(&prng->fortuna.lock); + LTC_MUTEX_UNLOCK(&prng->lock); return err; } @@ -318,16 +322,16 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen > 0); - LTC_MUTEX_LOCK(&prng->fortuna.lock); + LTC_MUTEX_LOCK(&prng->lock); - err = _fortuna_add(0, prng->fortuna.pool_idx, in, inlen, prng); + err = _fortuna_add(0, prng->u.fortuna.pool_idx, in, inlen, prng); if (err == CRYPT_OK) { - ++(prng->fortuna.pool_idx); - prng->fortuna.pool_idx %= LTC_FORTUNA_POOLS; + ++(prng->u.fortuna.pool_idx); + prng->u.fortuna.pool_idx %= LTC_FORTUNA_POOLS; } - LTC_MUTEX_UNLOCK(&prng->fortuna.lock); + LTC_MUTEX_UNLOCK(&prng->lock); return err; } @@ -342,18 +346,18 @@ int fortuna_ready(prng_state *prng) int err; LTC_ARGCHK(prng != NULL); - LTC_MUTEX_LOCK(&prng->fortuna.lock); + LTC_MUTEX_LOCK(&prng->lock); /* make sure the reseed doesn't fail because * of the chosen rate limit */ #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED - prng->fortuna.wd = _fortuna_current_time() - 1; + prng->u.fortuna.wd = _fortuna_current_time() - 1; #else - prng->fortuna.wd = LTC_FORTUNA_WD; + prng->u.fortuna.wd = LTC_FORTUNA_WD; #endif err = _fortuna_reseed(prng); - prng->fortuna.ready = (err == CRYPT_OK) ? 1 : 0; + prng->ready = (err == CRYPT_OK) ? 1 : 0; - LTC_MUTEX_UNLOCK(&prng->fortuna.lock); + LTC_MUTEX_UNLOCK(&prng->lock); return err; } @@ -371,21 +375,21 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state if (outlen == 0 || prng == NULL || out == NULL) return 0; - LTC_MUTEX_LOCK(&prng->fortuna.lock); + LTC_MUTEX_LOCK(&prng->lock); - if (!prng->fortuna.ready) { + if (!prng->ready) { goto LBL_UNLOCK; } /* do we have to reseed? */ - if (prng->fortuna.pool0_len >= 64) { + if (prng->u.fortuna.pool0_len >= 64) { if (_fortuna_reseed(prng) != CRYPT_OK) { goto LBL_UNLOCK; } } /* ensure that one reseed happened before allowing to read */ - if (prng->fortuna.reset_cnt == 0) { + if (prng->u.fortuna.reset_cnt == 0) { goto LBL_UNLOCK; } @@ -395,7 +399,7 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state /* handle whole blocks without the extra XMEMCPY */ while (outlen >= 16) { /* encrypt the IV and store it */ - rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey); + rijndael_ecb_encrypt(prng->u.fortuna.IV, out, &prng->u.fortuna.skey); out += 16; outlen -= 16; _fortuna_update_iv(prng); @@ -403,19 +407,19 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state /* left over bytes? */ if (outlen > 0) { - rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey); + rijndael_ecb_encrypt(prng->u.fortuna.IV, tmp, &prng->u.fortuna.skey); XMEMCPY(out, tmp, outlen); _fortuna_update_iv(prng); } /* generate new key */ - rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); + rijndael_ecb_encrypt(prng->u.fortuna.IV, prng->u.fortuna.K , &prng->u.fortuna.skey); _fortuna_update_iv(prng); - rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); + rijndael_ecb_encrypt(prng->u.fortuna.IV, prng->u.fortuna.K+16, &prng->u.fortuna.skey); _fortuna_update_iv(prng); - if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) { + if (rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey) != CRYPT_OK) { tlen = 0; } @@ -423,7 +427,7 @@ LBL_UNLOCK: #ifdef LTC_CLEAN_STACK zeromem(tmp, sizeof(tmp)); #endif - LTC_MUTEX_UNLOCK(&prng->fortuna.lock); + LTC_MUTEX_UNLOCK(&prng->lock); return tlen; } @@ -439,12 +443,12 @@ int fortuna_done(prng_state *prng) LTC_ARGCHK(prng != NULL); - LTC_MUTEX_LOCK(&prng->fortuna.lock); - prng->fortuna.ready = 0; + LTC_MUTEX_LOCK(&prng->lock); + prng->ready = 0; /* terminate all the hashes */ for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { + if ((err = sha256_done(&(prng->u.fortuna.pool[x]), tmp)) != CRYPT_OK) { goto LBL_UNLOCK; } } @@ -455,8 +459,8 @@ LBL_UNLOCK: #ifdef LTC_CLEAN_STACK zeromem(tmp, sizeof(tmp)); #endif - LTC_MUTEX_UNLOCK(&prng->fortuna.lock); - LTC_MUTEX_DESTROY(&prng->fortuna.lock); + LTC_MUTEX_UNLOCK(&prng->lock); + LTC_MUTEX_DESTROY(&prng->lock); return err; } |