summaryrefslogtreecommitdiff
path: root/src/ltc/prngs/fortuna.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ltc/prngs/fortuna.c')
-rw-r--r--src/ltc/prngs/fortuna.c124
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;
}