From 88ad3d8e8d09bd805ff062fb66ae65d2dfb193af Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sat, 23 Jun 2018 17:25:35 -0700 Subject: [PATCH 01/14] sosemanuk flow control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …controls which functions may be a called and in which order. Unless there is good reason to not, this pattern will be extended to each of the stream ciphers. See uploaded state diagrams. --- src/headers/tomcrypt_cipher.h | 32 ++--- src/stream/sosemanuk/sosemanuk.c | 201 +++++++++++++++++-------------- 2 files changed, 127 insertions(+), 106 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 4b983593d..894c2decc 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1043,23 +1043,25 @@ int xsalsa20_test(void); #ifdef LTC_SOSEMANUK typedef struct { - ulong32 kc[100]; /* key_context */ - ulong32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09; - ulong32 r1, r2; - /* - * Buffering: the stream cipher produces output data by - * blocks of 640 bits. buf[] contains such a block, and - * "ptr" is the index of the next output byte. - */ - unsigned char buf[80]; - unsigned ptr; + ulong32 kc[100]; /* key_context */ + ulong32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09; + ulong32 r1, r2; + /* + * Buffering: the stream cipher produces output data by + * blocks of 640 bits. buf[] contains such a block, and + * "ptr" is the index of the next output byte. + */ + unsigned char buf[80]; + unsigned ptr; + int ivlen; + int status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ } sosemanuk_state; -int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long keylen); -int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ivlen); -int sosemanuk_crypt(sosemanuk_state *ss, const unsigned char *in, unsigned long datalen, unsigned char *out); -int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen); -int sosemanuk_done(sosemanuk_state *ss); +int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen); +int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen); +int sosemanuk_crypt(sosemanuk_state *st, const unsigned char *in, unsigned long datalen, unsigned char *out); +int sosemanuk_keystream(sosemanuk_state *st, unsigned char *out, unsigned long outlen); +int sosemanuk_done(sosemanuk_state *st); int sosemanuk_test(void); #endif /* LTC_SOSEMANUK */ diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk.c index 7c5a602dd..c8230b97a 100644 --- a/src/stream/sosemanuk/sosemanuk.c +++ b/src/stream/sosemanuk/sosemanuk.c @@ -10,6 +10,12 @@ /* * This LTC implementation was adapted from: * http://www.ecrypt.eu.org/stream/e2-sosemanuk.html + * + * Sosemanuk specifications require: + * 1- a key of at least 128 bits (16 bytes), not exceeding 256 bits (32 bytes). + * 2- keys < 32 bytes are terminated with 0x01 followed by NULLs as needed. + * 3- an iv of 128 bits (16 bytes). + * See http://www.ecrypt.eu.org/stream/p3ciphers/sosemanuk/sosemanuk_p3.pdf */ /* @@ -191,17 +197,32 @@ x2 = ROLc(x2, 22); \ } while (0) +/* ======================================================================== */ + + int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + sosemanuk_state state; + + sosemanuk_setup(&state, key, keylen); + sosemanuk_setiv(&state, iv, ivlen); + sosemanuk_crypt(&state, datain, datalen, dataout); + sosemanuk_done(&state); +} + /* ======================================================================== */ /* * Initialize Sosemanuk's state by providing a key. The key is an array of - * 1 to 32 bytes. + * 16 to 32 bytes. * @param ss The Sosemanuk state * @param key Key * @param keylen Length of key in bytes * @return CRYPT_OK on success */ -int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long keylen) +int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen) { /* * This key schedule is actually a truncated Serpent key schedule. @@ -216,10 +237,10 @@ int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long r2 = w ## o2; \ r3 = w ## o3; \ S(r0, r1, r2, r3, r4); \ - ss->kc[i ++] = r ## d0; \ - ss->kc[i ++] = r ## d1; \ - ss->kc[i ++] = r ## d2; \ - ss->kc[i ++] = r ## d3; \ + st->kc[i ++] = r ## d0; \ + st->kc[i ++] = r ## d1; \ + st->kc[i ++] = r ## d2; \ + st->kc[i ++] = r ## d3; \ } while (0) #define SKS0 SKS(S0, 4, 5, 6, 7, 1, 4, 2, 0) @@ -255,9 +276,9 @@ int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long ulong32 w0, w1, w2, w3, w4, w5, w6, w7; int i = 0; - LTC_ARGCHK(ss != NULL); + LTC_ARGCHK(st != NULL); LTC_ARGCHK(key != NULL); - LTC_ARGCHK(keylen > 0 && keylen <= 32); + LTC_ARGCHK(keylen >= 16 && keylen <= 32); /* * The key is copied into the wbuf[] buffer and padded to 256 bits @@ -318,36 +339,31 @@ int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long #undef WUP0 #undef WUP1 - /* - * Initialize with a zero-value iv to ensure state is correct in the - * event user fails to call setiv(). - */ - return sosemanuk_setiv(ss, NULL, 0); + st->status = 1; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ + return CRYPT_OK; } /* - * Initialization continues by setting the IV. The IV length is up to 16 bytes. - * If "ivlen" is 0 (no IV), then the "iv" parameter can be NULL. If multiple - * encryptions/decryptions are to be performed with the same key and + * Initialization continues by setting the IV. The IV length is 16 bytes. If + * multiple encryptions/decryptions are to be performed with the same key and * sosemanuk_done() has not been called, only sosemanuk_setiv() need be called * to set the state. - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param iv Initialization vector - * @param ivlen Length of iv in bytes * @return CRYPT_OK on success */ -int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ivlen) +int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen) { /* * The Serpent key addition step. */ #define KA(zc, x0, x1, x2, x3) do { \ - x0 ^= ss->kc[(zc)]; \ - x1 ^= ss->kc[(zc) + 1]; \ - x2 ^= ss->kc[(zc) + 2]; \ - x3 ^= ss->kc[(zc) + 3]; \ + x0 ^= st->kc[(zc)]; \ + x1 ^= st->kc[(zc) + 1]; \ + x2 ^= st->kc[(zc) + 2]; \ + x3 ^= st->kc[(zc) + 3]; \ } while (0) /* @@ -377,11 +393,12 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ulong32 r0, r1, r2, r3, r4; unsigned char ivtmp[16] = {0}; - LTC_ARGCHK(ss != NULL); - LTC_ARGCHK(ivlen <= 16); - LTC_ARGCHK(iv != NULL || ivlen == 0); + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(ivlen == 16); + LTC_ARGCHK(st->status != 0); - if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen); + XMEMCPY(ivtmp, iv, ivlen); /* * Decode IV into four 32-bit words (little-endian). @@ -407,10 +424,10 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long FSS(36, S1, 1, 3, 2, 4, 0, 2, 1, 4, 3); FSS(40, S2, 2, 1, 4, 3, 0, 4, 3, 1, 0); FSS(44, S3, 4, 3, 1, 0, 2, 3, 1, 0, 2); - ss->s09 = r3; - ss->s08 = r1; - ss->s07 = r0; - ss->s06 = r2; + st->s09 = r3; + st->s08 = r1; + st->s07 = r0; + st->s06 = r2; FSS(48, S4, 3, 1, 0, 2, 4, 1, 4, 3, 2); FSS(52, S5, 1, 4, 3, 2, 0, 4, 2, 1, 3); @@ -418,10 +435,10 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long FSS(60, S7, 4, 2, 0, 1, 3, 3, 1, 2, 4); FSS(64, S0, 3, 1, 2, 4, 0, 1, 0, 2, 3); FSS(68, S1, 1, 0, 2, 3, 4, 2, 1, 3, 0); - ss->r1 = r2; - ss->s04 = r1; - ss->r2 = r3; - ss->s05 = r0; + st->r1 = r2; + st->s04 = r1; + st->r2 = r3; + st->s05 = r0; FSS(72, S2, 2, 1, 3, 0, 4, 3, 0, 1, 4); FSS(76, S3, 3, 0, 1, 4, 2, 0, 1, 4, 2); @@ -429,17 +446,18 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long FSS(84, S5, 1, 3, 0, 2, 4, 3, 2, 1, 0); FSS(88, S6, 3, 2, 1, 0, 4, 3, 2, 4, 1); FSF(92, S7, 3, 2, 4, 1, 0, 0, 1, 2, 3); - ss->s03 = r0; - ss->s02 = r1; - ss->s01 = r2; - ss->s00 = r3; + st->s03 = r0; + st->s02 = r1; + st->s01 = r2; + st->s00 = r3; - ss->ptr = sizeof(ss->buf); + st->ptr = sizeof(st->buf); #undef KA #undef FSS #undef FSF + st->status = 2; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ return CRYPT_OK; } @@ -588,7 +606,7 @@ static const ulong32 mul_ia[] = { * Compute the next block of bits of output stream. This is equivalent * to one full rotation of the shift register. */ -static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *ss) +static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *st) { /* * MUL_A(x) computes alpha * x (in F_{2^32}). @@ -659,24 +677,24 @@ static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *ss) */ #define SRD(S, x0, x1, x2, x3, ooff) do { \ S(u0, u1, u2, u3, u4); \ - STORE32L(u ## x0 ^ v0, ss->buf + ooff); \ - STORE32L(u ## x1 ^ v1, ss->buf + ooff + 4); \ - STORE32L(u ## x2 ^ v2, ss->buf + ooff + 8); \ - STORE32L(u ## x3 ^ v3, ss->buf + ooff + 12); \ + STORE32L(u ## x0 ^ v0, st->buf + ooff); \ + STORE32L(u ## x1 ^ v1, st->buf + ooff + 4); \ + STORE32L(u ## x2 ^ v2, st->buf + ooff + 8); \ + STORE32L(u ## x3 ^ v3, st->buf + ooff + 12); \ } while (0) - ulong32 s00 = ss->s00; - ulong32 s01 = ss->s01; - ulong32 s02 = ss->s02; - ulong32 s03 = ss->s03; - ulong32 s04 = ss->s04; - ulong32 s05 = ss->s05; - ulong32 s06 = ss->s06; - ulong32 s07 = ss->s07; - ulong32 s08 = ss->s08; - ulong32 s09 = ss->s09; - ulong32 r1 = ss->r1; - ulong32 r2 = ss->r2; + ulong32 s00 = st->s00; + ulong32 s01 = st->s01; + ulong32 s02 = st->s02; + ulong32 s03 = st->s03; + ulong32 s04 = st->s04; + ulong32 s05 = st->s05; + ulong32 s06 = st->s06; + ulong32 s07 = st->s07; + ulong32 s08 = st->s08; + ulong32 s09 = st->s09; + ulong32 r1 = st->r1; + ulong32 r2 = st->r2; ulong32 u0, u1, u2, u3, u4; ulong32 v0, v1, v2, v3; @@ -706,18 +724,18 @@ static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *ss) STEP(09, 00, 01, 02, 03, 04, 05, 06, 07, 08, v3, u3); SRD(S2, 2, 3, 1, 4, 64); - ss->s00 = s00; - ss->s01 = s01; - ss->s02 = s02; - ss->s03 = s03; - ss->s04 = s04; - ss->s05 = s05; - ss->s06 = s06; - ss->s07 = s07; - ss->s08 = s08; - ss->s09 = s09; - ss->r1 = r1; - ss->r2 = r2; + st->s00 = s00; + st->s01 = s01; + st->s02 = s02; + st->s03 = s03; + st->s04 = s04; + st->s05 = s05; + st->s06 = s06; + st->s07 = s07; + st->s08 = s08; + st->s09 = s09; + st->r1 = r1; + st->r2 = r2; } /* @@ -739,40 +757,41 @@ static LTC_INLINE void _xorbuf(const unsigned char *in1, const unsigned char *in * buffer, combined by XOR with the stream, and the result is written * in the "out" buffer. "in" and "out" must be either equal, or * reference distinct buffers (no partial overlap is allowed). - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param in Data in * @param inlen Length of data in bytes * @param out Data out * @return CRYPT_OK on success */ -int sosemanuk_crypt(sosemanuk_state *ss, +int sosemanuk_crypt(sosemanuk_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) { - LTC_ARGCHK(ss != NULL); + LTC_ARGCHK(st != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); + LTC_ARGCHK(st->status == 2); - if (ss->ptr < (sizeof(ss->buf))) { - unsigned long rlen = (sizeof(ss->buf)) - ss->ptr; + if (st->ptr < (sizeof(st->buf))) { + unsigned long rlen = (sizeof(st->buf)) - st->ptr; if (rlen > inlen) rlen = inlen; - _xorbuf(ss->buf + ss->ptr, in, out, rlen); + _xorbuf(st->buf + st->ptr, in, out, rlen); in += rlen; out += rlen; inlen -= rlen; - ss->ptr += rlen; + st->ptr += rlen; } while (inlen > 0) { - _sosemanuk_internal(ss); - if (inlen >= sizeof(ss->buf)) { - _xorbuf(ss->buf, in, out, sizeof(ss->buf)); - in += sizeof(ss->buf); - out += sizeof(ss->buf); - inlen -= sizeof(ss->buf); + _sosemanuk_internal(st); + if (inlen >= sizeof(st->buf)) { + _xorbuf(st->buf, in, out, sizeof(st->buf)); + in += sizeof(st->buf); + out += sizeof(st->buf); + inlen -= sizeof(st->buf); } else { - _xorbuf(ss->buf, in, out, inlen); - ss->ptr = inlen; + _xorbuf(st->buf, in, out, inlen); + st->ptr = inlen; inlen = 0; } } @@ -784,29 +803,29 @@ int sosemanuk_crypt(sosemanuk_state *ss, /* * Cipher operation, as a PRNG: the provided output buffer is filled with * pseudo-random bytes as output from the stream cipher. - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param out Data out * @param outlen Length of output in bytes * @return CRYPT_OK on success */ -int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen) +int sosemanuk_keystream(sosemanuk_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 sosemanuk_crypt(ss, out, outlen, out); + return sosemanuk_crypt(st, out, outlen, out); } /* * Terminate and clear Sosemanuk key context - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @return CRYPT_OK on success */ -int sosemanuk_done(sosemanuk_state *ss) +int sosemanuk_done(sosemanuk_state *st) { - LTC_ARGCHK(ss != NULL); - XMEMSET(ss, 0, sizeof(sosemanuk_state)); + LTC_ARGCHK(st != NULL); + XMEMSET(st, 0, sizeof(sosemanuk_state)); return CRYPT_OK; } From 775a800e995005953eac42142eb8c9ba8786a10f Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sat, 23 Jun 2018 20:04:05 -0700 Subject: [PATCH 02/14] Salsa20/XSalsa20 flow control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …controls which functions may be a called and in which order. See also uploaded state diagrams. --- src/headers/tomcrypt_cipher.h | 4 ++-- src/stream/salsa20/salsa20_crypt.c | 8 ++++---- src/stream/salsa20/salsa20_ivctr64.c | 4 ++-- src/stream/salsa20/salsa20_setup.c | 4 ++-- src/stream/salsa20/xsalsa20_setup.c | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 894c2decc..4737abc9e 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1018,8 +1018,8 @@ typedef struct { ulong32 input[16]; unsigned char kstream[64]; unsigned long ksleft; - unsigned long ivlen; - int rounds; + int rounds; + int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } salsa20_state; int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, int rounds); diff --git a/src/stream/salsa20/salsa20_crypt.c b/src/stream/salsa20/salsa20_crypt.c index bf1b00167..07764ffc6 100644 --- a/src/stream/salsa20/salsa20_crypt.c +++ b/src/stream/salsa20/salsa20_crypt.c @@ -59,10 +59,10 @@ int salsa20_crypt(salsa20_state *st, const unsigned char *in, unsigned long inle if (inlen == 0) return CRYPT_OK; /* nothing to do */ - LTC_ARGCHK(st != NULL); - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(st->ivlen == 8 || st->ivlen == 24); + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(st->status == 2 || st->status == 3); if (st->ksleft > 0) { j = MIN(st->ksleft, inlen); diff --git a/src/stream/salsa20/salsa20_ivctr64.c b/src/stream/salsa20/salsa20_ivctr64.c index 9c7ac74f7..7c9c2f631 100644 --- a/src/stream/salsa20/salsa20_ivctr64.c +++ b/src/stream/salsa20/salsa20_ivctr64.c @@ -29,7 +29,7 @@ int salsa20_ivctr64(salsa20_state *st, const unsigned char *iv, unsigned long iv { LTC_ARGCHK(st != NULL); LTC_ARGCHK(iv != NULL); - /* Salsa20: 64-bit IV (nonce) + 64-bit counter */ + LTC_ARGCHK(st->status == 1 || st->status == 2); LTC_ARGCHK(ivlen == 8); LOAD32L(st->input[6], iv + 0); @@ -37,7 +37,7 @@ int salsa20_ivctr64(salsa20_state *st, const unsigned char *iv, unsigned long iv st->input[8] = (ulong32)(counter & 0xFFFFFFFF); st->input[9] = (ulong32)(counter >> 32); st->ksleft = 0; - st->ivlen = ivlen; + st->status = 2; return CRYPT_OK; } diff --git a/src/stream/salsa20/salsa20_setup.c b/src/stream/salsa20/salsa20_setup.c index 872bd121d..e727e22c1 100644 --- a/src/stream/salsa20/salsa20_setup.c +++ b/src/stream/salsa20/salsa20_setup.c @@ -37,7 +37,7 @@ int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long key LTC_ARGCHK(keylen == 32 || keylen == 16); if (rounds == 0) rounds = 20; - LTC_ARGCHK(rounds % 2 == 0); /* number of rounds must be evenly divisible by 2 */ + LTC_ARGCHK(rounds % 2 == 0); /* rounds must be evenly divisible by 2 */ LOAD32L(st->input[1], key + 0); LOAD32L(st->input[2], key + 4); @@ -58,7 +58,7 @@ int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long key LOAD32L(st->input[10], constants + 8); LOAD32L(st->input[15], constants + 12); st->rounds = rounds; /* default is 20 for salsa20 */ - st->ivlen = 0; /* will be set later by salsa20_ivctr(32|64) */ + st->status = 1; return CRYPT_OK; } diff --git a/src/stream/salsa20/xsalsa20_setup.c b/src/stream/salsa20/xsalsa20_setup.c index 94133a7f3..41e6b91fa 100644 --- a/src/stream/salsa20/xsalsa20_setup.c +++ b/src/stream/salsa20/xsalsa20_setup.c @@ -119,7 +119,7 @@ int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long ke st->input[ 9] = 0; st->rounds = rounds; st->ksleft = 0; - st->ivlen = 24; /* set switch to say nonce/IV has been loaded */ + st->status = 3; #ifdef LTC_CLEAN_STACK zeromem(x, sizeof(x)); From d8d8aea57c8f7f0a4cada18fb798798038481181 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sat, 23 Jun 2018 22:57:40 -0700 Subject: [PATCH 03/14] one call for sosemanuk, salsa20, xsalsa20 will implement this pattern for the rest of the stream ciphers. --- src/headers/tomcrypt_cipher.h | 25 +++++++++++++++++++++---- src/stream/salsa20/salsa20_setup.c | 22 +++++++++++++++++++++- src/stream/salsa20/xsalsa20_setup.c | 24 ++++++++++++++++++++++-- src/stream/sosemanuk/sosemanuk.c | 16 +++++++++++----- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 4737abc9e..84c986ad1 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1015,14 +1015,20 @@ int chacha_test(void); #ifdef LTC_SALSA20 typedef struct { - ulong32 input[16]; + ulong32 input[16]; unsigned char kstream[64]; unsigned long ksleft; int rounds; int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } salsa20_state; -int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, int rounds); +int salsa20_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout); + +int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, unsigned long rounds); int salsa20_ivctr64(salsa20_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); int salsa20_crypt(salsa20_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); int salsa20_keystream(salsa20_state *st, unsigned char *out, unsigned long outlen); @@ -1033,9 +1039,15 @@ int salsa20_test(void); #ifdef LTC_XSALSA20 +int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout); + int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, - int rounds); + unsigned long rounds); int xsalsa20_test(void); #endif /* LTC_XSALSA20 */ @@ -1054,9 +1066,14 @@ typedef struct { unsigned char buf[80]; unsigned ptr; int ivlen; - int status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ + int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } sosemanuk_state; +int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); + int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen); int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen); int sosemanuk_crypt(sosemanuk_state *st, const unsigned char *in, unsigned long datalen, unsigned char *out); diff --git a/src/stream/salsa20/salsa20_setup.c b/src/stream/salsa20/salsa20_setup.c index e727e22c1..0c3107d8b 100644 --- a/src/stream/salsa20/salsa20_setup.c +++ b/src/stream/salsa20/salsa20_setup.c @@ -20,6 +20,26 @@ static const char * const sigma = "expand 32-byte k"; static const char * const tau = "expand 16-byte k"; +/* ======================================================================== */ + +int salsa20_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout) +{ + salsa20_state state; + int err; + + if ((err = salsa20_setup(&state, key, keylen, rounds)) != CRYPT_OK) return err; + if ((err = salsa20_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) return err; + if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; + if ((err = salsa20_done(&state)) != CRYPT_OK) return err; + + return CRYPT_OK; +} + +/* ======================================================================== */ /** Initialize an Salsa20 context (only the key) @param st [out] The destination of the Salsa20 state @@ -28,7 +48,7 @@ static const char * const tau = "expand 16-byte k"; @param rounds Number of rounds (e.g. 20 for Salsa20) @return CRYPT_OK if successful */ -int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, int rounds) +int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, unsigned long rounds) { const char *constants; diff --git a/src/stream/salsa20/xsalsa20_setup.c b/src/stream/salsa20/xsalsa20_setup.c index 41e6b91fa..9514bc322 100644 --- a/src/stream/salsa20/xsalsa20_setup.c +++ b/src/stream/salsa20/xsalsa20_setup.c @@ -18,6 +18,26 @@ #ifdef LTC_XSALSA20 +/* ======================================================================== */ + +int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout) +{ + salsa20_state state; + int err; + + if ((err = xsalsa20_setup(&state, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) return err; + if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; + if ((err = salsa20_done(&state)) != CRYPT_OK) return err; + + return CRYPT_OK; +} + +/* ======================================================================== */ + static const char * const constants = "expand 32-byte k"; #define QUARTERROUND(a,b,c,d) \ @@ -59,7 +79,7 @@ static void _xsalsa20_doubleround(ulong32 *x, int rounds) */ int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, - int rounds) + unsigned long rounds) { const int sti[] = {0, 5, 10, 15, 6, 7, 8, 9}; /* indices used to build subkey fm x */ ulong32 x[64]; /* input to & output fm doubleround */ @@ -72,7 +92,7 @@ int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long ke LTC_ARGCHK(nonce != NULL); LTC_ARGCHK(noncelen == 24); if (rounds == 0) rounds = 20; - LTC_ARGCHK(rounds % 2 == 0); /* number of rounds must be evenly divisible by 2 */ + LTC_ARGCHK(rounds % 2 == 0); /* rounds must be evenly divisible by 2 */ /* load the state to "hash" the key */ LOAD32L(x[ 0], constants + 0); diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk.c index c8230b97a..55b0d9bd4 100644 --- a/src/stream/sosemanuk/sosemanuk.c +++ b/src/stream/sosemanuk/sosemanuk.c @@ -202,14 +202,20 @@ int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, const unsigned char *iv, unsigned long ivlen, const unsigned char *datain, unsigned long datalen, + int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout) { sosemanuk_state state; - - sosemanuk_setup(&state, key, keylen); - sosemanuk_setiv(&state, iv, ivlen); - sosemanuk_crypt(&state, datain, datalen, dataout); - sosemanuk_done(&state); + int err; + + if ((err = sosemanuk_setup(&state, key, keylen)) != CRYPT_OK) return err; + if ((err = sosemanuk_setiv(&state, iv, ivlen)) != CRYPT_OK) return err; + if ((err = sosemanuk_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; + if ((err = sosemanuk_done(&state)) != CRYPT_OK) return err; + + return CRYPT_OK; } /* ======================================================================== */ From b6b1274bc86e57131ad1528d18544c31ae2b6465 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sat, 23 Jun 2018 23:06:23 -0700 Subject: [PATCH 04/14] alternate and preferred way to get size will implement for the remaining stream ciphers. --- src/headers/tomcrypt_cipher.h | 4 ++++ src/stream/salsa20/salsa20_setup.c | 4 ++++ src/stream/sosemanuk/sosemanuk.c | 7 ++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 84c986ad1..66ee3cb20 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1022,6 +1022,8 @@ typedef struct { int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } salsa20_state; +int salsa20_state_size(void); + int salsa20_onecall(const unsigned char *key, unsigned long keylen, const unsigned char *iv, unsigned long ivlen, const unsigned char *datain, unsigned long datalen, @@ -1069,6 +1071,8 @@ typedef struct { int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } sosemanuk_state; +int sosemanuk_state_size(void); + int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, const unsigned char *iv, unsigned long ivlen, const unsigned char *datain, unsigned long datalen, diff --git a/src/stream/salsa20/salsa20_setup.c b/src/stream/salsa20/salsa20_setup.c index 0c3107d8b..97d5f7392 100644 --- a/src/stream/salsa20/salsa20_setup.c +++ b/src/stream/salsa20/salsa20_setup.c @@ -22,6 +22,10 @@ static const char * const tau = "expand 16-byte k"; /* ======================================================================== */ +int salsa20_state_size(void) { return sizeof(salsa20_state); } + +/* ======================================================================== */ + int salsa20_onecall(const unsigned char *key, unsigned long keylen, const unsigned char *iv, unsigned long ivlen, const unsigned char *datain, unsigned long datalen, diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk.c index 55b0d9bd4..ab705fa7f 100644 --- a/src/stream/sosemanuk/sosemanuk.c +++ b/src/stream/sosemanuk/sosemanuk.c @@ -199,9 +199,10 @@ /* ======================================================================== */ - int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *iv, unsigned long ivlen, - const unsigned char *datain, unsigned long datalen, +int sosemanuk_state_size(void) { return sizeof(sosemanuk_state); } + +/* ======================================================================== */ + int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, const unsigned char *iv, unsigned long ivlen, const unsigned char *datain, unsigned long datalen, From fa420938816e3f1223683202b17f9aca78f12e56 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sun, 24 Jun 2018 19:12:56 -0700 Subject: [PATCH 05/14] documentation updates --- doc/crypt.tex | 75 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/doc/crypt.tex b/doc/crypt.tex index 1c3a10288..150cc45b8 100644 --- a/doc/crypt.tex +++ b/doc/crypt.tex @@ -1250,13 +1250,17 @@ \chapter{Stream Ciphers} however LibTomCrypt's implementation works with bytes). The API for all stream ciphers operates in mode: \textit{setup} -- \textit{crypt} -- \textit{crypt} -- ... -- \textit{done}. +The proper order of progression through these modes is enforced with a \textit{status} flag in the cipher's state. +(An empty state has a \textit{status} of 0, a state after \textit{setup} has a \textit{status} of 1 or 3, +and a state after \textit{setiv} has a \textit{status} of 2.) + Please note that both encryption and decryption are implemented via \textit{crypt}. Another useful feature of the stream ciphers API is generation of a random stream of bytes which works like: \textit{setup} -- \textit{keystream} -- \textit{keystream} -- ... -- \textit{done}. The random stream generation is implemented like encryption of a stream of \textit{0x00} bytes. -Note: You shouldn't use the keystream interface as a PRNG, as it doesn't allow to re-seed the internal state. +Note: You shouldn't use the keystream interface as a PRNG, as it doesn't allow re-seeding the internal state. \mysection{ChaCha} @@ -1336,7 +1340,7 @@ \chapter{Stream Ciphers} \end{verbatim} To initialize \textit{XSalsa20} for the recommended 20 rounds with a 256-bit -key (32 bytes) and a 192-bit nonce (24 bytes), use: +key (32 bytes) and a 192-bit nonce (24 bytes), use: \begin{verbatim} salsa20_state st; @@ -1361,6 +1365,21 @@ \chapter{Stream Ciphers} err = salsa20_done(&st); \end{verbatim} +Many encryptions/decryptions are performed on small data. To make this process easier, +Salsa20 has a helper function \textit{salsa20\_onecall()} that with one function call, +will instantiate a state, call \textit{salsa20\_setup()}, \textit{salsa20\_ivctr64()}, +\textit{salsa20\_crypt()}, and \textit{salsa20\_done()}, returning the crypted data. +\begin{verbatim} +int salsa20_onecall(key, keylen, iv ivlen, datain, datalen, rounds, dataout); +\end{verbatim} + +XSalsa20 likewise has a helper function \textit{xsalsa20\_onecall()} that with one +function call, will instantiate a state, call \textit{xsalsa20\_setup()}, +\textit{salsa20\_crypt()}, and \textit{salsa20\_done()}, returning the crypted data. +\begin{verbatim} +int xsalsa20_onecall(key, keylen, nonce, noncelen, datain, datalen, rounds, dataout); +\end{verbatim} + For both \textit{Salsa20} and \textit{XSalsa20} rounds must be an even number and if set to 0 the default number of rounds, 20, will be used. \vspace{1mm} @@ -1387,10 +1406,9 @@ \chapter{Stream Ciphers} another stream cipher, and the block cipher Serpent. (Sosemanuk means "snow snake" in the Cree Indian language.) -Sosemanuk will accept a key between 1 and 256 bits, but Sosemanuk's security level of 128 -bits is achieved only if the key is between 128 and 256 bits. Keys longer than 128 bits -are not guaranteed to provided higher security. The initialization vector is 128 bits. -(All length arguments are expressed in bytes.) +Sosemanuk will accept a key between 16 and 32 bytes (128 and 256 bits). The initialization +vector is 16 bytes (128 bits). Keys longer than 128 bits are not guaranteed to increase +Sosemanuk's security level of 128 bits. All length arguments are expressed in bytes. See \url{http://www.ecrypt.eu.org/stream/p3ciphers/sosemanuk/sosemanuk_p3.pdf} for more information. @@ -1427,6 +1445,14 @@ \chapter{Stream Ciphers} you do not need to re-run \textit{sosemanuk\_setup()} again, unless of course, you called \textit{sosemanuk\_done()}. +Many encryptions/decryptions are performed on small data. To make this process easier, +Sosemanuk has a helper function \textit{sosemanuk\_onecall()} that with one function call, +will instantiate a state, call \textit{sosemanuk\_setup()}, \textit{sosemanuk\_setiv()}, +\textit{sosemanuk\_crypt()}, and \textit{sosemanuk\_done()}, returning the crypted data. +\begin{verbatim} +int sosemanuk_onecall(key, keylen, iv ivlen, datain, datalen, dataout); +\end{verbatim} + \mysection{Rabbit} \textit{Rabbit}, along with Salsa20, Sosemanuk, and HC-128, was named one of the winners @@ -7058,6 +7084,43 @@ \subsection{Radix to binary conversion} print(names_list.value) \end{verbatim} +For stream ciphers, currently only Salsa20/XSalsa20 and Sosemanuk, +LTC now supports an alternate and arguably a preferred way to get +state sizes. +\begin{verbatim} +size = salsa20_state_size(); +size = sosemanuk_state_size(); +\end{verbatim} + +These new functions greatly simplify the supporting code needed +in the calling programs. Using Python as an example, this new +function instantiates \textit{sosemanuk\_state} with one line. +\begin{verbatim} +import ctypes +... +LTC = ctypes.CDLL('libtomcrypt.dylib') +... +state = ctypes.c_buffer(LTC.sosemanuk_state_size()) +\end{verbatim} +replaces +\begin{verbatim} +import ctypes +... +LTC = ctypes.CDLL('libtomcrypt.dylib') +... +def _get_size(name): + size = ctypes.c_int(0) + rc = LTC.crypt_get_size(bytes(name), byref(size)) + if rc != 0: + raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc)) + return size.value +... +state = ctypes.c_buffer(_get_size(b'sosemanuk_state')) +\end{verbatim} + +Over time this new alternate method will applied to all cipher and +hash function state sizes. + \chapter{Programming Guidelines} From e30c737adf9cc215d57c8f5b1a411c781823968a Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sun, 24 Jun 2018 19:13:48 -0700 Subject: [PATCH 06/14] corrections --- src/headers/tomcrypt_cipher.h | 8 ++++---- src/stream/sosemanuk/sosemanuk_test.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 66ee3cb20..b46e45628 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1018,8 +1018,8 @@ typedef struct { ulong32 input[16]; unsigned char kstream[64]; unsigned long ksleft; - int rounds; - int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ + unsigned long rounds; + unsigned long status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } salsa20_state; int salsa20_state_size(void); @@ -1067,8 +1067,8 @@ typedef struct { */ unsigned char buf[80]; unsigned ptr; - int ivlen; - int status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ + unsigned long ivlen; + unsigned long status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ } sosemanuk_state; int sosemanuk_state_size(void); diff --git a/src/stream/sosemanuk/sosemanuk_test.c b/src/stream/sosemanuk/sosemanuk_test.c index e5514df10..8eb68b400 100644 --- a/src/stream/sosemanuk/sosemanuk_test.c +++ b/src/stream/sosemanuk/sosemanuk_test.c @@ -38,7 +38,7 @@ int sosemanuk_test(void) if ((err = sosemanuk_crypt(&ss, (unsigned char*)pt + 40, len - 40, out + 40)) != CRYPT_OK) return err; if (compare_testvector(out, len, ct, sizeof(ct), "SOSEMANUK-TV1", 1)) return CRYPT_FAIL_TESTVECTOR; - /* crypt in one go - using sosemanuk_ivctr64() */ + /* crypt in one go - using sosemanuk_setiv() */ if ((err = sosemanuk_setup(&ss, k, sizeof(k))) != CRYPT_OK) return err; if ((err = sosemanuk_setiv(&ss, n, sizeof(n))) != CRYPT_OK) return err; if ((err = sosemanuk_crypt(&ss, (unsigned char*)pt, len, out)) != CRYPT_OK) return err; From b0beea23be0ebb99487d116d8e87e28473152e53 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Sun, 24 Jun 2018 23:40:10 -0700 Subject: [PATCH 07/14] removing conflict to become mergable --- src/stream/sosemanuk/sosemanuk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk.c index ab705fa7f..73ee8b39d 100644 --- a/src/stream/sosemanuk/sosemanuk.c +++ b/src/stream/sosemanuk/sosemanuk.c @@ -347,6 +347,7 @@ int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long #undef WUP1 st->status = 1; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ + return CRYPT_OK; } From cc1c8459298a47f922f06fdca3d9bb56ed41cbc5 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Mon, 25 Jun 2018 12:09:51 -0700 Subject: [PATCH 08/14] move new state_size functions to crypt_sizes.c --- src/headers/tomcrypt_cipher.h | 2 ++ src/misc/crypt/crypt_sizes.c | 17 +++++++++++++++++ src/stream/sosemanuk/sosemanuk.c | 4 ---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index b46e45628..bde6870f8 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1041,6 +1041,8 @@ int salsa20_test(void); #ifdef LTC_XSALSA20 +int xsalsa20_state_size(void); + int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *datain, unsigned long datalen, diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index 17274147f..7f7ecc8d3 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -290,6 +290,22 @@ static const crypt_size _crypt_sizes[] = { }; + + + +/* ======================================================================== */ + +#ifdef LTC_SALSA20 +int salsa20_state_size(void) { return sizeof(salsa20_state); } +#endif +#ifdef LTC_XSALSA20 +int xsalsa20_state_size(void) { return sizeof(salsa20_state); } +#endif +#ifdef LTC_SOSEMANUK +int sosemanuk_state_size(void) { return sizeof(sosemanuk_state); } +#endif + +/* ======================================================================== */ /* crypt_get_size() * sizeout will be the size (bytes) of the named struct or union * return -1 if named item not found @@ -306,6 +322,7 @@ int crypt_get_size(const char* namein, unsigned int *sizeout) { return -1; } +/* ======================================================================== */ /* crypt_list_all_sizes() * if names_list is NULL, names_list_size will be the minimum * size needed to receive the complete names_list diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk.c index 73ee8b39d..d4041807b 100644 --- a/src/stream/sosemanuk/sosemanuk.c +++ b/src/stream/sosemanuk/sosemanuk.c @@ -197,10 +197,6 @@ x2 = ROLc(x2, 22); \ } while (0) -/* ======================================================================== */ - -int sosemanuk_state_size(void) { return sizeof(sosemanuk_state); } - /* ======================================================================== */ int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, From 6697809a61c3fa944a2ab9a1aa17a019b2df89e8 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Mon, 25 Jun 2018 12:30:11 -0700 Subject: [PATCH 09/14] move one call function to new file misc/crypt/crypt_helper_functions.c --- libtomcrypt_VS2008.vcproj | 4 ++ makefile.mingw | 12 ++-- makefile.msvc | 12 ++-- makefile.unix | 12 ++-- makefile_include.mk | 12 ++-- src/misc/crypt/crypt_helper_functions.c | 85 +++++++++++++++++++++++++ src/stream/salsa20/salsa20_setup.c | 23 ------- src/stream/salsa20/xsalsa20_setup.c | 18 ------ src/stream/sosemanuk/sosemanuk.c | 18 ------ 9 files changed, 113 insertions(+), 83 deletions(-) create mode 100644 src/misc/crypt/crypt_helper_functions.c diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index da4fccab7..fd6fe96ed 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -1486,6 +1486,10 @@ RelativePath="src\misc\crypt\crypt_hash_is_valid.c" > + + diff --git a/makefile.mingw b/makefile.mingw index 894b0422a..c7bfabb8e 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -101,12 +101,12 @@ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ -src/misc/crypt/crypt_inits.o src/misc/crypt/crypt_ltc_mp_descriptor.o \ -src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \ -src/misc/crypt/crypt_prng_rng_descriptor.o src/misc/crypt/crypt_register_all_ciphers.o \ -src/misc/crypt/crypt_register_all_hashes.o src/misc/crypt/crypt_register_all_prngs.o \ -src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \ -src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ +src/misc/crypt/crypt_helper_functions.o src/misc/crypt/crypt_inits.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_prng_rng_descriptor.o \ +src/misc/crypt/crypt_register_all_ciphers.o src/misc/crypt/crypt_register_all_hashes.o \ +src/misc/crypt/crypt_register_all_prngs.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \ src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ diff --git a/makefile.msvc b/makefile.msvc index 9e039034d..c09731c40 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -94,12 +94,12 @@ src/misc/crypt/crypt_find_cipher_id.obj src/misc/crypt/crypt_find_hash.obj \ src/misc/crypt/crypt_find_hash_any.obj src/misc/crypt/crypt_find_hash_id.obj \ src/misc/crypt/crypt_find_hash_oid.obj src/misc/crypt/crypt_find_prng.obj src/misc/crypt/crypt_fsa.obj \ src/misc/crypt/crypt_hash_descriptor.obj src/misc/crypt/crypt_hash_is_valid.obj \ -src/misc/crypt/crypt_inits.obj src/misc/crypt/crypt_ltc_mp_descriptor.obj \ -src/misc/crypt/crypt_prng_descriptor.obj src/misc/crypt/crypt_prng_is_valid.obj \ -src/misc/crypt/crypt_prng_rng_descriptor.obj src/misc/crypt/crypt_register_all_ciphers.obj \ -src/misc/crypt/crypt_register_all_hashes.obj src/misc/crypt/crypt_register_all_prngs.obj \ -src/misc/crypt/crypt_register_cipher.obj src/misc/crypt/crypt_register_hash.obj \ -src/misc/crypt/crypt_register_prng.obj src/misc/crypt/crypt_sizes.obj \ +src/misc/crypt/crypt_helper_functions.obj src/misc/crypt/crypt_inits.obj \ +src/misc/crypt/crypt_ltc_mp_descriptor.obj src/misc/crypt/crypt_prng_descriptor.obj \ +src/misc/crypt/crypt_prng_is_valid.obj src/misc/crypt/crypt_prng_rng_descriptor.obj \ +src/misc/crypt/crypt_register_all_ciphers.obj src/misc/crypt/crypt_register_all_hashes.obj \ +src/misc/crypt/crypt_register_all_prngs.obj src/misc/crypt/crypt_register_cipher.obj \ +src/misc/crypt/crypt_register_hash.obj src/misc/crypt/crypt_register_prng.obj src/misc/crypt/crypt_sizes.obj \ src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \ src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/hkdf/hkdf.obj \ src/misc/hkdf/hkdf_test.obj src/misc/mem_neq.obj src/misc/padding/padding_depad.obj \ diff --git a/makefile.unix b/makefile.unix index 4fa6ac732..f31b37cf5 100644 --- a/makefile.unix +++ b/makefile.unix @@ -111,12 +111,12 @@ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ -src/misc/crypt/crypt_inits.o src/misc/crypt/crypt_ltc_mp_descriptor.o \ -src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \ -src/misc/crypt/crypt_prng_rng_descriptor.o src/misc/crypt/crypt_register_all_ciphers.o \ -src/misc/crypt/crypt_register_all_hashes.o src/misc/crypt/crypt_register_all_prngs.o \ -src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \ -src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ +src/misc/crypt/crypt_helper_functions.o src/misc/crypt/crypt_inits.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_prng_rng_descriptor.o \ +src/misc/crypt/crypt_register_all_ciphers.o src/misc/crypt/crypt_register_all_hashes.o \ +src/misc/crypt/crypt_register_all_prngs.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \ src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ diff --git a/makefile_include.mk b/makefile_include.mk index b03f76d10..ec3d37f34 100644 --- a/makefile_include.mk +++ b/makefile_include.mk @@ -271,12 +271,12 @@ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ -src/misc/crypt/crypt_inits.o src/misc/crypt/crypt_ltc_mp_descriptor.o \ -src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \ -src/misc/crypt/crypt_prng_rng_descriptor.o src/misc/crypt/crypt_register_all_ciphers.o \ -src/misc/crypt/crypt_register_all_hashes.o src/misc/crypt/crypt_register_all_prngs.o \ -src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \ -src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ +src/misc/crypt/crypt_helper_functions.o src/misc/crypt/crypt_inits.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_prng_rng_descriptor.o \ +src/misc/crypt/crypt_register_all_ciphers.o src/misc/crypt/crypt_register_all_hashes.o \ +src/misc/crypt/crypt_register_all_prngs.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \ src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ diff --git a/src/misc/crypt/crypt_helper_functions.c b/src/misc/crypt/crypt_helper_functions.c new file mode 100644 index 000000000..316639201 --- /dev/null +++ b/src/misc/crypt/crypt_helper_functions.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +/** + @file crypt_helper_functions.c + + A home for the "one call" and other helper functions. + Larry Bugbee - June 2018 +*/ + +/* ======================================================================== */ + +#ifdef LTC_SALSA20 + +int salsa20_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout) +{ + salsa20_state state; + int err; + + if ((err = salsa20_setup(&state, key, keylen, rounds)) != CRYPT_OK) return err; + if ((err = salsa20_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) return err; + if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; + if ((err = salsa20_done(&state)) != CRYPT_OK) return err; + + return CRYPT_OK; +} + +#endif + +#ifdef LTC_XSALSA20 + +int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout) +{ + salsa20_state state; + int err; + + if ((err = xsalsa20_setup(&state, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) return err; + if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; + if ((err = salsa20_done(&state)) != CRYPT_OK) return err; + + return CRYPT_OK; +} + +#endif + +#ifdef LTC_SOSEMANUK + +int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + sosemanuk_state state; + int err; + + if ((err = sosemanuk_setup(&state, key, keylen)) != CRYPT_OK) return err; + if ((err = sosemanuk_setiv(&state, iv, ivlen)) != CRYPT_OK) return err; + if ((err = sosemanuk_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; + if ((err = sosemanuk_done(&state)) != CRYPT_OK) return err; + + return CRYPT_OK; +} + +#endif + +/* ======================================================================== */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/stream/salsa20/salsa20_setup.c b/src/stream/salsa20/salsa20_setup.c index 97d5f7392..fa4e5a2fa 100644 --- a/src/stream/salsa20/salsa20_setup.c +++ b/src/stream/salsa20/salsa20_setup.c @@ -20,29 +20,6 @@ static const char * const sigma = "expand 32-byte k"; static const char * const tau = "expand 16-byte k"; -/* ======================================================================== */ - -int salsa20_state_size(void) { return sizeof(salsa20_state); } - -/* ======================================================================== */ - -int salsa20_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *iv, unsigned long ivlen, - const unsigned char *datain, unsigned long datalen, - unsigned long rounds, - unsigned char *dataout) -{ - salsa20_state state; - int err; - - if ((err = salsa20_setup(&state, key, keylen, rounds)) != CRYPT_OK) return err; - if ((err = salsa20_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) return err; - if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; - if ((err = salsa20_done(&state)) != CRYPT_OK) return err; - - return CRYPT_OK; -} - /* ======================================================================== */ /** Initialize an Salsa20 context (only the key) diff --git a/src/stream/salsa20/xsalsa20_setup.c b/src/stream/salsa20/xsalsa20_setup.c index 9514bc322..41bf0a9d1 100644 --- a/src/stream/salsa20/xsalsa20_setup.c +++ b/src/stream/salsa20/xsalsa20_setup.c @@ -20,24 +20,6 @@ /* ======================================================================== */ -int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *datain, unsigned long datalen, - unsigned long rounds, - unsigned char *dataout) -{ - salsa20_state state; - int err; - - if ((err = xsalsa20_setup(&state, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) return err; - if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; - if ((err = salsa20_done(&state)) != CRYPT_OK) return err; - - return CRYPT_OK; -} - -/* ======================================================================== */ - static const char * const constants = "expand 32-byte k"; #define QUARTERROUND(a,b,c,d) \ diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk.c index c24c11ef0..4caa7ecf7 100644 --- a/src/stream/sosemanuk/sosemanuk.c +++ b/src/stream/sosemanuk/sosemanuk.c @@ -197,24 +197,6 @@ x2 = ROLc(x2, 22); \ } while (0) -/* ======================================================================== */ - - int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *iv, unsigned long ivlen, - const unsigned char *datain, unsigned long datalen, - unsigned char *dataout) -{ - sosemanuk_state state; - int err; - - if ((err = sosemanuk_setup(&state, key, keylen)) != CRYPT_OK) return err; - if ((err = sosemanuk_setiv(&state, iv, ivlen)) != CRYPT_OK) return err; - if ((err = sosemanuk_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; - if ((err = sosemanuk_done(&state)) != CRYPT_OK) return err; - - return CRYPT_OK; -} - /* ======================================================================== */ /* From 6df50c1f3312786d77a5d1ca21ad6517885a3a06 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Mon, 25 Jun 2018 21:43:03 -0700 Subject: [PATCH 10/14] added flow control for ChaCha, Rabbit, RC4, SOBER128 --- src/headers/tomcrypt_cipher.h | 44 ++++++++++++---------- src/stream/chacha/chacha_crypt.c | 8 ++-- src/stream/chacha/chacha_done.c | 1 + src/stream/chacha/chacha_ivctr32.c | 6 +-- src/stream/chacha/chacha_ivctr64.c | 6 +-- src/stream/chacha/chacha_setup.c | 3 +- src/stream/rabbit/rabbit.c | 53 +++++++++++++++------------ src/stream/rc4/rc4_stream.c | 2 + src/stream/salsa20/salsa20_ivctr64.c | 2 +- src/stream/sober128/sober128_stream.c | 5 +++ 10 files changed, 75 insertions(+), 55 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index bde6870f8..5c200e9c4 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -995,11 +995,12 @@ LTC_MUTEX_PROTO(ltc_cipher_mutex) #ifdef LTC_CHACHA typedef struct { - ulong32 input[16]; + ulong32 input[16]; unsigned char kstream[64]; unsigned long ksleft; + unsigned long rounds; unsigned long ivlen; - int rounds; + unsigned long status; /* 0=uninitialized, 1=finished setup(), 2=finished ivctrXX() */ } chacha_state; int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); @@ -1024,11 +1025,11 @@ typedef struct { int salsa20_state_size(void); -int salsa20_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *iv, unsigned long ivlen, - const unsigned char *datain, unsigned long datalen, - unsigned long rounds, - unsigned char *dataout); +int salsa20_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout); int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, unsigned long rounds); int salsa20_ivctr64(salsa20_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); @@ -1043,11 +1044,11 @@ int salsa20_test(void); int xsalsa20_state_size(void); -int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *datain, unsigned long datalen, - unsigned long rounds, - unsigned char *dataout); +int xsalsa20_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout); int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, @@ -1070,15 +1071,15 @@ typedef struct { unsigned char buf[80]; unsigned ptr; unsigned long ivlen; - unsigned long status; /* 0=uninitialized, 1,3=finished setup(), 2=finished setiv() */ + unsigned long status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ } sosemanuk_state; int sosemanuk_state_size(void); -int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, - const unsigned char *iv, unsigned long ivlen, - const unsigned char *datain, unsigned long datalen, - unsigned char *dataout); +int sosemanuk_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen); int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen); @@ -1100,8 +1101,9 @@ typedef struct { typedef struct { rabbit_ctx master_ctx; rabbit_ctx work_ctx; - unsigned char block[16]; /* last keystream block containing unused bytes */ - ulong32 unused; /* count fm right */ + unsigned char block[16]; /* last keystream block containing unused bytes */ + ulong32 unused; /* count fm right */ + ulong32 status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ } rabbit_state; int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen); @@ -1118,6 +1120,7 @@ int rabbit_test(void); typedef struct { unsigned int x, y; unsigned char buf[256]; + unsigned long status; /* 0=uninitialized, 1=finished setup() */ } rc4_state; int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen); @@ -1135,7 +1138,8 @@ typedef struct { initR[17], /* saved register contents */ konst, /* key dependent constant */ sbuf; /* partial word encryption buffer */ - int nbuf; /* number of part-word stream bits buffered */ + ulong32 nbuf; /* number of part-word stream bits buffered */ + ulong32 status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ } sober128_state; int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen); diff --git a/src/stream/chacha/chacha_crypt.c b/src/stream/chacha/chacha_crypt.c index d72c84e7e..9cca5459c 100644 --- a/src/stream/chacha/chacha_crypt.c +++ b/src/stream/chacha/chacha_crypt.c @@ -58,10 +58,10 @@ int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, if (inlen == 0) return CRYPT_OK; /* nothing to do */ - LTC_ARGCHK(st != NULL); - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(st->ivlen != 0); + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(st->status != -1); if (st->ksleft > 0) { j = MIN(st->ksleft, inlen); diff --git a/src/stream/chacha/chacha_done.c b/src/stream/chacha/chacha_done.c index dbf6f246a..5f983785e 100644 --- a/src/stream/chacha/chacha_done.c +++ b/src/stream/chacha/chacha_done.c @@ -20,6 +20,7 @@ int chacha_done(chacha_state *st) { LTC_ARGCHK(st != NULL); XMEMSET(st, 0, sizeof(chacha_state)); + st->ivlen = -1; return CRYPT_OK; } diff --git a/src/stream/chacha/chacha_ivctr32.c b/src/stream/chacha/chacha_ivctr32.c index 72856a090..54840bcfa 100644 --- a/src/stream/chacha/chacha_ivctr32.c +++ b/src/stream/chacha/chacha_ivctr32.c @@ -28,15 +28,15 @@ int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivle { LTC_ARGCHK(st != NULL); LTC_ARGCHK(iv != NULL); - /* 96bit IV + 32bit counter */ - LTC_ARGCHK(ivlen == 12); + LTC_ARGCHK(ivlen == 12); /* 96bit IV + 32bit counter */ + LTC_ARGCHK(st->status == 1 || st->status == 2); st->input[12] = counter; LOAD32L(st->input[13], iv + 0); LOAD32L(st->input[14], iv + 4); LOAD32L(st->input[15], iv + 8); st->ksleft = 0; - st->ivlen = ivlen; + st->status = 2; return CRYPT_OK; } diff --git a/src/stream/chacha/chacha_ivctr64.c b/src/stream/chacha/chacha_ivctr64.c index f7cf721fa..daaaebc31 100644 --- a/src/stream/chacha/chacha_ivctr64.c +++ b/src/stream/chacha/chacha_ivctr64.c @@ -28,15 +28,15 @@ int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivle { LTC_ARGCHK(st != NULL); LTC_ARGCHK(iv != NULL); - /* 64bit IV + 64bit counter */ - LTC_ARGCHK(ivlen == 8); + LTC_ARGCHK(ivlen == 8); /* 64bit IV + 64bit counter */ + LTC_ARGCHK(st->status == 1 || st->status == 2); st->input[12] = (ulong32)(counter & 0xFFFFFFFF); st->input[13] = (ulong32)(counter >> 32); LOAD32L(st->input[14], iv + 0); LOAD32L(st->input[15], iv + 4); st->ksleft = 0; - st->ivlen = ivlen; + st->status = 2; return CRYPT_OK; } diff --git a/src/stream/chacha/chacha_setup.c b/src/stream/chacha/chacha_setup.c index e997fc951..e98114fab 100644 --- a/src/stream/chacha/chacha_setup.c +++ b/src/stream/chacha/chacha_setup.c @@ -19,6 +19,7 @@ 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) @param st [out] The destination of the ChaCha state @@ -56,7 +57,7 @@ int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keyle LOAD32L(st->input[2], constants + 8); LOAD32L(st->input[3], constants + 12); st->rounds = rounds; /* e.g. 20 for chacha20 */ - st->ivlen = 0; /* will be set later by chacha_ivctr(32|64) */ + st->ivlen = -1; /* will be set later by chacha_ivctr(32|64) */ return CRYPT_OK; } diff --git a/src/stream/rabbit/rabbit.c b/src/stream/rabbit/rabbit.c index 4607bc9ed..9f6dfd646 100644 --- a/src/stream/rabbit/rabbit.c +++ b/src/stream/rabbit/rabbit.c @@ -19,46 +19,50 @@ * The eSTREAM submission was rather picky about the calling sequence of * ECRYPT_process_blocks() and ECRYPT_process_bytes(). That version allowed * calling ECRYPT_process_blocks() multiple times for a multiple of whole - * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls + * 16-byte blocks, but once ECRYPT_process_bytes() was called, no more calls * were supported correctly. This implementation handles the keystream * differently and rabbit_crypt() may be called as many times as desired, * crypting any number of bytes each time. * * http://www.ecrypt.eu.org/stream/e2-rabbit.html + * https://www.ietf.org/rfc/rfc4503.txt * * NB: One of the test vectors distributed by the eSTREAM site in the file * "rabbit_p3source.zip" is in error. Referring to "test-vectors.txt" * in that ZIP file, the 3rd line in "out1" should be * "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4". * + *--------------------------------------------------------------------------- * Here is the original legal notice accompanying the Rabbit submission * to the EU eSTREAM competition. - *--------------------------------------------------------------------------- - * Copyright (C) Cryptico A/S. All rights reserved. * - * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE. + * Copyright (C) Cryptico A/S. All rights reserved. + * + * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE. + * + * This software is developed by Cryptico A/S and/or its suppliers. + * All title and intellectual property rights in and to the software, + * including but not limited to patent rights and copyrights, are owned + * by Cryptico A/S and/or its suppliers. * - * This software is developed by Cryptico A/S and/or its suppliers. - * All title and intellectual property rights in and to the software, - * including but not limited to patent rights and copyrights, are owned - * by Cryptico A/S and/or its suppliers. + * The software may be used solely for non-commercial purposes + * without the prior written consent of Cryptico A/S. For further + * information on licensing terms and conditions please contact + * Cryptico A/S at info@cryptico.com * - * The software may be used solely for non-commercial purposes - * without the prior written consent of Cryptico A/S. For further - * information on licensing terms and conditions please contact - * Cryptico A/S at info@cryptico.com + * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption" + * are either trademarks or registered trademarks of Cryptico A/S. * - * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption" - * are either trademarks or registered trademarks of Cryptico A/S. + * Cryptico A/S shall not in any way be liable for any use of this + * software. The software is provided "as is" without any express or + * implied warranty. * - * Cryptico A/S shall not in any way be liable for any use of this - * software. The software is provided "as is" without any express or - * implied warranty. *--------------------------------------------------------------------------- * On October 6, 2008, Rabbit was "released into the public domain and * may be used freely for any purpose." + * * http://www.ecrypt.eu.org/stream/rabbitpf.html - * https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244 + * ******************************************************************************/ @@ -145,8 +149,7 @@ static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out) STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12); } -/* -------------------------------------------------------------------------- */ - +/* ======================================================================== */ /* Key setup */ int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen) { @@ -214,6 +217,7 @@ int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keyle /* ...and prepare block for crypt() */ XMEMSET(&(st->block), 0, sizeof(st->block)); st->unused = 0; + st->status = 1; return CRYPT_OK; } @@ -229,6 +233,7 @@ int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen) LTC_ARGCHK(st != NULL); LTC_ARGCHK(iv != NULL || ivlen == 0); LTC_ARGCHK(ivlen <= 8); + LTC_ARGCHK(st->status != 0); /* pad iv in tmpiv */ if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen); @@ -261,6 +266,7 @@ int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen) /* reset keystream buffer and unused count */ XMEMSET(&(st->block), 0, sizeof(st->block)); st->unused = 0; + st->status = 2; return CRYPT_OK; } @@ -275,9 +281,10 @@ int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, if (inlen == 0) return CRYPT_OK; /* nothing to do */ - LTC_ARGCHK(st != NULL); - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(st->status == 2); if (st->unused > 0) { j = MIN(st->unused, inlen); diff --git a/src/stream/rc4/rc4_stream.c b/src/stream/rc4/rc4_stream.c index f1c225d01..059f5505e 100644 --- a/src/stream/rc4/rc4_stream.c +++ b/src/stream/rc4/rc4_stream.c @@ -42,6 +42,7 @@ int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keyl } st->x = 0; st->y = 0; + st->status = 1; return CRYPT_OK; } @@ -61,6 +62,7 @@ int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen LTC_ARGCHK(st != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); + LTC_ARGCHK(st->status == 1); x = st->x; y = st->y; diff --git a/src/stream/salsa20/salsa20_ivctr64.c b/src/stream/salsa20/salsa20_ivctr64.c index 7c9c2f631..241999f5a 100644 --- a/src/stream/salsa20/salsa20_ivctr64.c +++ b/src/stream/salsa20/salsa20_ivctr64.c @@ -29,8 +29,8 @@ int salsa20_ivctr64(salsa20_state *st, const unsigned char *iv, unsigned long iv { LTC_ARGCHK(st != NULL); LTC_ARGCHK(iv != NULL); - LTC_ARGCHK(st->status == 1 || st->status == 2); LTC_ARGCHK(ivlen == 8); + LTC_ARGCHK(st->status == 1 || st->status == 2); LOAD32L(st->input[6], iv + 0); LOAD32L(st->input[7], iv + 4); diff --git a/src/stream/sober128/sober128_stream.c b/src/stream/sober128/sober128_stream.c index 44e0c3278..b5b8188a9 100644 --- a/src/stream/sober128/sober128_stream.c +++ b/src/stream/sober128/sober128_stream.c @@ -152,6 +152,7 @@ static void s128_diffuse(sober128_state *c) DROUND(16); } +/* ======================================================================== */ /** Initialize an Sober128 context (only the key) @param c [out] The destination of the Sober128 state @@ -195,6 +196,7 @@ int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned s128_genkonst(c); s128_savestate(c); c->nbuf = 0; + c->status = 1; return CRYPT_OK; } @@ -213,6 +215,7 @@ int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned l LTC_ARGCHK(c != NULL); LTC_ARGCHK(iv != NULL); LTC_ARGCHK(ivlen > 0); + LTC_ARGCHK(c->status != 0); /* ok we are adding an IV then... */ s128_reloadstate(c); @@ -235,6 +238,7 @@ int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned l /* now diffuse */ s128_diffuse(c); c->nbuf = 0; + c->status = 2; return CRYPT_OK; } @@ -258,6 +262,7 @@ int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned l if (inlen == 0) return CRYPT_OK; /* nothing to do */ LTC_ARGCHK(out != NULL); LTC_ARGCHK(c != NULL); + LTC_ARGCHK(c->status == 2); /* handle any previously buffered bytes */ while (c->nbuf != 0 && inlen != 0) { From f8b6c9ae40d75ba9d01ea55c0b4c2bdfb3963e1c Mon Sep 17 00:00:00 2001 From: buggywhip Date: Mon, 25 Jun 2018 21:48:19 -0700 Subject: [PATCH 11/14] add state_size functions for chacha, rabbit, rc4, sober128 --- src/headers/tomcrypt_cipher.h | 8 ++++++++ src/misc/crypt/crypt_sizes.c | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 5c200e9c4..d93a420f4 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1003,6 +1003,8 @@ typedef struct { unsigned long status; /* 0=uninitialized, 1=finished setup(), 2=finished ivctrXX() */ } chacha_state; +int chacha_state_size(void); + int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter); int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); @@ -1106,6 +1108,8 @@ typedef struct { ulong32 status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ } rabbit_state; +int rabbit_state_size(void); + int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen); int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen); int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out); @@ -1123,6 +1127,8 @@ typedef struct { unsigned long status; /* 0=uninitialized, 1=finished setup() */ } rc4_state; +int rc4_state_size(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); @@ -1142,6 +1148,8 @@ typedef struct { ulong32 status; /* 0=uninitialized, 1=finished setup(), 2=finished setiv() */ } sober128_state; +int sober128_state_size(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); diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index df9292dbc..7c9121dd4 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -290,20 +290,29 @@ static const crypt_size _crypt_sizes[] = { }; - - - /* ======================================================================== */ +#ifdef LTC_CHACHA +int chacha_state_size(void) { return sizeof(chacha_state); } +#endif #ifdef LTC_SALSA20 -int salsa20_state_size(void) { return sizeof(salsa20_state); } +int salsa20_state_size(void) { return sizeof(salsa20_state); } #endif #ifdef LTC_XSALSA20 -int xsalsa20_state_size(void) { return sizeof(salsa20_state); } +int xsalsa20_state_size(void) { return sizeof(salsa20_state); } #endif #ifdef LTC_SOSEMANUK int sosemanuk_state_size(void) { return sizeof(sosemanuk_state); } #endif +#ifdef LTC_RABBIT +int rabbit_state_size(void) { return sizeof(rabbit_state); } +#endif +#ifdef LTC_RC4_STREAM +int rc4_state_size(void) { return sizeof(rc4_state); } +#endif +#ifdef LTC_SOBER128_STREAM +int sober128_state_size(void) { return sizeof(sober128_state); } +#endif /* ======================================================================== */ /* crypt_get_size() From 2ef612a7c8b7a13c7e7ca12e5fbdeb99508aa5e0 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Tue, 26 Jun 2018 03:12:09 -0700 Subject: [PATCH 12/14] add one calls *_memory() for chacha, rabbit, rc4, sober128 includes a fix to chacha20poly1305_setiv.c to preserve flow control status. and a fix to wipe key if an error midstream of the one call. --- .../chachapoly/chacha20poly1305_setiv.c | 1 + src/headers/tomcrypt_cipher.h | 20 +++ src/misc/crypt/crypt_helper_functions.c | 132 +++++++++++++++--- src/stream/chacha/chacha_done.c | 1 - src/stream/chacha/chacha_ivctr32.c | 1 + src/stream/chacha/chacha_ivctr64.c | 1 + src/stream/chacha/chacha_setup.c | 2 +- 7 files changed, 137 insertions(+), 21 deletions(-) diff --git a/src/encauth/chachapoly/chacha20poly1305_setiv.c b/src/encauth/chachapoly/chacha20poly1305_setiv.c index 4e770a013..80a9a1b49 100644 --- a/src/encauth/chachapoly/chacha20poly1305_setiv.c +++ b/src/encauth/chachapoly/chacha20poly1305_setiv.c @@ -41,6 +41,7 @@ int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, /* copy chacha20 key to temporary state */ for(i = 0; i < 12; i++) tmp_st.input[i] = st->chacha.input[i]; tmp_st.rounds = 20; + tmp_st.status = st->chacha.status; /* set IV */ if (ivlen == 12) { /* IV 32bit */ diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index d93a420f4..34e9ad821 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -1005,6 +1005,12 @@ typedef struct { int chacha_state_size(void); +int chacha_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout); + int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter); int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); @@ -1110,6 +1116,11 @@ typedef struct { int rabbit_state_size(void); +int rabbit_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); + int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen); int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen); int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out); @@ -1129,6 +1140,10 @@ typedef struct { int rc4_state_size(void); +int rc4_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); + 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); @@ -1150,6 +1165,11 @@ typedef struct { int sober128_state_size(void); +int sober128_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); + 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); diff --git a/src/misc/crypt/crypt_helper_functions.c b/src/misc/crypt/crypt_helper_functions.c index 316639201..be5f476ec 100644 --- a/src/misc/crypt/crypt_helper_functions.c +++ b/src/misc/crypt/crypt_helper_functions.c @@ -17,6 +17,31 @@ /* ======================================================================== */ +#ifdef LTC_CHACHA + +int chacha_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned long rounds, + unsigned char *dataout) +{ + chacha_state state; + int err; + + if ((err = chacha_setup(&state, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY; + if (ivlen == 12) + if ((err = chacha_ivctr32(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; + else if ((err = chacha_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; + err = chacha_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = chacha_done(&state); + return err; +} + +#endif /* LTC_CHACHA */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + #ifdef LTC_SALSA20 int salsa20_onecall(const unsigned char *key, unsigned long keylen, @@ -28,15 +53,17 @@ int salsa20_onecall(const unsigned char *key, unsigned long keylen, salsa20_state state; int err; - if ((err = salsa20_setup(&state, key, keylen, rounds)) != CRYPT_OK) return err; - if ((err = salsa20_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) return err; - if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; - if ((err = salsa20_done(&state)) != CRYPT_OK) return err; - - return CRYPT_OK; + if ((err = salsa20_setup(&state, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY; + if ((err = salsa20_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; + err = salsa20_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = salsa20_done(&state); + return err; } -#endif +#endif /* LTC_SALSA20 */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #ifdef LTC_XSALSA20 @@ -49,14 +76,17 @@ int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, salsa20_state state; int err; - if ((err = xsalsa20_setup(&state, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) return err; - if ((err = salsa20_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; - if ((err = salsa20_done(&state)) != CRYPT_OK) return err; - - return CRYPT_OK; + if ((err = xsalsa20_setup(&state, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) goto WIPE_KEY; + err = salsa20_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = salsa20_done(&state); + return err; } -#endif +#endif /* LTC_XSALSA20 */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + #ifdef LTC_SOSEMANUK @@ -68,15 +98,79 @@ int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, sosemanuk_state state; int err; - if ((err = sosemanuk_setup(&state, key, keylen)) != CRYPT_OK) return err; - if ((err = sosemanuk_setiv(&state, iv, ivlen)) != CRYPT_OK) return err; - if ((err = sosemanuk_crypt(&state, datain, datalen, dataout)) != CRYPT_OK) return err; - if ((err = sosemanuk_done(&state)) != CRYPT_OK) return err; + if ((err = sosemanuk_setup(&state, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + if ((err = sosemanuk_setiv(&state, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; + err = sosemanuk_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = sosemanuk_done(&state); + return err; +} + +#endif /* LTC_SOSEMANUK */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef LTC_RABBIT + +int rabbit_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + rabbit_state state; + int err; + + if ((err = rabbit_setup(&state, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + if ((err = rabbit_setiv(&state, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; + err = rabbit_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = rabbit_done(&state); + return err; +} + +#endif /* LTC_RABBIT */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef LTC_RC4_STREAM + +int rc4_stream_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + rc4_state state; + int err; + + if ((err = rc4_stream_setup(&state, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + err = rc4_stream_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = rc4_stream_done(&state); + return err; +} + +#endif /* LTC_RC4_STREAM */ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef LTC_SOBER128_STREAM + +int sober128_stream_onecall(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + sober128_state state; + int err; - return CRYPT_OK; + if ((err = sober128_stream_setup(&state, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + if ((err = sober128_stream_setiv(&state, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; + err = sober128_stream_crypt(&state, datain, datalen, dataout); +WIPE_KEY: + err = sober128_stream_done(&state); + return err; } -#endif +#endif /* LTC_SOBER128_STREAM */ /* ======================================================================== */ diff --git a/src/stream/chacha/chacha_done.c b/src/stream/chacha/chacha_done.c index 5f983785e..dbf6f246a 100644 --- a/src/stream/chacha/chacha_done.c +++ b/src/stream/chacha/chacha_done.c @@ -20,7 +20,6 @@ int chacha_done(chacha_state *st) { LTC_ARGCHK(st != NULL); XMEMSET(st, 0, sizeof(chacha_state)); - st->ivlen = -1; return CRYPT_OK; } diff --git a/src/stream/chacha/chacha_ivctr32.c b/src/stream/chacha/chacha_ivctr32.c index 54840bcfa..fe22e2b43 100644 --- a/src/stream/chacha/chacha_ivctr32.c +++ b/src/stream/chacha/chacha_ivctr32.c @@ -37,6 +37,7 @@ int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivle LOAD32L(st->input[15], iv + 8); st->ksleft = 0; st->status = 2; + st->ivlen = ivlen; return CRYPT_OK; } diff --git a/src/stream/chacha/chacha_ivctr64.c b/src/stream/chacha/chacha_ivctr64.c index daaaebc31..1a27dc13d 100644 --- a/src/stream/chacha/chacha_ivctr64.c +++ b/src/stream/chacha/chacha_ivctr64.c @@ -36,6 +36,7 @@ int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivle LOAD32L(st->input[14], iv + 0); LOAD32L(st->input[15], iv + 4); st->ksleft = 0; + st->ivlen = ivlen; st->status = 2; return CRYPT_OK; } diff --git a/src/stream/chacha/chacha_setup.c b/src/stream/chacha/chacha_setup.c index e98114fab..e6526389a 100644 --- a/src/stream/chacha/chacha_setup.c +++ b/src/stream/chacha/chacha_setup.c @@ -57,7 +57,7 @@ int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keyle LOAD32L(st->input[2], constants + 8); LOAD32L(st->input[3], constants + 12); st->rounds = rounds; /* e.g. 20 for chacha20 */ - st->ivlen = -1; /* will be set later by chacha_ivctr(32|64) */ + st->status = 1; return CRYPT_OK; } From 24eaff4db91c1debcdf7b506290126d9dd0ece20 Mon Sep 17 00:00:00 2001 From: buggywhip Date: Tue, 26 Jun 2018 15:56:31 -0700 Subject: [PATCH 13/14] fix Travis errors/warnings --- src/misc/crypt/crypt_helper_functions.c | 6 ++++-- src/stream/chacha/chacha_crypt.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/misc/crypt/crypt_helper_functions.c b/src/misc/crypt/crypt_helper_functions.c index be5f476ec..209ac691f 100644 --- a/src/misc/crypt/crypt_helper_functions.c +++ b/src/misc/crypt/crypt_helper_functions.c @@ -29,9 +29,11 @@ int chacha_memory(const unsigned char *key, unsigned long keylen, int err; if ((err = chacha_setup(&state, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY; - if (ivlen == 12) + if (ivlen == 12) { if ((err = chacha_ivctr32(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; - else if ((err = chacha_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; + } else { + if ((err = chacha_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; + ) err = chacha_crypt(&state, datain, datalen, dataout); WIPE_KEY: err = chacha_done(&state); diff --git a/src/stream/chacha/chacha_crypt.c b/src/stream/chacha/chacha_crypt.c index 9cca5459c..d67d55868 100644 --- a/src/stream/chacha/chacha_crypt.c +++ b/src/stream/chacha/chacha_crypt.c @@ -61,7 +61,7 @@ int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, LTC_ARGCHK(st != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); - LTC_ARGCHK(st->status != -1); + LTC_ARGCHK(st->status == 2); if (st->ksleft > 0) { j = MIN(st->ksleft, inlen); From 445bad17a1d25139e97ffcd671b330670ab67faf Mon Sep 17 00:00:00 2001 From: buggywhip Date: Tue, 26 Jun 2018 17:08:10 -0700 Subject: [PATCH 14/14] cleanup helper functions the plan is to extend the helper function concept to block ciphers and hash functions --- src/headers/tomcrypt_custom.h | 3 +++ src/misc/crypt/crypt_helper_functions.c | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 277271868..cc2e9cb33 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -641,6 +641,9 @@ #endif +/* helper functions for stream ciphers (disable to prevent building them) */ +#define LTC_HELPER_FUNCTIONS + /* Debuggers */ /* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */ diff --git a/src/misc/crypt/crypt_helper_functions.c b/src/misc/crypt/crypt_helper_functions.c index 209ac691f..f4c7714bb 100644 --- a/src/misc/crypt/crypt_helper_functions.c +++ b/src/misc/crypt/crypt_helper_functions.c @@ -8,6 +8,8 @@ */ #include "tomcrypt_private.h" +#ifdef LTC_HELPER_FUNCTIONS + /** @file crypt_helper_functions.c @@ -33,10 +35,10 @@ int chacha_memory(const unsigned char *key, unsigned long keylen, if ((err = chacha_ivctr32(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; } else { if ((err = chacha_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; - ) + } err = chacha_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = chacha_done(&state); + chacha_done(&state); return err; } @@ -59,7 +61,7 @@ int salsa20_onecall(const unsigned char *key, unsigned long keylen, if ((err = salsa20_ivctr64(&state, iv, ivlen, 0)) != CRYPT_OK) goto WIPE_KEY; err = salsa20_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = salsa20_done(&state); + salsa20_done(&state); return err; } @@ -81,7 +83,7 @@ int xsalsa20_onecall(const unsigned char *key, unsigned long keylen, if ((err = xsalsa20_setup(&state, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) goto WIPE_KEY; err = salsa20_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = salsa20_done(&state); + salsa20_done(&state); return err; } @@ -104,7 +106,7 @@ int sosemanuk_onecall(const unsigned char *key, unsigned long keylen, if ((err = sosemanuk_setiv(&state, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; err = sosemanuk_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = sosemanuk_done(&state); + sosemanuk_done(&state); return err; } @@ -126,7 +128,7 @@ int rabbit_onecall(const unsigned char *key, unsigned long keylen, if ((err = rabbit_setiv(&state, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; err = rabbit_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = rabbit_done(&state); + rabbit_done(&state); return err; } @@ -146,7 +148,7 @@ int rc4_stream_onecall(const unsigned char *key, unsigned long keylen, if ((err = rc4_stream_setup(&state, key, keylen)) != CRYPT_OK) goto WIPE_KEY; err = rc4_stream_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = rc4_stream_done(&state); + rc4_stream_done(&state); return err; } @@ -168,7 +170,7 @@ int sober128_stream_onecall(const unsigned char *key, unsigned long keylen, if ((err = sober128_stream_setiv(&state, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; err = sober128_stream_crypt(&state, datain, datalen, dataout); WIPE_KEY: - err = sober128_stream_done(&state); + sober128_stream_done(&state); return err; } @@ -176,6 +178,8 @@ int sober128_stream_onecall(const unsigned char *key, unsigned long keylen, /* ======================================================================== */ +#endif /* LTC_HELPER_FUNCTIONS */ + /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */