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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 69 additions & 6 deletions doc/crypt.tex
Original file line number Diff line number Diff line change
Expand Up @@ -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}

Expand Down Expand Up @@ -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;
Expand All @@ -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}
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}

Expand Down
4 changes: 4 additions & 0 deletions libtomcrypt_VS2008.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,10 @@
RelativePath="src\misc\crypt\crypt_hash_is_valid.c"
>
</File>
<File
RelativePath="src\misc\crypt\crypt_helper_functions.c"
>
</File>
<File
RelativePath="src\misc\crypt\crypt_inits.c"
>
Expand Down
12 changes: 6 additions & 6 deletions makefile.mingw
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
12 changes: 6 additions & 6 deletions makefile.msvc
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
12 changes: 6 additions & 6 deletions makefile.unix
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
12 changes: 6 additions & 6 deletions makefile_include.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions src/encauth/chachapoly/chacha20poly1305_setiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
107 changes: 82 additions & 25 deletions src/headers/tomcrypt_cipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -995,13 +995,22 @@ 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_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);
Expand All @@ -1015,14 +1024,22 @@ int chacha_test(void);
#ifdef LTC_SALSA20

typedef struct {
ulong32 input[16];
ulong32 input[16];
unsigned char kstream[64];
unsigned long ksleft;
unsigned long ivlen;
int rounds;
unsigned long rounds;
unsigned long 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_state_size(void);

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);
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);
Expand All @@ -1033,33 +1050,50 @@ int salsa20_test(void);

#ifdef LTC_XSALSA20

int xsalsa20_state_size(void);

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,
int rounds);
unsigned long rounds);
int xsalsa20_test(void);

#endif /* LTC_XSALSA20 */

#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;
unsigned long ivlen;
unsigned long 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_state_size(void);

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);
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 */
Expand All @@ -1075,10 +1109,18 @@ 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_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);
Expand All @@ -1093,8 +1135,15 @@ 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_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);
Expand All @@ -1110,9 +1159,17 @@ 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_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);
Expand Down
Loading