avoid anonymous union (which is not supported by some compilers)

This commit is contained in:
Karel Miko 2018-06-03 19:47:27 +02:00
parent 10355675a9
commit 5834223db5
6 changed files with 129 additions and 129 deletions

View File

@ -72,7 +72,7 @@ typedef struct {
#ifdef LTC_SOBER128 #ifdef LTC_SOBER128
struct sober128_prng sober128; struct sober128_prng sober128;
#endif #endif
}; } u;
short ready; /* ready flag 0-1 */ short ready; /* ready flag 0-1 */
LTC_MUTEX_TYPE(lock) /* lock */ LTC_MUTEX_TYPE(lock) /* lock */
} prng_state; } prng_state;

View File

@ -38,8 +38,8 @@ int chacha20_prng_start(prng_state *prng)
{ {
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
prng->ready = 0; prng->ready = 0;
XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent)); XMEMSET(&prng->u.chacha.ent, 0, sizeof(prng->u.chacha.ent));
prng->chacha.idx = 0; prng->u.chacha.idx = 0;
LTC_MUTEX_INIT(&prng->lock) LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK; return CRYPT_OK;
} }
@ -64,18 +64,18 @@ int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { if (prng->ready) {
/* chacha20_prng_ready() was already called, do "rekey" operation */ /* 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]; for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
/* key 32 bytes, 20 rounds */ /* 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 */ /* 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 */ /* clear KEY + IV */
zeromem(buf, sizeof(buf)); zeromem(buf, sizeof(buf));
} }
else { else {
/* chacha20_prng_ready() was not called yet, add entropy to ent buffer */ /* 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; err = CRYPT_OK;
LBL_UNLOCK: LBL_UNLOCK:
@ -97,11 +97,11 @@ int chacha20_prng_ready(prng_state *prng)
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; } if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
/* key 32 bytes, 20 rounds */ /* 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 */ /* iv 8 bytes */
if ((err = chacha_ivctr64(&prng->chacha.s, prng->chacha.ent + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK; if ((err = chacha_ivctr64(&prng->u.chacha.s, prng->u.chacha.ent + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent)); XMEMSET(&prng->u.chacha.ent, 0, sizeof(prng->u.chacha.ent));
prng->chacha.idx = 0; prng->u.chacha.idx = 0;
prng->ready = 1; prng->ready = 1;
LBL_UNLOCK: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
@ -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; if (outlen == 0 || prng == NULL || out == NULL) return 0;
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; } 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: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
return outlen; return outlen;
@ -137,7 +137,7 @@ int chacha20_prng_done(prng_state *prng)
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
prng->ready = 0; prng->ready = 0;
err = chacha_done(&prng->chacha.s); err = chacha_done(&prng->u.chacha.s);
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
LTC_MUTEX_DESTROY(&prng->lock); LTC_MUTEX_DESTROY(&prng->lock);
return err; return err;

View File

@ -64,7 +64,7 @@ static void _fortuna_update_iv(prng_state *prng)
int x; int x;
unsigned char *IV; unsigned char *IV;
/* update IV */ /* update IV */
IV = prng->fortuna.IV; IV = prng->u.fortuna.IV;
for (x = 0; x < 16; x++) { for (x = 0; x < 16; x++) {
IV[x] = (IV[x] + 1) & 255; IV[x] = (IV[x] + 1) & 255;
if (IV[x] != 0) break; if (IV[x] != 0) break;
@ -108,26 +108,26 @@ static int _fortuna_reseed(prng_state *prng)
#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
ulong64 now = _fortuna_current_time(); ulong64 now = _fortuna_current_time();
if (now == prng->fortuna.wd) if (now == prng->u.fortuna.wd)
return CRYPT_OK; return CRYPT_OK;
#else #else
if (++prng->fortuna.wd < LTC_FORTUNA_WD) if (++prng->u.fortuna.wd < LTC_FORTUNA_WD)
return CRYPT_OK; return CRYPT_OK;
#endif #endif
/* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */
sha256_init(&md); 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); sha256_done(&md, tmp);
return err; 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++) { for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) { if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) {
/* terminate this hash */ /* 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); sha256_done(&md, tmp);
return err; return err;
} }
@ -137,7 +137,7 @@ static int _fortuna_reseed(prng_state *prng)
return err; return err;
} }
/* reset this pool */ /* 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); sha256_done(&md, tmp);
return err; return err;
} }
@ -147,22 +147,22 @@ static int _fortuna_reseed(prng_state *prng)
} }
/* finish key */ /* 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; 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; return err;
} }
_fortuna_update_iv(prng); _fortuna_update_iv(prng);
/* reset/update internals */ /* reset/update internals */
prng->fortuna.pool0_len = 0; prng->u.fortuna.pool0_len = 0;
#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
prng->fortuna.wd = now; prng->u.fortuna.wd = now;
#else #else
prng->fortuna.wd = 0; prng->u.fortuna.wd = 0;
#endif #endif
prng->fortuna.reset_cnt = reset_cnt; prng->u.fortuna.reset_cnt = reset_cnt;
#ifdef LTC_CLEAN_STACK #ifdef LTC_CLEAN_STACK
@ -190,7 +190,7 @@ int fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
/* new K = LTC_SHA256(K || in) */ /* new K = LTC_SHA256(K || in) */
sha256_init(&md); 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); sha256_done(&md, tmp);
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
@ -199,7 +199,7 @@ int fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
/* finish key */ /* 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; goto LBL_UNLOCK;
} }
_fortuna_update_iv(prng); _fortuna_update_iv(prng);
@ -228,25 +228,25 @@ int fortuna_start(prng_state *prng)
/* initialize the pools */ /* initialize the pools */
for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 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++) { for (y = 0; y < x; y++) {
sha256_done(&prng->fortuna.pool[y], tmp); sha256_done(&prng->u.fortuna.pool[y], tmp);
} }
return err; return err;
} }
} }
prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0; prng->u.fortuna.pool_idx = prng->u.fortuna.pool0_len = prng->u.fortuna.wd = 0;
prng->fortuna.reset_cnt = 0; prng->u.fortuna.reset_cnt = 0;
/* reset bufs */ /* reset bufs */
zeromem(prng->fortuna.K, 32); zeromem(prng->u.fortuna.K, 32);
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) {
for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 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; return err;
} }
zeromem(prng->fortuna.IV, 16); zeromem(prng->u.fortuna.IV, 16);
LTC_MUTEX_INIT(&prng->lock) LTC_MUTEX_INIT(&prng->lock)
@ -267,14 +267,14 @@ static int _fortuna_add(unsigned long source, unsigned long pool, const unsigned
tmp[0] = (unsigned char)source; tmp[0] = (unsigned char)source;
tmp[1] = (unsigned char)inlen; 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; 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; return err;
} }
if (pool == 0) { if (pool == 0) {
prng->fortuna.pool0_len += inlen; prng->u.fortuna.pool0_len += inlen;
} }
return CRYPT_OK; /* success */ return CRYPT_OK; /* success */
} }
@ -324,11 +324,11 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
LTC_MUTEX_LOCK(&prng->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) { if (err == CRYPT_OK) {
++(prng->fortuna.pool_idx); ++(prng->u.fortuna.pool_idx);
prng->fortuna.pool_idx %= LTC_FORTUNA_POOLS; prng->u.fortuna.pool_idx %= LTC_FORTUNA_POOLS;
} }
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
@ -350,9 +350,9 @@ int fortuna_ready(prng_state *prng)
/* make sure the reseed doesn't fail because /* make sure the reseed doesn't fail because
* of the chosen rate limit */ * of the chosen rate limit */
#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
prng->fortuna.wd = _fortuna_current_time() - 1; prng->u.fortuna.wd = _fortuna_current_time() - 1;
#else #else
prng->fortuna.wd = LTC_FORTUNA_WD; prng->u.fortuna.wd = LTC_FORTUNA_WD;
#endif #endif
err = _fortuna_reseed(prng); err = _fortuna_reseed(prng);
prng->ready = (err == CRYPT_OK) ? 1 : 0; prng->ready = (err == CRYPT_OK) ? 1 : 0;
@ -382,14 +382,14 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state
} }
/* do we have to reseed? */ /* do we have to reseed? */
if (prng->fortuna.pool0_len >= 64) { if (prng->u.fortuna.pool0_len >= 64) {
if (_fortuna_reseed(prng) != CRYPT_OK) { if (_fortuna_reseed(prng) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
} }
/* ensure that one reseed happened before allowing to read */ /* 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; goto LBL_UNLOCK;
} }
@ -399,7 +399,7 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state
/* handle whole blocks without the extra XMEMCPY */ /* handle whole blocks without the extra XMEMCPY */
while (outlen >= 16) { while (outlen >= 16) {
/* encrypt the IV and store it */ /* 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; out += 16;
outlen -= 16; outlen -= 16;
_fortuna_update_iv(prng); _fortuna_update_iv(prng);
@ -407,19 +407,19 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state
/* left over bytes? */ /* left over bytes? */
if (outlen > 0) { 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); XMEMCPY(out, tmp, outlen);
_fortuna_update_iv(prng); _fortuna_update_iv(prng);
} }
/* generate new key */ /* 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); _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); _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; tlen = 0;
} }
@ -448,7 +448,7 @@ int fortuna_done(prng_state *prng)
/* terminate all the hashes */ /* terminate all the hashes */
for (x = 0; x < LTC_FORTUNA_POOLS; x++) { 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; goto LBL_UNLOCK;
} }
} }

