Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ltc/headers/tomcrypt_prng.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ typedef struct {
#ifdef LTC_SOBER128
struct sober128_prng sober128;
#endif
};
} u;
short ready; /* ready flag 0-1 */
LTC_MUTEX_TYPE(lock) /* lock */
} prng_state;
Expand Down
24 changes: 12 additions & 12 deletions src/ltc/prngs/chacha20.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ int chacha20_prng_start(prng_state *prng)
{
LTC_ARGCHK(prng != NULL);
prng->ready = 0;
XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent));
prng->chacha.idx = 0;
XMEMSET(&prng->u.chacha.ent, 0, sizeof(prng->u.chacha.ent));
prng->u.chacha.idx = 0;
LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
Expand All @@ -64,18 +64,18 @@ int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng
LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) {
/* chacha20_prng_ready() was already called, do "rekey" operation */
if ((err = chacha_keystream(&prng->chacha.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
if ((err = chacha_keystream(&prng->u.chacha.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
/* key 32 bytes, 20 rounds */
if ((err = chacha_setup(&prng->chacha.s, buf, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK;
if ((err = chacha_setup(&prng->u.chacha.s, buf, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK;
/* iv 8 bytes */
if ((err = chacha_ivctr64(&prng->chacha.s, buf + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
if ((err = chacha_ivctr64(&prng->u.chacha.s, buf + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
/* clear KEY + IV */
zeromem(buf, sizeof(buf));
}
else {
/* chacha20_prng_ready() was not called yet, add entropy to ent buffer */
while (inlen--) prng->chacha.ent[prng->chacha.idx++ % sizeof(prng->chacha.ent)] ^= *in++;
while (inlen--) prng->u.chacha.ent[prng->u.chacha.idx++ % sizeof(prng->u.chacha.ent)] ^= *in++;
}
err = CRYPT_OK;
LBL_UNLOCK:
Expand All @@ -97,11 +97,11 @@ int chacha20_prng_ready(prng_state *prng)
LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
/* key 32 bytes, 20 rounds */
if ((err = chacha_setup(&prng->chacha.s, prng->chacha.ent, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK;
if ((err = chacha_setup(&prng->u.chacha.s, prng->u.chacha.ent, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK;
/* iv 8 bytes */
if ((err = chacha_ivctr64(&prng->chacha.s, prng->chacha.ent + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent));
prng->chacha.idx = 0;
if ((err = chacha_ivctr64(&prng->u.chacha.s, prng->u.chacha.ent + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
XMEMSET(&prng->u.chacha.ent, 0, sizeof(prng->u.chacha.ent));
prng->u.chacha.idx = 0;
prng->ready = 1;
LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock);
Expand All @@ -120,7 +120,7 @@ unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_
if (outlen == 0 || prng == NULL || out == NULL) return 0;
LTC_MUTEX_LOCK(&prng->lock);
if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
if (chacha_keystream(&prng->chacha.s, out, outlen) != CRYPT_OK) outlen = 0;
if (chacha_keystream(&prng->u.chacha.s, out, outlen) != CRYPT_OK) outlen = 0;
LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock);
return outlen;
Expand All @@ -137,7 +137,7 @@ int chacha20_prng_done(prng_state *prng)
LTC_ARGCHK(prng != NULL);
LTC_MUTEX_LOCK(&prng->lock);
prng->ready = 0;
err = chacha_done(&prng->chacha.s);
err = chacha_done(&prng->u.chacha.s);
LTC_MUTEX_UNLOCK(&prng->lock);
LTC_MUTEX_DESTROY(&prng->lock);
return err;
Expand Down
78 changes: 39 additions & 39 deletions src/ltc/prngs/fortuna.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,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;
Expand Down Expand Up @@ -104,26 +104,26 @@ static int _fortuna_reseed(prng_state *prng)

#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
unsigned long now = _fortuna_current_time();
if (now == prng->fortuna.wd)
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;
}
Expand All @@ -133,7 +133,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;
}
Expand All @@ -143,22 +143,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
Expand Down Expand Up @@ -186,7 +186,7 @@ int fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state
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;
}
Expand All @@ -195,7 +195,7 @@ 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);
Expand Down Expand Up @@ -224,25 +224,25 @@ int fortuna_start(prng_state *prng)

/* 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->lock)

Expand All @@ -263,14 +263,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 */
}
Expand Down Expand Up @@ -320,11 +320,11 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state

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->lock);
Expand All @@ -346,9 +346,9 @@ int fortuna_ready(prng_state *prng)
/* 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->ready = (err == CRYPT_OK) ? 1 : 0;
Expand Down Expand Up @@ -378,14 +378,14 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state
}

/* 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;
}

Expand All @@ -395,27 +395,27 @@ 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);
}

/* 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;
}

Expand Down Expand Up @@ -444,7 +444,7 @@ int fortuna_done(prng_state *prng)

/* 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;
}
}
Expand Down
24 changes: 12 additions & 12 deletions src/ltc/prngs/rc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ int rc4_start(prng_state *prng)
LTC_ARGCHK(prng != NULL);
prng->ready = 0;
/* set entropy (key) size to zero */
prng->rc4.s.x = 0;
prng->u.rc4.s.x = 0;
/* clear entropy (key) buffer */
XMEMSET(&prng->rc4.s.buf, 0, sizeof(prng->rc4.s.buf));
XMEMSET(&prng->u.rc4.s.buf, 0, sizeof(prng->u.rc4.s.buf));
LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
Expand All @@ -66,17 +66,17 @@ int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *pr
LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) {
/* rc4_ready() was already called, do "rekey" operation */
if ((err = rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
if ((err = rc4_stream_keystream(&prng->u.rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
/* initialize RC4 */
if ((err = rc4_stream_setup(&prng->rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
if ((err = rc4_stream_setup(&prng->u.rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
/* drop first 3072 bytes - https://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack */
for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf));
for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->u.rc4.s, buf, sizeof(buf));
zeromem(buf, sizeof(buf));
}
else {
/* rc4_ready() was not called yet, add entropy to the buffer */
while (inlen--) prng->rc4.s.buf[prng->rc4.s.x++ % sizeof(prng->rc4.s.buf)] ^= *in++;
while (inlen--) prng->u.rc4.s.buf[prng->u.rc4.s.x++ % sizeof(prng->u.rc4.s.buf)] ^= *in++;
}
err = CRYPT_OK;
LBL_UNLOCK:
Expand All @@ -99,12 +99,12 @@ int rc4_ready(prng_state *prng)

LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
XMEMCPY(buf, prng->rc4.s.buf, sizeof(buf));
XMEMCPY(buf, prng->u.rc4.s.buf, sizeof(buf));
/* initialize RC4 */
len = MIN(prng->rc4.s.x, 256); /* TODO: we can perhaps always use all 256 bytes */
if ((err = rc4_stream_setup(&prng->rc4.s, buf, len)) != CRYPT_OK) goto LBL_UNLOCK;
len = MIN(prng->u.rc4.s.x, 256); /* TODO: we can perhaps always use all 256 bytes */
if ((err = rc4_stream_setup(&prng->u.rc4.s, buf, len)) != CRYPT_OK) goto LBL_UNLOCK;
/* drop first 3072 bytes - https://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack */
for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf));
for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->u.rc4.s, buf, sizeof(buf));
prng->ready = 1;
LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock);
Expand All @@ -123,7 +123,7 @@ unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prn
if (outlen == 0 || prng == NULL || out == NULL) return 0;
LTC_MUTEX_LOCK(&prng->lock);
if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
if (rc4_stream_keystream(&prng->rc4.s, out, outlen) != CRYPT_OK) outlen = 0;
if (rc4_stream_keystream(&prng->u.rc4.s, out, outlen) != CRYPT_OK) outlen = 0;
LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock);
return outlen;
Expand All @@ -140,7 +140,7 @@ int rc4_done(prng_state *prng)
LTC_ARGCHK(prng != NULL);
LTC_MUTEX_LOCK(&prng->lock);
prng->ready = 0;
err = rc4_stream_done(&prng->rc4.s);
err = rc4_stream_done(&prng->u.rc4.s);
LTC_MUTEX_UNLOCK(&prng->lock);
LTC_MUTEX_DESTROY(&prng->lock);
return err;
Expand Down
Loading