summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CryptX.xs4
-rw-r--r--inc/CryptX_Stream_RC4.xs.inc14
-rw-r--r--inc/CryptX_Stream_Sober128.xs.inc18
-rw-r--r--src/ltc/hashes/helper/hash_filehandle.c26
-rw-r--r--src/ltc/headers/tomcrypt_cipher.h32
-rw-r--r--src/ltc/headers/tomcrypt_custom.h16
-rw-r--r--src/ltc/headers/tomcrypt_prng.h59
-rw-r--r--src/ltc/mac/f9/f9_file.c51
-rw-r--r--src/ltc/mac/hmac/hmac_file.c43
-rw-r--r--src/ltc/mac/omac/omac_file.c39
-rw-r--r--src/ltc/mac/pmac/pmac_file.c39
-rw-r--r--src/ltc/mac/poly1305/poly1305_file.c32
-rw-r--r--src/ltc/mac/poly1305/poly1305_memory.c2
-rw-r--r--src/ltc/mac/poly1305/poly1305_memory_multi.c2
-rw-r--r--src/ltc/mac/xcbc/xcbc_file.c39
-rw-r--r--src/ltc/misc/crypt/crypt.c19
-rw-r--r--src/ltc/prngs/chacha20.c137
-rw-r--r--src/ltc/prngs/fortuna.c103
-rw-r--r--src/ltc/prngs/rc4.c179
-rw-r--r--src/ltc/prngs/rng_get_bytes.c2
-rw-r--r--src/ltc/prngs/rng_make_prng.c2
-rw-r--r--src/ltc/prngs/sober128.c173
-rw-r--r--src/ltc/prngs/sprng.c17
-rw-r--r--src/ltc/prngs/yarrow.c109
-rw-r--r--src/ltc/stream/chacha/chacha_crypt.c13
-rw-r--r--src/ltc/stream/chacha/chacha_done.c2
-rw-r--r--src/ltc/stream/chacha/chacha_ivctr32.c2
-rw-r--r--src/ltc/stream/chacha/chacha_ivctr64.c2
-rw-r--r--src/ltc/stream/chacha/chacha_setup.c9
-rw-r--r--src/ltc/stream/rc4/rc4.c12
-rw-r--r--src/ltc/stream/sober128/sober128.c12
31 files changed, 677 insertions, 532 deletions
diff --git a/CryptX.xs b/CryptX.xs
index bdf8c822..941b5efc 100644
--- a/CryptX.xs
+++ b/CryptX.xs
@@ -382,8 +382,8 @@ BOOT:
/* --- */
if(register_prng(&fortuna_desc)==-1) { croak("FATAL: cannot register_prng fortuna"); }
if(register_prng(&yarrow_desc)==-1) { croak("FATAL: cannot register_prng yarrow"); }
- if(register_prng(&rc4_prng_desc)==-1) { croak("FATAL: cannot register_prng rc4"); }
- if(register_prng(&sober128_prng_desc)==-1) { croak("FATAL: cannot register_prng sober128"); }
+ if(register_prng(&rc4_desc)==-1) { croak("FATAL: cannot register_prng rc4"); }
+ if(register_prng(&sober128_desc)==-1) { croak("FATAL: cannot register_prng sober128"); }
if(register_prng(&chacha20_prng_desc)==-1) { croak("FATAL: cannot register_prng chacha20"); }
/* --- */
#ifdef TFM_DESC
diff --git a/inc/CryptX_Stream_RC4.xs.inc b/inc/CryptX_Stream_RC4.xs.inc
index 7707ded8..45a047dc 100644
--- a/inc/CryptX_Stream_RC4.xs.inc
+++ b/inc/CryptX_Stream_RC4.xs.inc
@@ -14,8 +14,8 @@ _new(SV * key)
Newz(0, RETVAL, 1, struct rc4_struct);
if (!RETVAL) croak("FATAL: Newz failed");
- rv = rc4_setup(&RETVAL->state, k, (unsigned long)k_len);
- if (rv != CRYPT_OK) croak("FATAL: rc4_setup failed: %s", error_to_string(rv));
+ rv = rc4_stream_setup(&RETVAL->state, k, (unsigned long)k_len);
+ if (rv != CRYPT_OK) croak("FATAL: rc4_stream_setup failed: %s", error_to_string(rv));
}
OUTPUT:
RETVAL
@@ -23,7 +23,7 @@ _new(SV * key)
void
DESTROY(Crypt::Stream::RC4 self)
CODE:
- rc4_done(&self->state);
+ rc4_stream_done(&self->state);
Safefree(self);
Crypt::Stream::RC4
@@ -46,8 +46,8 @@ keystream(Crypt::Stream::RC4 self, STRLEN out_len)
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, out_len);
out_data = (unsigned char *)SvPV_nolen(RETVAL);
- rv = rc4_keystream(&self->state, out_data, out_len);
- if (rv != CRYPT_OK) croak("FATAL: rc4_keystream failed: %s", error_to_string(rv));
+ rv = rc4_stream_keystream(&self->state, out_data, out_len);
+ if (rv != CRYPT_OK) croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv));
}
OUTPUT:
RETVAL
@@ -69,8 +69,8 @@ crypt(Crypt::Stream::RC4 self, SV * data)
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, in_data_len);
out_data = (unsigned char *)SvPV_nolen(RETVAL);
- rv = rc4_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
- if (rv != CRYPT_OK) croak("FATAL: rc4_crypt failed: %s", error_to_string(rv));
+ rv = rc4_stream_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
+ if (rv != CRYPT_OK) croak("FATAL: rc4_stream_crypt failed: %s", error_to_string(rv));
}
}
OUTPUT:
diff --git a/inc/CryptX_Stream_Sober128.xs.inc b/inc/CryptX_Stream_Sober128.xs.inc
index 340700f8..5269afc2 100644
--- a/inc/CryptX_Stream_Sober128.xs.inc
+++ b/inc/CryptX_Stream_Sober128.xs.inc
@@ -16,11 +16,11 @@ _new(SV * key, SV * nonce)
Newz(0, RETVAL, 1, struct sober128_struct);
if (!RETVAL) croak("FATAL: Newz failed");
- rv = sober128_setup(&RETVAL->state, k, (unsigned long)k_len);
- if (rv != CRYPT_OK) croak("FATAL: sober128_setup failed: %s", error_to_string(rv));
+ rv = sober128_stream_setup(&RETVAL->state, k, (unsigned long)k_len);
+ if (rv != CRYPT_OK) croak("FATAL: sober128_stream_setup failed: %s", error_to_string(rv));
- rv = sober128_setiv(&RETVAL->state, iv, (unsigned long)iv_len);
- if (rv != CRYPT_OK) croak("FATAL: sober128_setiv failed: %s", error_to_string(rv));
+ rv = sober128_stream_setiv(&RETVAL->state, iv, (unsigned long)iv_len);
+ if (rv != CRYPT_OK) croak("FATAL: sober128_stream_setiv failed: %s", error_to_string(rv));
}
OUTPUT:
RETVAL
@@ -28,7 +28,7 @@ _new(SV * key, SV * nonce)
void
DESTROY(Crypt::Stream::Sober128 self)
CODE:
- sober128_done(&self->state);
+ sober128_stream_done(&self->state);
Safefree(self);
Crypt::Stream::Sober128
@@ -51,8 +51,8 @@ keystream(Crypt::Stream::Sober128 self, STRLEN out_len)
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, out_len);
out_data = (unsigned char *)SvPV_nolen(RETVAL);
- rv = sober128_keystream(&self->state, out_data, out_len);
- if (rv != CRYPT_OK) croak("FATAL: sober128_keystream failed: %s", error_to_string(rv));
+ rv = sober128_stream_keystream(&self->state, out_data, out_len);
+ if (rv != CRYPT_OK) croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv));
}
OUTPUT:
RETVAL
@@ -74,8 +74,8 @@ crypt(Crypt::Stream::Sober128 self, SV * data)
SvPOK_only(RETVAL);
SvCUR_set(RETVAL, in_data_len);
out_data = (unsigned char *)SvPV_nolen(RETVAL);
- rv = sober128_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
- if (rv != CRYPT_OK) croak("FATAL: sober128_crypt failed: %s", error_to_string(rv));
+ rv = sober128_stream_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
+ if (rv != CRYPT_OK) croak("FATAL: sober128_stream_crypt failed: %s", error_to_string(rv));
}
}
OUTPUT:
diff --git a/src/ltc/hashes/helper/hash_filehandle.c b/src/ltc/hashes/helper/hash_filehandle.c
index 41832fdf..e1d037e8 100644
--- a/src/ltc/hashes/helper/hash_filehandle.c
+++ b/src/ltc/hashes/helper/hash_filehandle.c
@@ -27,7 +27,7 @@
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
{
hash_state md;
- unsigned char buf[512];
+ unsigned char *buf;
size_t x;
int err;
@@ -35,30 +35,36 @@ int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outle
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(in != NULL);
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
+ }
+
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
- return err;
+ goto LBL_ERR;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
- return CRYPT_BUFFER_OVERFLOW;
+ err = CRYPT_BUFFER_OVERFLOW;
+ goto LBL_ERR;
}
if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) {
- return err;
+ goto LBL_ERR;
}
*outlen = hash_descriptor[hash].hashsize;
do {
- x = fread(buf, 1, sizeof(buf), in);
+ x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = hash_descriptor[hash].process(&md, buf, (unsigned long)x)) != CRYPT_OK) {
- return err;
+ goto LBL_CLEANBUF;
}
- } while (x == sizeof(buf));
+ } while (x == LTC_FILE_READ_BUFSIZE);
err = hash_descriptor[hash].done(&md, out);
-#ifdef LTC_CLEAN_STACK
- zeromem(buf, sizeof(buf));
-#endif
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
+LBL_ERR:
+ XFREE(buf);
return err;
}
#endif /* #ifndef LTC_NO_FILE */
diff --git a/src/ltc/headers/tomcrypt_cipher.h b/src/ltc/headers/tomcrypt_cipher.h
index 603f24ad..58f02db4 100644
--- a/src/ltc/headers/tomcrypt_cipher.h
+++ b/src/ltc/headers/tomcrypt_cipher.h
@@ -959,22 +959,22 @@ int chacha_test(void);
#endif /* LTC_CHACHA */
-#ifdef LTC_RC4
+#ifdef LTC_RC4_STREAM
typedef struct {
- int x, y;
+ unsigned int x, y;
unsigned char buf[256];
} rc4_state;
-int rc4_setup(rc4_state *st, const unsigned char *key, unsigned long keylen);
-int rc4_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out);
-int rc4_keystream(rc4_state *st, unsigned char *out, unsigned long outlen);
-int rc4_done(rc4_state *st);
-int rc4_test(void);
+int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen);
+int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out);
+int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen);
+int rc4_stream_done(rc4_state *st);
+int rc4_stream_test(void);
-#endif /* LTC_RC4 */
+#endif /* LTC_RC4_STREAM */
-#ifdef LTC_SOBER128
+#ifdef LTC_SOBER128_STREAM
typedef struct {
ulong32 R[17], /* Working storage for the shift register */
@@ -984,14 +984,14 @@ typedef struct {
int nbuf; /* number of part-word stream bits buffered */
} sober128_state;
-int sober128_setup(sober128_state *st, const unsigned char *key, unsigned long keylen);
-int sober128_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen);
-int sober128_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out);
-int sober128_keystream(sober128_state *st, unsigned char *out, unsigned long outlen);
-int sober128_done(sober128_state *st);
-int sober128_test(void);
+int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen);
+int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen);
+int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out);
+int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen);
+int sober128_stream_done(sober128_state *st);
+int sober128_stream_test(void);
-#endif /* LTC_SOBER128 */
+#endif /* LTC_SOBER128_STREAM */
/* $Source$ */
/* $Revision$ */
diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h
index a118d7ca..085a5623 100644
--- a/src/ltc/headers/tomcrypt_custom.h
+++ b/src/ltc/headers/tomcrypt_custom.h
@@ -195,8 +195,8 @@
/* stream ciphers */
#define LTC_CHACHA
-#define LTC_RC4
-#define LTC_SOBER128
+#define LTC_RC4_STREAM
+#define LTC_SOBER128_STREAM
#endif /* LTC_NO_CIPHERS */
@@ -302,7 +302,7 @@
#define LTC_SPRNG
/* The RC4 stream cipher based PRNG */
-#define LTC_RC4_PRNG
+#define LTC_RC4
/* The ChaCha20 stream cipher based PRNG */
#define LTC_CHACHA20_PRNG
@@ -311,7 +311,7 @@
#define LTC_FORTUNA
/* Greg's SOBER128 stream cipher based PRNG */
-#define LTC_SOBER128_PRNG
+#define LTC_SOBER128
/* the *nix style /dev/random device */
#define LTC_DEVRANDOM
@@ -557,12 +557,12 @@
#error LTC_CHACHA20_PRNG requires LTC_CHACHA
#endif
-#if defined(LTC_RC4_PRNG) && !defined(LTC_RC4)
- #error LTC_RC4_PRNG requires LTC_RC4
+#if defined(LTC_RC4) && !defined(LTC_RC4_STREAM)
+ #error LTC_RC4 requires LTC_RC4_STREAM
#endif
-#if defined(LTC_SOBER128_PRNG) && !defined(LTC_SOBER128)
- #error LTC_SOBER128_PRNG requires LTC_SOBER128
+#if defined(LTC_SOBER128) && !defined(LTC_SOBER128_STREAM)
+ #error LTC_SOBER128 requires LTC_SOBER128_STREAM
#endif
#if defined(LTC_BLAKE2SMAC) && !defined(LTC_BLAKE2S)
diff --git a/src/ltc/headers/tomcrypt_prng.h b/src/ltc/headers/tomcrypt_prng.h
index 83807542..b90d36b5 100644
--- a/src/ltc/headers/tomcrypt_prng.h
+++ b/src/ltc/headers/tomcrypt_prng.h
@@ -4,14 +4,12 @@ struct yarrow_prng {
int cipher, hash;
unsigned char pool[MAXBLOCKSIZE];
symmetric_CTR ctr;
- LTC_MUTEX_TYPE(prng_lock)
};
#endif
#ifdef LTC_RC4
struct rc4_prng {
rc4_state s;
- short ready;
};
#endif
@@ -20,7 +18,6 @@ struct chacha20_prng {
chacha_state s; /* chacha state */
unsigned char ent[40]; /* entropy buffer */
unsigned long idx; /* entropy counter */
- short ready; /* ready flag 0-1 */
};
#endif
@@ -38,7 +35,6 @@ struct fortuna_prng {
wd;
ulong64 reset_cnt; /* number of times we have reset */
- LTC_MUTEX_TYPE(prng_lock)
};
#endif
@@ -47,27 +43,30 @@ struct sober128_prng {
sober128_state s; /* sober128 state */
unsigned char ent[40]; /* entropy buffer */
unsigned long idx; /* entropy counter */
- short ready; /* ready flag 0-1 */
};
#endif
-typedef union Prng_state {
- char dummy[1];
+typedef struct {
+ union {
+ char dummy[1];
#ifdef LTC_YARROW
- struct yarrow_prng yarrow;
+ struct yarrow_prng yarrow;
#endif
#ifdef LTC_RC4
- struct rc4_prng rc4;
+ struct rc4_prng rc4;
#endif
#ifdef LTC_CHACHA20_PRNG
- struct chacha20_prng chacha;
+ struct chacha20_prng chacha;
#endif
#ifdef LTC_FORTUNA
- struct fortuna_prng fortuna;
+ struct fortuna_prng fortuna;
#endif
#ifdef LTC_SOBER128
- struct sober128_prng sober128;
+ struct sober128_prng sober128;
#endif
+ };
+ short ready; /* ready flag 0-1 */
+ LTC_MUTEX_TYPE(lock); /* lock */
} prng_state;
/** PRNG descriptor */
@@ -150,15 +149,15 @@ extern const struct ltc_prng_descriptor fortuna_desc;
#endif
#ifdef LTC_RC4
-int rc4_prng_start(prng_state *prng);
-int rc4_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
-int rc4_prng_ready(prng_state *prng);
-unsigned long rc4_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
-int rc4_prng_done(prng_state *prng);
-int rc4_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
-int rc4_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
-int rc4_prng_test(void);
-extern const struct ltc_prng_descriptor rc4_prng_desc;
+int rc4_start(prng_state *prng);
+int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
+int rc4_ready(prng_state *prng);
+unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng);
+int rc4_done(prng_state *prng);
+int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
+int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
+int rc4_test(void);
+extern const struct ltc_prng_descriptor rc4_desc;
#endif
#ifdef LTC_CHACHA20_PRNG
@@ -186,15 +185,15 @@ extern const struct ltc_prng_descriptor sprng_desc;
#endif
#ifdef LTC_SOBER128
-int sober128_prng_start(prng_state *prng);
-int sober128_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
-int sober128_prng_ready(prng_state *prng);
-unsigned long sober128_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
-int sober128_prng_done(prng_state *prng);
-int sober128_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
-int sober128_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
-int sober128_prng_test(void);
-extern const struct ltc_prng_descriptor sober128_prng_desc;
+int sober128_start(prng_state *prng);
+int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
+int sober128_ready(prng_state *prng);
+unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng);
+int sober128_done(prng_state *prng);
+int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
+int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
+int sober128_test(void);
+extern const struct ltc_prng_descriptor sober128_desc;
#endif
int find_prng(const char *name);
diff --git a/src/ltc/mac/f9/f9_file.c b/src/ltc/mac/f9/f9_file.c
index 5d885fb5..c99d7a39 100644
--- a/src/ltc/mac/f9/f9_file.c
+++ b/src/ltc/mac/f9/f9_file.c
@@ -22,14 +22,14 @@
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the secret key (octets)
- @param filename The name of the file you wish to f9
+ @param fname The name of the file you wish to f9
@param out [out] Where the authentication tag is to be stored
@param outlen [in/out] The max size and resulting size of the authentication tag
@return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
*/
int f9_file(int cipher,
const unsigned char *key, unsigned long keylen,
- const char *filename,
+ const char *fname,
unsigned char *out, unsigned long *outlen)
{
#ifdef LTC_NO_FILE
@@ -39,41 +39,50 @@ int f9_file(int cipher,
int err;
f9_state f9;
FILE *in;
- unsigned char buf[512];
+ unsigned char *buf;
- LTC_ARGCHK(key != NULL);
- LTC_ARGCHK(filename != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
+ LTC_ARGCHK(key != NULL);
+ LTC_ARGCHK(fname != NULL);
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
- in = fopen(filename, "rb");
- if (in == NULL) {
- return CRYPT_FILE_NOTFOUND;
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
}
if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) {
- fclose(in);
- return err;
+ goto LBL_ERR;
+ }
+
+ in = fopen(fname, "rb");
+ if (in == NULL) {
+ err = CRYPT_FILE_NOTFOUND;
+ goto LBL_ERR;
}
do {
- x = fread(buf, 1, sizeof(buf), in);
+ x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = f9_process(&f9, buf, (unsigned long)x)) != CRYPT_OK) {
fclose(in);
- return err;
+ goto LBL_CLEANBUF;
}
- } while (x == sizeof(buf));
- fclose(in);
+ } while (x == LTC_FILE_READ_BUFSIZE);
- if ((err = f9_done(&f9, out, outlen)) != CRYPT_OK) {
- return err;
+ if (fclose(in) != 0) {
+ err = CRYPT_ERROR;
+ goto LBL_CLEANBUF;
}
+ err = f9_done(&f9, out, outlen);
+
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
+LBL_ERR:
#ifdef LTC_CLEAN_STACK
- zeromem(buf, sizeof(buf));
+ zeromem(&f9, sizeof(f9_state));
#endif
-
- return CRYPT_OK;
+ XFREE(buf);
+ return err;
#endif
}
diff --git a/src/ltc/mac/hmac/hmac_file.c b/src/ltc/mac/hmac/hmac_file.c
index 8558c2ac..f74505c0 100644
--- a/src/ltc/mac/hmac/hmac_file.c
+++ b/src/ltc/mac/hmac/hmac_file.c
@@ -36,7 +36,7 @@ int hmac_file(int hash, const char *fname,
#else
hmac_state hmac;
FILE *in;
- unsigned char buf[512];
+ unsigned char *buf;
size_t x;
int err;
@@ -45,49 +45,52 @@ int hmac_file(int hash, const char *fname,
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
- if((err = hash_is_valid(hash)) != CRYPT_OK) {
- return err;
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
+ }
+
+ if ((err = hash_is_valid(hash)) != CRYPT_OK) {
+ goto LBL_ERR;
}
if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
- return err;
+ goto LBL_ERR;
}
in = fopen(fname, "rb");
if (in == NULL) {
- return CRYPT_FILE_NOTFOUND;
+ err = CRYPT_FILE_NOTFOUND;
+ goto LBL_ERR;
}
- /* process the file contents */
do {
- x = fread(buf, 1, sizeof(buf), in);
+ x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) {
- /* we don't trap this error since we're already returning an error! */
- fclose(in);
- return err;
+ fclose(in); /* we don't trap this error since we're already returning an error! */
+ goto LBL_CLEANBUF;
}
- } while (x == sizeof(buf));
+ } while (x == LTC_FILE_READ_BUFSIZE);
if (fclose(in) != 0) {
- return CRYPT_ERROR;
+ err = CRYPT_ERROR;
+ goto LBL_CLEANBUF;
}
- /* get final hmac */
- if ((err = hmac_done(&hmac, out, outlen)) != CRYPT_OK) {
- return err;
- }
+ err = hmac_done(&hmac, out, outlen);
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
+LBL_ERR:
#ifdef LTC_CLEAN_STACK
- /* clear memory */
- zeromem(buf, sizeof(buf));
+ zeromem(&hmac, sizeof(hmac_state));
#endif
- return CRYPT_OK;
+ XFREE(buf);
+ return err;
#endif
}
#endif
-
/* $Source$ */
/* $Revision$ */
/* $Date$ */
diff --git a/src/ltc/mac/omac/omac_file.c b/src/ltc/mac/omac/omac_file.c
index bbff793d..51c67b78 100644
--- a/src/ltc/mac/omac/omac_file.c
+++ b/src/ltc/mac/omac/omac_file.c
@@ -39,41 +39,50 @@ int omac_file(int cipher,
int err;
omac_state omac;
FILE *in;
- unsigned char buf[512];
+ unsigned char *buf;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(filename != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
- in = fopen(filename, "rb");
- if (in == NULL) {
- return CRYPT_FILE_NOTFOUND;
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
}
if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
- fclose(in);
- return err;
+ goto LBL_ERR;
+ }
+
+ in = fopen(filename, "rb");
+ if (in == NULL) {
+ err = CRYPT_FILE_NOTFOUND;
+ goto LBL_ERR;
}
do {
- x = fread(buf, 1, sizeof(buf), in);
+ x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = omac_process(&omac, buf, (unsigned long)x)) != CRYPT_OK) {
fclose(in);
- return err;
+ goto LBL_CLEANBUF;
}
- } while (x == sizeof(buf));
- fclose(in);
+ } while (x == LTC_FILE_READ_BUFSIZE);
- if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
- return err;
+ if (fclose(in) != 0) {
+ err = CRYPT_ERROR;
+ goto LBL_CLEANBUF;
}
+ err = omac_done(&omac, out, outlen);
+
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
+LBL_ERR:
#ifdef LTC_CLEAN_STACK
- zeromem(buf, sizeof(buf));
+ zeromem(&omac, sizeof(omac_state));
#endif
-
- return CRYPT_OK;
+ XFREE(buf);
+ return err;
#endif
}
diff --git a/src/ltc/mac/pmac/pmac_file.c b/src/ltc/mac/pmac/pmac_file.c
index b484400f..c7d9877d 100644
--- a/src/ltc/mac/pmac/pmac_file.c
+++ b/src/ltc/mac/pmac/pmac_file.c
@@ -39,7 +39,7 @@ int pmac_file(int cipher,
int err;
pmac_state pmac;
FILE *in;
- unsigned char buf[512];
+ unsigned char *buf;
LTC_ARGCHK(key != NULL);
@@ -47,34 +47,43 @@ int pmac_file(int cipher,
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
- in = fopen(filename, "rb");
- if (in == NULL) {
- return CRYPT_FILE_NOTFOUND;
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
}
if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) {
- fclose(in);
- return err;
+ goto LBL_ERR;
+ }
+
+ in = fopen(filename, "rb");
+ if (in == NULL) {
+ err = CRYPT_FILE_NOTFOUND;
+ goto LBL_ERR;
}
do {
- x = fread(buf, 1, sizeof(buf), in);
+ x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = pmac_process(&pmac, buf, (unsigned long)x)) != CRYPT_OK) {
fclose(in);
- return err;
+ goto LBL_CLEANBUF;
}
- } while (x == sizeof(buf));
- fclose(in);
+ } while (x == LTC_FILE_READ_BUFSIZE);
- if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) {
- return err;
+ if (fclose(in) != 0) {
+ err = CRYPT_ERROR;
+ goto LBL_CLEANBUF;
}
+ err = pmac_done(&pmac, out, outlen);
+
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
+LBL_ERR:
#ifdef LTC_CLEAN_STACK
- zeromem(buf, sizeof(buf));
+ zeromem(&pmac, sizeof(pmac_state));
#endif
-
- return CRYPT_OK;
+ XFREE(buf);
+ return err;
#endif
}
diff --git a/src/ltc/mac/poly1305/poly1305_file.c b/src/ltc/mac/poly1305/poly1305_file.c
index e119b924..42afdc3e 100644
--- a/src/ltc/mac/poly1305/poly1305_file.c
+++ b/src/ltc/mac/poly1305/poly1305_file.c
@@ -21,8 +21,8 @@
@param fname The name of the file you wish to POLY1305
@param key The secret key
@param keylen The length of the secret key
- @param out [out] The POLY1305 authentication tag
- @param outlen [in/out] The max size and resulting size of the authentication tag
+ @param mac [out] The POLY1305 authentication tag
+ @param maclen [in/out] The max size and resulting size of the authentication tag
@return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
*/
int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
@@ -41,23 +41,37 @@ int poly1305_file(const char *fname, const unsigned char *key, unsigned long key
LTC_ARGCHK(mac != NULL);
LTC_ARGCHK(maclen != NULL);
- if ((in = fopen(fname, "rb")) == NULL) { return CRYPT_FILE_NOTFOUND; }
- if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { return CRYPT_MEM; }
- if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; }
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
+ }
+
+ if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) {
+ goto LBL_ERR;
+ }
+
+ in = fopen(fname, "rb");
+ if (in == NULL) {
+ err = CRYPT_FILE_NOTFOUND;
+ goto LBL_ERR;
+ }
do {
x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = poly1305_process(&st, buf, (unsigned long)x)) != CRYPT_OK) {
fclose(in);
- goto LBL_ERR;
+ goto LBL_CLEANBUF;
}
} while (x == LTC_FILE_READ_BUFSIZE);
- if (fclose(in) != 0) {
+
+ if (fclose(in) != 0) {
err = CRYPT_ERROR;
- goto LBL_ERR;
+ goto LBL_CLEANBUF;
}
+
err = poly1305_done(&st, mac, maclen);
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(&st, sizeof(poly1305_state));
@@ -65,6 +79,6 @@ LBL_ERR:
XFREE(buf);
return err;
#endif
-};
+}
#endif
diff --git a/src/ltc/mac/poly1305/poly1305_memory.c b/src/ltc/mac/poly1305/poly1305_memory.c
index 2f7a8e04..b948efb3 100644
--- a/src/ltc/mac/poly1305/poly1305_memory.c
+++ b/src/ltc/mac/poly1305/poly1305_memory.c
@@ -44,6 +44,6 @@ LBL_ERR:
zeromem(&st, sizeof(poly1305_state));
#endif
return err;
-};
+}
#endif
diff --git a/src/ltc/mac/poly1305/poly1305_memory_multi.c b/src/ltc/mac/poly1305/poly1305_memory_multi.c
index 047f5fd7..0ac122e5 100644
--- a/src/ltc/mac/poly1305/poly1305_memory_multi.c
+++ b/src/ltc/mac/poly1305/poly1305_memory_multi.c
@@ -58,6 +58,6 @@ LBL_ERR:
#endif
va_end(args);
return err;
-};
+}
#endif
diff --git a/src/ltc/mac/xcbc/xcbc_file.c b/src/ltc/mac/xcbc/xcbc_file.c
index bba0d48e..c8119f9a 100644
--- a/src/ltc/mac/xcbc/xcbc_file.c
+++ b/src/ltc/mac/xcbc/xcbc_file.c
@@ -39,41 +39,50 @@ int xcbc_file(int cipher,
int err;
xcbc_state xcbc;
FILE *in;
- unsigned char buf[512];
+ unsigned char *buf;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(filename != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
- in = fopen(filename, "rb");
- if (in == NULL) {
- return CRYPT_FILE_NOTFOUND;
+ if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
+ return CRYPT_MEM;
}
if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) {
- fclose(in);
- return err;
+ goto LBL_ERR;
+ }
+
+ in = fopen(filename, "rb");
+ if (in == NULL) {
+ err = CRYPT_FILE_NOTFOUND;
+ goto LBL_ERR;
}
do {
- x = fread(buf, 1, sizeof(buf), in);
+ x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = xcbc_process(&xcbc, buf, (unsigned long)x)) != CRYPT_OK) {
fclose(in);
- return err;
+ goto LBL_CLEANBUF;
}
- } while (x == sizeof(buf));
- fclose(in);
+ } while (x == LTC_FILE_READ_BUFSIZE);
- if ((err = xcbc_done(&xcbc, out, outlen)) != CRYPT_OK) {
- return err;
+ if (fclose(in) != 0) {
+ err = CRYPT_ERROR;
+ goto LBL_CLEANBUF;
}
+ err = xcbc_done(&xcbc, out, outlen);
+
+LBL_CLEANBUF:
+ zeromem(buf, LTC_FILE_READ_BUFSIZE);
+LBL_ERR:
#ifdef LTC_CLEAN_STACK
- zeromem(buf, sizeof(buf));
+ zeromem(&xcbc, sizeof(xcbc_state));
#endif
-
- return CRYPT_OK;
+ XFREE(buf);
+ return err;
#endif
}
diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c
index 43314061..cfe26063 100644
--- a/src/ltc/misc/crypt/crypt.c
+++ b/src/ltc/misc/crypt/crypt.c
@@ -124,9 +124,16 @@ const char *crypt_build_settings =
#if defined(LTC_CAMELLIA)
" Camellia\n"
#endif
+ "Stream ciphers built-in:\n"
#if defined(LTC_CHACHA)
" ChaCha\n"
#endif
+#if defined(LTC_RC4_STREAM)
+ " RC4\n"
+#endif
+#if defined(LTC_SOBER128_STREAM)
+ " SOBER128\n"
+#endif
"\nHashes built-in:\n"
#if defined(LTC_SHA3)
@@ -180,6 +187,12 @@ const char *crypt_build_settings =
#if defined(LTC_WHIRLPOOL)
" WHIRLPOOL\n"
#endif
+#if defined(LTC_BLAKE2S)
+ " BLAKE2S\n"
+#endif
+#if defined(LTC_BLAKE2B)
+ " BLAKE2B\n"
+#endif
#if defined(LTC_CHC_HASH)
" CHC_HASH\n"
#endif
@@ -236,6 +249,12 @@ const char *crypt_build_settings =
#if defined(LTC_POLY1305)
" POLY1305\n"
#endif
+#if defined(LTC_BLAKE2SMAC)
+ " BLAKE2S MAC\n"
+#endif
+#if defined(LTC_BLAKE2BMAC)
+ " BLAKE2B MAC\n"
+#endif
"\nENC + AUTH modes:\n"
#if defined(LTC_EAX_MODE)
diff --git a/src/ltc/prngs/chacha20.c b/src/ltc/prngs/chacha20.c
index 3faa3a24..faaf629e 100644
--- a/src/ltc/prngs/chacha20.c
+++ b/src/ltc/prngs/chacha20.c
@@ -18,7 +18,7 @@
const struct ltc_prng_descriptor chacha20_prng_desc =
{
"chacha20",
- sizeof(chacha_state),
+ 40,
&chacha20_prng_start,
&chacha20_prng_add_entropy,
&chacha20_prng_ready,
@@ -37,9 +37,10 @@ const struct ltc_prng_descriptor chacha20_prng_desc =
int chacha20_prng_start(prng_state *prng)
{
LTC_ARGCHK(prng != NULL);
- prng->chacha.ready = 0;
- XMEMSET(&prng->chacha.ent, 0, 40);
+ prng->ready = 0;
+ XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent));
prng->chacha.idx = 0;
+ LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
@@ -60,23 +61,26 @@ int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen > 0);
- if (prng->chacha.ready) {
+ 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, 40)) != CRYPT_OK) return err;
- for(i = 0; i < inlen; i++) buf[i % 40] ^= in[i];
+ if ((err = chacha_keystream(&prng->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) return err;
+ if ((err = chacha_setup(&prng->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) return err;
+ if ((err = chacha_ivctr64(&prng->chacha.s, buf + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
/* clear KEY + IV */
- XMEMSET(buf, 0, 40);
+ XMEMSET(buf, 0, sizeof(buf));
}
else {
/* chacha20_prng_ready() was not called yet, add entropy to ent buffer */
- while (inlen--) prng->chacha.ent[prng->chacha.idx++ % 40] ^= *in++;
+ while (inlen--) prng->chacha.ent[prng->chacha.idx++ % sizeof(prng->chacha.ent)] ^= *in++;
}
-
- return CRYPT_OK;
+ err = CRYPT_OK;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -89,16 +93,19 @@ int chacha20_prng_ready(prng_state *prng)
int err;
LTC_ARGCHK(prng != NULL);
- if (prng->chacha.ready) return CRYPT_OK;
+ 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) return err;
+ if ((err = chacha_setup(&prng->chacha.s, prng->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) return err;
- XMEMSET(&prng->chacha.ent, 0, 40);
- prng->chacha.ready = 1;
+ 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;
- return CRYPT_OK;
+ prng->ready = 1;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -110,9 +117,12 @@ int chacha20_prng_ready(prng_state *prng)
*/
unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
- LTC_ARGCHK(prng != NULL);
- if (!prng->chacha.ready) return 0;
- if (chacha_keystream(&prng->chacha.s, out, outlen) != CRYPT_OK) return 0;
+ 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;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
return outlen;
}
@@ -124,11 +134,12 @@ unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_
int chacha20_prng_done(prng_state *prng)
{
int err;
-
LTC_ARGCHK(prng != NULL);
- if ((err = chacha_done(&prng->chacha.s)) != CRYPT_OK) return err;
- prng->chacha.ready = 0;
- return CRYPT_OK;
+ LTC_MUTEX_LOCK(&prng->lock);
+ prng->ready = 0;
+ err = chacha_done(&prng->chacha.s);
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -140,19 +151,21 @@ int chacha20_prng_done(prng_state *prng)
*/
int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
{
- unsigned long len = sizeof(chacha_state);
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(out != NULL);
+ unsigned long len = chacha20_prng_desc.export_size;
+
LTC_ARGCHK(prng != NULL);
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
- if (!prng->chacha.ready) {
- return CRYPT_ERROR;
- }
if (*outlen < len) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
- XMEMCPY(out, &prng->chacha.s, len);
+
+ if (chacha20_prng_read(out, len, prng) != len) {
+ return CRYPT_ERROR_READPRNG;
+ }
+
*outlen = len;
return CRYPT_OK;
}
@@ -166,13 +179,14 @@ int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *
*/
int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
- unsigned long len = sizeof(chacha_state);
- LTC_ARGCHK(in != NULL);
+ int err;
+
LTC_ARGCHK(prng != NULL);
+ LTC_ARGCHK(in != NULL);
+ if (inlen < (unsigned long)chacha20_prng_desc.export_size) return CRYPT_INVALID_ARG;
- if (inlen != len) return CRYPT_INVALID_ARG;
- XMEMCPY(&prng->chacha.s, in, inlen);
- prng->chacha.ready = 1;
+ if ((err = chacha20_prng_start(prng)) != CRYPT_OK) return err;
+ if ((err = chacha20_prng_add_entropy(in, inlen, prng)) != CRYPT_OK) return err;
return CRYPT_OK;
}
@@ -194,29 +208,32 @@ int chacha20_prng_test(void)
unsigned char dmp[300];
unsigned long dmplen = sizeof(dmp);
unsigned char out[500];
- unsigned char t1[] = { 0x59, 0xb2, 0x26, 0x95, 0x2b, 0x01, 0x8f, 0x05, 0xbe, 0xd8 };
- unsigned char t2[] = { 0x30, 0x34, 0x5c, 0x6e, 0x56, 0x18, 0x8c, 0x46, 0xbe, 0x8a };
-
- chacha20_prng_start(&st);
- chacha20_prng_add_entropy(en, sizeof(en), &st); /* add entropy to uninitialized prng */
- chacha20_prng_ready(&st);
- chacha20_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t1, sizeof(t1), "CHACHA-PRNG", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
- chacha20_prng_read(out, 500, &st);
- chacha20_prng_add_entropy(en, sizeof(en), &st); /* add entropy to already initialized prng */
- chacha20_prng_read(out, 500, &st);
- chacha20_prng_export(dmp, &dmplen, &st);
- chacha20_prng_read(out, 500, &st); /* skip 500 bytes */
- chacha20_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
- chacha20_prng_done(&st);
-
- XMEMSET(&st, 0xFF, sizeof(st)); /* just to be sure */
- chacha20_prng_import(dmp, dmplen, &st);
- chacha20_prng_read(out, 500, &st); /* skip 500 bytes */
- chacha20_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
- chacha20_prng_done(&st);
+ unsigned char t1[] = { 0x59, 0xB2, 0x26, 0x95, 0x2B, 0x01, 0x8F, 0x05, 0xBE, 0xD8 };
+ unsigned char t2[] = { 0x47, 0xC9, 0x0D, 0x03, 0xE4, 0x75, 0x34, 0x27, 0xBD, 0xDE };
+ unsigned char t3[] = { 0xBC, 0xFA, 0xEF, 0x59, 0x37, 0x7F, 0x1A, 0x91, 0x1A, 0xA6 };
+ int err;
+
+ if ((err = chacha20_prng_start(&st)) != CRYPT_OK) return err;
+ /* add entropy to uninitialized prng */
+ if ((err = chacha20_prng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if ((err = chacha20_prng_ready(&st)) != CRYPT_OK) return err;
+ if (chacha20_prng_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t1, sizeof(t1), "CHACHA-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR;
+ if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ /* add entropy to already initialized prng */
+ if ((err = chacha20_prng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if ((err = chacha20_prng_export(dmp, &dmplen, &st)) != CRYPT_OK) return err;
+ if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if (chacha20_prng_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR;
+ if ((err = chacha20_prng_done(&st)) != CRYPT_OK) return err;
+ if ((err = chacha20_prng_import(dmp, dmplen, &st)) != CRYPT_OK) return err;
+ if ((err = chacha20_prng_ready(&st)) != CRYPT_OK) return err;
+ if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if (chacha20_prng_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t3, sizeof(t3), "CHACHA-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR;
+ if ((err = chacha20_prng_done(&st)) != CRYPT_OK) return err;
return CRYPT_OK;
#endif
diff --git a/src/ltc/prngs/fortuna.c b/src/ltc/prngs/fortuna.c
index 173deea5..15f3c4c5 100644
--- a/src/ltc/prngs/fortuna.c
+++ b/src/ltc/prngs/fortuna.c
@@ -5,8 +5,6 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
@@ -38,7 +36,8 @@ we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to t
#endif
const struct ltc_prng_descriptor fortuna_desc = {
- "fortuna", 1024,
+ "fortuna",
+ (32 * LTC_FORTUNA_POOLS), /* default: 1024 */
&fortuna_start,
&fortuna_add_entropy,
&fortuna_ready,
@@ -133,6 +132,7 @@ int fortuna_start(prng_state *prng)
unsigned char tmp[MAXBLOCKSIZE];
LTC_ARGCHK(prng != NULL);
+ prng->ready = 0;
/* initialize the pools */
for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
@@ -156,7 +156,7 @@ int fortuna_start(prng_state *prng)
}
zeromem(prng->fortuna.IV, 16);
- LTC_MUTEX_INIT(&prng->fortuna.prng_lock)
+ LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
@@ -173,27 +173,25 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
unsigned char tmp[2];
int err;
- LTC_ARGCHK(in != NULL);
LTC_ARGCHK(prng != NULL);
-
- LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(inlen > 0);
/* ensure inlen <= 32 */
if (inlen > 32) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return CRYPT_INVALID_ARG;
+ inlen = 32;
}
/* add s || length(in) || in to pool[pool_idx] */
tmp[0] = 0;
tmp[1] = (unsigned char)inlen;
+
+ LTC_MUTEX_LOCK(&prng->lock);
if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
if (prng->fortuna.pool_idx == 0) {
prng->fortuna.pool0_len += inlen;
@@ -201,9 +199,11 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) {
prng->fortuna.pool_idx = 0;
}
+ err = CRYPT_OK; /* success */
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return CRYPT_OK;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -213,7 +213,15 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
*/
int fortuna_ready(prng_state *prng)
{
- return fortuna_reseed(prng);
+ int err;
+ LTC_ARGCHK(prng != NULL);
+
+ LTC_MUTEX_LOCK(&prng->lock);
+ err = fortuna_reseed(prng);
+ prng->ready = (err == CRYPT_OK) ? 1 : 0;
+
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -226,18 +234,20 @@ int fortuna_ready(prng_state *prng)
unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
unsigned char tmp[16];
- unsigned long tlen;
+ unsigned long tlen = 0;
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(prng != NULL);
+ if (outlen == 0 || prng == NULL || out == NULL) return 0;
+
+ LTC_MUTEX_LOCK(&prng->lock);
- LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
+ if (!prng->ready) {
+ goto LBL_UNLOCK;
+ }
/* do we have to reseed? */
if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) {
if (fortuna_reseed(prng) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return 0;
+ goto LBL_UNLOCK;
}
}
@@ -268,14 +278,14 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state
fortuna_update_iv(prng);
if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return 0;
+ tlen = 0;
}
+LBL_UNLOCK:
#ifdef LTC_CLEAN_STACK
zeromem(tmp, sizeof(tmp));
#endif
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
+ LTC_MUTEX_UNLOCK(&prng->lock);
return tlen;
}
@@ -290,23 +300,25 @@ int fortuna_done(prng_state *prng)
unsigned char tmp[32];
LTC_ARGCHK(prng != NULL);
- LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
+
+ 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) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
}
/* call cipher done when we invent one ;-) */
+ err = CRYPT_OK; /* success */
+LBL_UNLOCK:
#ifdef LTC_CLEAN_STACK
zeromem(tmp, sizeof(tmp));
#endif
-
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return CRYPT_OK;
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -320,24 +332,30 @@ int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
{
int x, err;
hash_state *md;
+ unsigned long len = fortuna_desc.export_size;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(prng != NULL);
- LTC_MUTEX_LOCK(&prng->fortuna.prng_lock);
+ LTC_MUTEX_LOCK(&prng->lock);
+
+ if (!prng->ready) {
+ err = CRYPT_ERROR;
+ goto LBL_UNLOCK;
+ }
/* we'll write bytes for s&g's */
- if (*outlen < 32*LTC_FORTUNA_POOLS) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- *outlen = 32*LTC_FORTUNA_POOLS;
- return CRYPT_BUFFER_OVERFLOW;
+ if (*outlen < len) {
+ *outlen = len;
+ err = CRYPT_BUFFER_OVERFLOW;
+ goto LBL_UNLOCK;
}
md = XMALLOC(sizeof(hash_state));
if (md == NULL) {
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
- return CRYPT_MEM;
+ err = CRYPT_MEM;
+ goto LBL_UNLOCK;
}
/* to emit the state we copy each pool, terminate it then hash it again so
@@ -363,7 +381,7 @@ int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
goto LBL_ERR;
}
}
- *outlen = 32*LTC_FORTUNA_POOLS;
+ *outlen = len;
err = CRYPT_OK;
LBL_ERR:
@@ -371,7 +389,8 @@ LBL_ERR:
zeromem(md, sizeof(*md));
#endif
XFREE(md);
- LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
return err;
}
@@ -389,7 +408,7 @@ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prn
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(prng != NULL);
- if (inlen != 32*LTC_FORTUNA_POOLS) {
+ if (inlen < (unsigned long)fortuna_desc.export_size) {
return CRYPT_INVALID_ARG;
}
@@ -401,7 +420,7 @@ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prn
return err;
}
}
- return err;
+ return CRYPT_OK;
}
/**
diff --git a/src/ltc/prngs/rc4.c b/src/ltc/prngs/rc4.c
index 777bdfa5..e7d3afcc 100644
--- a/src/ltc/prngs/rc4.c
+++ b/src/ltc/prngs/rc4.c
@@ -5,30 +5,28 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
/**
@file rc4.c
- LTC_RC4 PRNG, Tom St Denis
+ RC4 PRNG, Tom St Denis
*/
#ifdef LTC_RC4
-const struct ltc_prng_descriptor rc4_prng_desc =
+const struct ltc_prng_descriptor rc4_desc =
{
"rc4",
- sizeof(rc4_state),
- &rc4_prng_start,
- &rc4_prng_add_entropy,
- &rc4_prng_ready,
- &rc4_prng_read,
- &rc4_prng_done,
- &rc4_prng_export,
- &rc4_prng_import,
- &rc4_prng_test
+ 32,
+ &rc4_start,
+ &rc4_add_entropy,
+ &rc4_ready,
+ &rc4_read,
+ &rc4_done,
+ &rc4_export,
+ &rc4_import,
+ &rc4_test
};
/**
@@ -36,16 +34,15 @@ const struct ltc_prng_descriptor rc4_prng_desc =
@param prng [out] The PRNG state to initialize
@return CRYPT_OK if successful
*/
-int rc4_prng_start(prng_state *prng)
+int rc4_start(prng_state *prng)
{
LTC_ARGCHK(prng != NULL);
- prng->rc4.ready = 0;
-
+ prng->ready = 0;
/* set entropy (key) size to zero */
prng->rc4.s.x = 0;
/* clear entropy (key) buffer */
- XMEMSET(&prng->rc4.s.buf, 0, 256);
-
+ XMEMSET(&prng->rc4.s.buf, 0, sizeof(prng->rc4.s.buf));
+ LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
@@ -56,7 +53,7 @@ int rc4_prng_start(prng_state *prng)
@param prng PRNG state to update
@return CRYPT_OK if successful
*/
-int rc4_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
+int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
unsigned char buf[256];
unsigned long i;
@@ -66,21 +63,24 @@ int rc4_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_stat
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen > 0);
- if (prng->rc4.ready) {
- /* rc4_prng_ready() was already called, do "rekey" operation */
- if ((err = rc4_keystream(&prng->rc4.s, buf, 256)) != CRYPT_OK) return err;
- for(i = 0; i < inlen; i++) buf[i % 256] ^= in[i];
+ 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;
+ for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
/* initialize RC4 */
- if ((err = rc4_setup(&prng->rc4.s, buf, 256)) != CRYPT_OK) return err;
+ if ((err = rc4_stream_setup(&prng->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_keystream(&prng->rc4.s, buf, 256);
+ for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf));
}
else {
- /* rc4_prng_ready() was not called yet, add entropy to the buffer */
- while (inlen--) prng->rc4.s.buf[prng->rc4.s.x++ % 256] ^= *in++;
+ /* 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++;
}
-
- return CRYPT_OK;
+ err = CRYPT_OK;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -88,25 +88,26 @@ int rc4_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_stat
@param prng The PRNG to make active
@return CRYPT_OK if successful
*/
-int rc4_prng_ready(prng_state *prng)
+int rc4_ready(prng_state *prng)
{
- unsigned char buf[256];
+ unsigned char buf[256] = { 0 };
unsigned long len;
int err, i;
LTC_ARGCHK(prng != NULL);
- if (prng->rc4.ready) return CRYPT_OK;
-
- len = MIN(prng->rc4.s.x, 256);
- if (len < 5) return CRYPT_ERROR;
- XMEMCPY(buf, prng->rc4.s.buf, len);
+ LTC_MUTEX_LOCK(&prng->lock);
+ if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
+ XMEMCPY(buf, prng->rc4.s.buf, sizeof(buf));
/* initialize RC4 */
- if ((err = rc4_setup(&prng->rc4.s, buf, len)) != CRYPT_OK) return err;
+ 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;
/* drop first 3072 bytes - https://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack */
- for (i = 0; i < 12; i++) rc4_keystream(&prng->rc4.s, buf, 256);
- prng->rc4.ready = 1;
- return CRYPT_OK;
+ for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf));
+ prng->ready = 1;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -116,11 +117,14 @@ int rc4_prng_ready(prng_state *prng)
@param prng The active PRNG to read from
@return Number of octets read
*/
-unsigned long rc4_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
+unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
- LTC_ARGCHK(prng != NULL);
- if (!prng->rc4.ready) return 0;
- if (rc4_keystream(&prng->rc4.s, out, outlen) != CRYPT_OK) return 0;
+ 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;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
return outlen;
}
@@ -129,14 +133,15 @@ unsigned long rc4_prng_read(unsigned char *out, unsigned long outlen, prng_state
@param prng The PRNG to terminate
@return CRYPT_OK if successful
*/
-int rc4_prng_done(prng_state *prng)
+int rc4_done(prng_state *prng)
{
int err;
-
LTC_ARGCHK(prng != NULL);
- if ((err = rc4_done(&prng->rc4.s)) != CRYPT_OK) return err;
- prng->rc4.ready = 0;
- return CRYPT_OK;
+ LTC_MUTEX_LOCK(&prng->lock);
+ prng->ready = 0;
+ err = rc4_stream_done(&prng->rc4.s);
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -146,21 +151,23 @@ int rc4_prng_done(prng_state *prng)
@param prng The PRNG to export
@return CRYPT_OK if successful
*/
-int rc4_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
+int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
{
- unsigned long len = sizeof(rc4_state);
+ unsigned long len = rc4_desc.export_size;
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(out != NULL);
LTC_ARGCHK(prng != NULL);
-
- if (!prng->rc4.ready) return CRYPT_ERROR;
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
if (*outlen < len) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
- XMEMCPY(out, &prng->rc4.s, len);
+
+ if (rc4_read(out, len, prng) != len) {
+ return CRYPT_ERROR_READPRNG;
+ }
+
*outlen = len;
return CRYPT_OK;
}
@@ -172,15 +179,16 @@ int rc4_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
@param prng The PRNG to import
@return CRYPT_OK if successful
*/
-int rc4_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
+int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(prng != NULL);
+ int err;
- if (inlen != sizeof(rc4_state)) return CRYPT_INVALID_ARG;
+ LTC_ARGCHK(prng != NULL);
+ LTC_ARGCHK(in != NULL);
+ if (inlen < (unsigned long)rc4_desc.export_size) return CRYPT_INVALID_ARG;
- XMEMCPY(&prng->rc4.s, in, inlen);
- prng->rc4.ready = 1;
+ if ((err = rc4_start(prng)) != CRYPT_OK) return err;
+ if ((err = rc4_add_entropy(in, inlen, prng)) != CRYPT_OK) return err;
return CRYPT_OK;
}
@@ -188,7 +196,7 @@ int rc4_prng_import(const unsigned char *in, unsigned long inlen, prng_state *pr
PRNG self-test
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
-int rc4_prng_test(void)
+int rc4_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
@@ -203,26 +211,31 @@ int rc4_prng_test(void)
unsigned long dmplen = sizeof(dmp);
unsigned char out[1000];
unsigned char t1[] = { 0xE0, 0x4D, 0x9A, 0xF6, 0xA8, 0x9D, 0x77, 0x53, 0xAE, 0x09 };
- unsigned char t2[] = { 0xEC, 0x66, 0x32, 0xAF, 0xD8, 0xBD, 0x4C, 0x42, 0x1F, 0xCB };
-
- rc4_prng_start(&st);
- rc4_prng_add_entropy(en, sizeof(en), &st);
- rc4_prng_ready(&st);
- rc4_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t1, sizeof(t1), "RC4-PRNG", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
- rc4_prng_read(out, 500, &st);
- rc4_prng_export(dmp, &dmplen, &st);
- rc4_prng_read(out, 500, &st); /* skip 500 bytes */
- rc4_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t2, sizeof(t2), "RC4-PRNG", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
- rc4_prng_done(&st);
-
- XMEMSET(&st, 0xFF, sizeof(st)); /* just to be sure */
- rc4_prng_import(dmp, dmplen, &st);
- rc4_prng_read(out, 500, &st); /* skip 500 bytes */
- rc4_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t2, sizeof(t2), "RC4-PRNG", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
- rc4_prng_done(&st);
+ unsigned char t2[] = { 0xEF, 0x80, 0xA2, 0xE6, 0x50, 0x91, 0xF3, 0x17, 0x4A, 0x8A };
+ unsigned char t3[] = { 0x4B, 0xD6, 0x5C, 0x67, 0x99, 0x03, 0x56, 0x12, 0x80, 0x48 };
+ int err;
+
+ if ((err = rc4_start(&st)) != CRYPT_OK) return err;
+ /* add entropy to uninitialized prng */
+ if ((err = rc4_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if ((err = rc4_ready(&st)) != CRYPT_OK) return err;
+ if (rc4_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t1, sizeof(t1), "RC4-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR;
+ if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ /* add entropy to already initialized prng */
+ if ((err = rc4_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if ((err = rc4_export(dmp, &dmplen, &st)) != CRYPT_OK) return err;
+ if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if (rc4_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t2, sizeof(t2), "RC4-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR;
+ if ((err = rc4_done(&st)) != CRYPT_OK) return err;
+ if ((err = rc4_import(dmp, dmplen, &st)) != CRYPT_OK) return err;
+ if ((err = rc4_ready(&st)) != CRYPT_OK) return err;
+ if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if (rc4_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t3, sizeof(t3), "RC4-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR;
+ if ((err = rc4_done(&st)) != CRYPT_OK) return err;
return CRYPT_OK;
#endif
diff --git a/src/ltc/prngs/rng_get_bytes.c b/src/ltc/prngs/rng_get_bytes.c
index 28e8585e..2c05d0dd 100644
--- a/src/ltc/prngs/rng_get_bytes.c
+++ b/src/ltc/prngs/rng_get_bytes.c
@@ -5,8 +5,6 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
diff --git a/src/ltc/prngs/rng_make_prng.c b/src/ltc/prngs/rng_make_prng.c
index 05af4059..fff92c78 100644
--- a/src/ltc/prngs/rng_make_prng.c
+++ b/src/ltc/prngs/rng_make_prng.c
@@ -5,8 +5,6 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
diff --git a/src/ltc/prngs/sober128.c b/src/ltc/prngs/sober128.c
index d791ec1e..56f873cf 100644
--- a/src/ltc/prngs/sober128.c
+++ b/src/ltc/prngs/sober128.c
@@ -17,18 +17,18 @@
#ifdef LTC_SOBER128
-const struct ltc_prng_descriptor sober128_prng_desc =
+const struct ltc_prng_descriptor sober128_desc =
{
"sober128",
- sizeof(sober128_state),
- &sober128_prng_start,
- &sober128_prng_add_entropy,
- &sober128_prng_ready,
- &sober128_prng_read,
- &sober128_prng_done,
- &sober128_prng_export,
- &sober128_prng_import,
- &sober128_prng_test
+ 40,
+ &sober128_start,
+ &sober128_add_entropy,
+ &sober128_ready,
+ &sober128_read,
+ &sober128_done,
+ &sober128_export,
+ &sober128_import,
+ &sober128_test
};
/**
@@ -36,12 +36,13 @@ const struct ltc_prng_descriptor sober128_prng_desc =
@param prng [out] The PRNG state to initialize
@return CRYPT_OK if successful
*/
-int sober128_prng_start(prng_state *prng)
+int sober128_start(prng_state *prng)
{
LTC_ARGCHK(prng != NULL);
- prng->sober128.ready = 0;
- XMEMSET(&prng->sober128.ent, 0, 40);
+ prng->ready = 0;
+ XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent));
prng->sober128.idx = 0;
+ LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
@@ -52,7 +53,7 @@ int sober128_prng_start(prng_state *prng)
@param prng PRNG state to update
@return CRYPT_OK if successful
*/
-int sober128_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
+int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
unsigned char buf[40];
unsigned long i;
@@ -62,23 +63,26 @@ int sober128_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen > 0);
- if (prng->sober128.ready) {
- /* sober128_prng_ready() was already called, do "rekey" operation */
- if ((err = sober128_keystream(&prng->sober128.s, buf, 40)) != CRYPT_OK) return err;
- for(i = 0; i < inlen; i++) buf[i % 40] ^= in[i];
+ LTC_MUTEX_LOCK(&prng->lock);
+ if (prng->ready) {
+ /* sober128_ready() was already called, do "rekey" operation */
+ if ((err = sober128_stream_keystream(&prng->sober128.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 = sober128_setup(&prng->sober128.s, buf, 32)) != CRYPT_OK) return err;
+ if ((err = sober128_stream_setup(&prng->sober128.s, buf, 32)) != CRYPT_OK) goto LBL_UNLOCK;
/* iv 8 bytes */
- if ((err = sober128_setiv(&prng->sober128.s, buf + 32, 8)) != CRYPT_OK) return err;
+ if ((err = sober128_stream_setiv(&prng->sober128.s, buf + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK;
/* clear KEY + IV */
- XMEMSET(buf, 0, 40);
+ XMEMSET(buf, 0, sizeof(buf));
}
else {
- /* sober128_prng_ready() was not called yet, add entropy to ent buffer */
- while (inlen--) prng->sober128.ent[prng->sober128.idx++ % 40] ^= *in++;
+ /* sober128_ready() was not called yet, add entropy to ent buffer */
+ while (inlen--) prng->sober128.ent[prng->sober128.idx++ % sizeof(prng->sober128.ent)] ^= *in++;
}
-
- return CRYPT_OK;
+ err = CRYPT_OK;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -86,21 +90,24 @@ int sober128_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng
@param prng The PRNG to make active
@return CRYPT_OK if successful
*/
-int sober128_prng_ready(prng_state *prng)
+int sober128_ready(prng_state *prng)
{
int err;
LTC_ARGCHK(prng != NULL);
- if (prng->sober128.ready) return CRYPT_OK;
+ LTC_MUTEX_LOCK(&prng->lock);
+ if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
/* key 32 bytes, 20 rounds */
- if ((err = sober128_setup(&prng->sober128.s, prng->sober128.ent, 32)) != CRYPT_OK) return err;
+ if ((err = sober128_stream_setup(&prng->sober128.s, prng->sober128.ent, 32)) != CRYPT_OK) goto LBL_UNLOCK;
/* iv 8 bytes */
- if ((err = sober128_setiv(&prng->sober128.s, prng->sober128.ent + 32, 8)) != CRYPT_OK) return err;
- XMEMSET(&prng->sober128.ent, 0, 40);
- prng->sober128.ready = 1;
+ if ((err = sober128_stream_setiv(&prng->sober128.s, prng->sober128.ent + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK;
+ XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent));
prng->sober128.idx = 0;
- return CRYPT_OK;
+ prng->ready = 1;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -110,11 +117,14 @@ int sober128_prng_ready(prng_state *prng)
@param prng The active PRNG to read from
@return Number of octets read
*/
-unsigned long sober128_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
+unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
- LTC_ARGCHK(prng != NULL);
- if (!prng->sober128.ready) return 0;
- if (sober128_keystream(&prng->sober128.s, out, outlen) != CRYPT_OK) return 0;
+ if (outlen == 0 || prng == NULL || out == NULL) return 0;
+ LTC_MUTEX_LOCK(&prng->lock);
+ if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
+ if (sober128_stream_keystream(&prng->sober128.s, out, outlen) != CRYPT_OK) outlen = 0;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
return outlen;
}
@@ -123,14 +133,15 @@ unsigned long sober128_prng_read(unsigned char *out, unsigned long outlen, prng_
@param prng The PRNG to terminate
@return CRYPT_OK if successful
*/
-int sober128_prng_done(prng_state *prng)
+int sober128_done(prng_state *prng)
{
int err;
-
LTC_ARGCHK(prng != NULL);
- if ((err = sober128_done(&prng->sober128.s)) != CRYPT_OK) return err;
- prng->sober128.ready = 0;
- return CRYPT_OK;
+ LTC_MUTEX_LOCK(&prng->lock);
+ prng->ready = 0;
+ err = sober128_stream_done(&prng->sober128.s);
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -140,21 +151,23 @@ int sober128_prng_done(prng_state *prng)
@param prng The PRNG to export
@return CRYPT_OK if successful
*/
-int sober128_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
+int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
{
- unsigned long len = sizeof(sober128_state);
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(out != NULL);
+ unsigned long len = sober128_desc.export_size;
+
LTC_ARGCHK(prng != NULL);
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
- if (!prng->sober128.ready) {
- return CRYPT_ERROR;
- }
if (*outlen < len) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
- XMEMCPY(out, &prng->sober128.s, len);
+
+ if (sober128_read(out, len, prng) != len) {
+ return CRYPT_ERROR_READPRNG;
+ }
+
*outlen = len;
return CRYPT_OK;
}
@@ -166,15 +179,16 @@ int sober128_prng_export(unsigned char *out, unsigned long *outlen, prng_state *
@param prng The PRNG to import
@return CRYPT_OK if successful
*/
-int sober128_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
+int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
- unsigned long len = sizeof(sober128_state);
- LTC_ARGCHK(in != NULL);
+ int err;
+
LTC_ARGCHK(prng != NULL);
+ LTC_ARGCHK(in != NULL);
+ if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG;
- if (inlen != len) return CRYPT_INVALID_ARG;
- XMEMCPY(&prng->sober128.s, in, inlen);
- prng->sober128.ready = 1;
+ if ((err = sober128_start(prng)) != CRYPT_OK) return err;
+ if ((err = sober128_add_entropy(in, sober128_desc.export_size, prng)) != CRYPT_OK) return err;
return CRYPT_OK;
}
@@ -182,7 +196,7 @@ int sober128_prng_import(const unsigned char *in, unsigned long inlen, prng_stat
PRNG self-test
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
-int sober128_prng_test(void)
+int sober128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
@@ -197,28 +211,31 @@ int sober128_prng_test(void)
unsigned long dmplen = sizeof(dmp);
unsigned char out[500];
unsigned char t1[] = { 0x31, 0x82, 0xA7, 0xA5, 0x8B, 0xD7, 0xCB, 0x39, 0x86, 0x1A };
- unsigned char t2[] = { 0x5C, 0xD6, 0x92, 0x4E, 0xE9, 0x2F, 0xD4, 0x82, 0x16, 0xD4 };
-
- sober128_prng_start(&st);
- sober128_prng_add_entropy(en, sizeof(en), &st); /* add entropy to uninitialized prng */
- sober128_prng_ready(&st);
- sober128_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t1, sizeof(t1), "SOBER128-PRNG", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
- sober128_prng_read(out, 500, &st);
- sober128_prng_add_entropy(en, sizeof(en), &st); /* add entropy to already initialized prng */
- sober128_prng_read(out, 500, &st);
- sober128_prng_export(dmp, &dmplen, &st);
- sober128_prng_read(out, 500, &st); /* skip 500 bytes */
- sober128_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t2, sizeof(t2), "SOBER128-PRNG", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
- sober128_prng_done(&st);
-
- XMEMSET(&st, 0xFF, sizeof(st)); /* just to be sure */
- sober128_prng_import(dmp, dmplen, &st);
- sober128_prng_read(out, 500, &st); /* skip 500 bytes */
- sober128_prng_read(out, 10, &st); /* 10 bytes for testing */
- if (compare_testvector(out, 10, t2, sizeof(t2), "SOBER128-PRNG", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
- sober128_prng_done(&st);
+ unsigned char t2[] = { 0x6B, 0x43, 0x9E, 0xBC, 0xE7, 0x62, 0x9B, 0xE6, 0x9B, 0x83 };
+ unsigned char t3[] = { 0x4A, 0x0E, 0x6C, 0xC1, 0xCF, 0xB4, 0x73, 0x49, 0x99, 0x05 };
+ int err;
+
+ if ((err = sober128_start(&st)) != CRYPT_OK) return err;
+ /* add entropy to uninitialized prng */
+ if ((err = sober128_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if ((err = sober128_ready(&st)) != CRYPT_OK) return err;
+ if (sober128_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t1, sizeof(t1), "SOBER128-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR;
+ if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ /* add entropy to already initialized prng */
+ if ((err = sober128_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if ((err = sober128_export(dmp, &dmplen, &st)) != CRYPT_OK) return err;
+ if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if (sober128_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t2, sizeof(t2), "SOBER128-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR;
+ if ((err = sober128_done(&st)) != CRYPT_OK) return err;
+ if ((err = sober128_import(dmp, dmplen, &st)) != CRYPT_OK) return err;
+ if ((err = sober128_ready(&st)) != CRYPT_OK) return err;
+ if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if (sober128_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */
+ if (compare_testvector(out, 10, t3, sizeof(t3), "SOBER128-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR;
+ if ((err = sober128_done(&st)) != CRYPT_OK) return err;
return CRYPT_OK;
#endif
diff --git a/src/ltc/prngs/sprng.c b/src/ltc/prngs/sprng.c
index 7b538dd4..7e1865f4 100644
--- a/src/ltc/prngs/sprng.c
+++ b/src/ltc/prngs/sprng.c
@@ -5,8 +5,6 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
@@ -135,7 +133,22 @@ int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
*/
int sprng_test(void)
{
+#ifndef LTC_TEST
+ return CRYPT_NOP;
+#else
+ prng_state st;
+ unsigned char en[] = { 0x01, 0x02, 0x03, 0x04 };
+ unsigned char out[1000];
+ int err;
+
+ if ((err = sprng_start(&st)) != CRYPT_OK) return err;
+ if ((err = sprng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err;
+ if ((err = sprng_ready(&st)) != CRYPT_OK) return err;
+ if (sprng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
+ if ((err = sprng_done(&st)) != CRYPT_OK) return err;
+
return CRYPT_OK;
+#endif
}
#endif
diff --git a/src/ltc/prngs/yarrow.c b/src/ltc/prngs/yarrow.c
index d6566e6e..7275ac89 100644
--- a/src/ltc/prngs/yarrow.c
+++ b/src/ltc/prngs/yarrow.c
@@ -5,8 +5,6 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
@@ -40,6 +38,7 @@ int yarrow_start(prng_state *prng)
int err;
LTC_ARGCHK(prng != NULL);
+ prng->ready = 0;
/* these are the default hash/cipher combo used */
#ifdef LTC_RIJNDAEL
@@ -120,7 +119,7 @@ int yarrow_start(prng_state *prng)
/* zero the memory used */
zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
- LTC_MUTEX_INIT(&prng->yarrow.prng_lock)
+ LTC_MUTEX_INIT(&prng->lock)
return CRYPT_OK;
}
@@ -137,43 +136,38 @@ int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
hash_state md;
int err;
- LTC_ARGCHK(in != NULL);
LTC_ARGCHK(prng != NULL);
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(inlen > 0);
- LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
+ LTC_MUTEX_LOCK(&prng->lock);
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
/* start the hash */
if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
/* hash the current pool */
if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
/* add the new entropy */
if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
/* store result */
- if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
- }
+ err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool);
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return CRYPT_OK;
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -186,23 +180,21 @@ int yarrow_ready(prng_state *prng)
int ks, err;
LTC_ARGCHK(prng != NULL);
- LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
+
+ LTC_MUTEX_LOCK(&prng->lock);
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
/* setup CTR mode using the "pool" as the key */
ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
@@ -211,11 +203,13 @@ int yarrow_ready(prng_state *prng)
0, /* number of rounds */
CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
&prng->yarrow.ctr)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ goto LBL_UNLOCK;
}
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return CRYPT_OK;
+ prng->ready = 1;
+
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
+ return err;
}
/**
@@ -227,20 +221,25 @@ int yarrow_ready(prng_state *prng)
*/
unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(prng != NULL);
+ if (outlen == 0 || prng == NULL || out == NULL) return 0;
+
+ LTC_MUTEX_LOCK(&prng->lock);
- LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
+ if (!prng->ready) {
+ outlen = 0;
+ goto LBL_UNLOCK;
+ }
/* put out in predictable state first */
zeromem(out, outlen);
/* now randomize it */
if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return 0;
+ outlen = 0;
}
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
+
+LBL_UNLOCK:
+ LTC_MUTEX_UNLOCK(&prng->lock);
return outlen;
}
@@ -254,14 +253,15 @@ int yarrow_done(prng_state *prng)
int err;
LTC_ARGCHK(prng != NULL);
- LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
+ LTC_MUTEX_LOCK(&prng->lock);
+ prng->ready = 0;
/* call cipher done when we invent one ;-) */
/* we invented one */
err = ctr_done(&prng->yarrow.ctr);
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
+ LTC_MUTEX_UNLOCK(&prng->lock);
return err;
}
@@ -274,25 +274,22 @@ int yarrow_done(prng_state *prng)
*/
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
{
+ unsigned long len = yarrow_desc.export_size;
+
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(prng != NULL);
- LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
-
- /* we'll write 64 bytes for s&g's */
- if (*outlen < 64) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- *outlen = 64;
+ if (*outlen < len) {
+ *outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
- if (yarrow_read(out, 64, prng) != 64) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
+ if (yarrow_read(out, len, prng) != len) {
return CRYPT_ERROR_READPRNG;
}
- *outlen = 64;
+ *outlen = len;
return CRYPT_OK;
}
@@ -309,21 +306,11 @@ int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(prng != NULL);
+ if (inlen < (unsigned long)yarrow_desc.export_size) return CRYPT_INVALID_ARG;
- LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
-
- if (inlen != 64) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return CRYPT_INVALID_ARG;
- }
-
- if ((err = yarrow_start(prng)) != CRYPT_OK) {
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
- }
- err = yarrow_add_entropy(in, 64, prng);
- LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
- return err;
+ if ((err = yarrow_start(prng)) != CRYPT_OK) return err;
+ if ((err = yarrow_add_entropy(in, inlen, prng)) != CRYPT_OK) return err;
+ return CRYPT_OK;
}
/**
diff --git a/src/ltc/stream/chacha/chacha_crypt.c b/src/ltc/stream/chacha/chacha_crypt.c
index dbd7e9cb..30b5da7a 100644
--- a/src/ltc/stream/chacha/chacha_crypt.c
+++ b/src/ltc/stream/chacha/chacha_crypt.c
@@ -71,8 +71,14 @@ int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen,
}
for (;;) {
_chacha_block(buf, st->input, st->rounds);
- /* increment the counter */
- if (!++st->input[12] && !++st->input[13] && !++st->input[14]) { ++st->input[15]; }
+ if (st->ivlen == 8) {
+ /* IV-64bit, increment 64bit counter */
+ if (0 == ++st->input[12] && 0 == ++st->input[13]) return CRYPT_OVERFLOW;
+ }
+ else {
+ /* IV-96bit, increment 32bit counter */
+ if (0 == ++st->input[12]) return CRYPT_OVERFLOW;
+ }
if (inlen <= 64) {
for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
st->ksleft = 64 - inlen;
@@ -84,7 +90,6 @@ int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen,
out += 64;
in += 64;
}
- return CRYPT_OK;
-};
+}
#endif
diff --git a/src/ltc/stream/chacha/chacha_done.c b/src/ltc/stream/chacha/chacha_done.c
index 2e25177b..4d6e278b 100644
--- a/src/ltc/stream/chacha/chacha_done.c
+++ b/src/ltc/stream/chacha/chacha_done.c
@@ -21,6 +21,6 @@ int chacha_done(chacha_state *st)
LTC_ARGCHK(st != NULL);
XMEMSET(st, 0, sizeof(chacha_state));
return CRYPT_OK;
-};
+}
#endif
diff --git a/src/ltc/stream/chacha/chacha_ivctr32.c b/src/ltc/stream/chacha/chacha_ivctr32.c
index 0321568a..9884a1ee 100644
--- a/src/ltc/stream/chacha/chacha_ivctr32.c
+++ b/src/ltc/stream/chacha/chacha_ivctr32.c
@@ -38,6 +38,6 @@ int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivle
st->ksleft = 0;
st->ivlen = ivlen;
return CRYPT_OK;
-};
+}
#endif
diff --git a/src/ltc/stream/chacha/chacha_ivctr64.c b/src/ltc/stream/chacha/chacha_ivctr64.c
index ccc39727..82d39fb4 100644
--- a/src/ltc/stream/chacha/chacha_ivctr64.c
+++ b/src/ltc/stream/chacha/chacha_ivctr64.c
@@ -38,6 +38,6 @@ int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivle
st->ksleft = 0;
st->ivlen = ivlen;
return CRYPT_OK;
-};
+}
#endif
diff --git a/src/ltc/stream/chacha/chacha_setup.c b/src/ltc/stream/chacha/chacha_setup.c
index f56f667a..69a14833 100644
--- a/src/ltc/stream/chacha/chacha_setup.c
+++ b/src/ltc/stream/chacha/chacha_setup.c
@@ -16,8 +16,8 @@
#ifdef LTC_CHACHA
-static const char sigma[16] = "expand 32-byte k";
-static const char tau[16] = "expand 16-byte k";
+static const char * const sigma = "expand 32-byte k";
+static const char * const tau = "expand 16-byte k";
/**
Initialize an ChaCha context (only the key)
@@ -53,8 +53,9 @@ int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keyle
LOAD32L(st->input[1], constants + 4);
LOAD32L(st->input[2], constants + 8);
LOAD32L(st->input[3], constants + 12);
- st->rounds = rounds; /* e.g. 20 for chacha20 */
+ st->rounds = rounds; /* e.g. 20 for chacha20 */
+ st->ivlen = 0; /* will be set later by chacha_ivctr(32|64) */
return CRYPT_OK;
-};
+}
#endif
diff --git a/src/ltc/stream/rc4/rc4.c b/src/ltc/stream/rc4/rc4.c
index 06248023..ec174a0c 100644
--- a/src/ltc/stream/rc4/rc4.c
+++ b/src/ltc/stream/rc4/rc4.c
@@ -9,7 +9,7 @@
#include "tomcrypt.h"
-#ifdef LTC_RC4
+#ifdef LTC_RC4_STREAM
/**
Initialize an RC4 context (only the key)
@@ -18,7 +18,7 @@
@param keylen The length of the secret key (8 - 256 bytes)
@return CRYPT_OK if successful
*/
-int rc4_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
+int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
{
unsigned char tmp, *s;
int x, y;
@@ -54,7 +54,7 @@ int rc4_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
@param out [out] The ciphertext (or plaintext), length inlen
@return CRYPT_OK if successful
*/
-int rc4_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
+int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
{
unsigned char x, y, *s, tmp;
@@ -84,12 +84,12 @@ int rc4_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsig
@param outlen The output length
@return CRYPT_OK on success
*/
-int rc4_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
+int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
{
if (outlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(out != NULL);
XMEMSET(out, 0, outlen);
- return rc4_crypt(st, out, outlen, out);
+ return rc4_stream_crypt(st, out, outlen, out);
}
/**
@@ -97,7 +97,7 @@ int rc4_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
@param st The RC4 state
@return CRYPT_OK on success
*/
-int rc4_done(rc4_state *st)
+int rc4_stream_done(rc4_state *st)
{
LTC_ARGCHK(st != NULL);
XMEMSET(st, 0, sizeof(rc4_state));
diff --git a/src/ltc/stream/sober128/sober128.c b/src/ltc/stream/sober128/sober128.c
index ec838a07..b192d9a7 100644
--- a/src/ltc/stream/sober128/sober128.c
+++ b/src/ltc/stream/sober128/sober128.c
@@ -161,7 +161,7 @@ static void s128_diffuse(sober128_state *c)
@param keylen The length of the secret key (octets)
@return CRYPT_OK if successful
*/
-int sober128_setup(sober128_state *c, const unsigned char *key, unsigned long keylen)
+int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen)
{
ulong32 i, k;
@@ -208,7 +208,7 @@ int sober128_setup(sober128_state *c, const unsigned char *key, unsigned long ke
@param inlen The length of the IV (must be 12)
@return CRYPT_OK on success
*/
-int sober128_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen)
+int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen)
{
ulong32 i, k;
@@ -253,7 +253,7 @@ int sober128_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivl
@param out [out] The ciphertext (or plaintext), length inlen
@return CRYPT_OK if successful
*/
-int sober128_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out)
+int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out)
{
ulong32 t;
@@ -321,12 +321,12 @@ int sober128_crypt(sober128_state *c, const unsigned char *in, unsigned long inl
return CRYPT_OK;
}
-int sober128_keystream(sober128_state *c, unsigned char *out, unsigned long outlen)
+int sober128_stream_keystream(sober128_state *c, unsigned char *out, unsigned long outlen)
{
if (outlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(out != NULL);
XMEMSET(out, 0, outlen);
- return sober128_crypt(c, out, outlen, out);
+ return sober128_stream_crypt(c, out, outlen, out);
}
/**
@@ -334,7 +334,7 @@ int sober128_keystream(sober128_state *c, unsigned char *out, unsigned long outl
@param c The Sober128 state
@return CRYPT_OK on success
*/
-int sober128_done(sober128_state *c)
+int sober128_stream_done(sober128_state *c)
{
LTC_ARGCHK(c != NULL);
XMEMSET(c, 0, sizeof(sober128_state));