View File

@ -39,9 +39,9 @@ int rc4_start(prng_state *prng)
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
prng->ready = 0; prng->ready = 0;
/* set entropy (key) size to zero */ /* set entropy (key) size to zero */
prng->rc4.s.x = 0; prng->u.rc4.s.x = 0;
/* clear entropy (key) buffer */ /* 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) LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK; return CRYPT_OK;
} }
@ -66,17 +66,17 @@ int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *pr
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { if (prng->ready) {
/* rc4_ready() was already called, do "rekey" operation */ /* 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]; for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
/* initialize RC4 */ /* 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 */ /* 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)); zeromem(buf, sizeof(buf));
} }
else { else {
/* rc4_ready() was not called yet, add entropy to the buffer */ /* 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; err = CRYPT_OK;
LBL_UNLOCK: LBL_UNLOCK:
@ -99,12 +99,12 @@ int rc4_ready(prng_state *prng)
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; } 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 */ /* initialize RC4 */
len = MIN(prng->rc4.s.x, 256); /* TODO: we can perhaps always use all 256 bytes */ len = MIN(prng->u.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; 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 */ /* 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; prng->ready = 1;
LBL_UNLOCK: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
@ -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; if (outlen == 0 || prng == NULL || out == NULL) return 0;
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; } 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: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
return outlen; return outlen;
@ -140,7 +140,7 @@ int rc4_done(prng_state *prng)
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
prng->ready = 0; 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_UNLOCK(&prng->lock);
LTC_MUTEX_DESTROY(&prng->lock); LTC_MUTEX_DESTROY(&prng->lock);
return err; return err;

View File

@ -40,8 +40,8 @@ int sober128_start(prng_state *prng)
{ {
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
prng->ready = 0; prng->ready = 0;
XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent)); XMEMSET(&prng->u.sober128.ent, 0, sizeof(prng->u.sober128.ent));
prng->sober128.idx = 0; prng->u.sober128.idx = 0;
LTC_MUTEX_INIT(&prng->lock) LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK; return CRYPT_OK;
} }
@ -66,18 +66,18 @@ int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_stat
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { if (prng->ready) {
/* sober128_ready() was already called, do "rekey" operation */ /* sober128_ready() was already called, do "rekey" operation */
if ((err = sober128_stream_keystream(&prng->sober128.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK; if ((err = sober128_stream_keystream(&prng->u.sober128.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i]; for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
/* key 32 bytes, 20 rounds */ /* key 32 bytes, 20 rounds */
if ((err = sober128_stream_setup(&prng->sober128.s, buf, 32)) != CRYPT_OK) goto LBL_UNLOCK; if ((err = sober128_stream_setup(&prng->u.sober128.s, buf, 32)) != CRYPT_OK) goto LBL_UNLOCK;
/* iv 8 bytes */ /* iv 8 bytes */
if ((err = sober128_stream_setiv(&prng->sober128.s, buf + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK; if ((err = sober128_stream_setiv(&prng->u.sober128.s, buf + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK;
/* clear KEY + IV */ /* clear KEY + IV */
zeromem(buf, sizeof(buf)); zeromem(buf, sizeof(buf));
} }
else { else {
/* sober128_ready() was not called yet, add entropy to ent buffer */ /* sober128_ready() was not called yet, add entropy to ent buffer */
while (inlen--) prng->sober128.ent[prng->sober128.idx++ % sizeof(prng->sober128.ent)] ^= *in++; while (inlen--) prng->u.sober128.ent[prng->u.sober128.idx++ % sizeof(prng->u.sober128.ent)] ^= *in++;
} }
err = CRYPT_OK; err = CRYPT_OK;
LBL_UNLOCK: LBL_UNLOCK:
@ -99,11 +99,11 @@ int sober128_ready(prng_state *prng)
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; } if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
/* key 32 bytes, 20 rounds */ /* key 32 bytes, 20 rounds */
if ((err = sober128_stream_setup(&prng->sober128.s, prng->sober128.ent, 32)) != CRYPT_OK) goto LBL_UNLOCK; if ((err = sober128_stream_setup(&prng->u.sober128.s, prng->u.sober128.ent, 32)) != CRYPT_OK) goto LBL_UNLOCK;
/* iv 8 bytes */ /* iv 8 bytes */
if ((err = sober128_stream_setiv(&prng->sober128.s, prng->sober128.ent + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK; if ((err = sober128_stream_setiv(&prng->u.sober128.s, prng->u.sober128.ent + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK;
XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent)); XMEMSET(&prng->u.sober128.ent, 0, sizeof(prng->u.sober128.ent));
prng->sober128.idx = 0; prng->u.sober128.idx = 0;
prng->ready = 1; prng->ready = 1;
LBL_UNLOCK: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
@ -122,7 +122,7 @@ unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state
if (outlen == 0 || prng == NULL || out == NULL) return 0; if (outlen == 0 || prng == NULL || out == NULL) return 0;
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; } if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
if (sober128_stream_keystream(&prng->sober128.s, out, outlen) != CRYPT_OK) outlen = 0; if (sober128_stream_keystream(&prng->u.sober128.s, out, outlen) != CRYPT_OK) outlen = 0;
LBL_UNLOCK: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
return outlen; return outlen;
@ -139,7 +139,7 @@ int sober128_done(prng_state *prng)
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(prng != NULL);
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
prng->ready = 0; prng->ready = 0;
err = sober128_stream_done(&prng->sober128.s); err = sober128_stream_done(&prng->u.sober128.s);
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
LTC_MUTEX_DESTROY(&prng->lock); LTC_MUTEX_DESTROY(&prng->lock);
return err; return err;

View File

@ -43,82 +43,82 @@ int yarrow_start(prng_state *prng)
/* these are the default hash/cipher combo used */ /* these are the default hash/cipher combo used */
#ifdef LTC_RIJNDAEL #ifdef LTC_RIJNDAEL
#if LTC_YARROW_AES==0 #if LTC_YARROW_AES==0
prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); prng->u.yarrow.cipher = register_cipher(&rijndael_enc_desc);
#elif LTC_YARROW_AES==1 #elif LTC_YARROW_AES==1
prng->yarrow.cipher = register_cipher(&aes_enc_desc); prng->u.yarrow.cipher = register_cipher(&aes_enc_desc);
#elif LTC_YARROW_AES==2 #elif LTC_YARROW_AES==2
prng->yarrow.cipher = register_cipher(&rijndael_desc); prng->u.yarrow.cipher = register_cipher(&rijndael_desc);
#elif LTC_YARROW_AES==3 #elif LTC_YARROW_AES==3
prng->yarrow.cipher = register_cipher(&aes_desc); prng->u.yarrow.cipher = register_cipher(&aes_desc);
#endif #endif
#elif defined(LTC_BLOWFISH) #elif defined(LTC_BLOWFISH)
prng->yarrow.cipher = register_cipher(&blowfish_desc); prng->u.yarrow.cipher = register_cipher(&blowfish_desc);
#elif defined(LTC_TWOFISH) #elif defined(LTC_TWOFISH)
prng->yarrow.cipher = register_cipher(&twofish_desc); prng->u.yarrow.cipher = register_cipher(&twofish_desc);
#elif defined(LTC_RC6) #elif defined(LTC_RC6)
prng->yarrow.cipher = register_cipher(&rc6_desc); prng->u.yarrow.cipher = register_cipher(&rc6_desc);
#elif defined(LTC_RC5) #elif defined(LTC_RC5)
prng->yarrow.cipher = register_cipher(&rc5_desc); prng->u.yarrow.cipher = register_cipher(&rc5_desc);
#elif defined(LTC_SAFERP) #elif defined(LTC_SAFERP)
prng->yarrow.cipher = register_cipher(&saferp_desc); prng->u.yarrow.cipher = register_cipher(&saferp_desc);
#elif defined(LTC_RC2) #elif defined(LTC_RC2)
prng->yarrow.cipher = register_cipher(&rc2_desc); prng->u.yarrow.cipher = register_cipher(&rc2_desc);
#elif defined(LTC_NOEKEON) #elif defined(LTC_NOEKEON)
prng->yarrow.cipher = register_cipher(&noekeon_desc); prng->u.yarrow.cipher = register_cipher(&noekeon_desc);
#elif defined(LTC_ANUBIS) #elif defined(LTC_ANUBIS)
prng->yarrow.cipher = register_cipher(&anubis_desc); prng->u.yarrow.cipher = register_cipher(&anubis_desc);
#elif defined(LTC_KSEED) #elif defined(LTC_KSEED)
prng->yarrow.cipher = register_cipher(&kseed_desc); prng->u.yarrow.cipher = register_cipher(&kseed_desc);
#elif defined(LTC_KHAZAD) #elif defined(LTC_KHAZAD)
prng->yarrow.cipher = register_cipher(&khazad_desc); prng->u.yarrow.cipher = register_cipher(&khazad_desc);
#elif defined(LTC_CAST5) #elif defined(LTC_CAST5)
prng->yarrow.cipher = register_cipher(&cast5_desc); prng->u.yarrow.cipher = register_cipher(&cast5_desc);
#elif defined(LTC_XTEA) #elif defined(LTC_XTEA)
prng->yarrow.cipher = register_cipher(&xtea_desc); prng->u.yarrow.cipher = register_cipher(&xtea_desc);
#elif defined(LTC_SAFER) #elif defined(LTC_SAFER)
prng->yarrow.cipher = register_cipher(&safer_sk128_desc); prng->u.yarrow.cipher = register_cipher(&safer_sk128_desc);
#elif defined(LTC_DES) #elif defined(LTC_DES)
prng->yarrow.cipher = register_cipher(&des3_desc); prng->u.yarrow.cipher = register_cipher(&des3_desc);
#else #else
#error LTC_YARROW needs at least one CIPHER #error LTC_YARROW needs at least one CIPHER
#endif #endif
if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(prng->u.yarrow.cipher)) != CRYPT_OK) {
return err; return err;
} }
#ifdef LTC_SHA256 #ifdef LTC_SHA256
prng->yarrow.hash = register_hash(&sha256_desc); prng->u.yarrow.hash = register_hash(&sha256_desc);
#elif defined(LTC_SHA512) #elif defined(LTC_SHA512)
prng->yarrow.hash = register_hash(&sha512_desc); prng->u.yarrow.hash = register_hash(&sha512_desc);
#elif defined(LTC_TIGER) #elif defined(LTC_TIGER)
prng->yarrow.hash = register_hash(&tiger_desc); prng->u.yarrow.hash = register_hash(&tiger_desc);
#elif defined(LTC_SHA1) #elif defined(LTC_SHA1)
prng->yarrow.hash = register_hash(&sha1_desc); prng->u.yarrow.hash = register_hash(&sha1_desc);
#elif defined(LTC_RIPEMD320) #elif defined(LTC_RIPEMD320)
prng->yarrow.hash = register_hash(&rmd320_desc); prng->u.yarrow.hash = register_hash(&rmd320_desc);
#elif defined(LTC_RIPEMD256) #elif defined(LTC_RIPEMD256)
prng->yarrow.hash = register_hash(&rmd256_desc); prng->u.yarrow.hash = register_hash(&rmd256_desc);
#elif defined(LTC_RIPEMD160) #elif defined(LTC_RIPEMD160)
prng->yarrow.hash = register_hash(&rmd160_desc); prng->u.yarrow.hash = register_hash(&rmd160_desc);
#elif defined(LTC_RIPEMD128) #elif defined(LTC_RIPEMD128)
prng->yarrow.hash = register_hash(&rmd128_desc); prng->u.yarrow.hash = register_hash(&rmd128_desc);
#elif defined(LTC_MD5) #elif defined(LTC_MD5)
prng->yarrow.hash = register_hash(&md5_desc); prng->u.yarrow.hash = register_hash(&md5_desc);
#elif defined(LTC_MD4) #elif defined(LTC_MD4)
prng->yarrow.hash = register_hash(&md4_desc); prng->u.yarrow.hash = register_hash(&md4_desc);
#elif defined(LTC_MD2) #elif defined(LTC_MD2)
prng->yarrow.hash = register_hash(&md2_desc); prng->u.yarrow.hash = register_hash(&md2_desc);
#elif defined(LTC_WHIRLPOOL) #elif defined(LTC_WHIRLPOOL)
prng->yarrow.hash = register_hash(&whirlpool_desc); prng->u.yarrow.hash = register_hash(&whirlpool_desc);
#else #else
#error LTC_YARROW needs at least one HASH #error LTC_YARROW needs at least one HASH
#endif #endif
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { if ((err = hash_is_valid(prng->u.yarrow.hash)) != CRYPT_OK) {
return err; return err;
} }
/* zero the memory used */ /* zero the memory used */
zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); zeromem(prng->u.yarrow.pool, sizeof(prng->u.yarrow.pool));
LTC_MUTEX_INIT(&prng->lock) LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK; return CRYPT_OK;
@ -142,28 +142,28 @@ int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { if ((err = hash_is_valid(prng->u.yarrow.hash)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
/* start the hash */ /* start the hash */
if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { if ((err = hash_descriptor[prng->u.yarrow.hash].init(&md)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
/* hash the current pool */ /* hash the current pool */
if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, if ((err = hash_descriptor[prng->u.yarrow.hash].process(&md, prng->u.yarrow.pool,
hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { hash_descriptor[prng->u.yarrow.hash].hashsize)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
/* add the new entropy */ /* add the new entropy */
if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { if ((err = hash_descriptor[prng->u.yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
/* store result */ /* store result */
err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); err = hash_descriptor[prng->u.yarrow.hash].done(&md, prng->u.yarrow.pool);
LBL_UNLOCK: LBL_UNLOCK:
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
@ -183,26 +183,26 @@ int yarrow_ready(prng_state *prng)
LTC_MUTEX_LOCK(&prng->lock); LTC_MUTEX_LOCK(&prng->lock);
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { if ((err = hash_is_valid(prng->u.yarrow.hash)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(prng->u.yarrow.cipher)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
/* setup CTR mode using the "pool" as the key */ /* setup CTR mode using the "pool" as the key */
ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; ks = (int)hash_descriptor[prng->u.yarrow.hash].hashsize;
if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { if ((err = cipher_descriptor[prng->u.yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ if ((err = ctr_start(prng->u.yarrow.cipher, /* what cipher to use */
prng->yarrow.pool, /* IV */ prng->u.yarrow.pool, /* IV */
prng->yarrow.pool, ks, /* KEY and key size */ prng->u.yarrow.pool, ks, /* KEY and key size */
0, /* number of rounds */ 0, /* number of rounds */
CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
&prng->yarrow.ctr)) != CRYPT_OK) { &prng->u.yarrow.ctr)) != CRYPT_OK) {
goto LBL_UNLOCK; goto LBL_UNLOCK;
} }
prng->ready = 1; prng->ready = 1;
@ -234,7 +234,7 @@ unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *
zeromem(out, outlen); zeromem(out, outlen);
/* now randomize it */ /* now randomize it */
if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { if (ctr_encrypt(out, out, outlen, &prng->u.yarrow.ctr) != CRYPT_OK) {
outlen = 0; outlen = 0;
} }
@ -259,7 +259,7 @@ int yarrow_done(prng_state *prng)
/* call cipher done when we invent one ;-) */ /* call cipher done when we invent one ;-) */
/* we invented one */ /* we invented one */
err = ctr_done(&prng->yarrow.ctr); err = ctr_done(&prng->u.yarrow.ctr);
LTC_MUTEX_UNLOCK(&prng->lock); LTC_MUTEX_UNLOCK(&prng->lock);
LTC_MUTEX_DESTROY(&prng->lock); LTC_MUTEX_DESTROY(&prng->lock);
@ -312,12 +312,12 @@ int yarrow_test(void)
} }
/* now let's test the hash/cipher that was chosen */ /* now let's test the hash/cipher that was chosen */
if (cipher_descriptor[prng.yarrow.cipher].test && if (cipher_descriptor[prng.u.yarrow.cipher].test &&
((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK)) { ((err = cipher_descriptor[prng.u.yarrow.cipher].test()) != CRYPT_OK)) {
return err; return err;
} }
if (hash_descriptor[prng.yarrow.hash].test && if (hash_descriptor[prng.u.yarrow.hash].test &&
((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK)) { ((err = hash_descriptor[prng.u.yarrow.hash].test()) != CRYPT_OK)) {
return err; return err;
} }