summaryrefslogtreecommitdiff
path: root/src/ltc
diff options
context:
space:
mode:
authorgregor herrmann <gregoa@debian.org>2018-01-03 20:36:37 +0100
committergregor herrmann <gregoa@debian.org>2018-01-03 20:36:37 +0100
commit5b7253046b660592f2e7db7afd2857c8ac517621 (patch)
tree0bb309447b14b81de91bc8542da855a8083732b9 /src/ltc
parentb3d0c9e280ed278158bcf1d15963b7c6f66057df (diff)
parent6e8abedfd93462d12874c2ba837012f2ab5eaaf9 (diff)
New upstream version 0.056
Diffstat (limited to 'src/ltc')
-rw-r--r--src/ltc/encauth/ccm/ccm_memory.c24
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_add_aad.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_decrypt.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_decrypt_last.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_done.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_encrypt.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_encrypt_last.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_init.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_int_ntz.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c0
-rw-r--r--src/ltc/headers/tomcrypt_cipher.h24
-rw-r--r--src/ltc/headers/tomcrypt_custom.h3
-rw-r--r--src/ltc/headers/tomcrypt_mac.h182
-rw-r--r--src/ltc/headers/tomcrypt_misc.h3
-rw-r--r--src/ltc/misc/compare_testvector.c4
-rw-r--r--src/ltc/misc/copy_or_zeromem.c61
-rw-r--r--src/ltc/misc/crypt/crypt.c3
-rw-r--r--src/ltc/misc/crypt/crypt_sizes.c3
-rw-r--r--src/ltc/pk/asn1/der/bit/der_encode_bit_string.c2
-rw-r--r--src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c2
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_decrypt_key.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_encrypt_key.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_export.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_exptmod.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_free.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_get_size.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_import.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_import_pkcs8.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_import_x509.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_make_key.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_sign_hash.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_sign_saltlen_get.c0
-rw-r--r--[-rwxr-xr-x]src/ltc/pk/rsa/rsa_verify_hash.c0
-rw-r--r--src/ltc/prngs/chacha20.c1
-rw-r--r--src/ltc/prngs/fortuna.c1
-rw-r--r--src/ltc/prngs/rc4.c1
-rw-r--r--src/ltc/prngs/sober128.c1
-rw-r--r--src/ltc/prngs/yarrow.c1
-rw-r--r--src/ltc/stream/rabbit/rabbit.c446
-rw-r--r--src/ltc/stream/sosemanuk/sosemanuk.c49
42 files changed, 672 insertions, 139 deletions
diff --git a/src/ltc/encauth/ccm/ccm_memory.c b/src/ltc/encauth/ccm/ccm_memory.c
index 3326ce5c..0ffdbcef 100644
--- a/src/ltc/encauth/ccm/ccm_memory.c
+++ b/src/ltc/encauth/ccm/ccm_memory.c
@@ -51,10 +51,6 @@ int ccm_memory(int cipher,
symmetric_key *skey;
int err;
unsigned long len, L, x, y, z, CTRlen;
-#ifdef LTC_FAST
- LTC_FAST_TYPE fastMask = ~0; /* initialize fastMask at all zeroes */
-#endif
- unsigned char mask = 0xff; /* initialize mask at all zeroes */
if (uskey == NULL) {
LTC_ARGCHK(key != NULL);
@@ -360,29 +356,11 @@ int ccm_memory(int cipher,
/* Zero the plaintext if the tag was invalid (in constant time) */
if (ptlen > 0) {
- y = 0;
- mask *= 1 - err; /* mask = ( err ? 0 : 0xff ) */
-#ifdef LTC_FAST
- fastMask *= 1 - err;
- if (ptlen & ~15) {
- for (; y < (ptlen & ~15); y += 16) {
- for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
- *(LTC_FAST_TYPE_PTR_CAST(&pt_real[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) & fastMask;
- }
- }
- }
-#endif
- for (; y < ptlen; y++) {
- pt_real[y] = pt[y] & mask;
- }
+ copy_or_zeromem(pt, pt_real, ptlen, err);
}
}
#ifdef LTC_CLEAN_STACK
-#ifdef LTC_FAST
- fastMask = 0;
-#endif
- mask = 0;
zeromem(PAD, sizeof(PAD));
zeromem(CTRPAD, sizeof(CTRPAD));
if (pt_work != NULL) {
diff --git a/src/ltc/encauth/ocb3/ocb3_add_aad.c b/src/ltc/encauth/ocb3/ocb3_add_aad.c
index 70e3211a..70e3211a 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_add_aad.c
+++ b/src/ltc/encauth/ocb3/ocb3_add_aad.c
diff --git a/src/ltc/encauth/ocb3/ocb3_decrypt.c b/src/ltc/encauth/ocb3/ocb3_decrypt.c
index 4973bd2f..4973bd2f 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_decrypt.c
+++ b/src/ltc/encauth/ocb3/ocb3_decrypt.c
diff --git a/src/ltc/encauth/ocb3/ocb3_decrypt_last.c b/src/ltc/encauth/ocb3/ocb3_decrypt_last.c
index 70608dc7..70608dc7 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_decrypt_last.c
+++ b/src/ltc/encauth/ocb3/ocb3_decrypt_last.c
diff --git a/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c b/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c
index 066b62cb..066b62cb 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c
+++ b/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c
diff --git a/src/ltc/encauth/ocb3/ocb3_done.c b/src/ltc/encauth/ocb3/ocb3_done.c
index b913d3a4..b913d3a4 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_done.c
+++ b/src/ltc/encauth/ocb3/ocb3_done.c
diff --git a/src/ltc/encauth/ocb3/ocb3_encrypt.c b/src/ltc/encauth/ocb3/ocb3_encrypt.c
index 337b0253..337b0253 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_encrypt.c
+++ b/src/ltc/encauth/ocb3/ocb3_encrypt.c
diff --git a/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c b/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
index efc1a8fb..efc1a8fb 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
+++ b/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
diff --git a/src/ltc/encauth/ocb3/ocb3_encrypt_last.c b/src/ltc/encauth/ocb3/ocb3_encrypt_last.c
index 8110a3c0..8110a3c0 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_encrypt_last.c
+++ b/src/ltc/encauth/ocb3/ocb3_encrypt_last.c
diff --git a/src/ltc/encauth/ocb3/ocb3_init.c b/src/ltc/encauth/ocb3/ocb3_init.c
index a3cabae8..a3cabae8 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_init.c
+++ b/src/ltc/encauth/ocb3/ocb3_init.c
diff --git a/src/ltc/encauth/ocb3/ocb3_int_ntz.c b/src/ltc/encauth/ocb3/ocb3_int_ntz.c
index 3c5b18d0..3c5b18d0 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_int_ntz.c
+++ b/src/ltc/encauth/ocb3/ocb3_int_ntz.c
diff --git a/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c b/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c
index 798bddcd..798bddcd 100755..100644
--- a/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c
+++ b/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c
diff --git a/src/ltc/headers/tomcrypt_cipher.h b/src/ltc/headers/tomcrypt_cipher.h
index a7b46686..4cfa18a4 100644
--- a/src/ltc/headers/tomcrypt_cipher.h
+++ b/src/ltc/headers/tomcrypt_cipher.h
@@ -1031,8 +1031,6 @@ int salsa20_test(void);
#endif /* LTC_SALSA20 */
-
-
#ifdef LTC_SOSEMANUK
typedef struct {
@@ -1057,7 +1055,29 @@ int sosemanuk_test(void);
#endif /* LTC_SOSEMANUK */
+#ifdef LTC_RABBIT
+typedef struct {
+ ulong32 x[8];
+ ulong32 c[8];
+ ulong32 carry;
+} rabbit_ctx;
+
+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 */
+} rabbit_state;
+
+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);
+int rabbit_keystream(rabbit_state* st, unsigned char *out, unsigned long outlen);
+int rabbit_done(rabbit_state *st);
+int rabbit_test(void);
+
+#endif /* LTC_RABBIT */
#ifdef LTC_RC4_STREAM
diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h
index 8b40c9bc..5a218ff3 100644
--- a/src/ltc/headers/tomcrypt_custom.h
+++ b/src/ltc/headers/tomcrypt_custom.h
@@ -209,6 +209,7 @@
#define LTC_CHACHA
#define LTC_SALSA20
#define LTC_SOSEMANUK
+#define LTC_RABBIT
#define LTC_RC4_STREAM
#define LTC_SOBER128_STREAM
@@ -583,6 +584,7 @@
#define LTC_MUTEX_INIT(x) LTC_ARGCHK(pthread_mutex_init(x, NULL) == 0);
#define LTC_MUTEX_LOCK(x) LTC_ARGCHK(pthread_mutex_lock(x) == 0);
#define LTC_MUTEX_UNLOCK(x) LTC_ARGCHK(pthread_mutex_unlock(x) == 0);
+#define LTC_MUTEX_DESTROY(x) LTC_ARGCHK(pthread_mutex_destroy(x) == 0);
#else
@@ -593,6 +595,7 @@
#define LTC_MUTEX_INIT(x)
#define LTC_MUTEX_LOCK(x)
#define LTC_MUTEX_UNLOCK(x)
+#define LTC_MUTEX_DESTROY(x)
#endif
diff --git a/src/ltc/headers/tomcrypt_mac.h b/src/ltc/headers/tomcrypt_mac.h
index 9c260214..c4b24239 100644
--- a/src/ltc/headers/tomcrypt_mac.h
+++ b/src/ltc/headers/tomcrypt_mac.h
@@ -146,6 +146,99 @@ int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long k
int blake2bmac_test(void);
#endif /* LTC_BLAKE2BMAC */
+#ifdef LTC_PELICAN
+
+typedef struct pelican_state
+{
+ symmetric_key K;
+ unsigned char state[16];
+ int buflen;
+} pelican_state;
+
+int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
+int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
+int pelican_done(pelican_state *pelmac, unsigned char *out);
+int pelican_test(void);
+
+int pelican_memory(const unsigned char *key, unsigned long keylen,
+ const unsigned char *in, unsigned long inlen,
+ unsigned char *out);
+
+#endif
+
+#ifdef LTC_XCBC
+
+/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
+#define LTC_XCBC_PURE 0x8000UL
+
+typedef struct {
+ unsigned char K[3][MAXBLOCKSIZE],
+ IV[MAXBLOCKSIZE];
+
+ symmetric_key key;
+
+ int cipher,
+ buflen,
+ blocksize;
+} xcbc_state;
+
+int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
+int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
+int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
+int xcbc_memory(int cipher,
+ const unsigned char *key, unsigned long keylen,
+ const unsigned char *in, unsigned long inlen,
+ unsigned char *out, unsigned long *outlen);
+int xcbc_memory_multi(int cipher,
+ const unsigned char *key, unsigned long keylen,
+ unsigned char *out, unsigned long *outlen,
+ const unsigned char *in, unsigned long inlen, ...);
+int xcbc_file(int cipher,
+ const unsigned char *key, unsigned long keylen,
+ const char *filename,
+ unsigned char *out, unsigned long *outlen);
+int xcbc_test(void);
+
+#endif
+
+#ifdef LTC_F9_MODE
+
+typedef struct {
+ unsigned char akey[MAXBLOCKSIZE],
+ ACC[MAXBLOCKSIZE],
+ IV[MAXBLOCKSIZE];
+
+ symmetric_key key;
+
+ int cipher,
+ buflen,
+ keylen,
+ blocksize;
+} f9_state;
+
+int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
+int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
+int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
+int f9_memory(int cipher,
+ const unsigned char *key, unsigned long keylen,
+ const unsigned char *in, unsigned long inlen,
+ unsigned char *out, unsigned long *outlen);
+int f9_memory_multi(int cipher,
+ const unsigned char *key, unsigned long keylen,
+ unsigned char *out, unsigned long *outlen,
+ const unsigned char *in, unsigned long inlen, ...);
+int f9_file(int cipher,
+ const unsigned char *key, unsigned long keylen,
+ const char *filename,
+ unsigned char *out, unsigned long *outlen);
+int f9_test(void);
+
+#endif
+
+/*
+ * ENC+AUTH modes
+ */
+
#ifdef LTC_EAX_MODE
#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
@@ -440,95 +533,6 @@ int gcm_test(void);
#endif /* LTC_GCM_MODE */
-#ifdef LTC_PELICAN
-
-typedef struct pelican_state
-{
- symmetric_key K;
- unsigned char state[16];
- int buflen;
-} pelican_state;
-
-int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
-int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
-int pelican_done(pelican_state *pelmac, unsigned char *out);
-int pelican_test(void);
-
-int pelican_memory(const unsigned char *key, unsigned long keylen,
- const unsigned char *in, unsigned long inlen,
- unsigned char *out);
-
-#endif
-
-#ifdef LTC_XCBC
-
-/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
-#define LTC_XCBC_PURE 0x8000UL
-
-typedef struct {
- unsigned char K[3][MAXBLOCKSIZE],
- IV[MAXBLOCKSIZE];
-
- symmetric_key key;
-
- int cipher,
- buflen,
- blocksize;
-} xcbc_state;
-
-int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
-int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
-int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
-int xcbc_memory(int cipher,
- const unsigned char *key, unsigned long keylen,
- const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen);
-int xcbc_memory_multi(int cipher,
- const unsigned char *key, unsigned long keylen,
- unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
-int xcbc_file(int cipher,
- const unsigned char *key, unsigned long keylen,
- const char *filename,
- unsigned char *out, unsigned long *outlen);
-int xcbc_test(void);
-
-#endif
-
-#ifdef LTC_F9_MODE
-
-typedef struct {
- unsigned char akey[MAXBLOCKSIZE],
- ACC[MAXBLOCKSIZE],
- IV[MAXBLOCKSIZE];
-
- symmetric_key key;
-
- int cipher,
- buflen,
- keylen,
- blocksize;
-} f9_state;
-
-int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
-int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
-int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
-int f9_memory(int cipher,
- const unsigned char *key, unsigned long keylen,
- const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen);
-int f9_memory_multi(int cipher,
- const unsigned char *key, unsigned long keylen,
- unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
-int f9_file(int cipher,
- const unsigned char *key, unsigned long keylen,
- const char *filename,
- unsigned char *out, unsigned long *outlen);
-int f9_test(void);
-
-#endif
-
#ifdef LTC_CHACHA20POLY1305_MODE
typedef struct {
diff --git a/src/ltc/headers/tomcrypt_misc.h b/src/ltc/headers/tomcrypt_misc.h
index 0440a5ef..63fc3a89 100644
--- a/src/ltc/headers/tomcrypt_misc.h
+++ b/src/ltc/headers/tomcrypt_misc.h
@@ -72,6 +72,9 @@ int hkdf(int hash_idx,
/* ---- MEM routines ---- */
int mem_neq(const void *a, const void *b, size_t len);
void zeromem(volatile void *dst, size_t len);
+#ifdef LTC_SOURCE
+void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz);
+#endif
void burn_stack(unsigned long len);
const char *error_to_string(int err);
diff --git a/src/ltc/misc/compare_testvector.c b/src/ltc/misc/compare_testvector.c
index 82433c6f..74cebcc3 100644
--- a/src/ltc/misc/compare_testvector.c
+++ b/src/ltc/misc/compare_testvector.c
@@ -73,6 +73,10 @@ int compare_testvector(const void* is, const unsigned long is_len, const void* s
fprintf(stderr, "Testvector #%i of %s failed:\n", which, what);
_print_hex("SHOULD", should, should_len);
_print_hex("IS ", is, is_len);
+#if LTC_TEST_DBG > 1
+ } else {
+ fprintf(stderr, "Testvector #%i of %s passed!\n", which, what);
+#endif
}
#else
LTC_UNUSED_PARAM(which);
diff --git a/src/ltc/misc/copy_or_zeromem.c b/src/ltc/misc/copy_or_zeromem.c
new file mode 100644
index 00000000..ec78fed6
--- /dev/null
+++ b/src/ltc/misc/copy_or_zeromem.c
@@ -0,0 +1,61 @@
+/* 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.h"
+
+/**
+ @file copy_or_zeromem.c
+ Either copy or zero a block of memory in constant time, Steffen Jaeckel
+*/
+
+/**
+ Either copy or zero a block of memory in constant time
+ @param src The source where to read from
+ @param dest The destination where to write to
+ @param len The length of the area to process (octets)
+ @param coz Copy (on 0) Or Zero (> 0)
+*/
+void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz)
+{
+ unsigned long y;
+#ifdef LTC_FAST
+ unsigned long z;
+ LTC_FAST_TYPE fastMask = ~0; /* initialize fastMask at all ones */
+#endif
+ unsigned char mask = 0xff; /* initialize mask at all ones */
+
+ LTC_ARGCHK(src != NULL);
+ LTC_ARGCHK(dest != NULL);
+
+ if (coz != 0) coz = 1;
+ y = 0;
+ mask *= 1 - coz; /* mask = ( coz ? 0 : 0xff ) */
+#ifdef LTC_FAST
+ fastMask *= 1 - coz;
+ if (len & ~15) {
+ for (; y < (len & ~15); y += 16) {
+ for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
+ *(LTC_FAST_TYPE_PTR_CAST(&dest[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&src[y+z])) & fastMask;
+ }
+ }
+ }
+#endif
+ for (; y < len; y++) {
+ dest[y] = src[y] & mask;
+ }
+#ifdef LTC_CLEAN_STACK
+#ifdef LTC_FAST
+ fastMask = 0;
+#endif
+ mask = 0;
+#endif
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c
index 4a16e7ae..bd656325 100644
--- a/src/ltc/misc/crypt/crypt.c
+++ b/src/ltc/misc/crypt/crypt.c
@@ -138,6 +138,9 @@ const char *crypt_build_settings =
#if defined(LTC_SOSEMANUK)
" Sosemanuk\n"
#endif
+#if defined(LTC_RABBIT)
+ " Rabbit\n"
+#endif
#if defined(LTC_RC4_STREAM)
" RC4\n"
#endif
diff --git a/src/ltc/misc/crypt/crypt_sizes.c b/src/ltc/misc/crypt/crypt_sizes.c
index 744653f0..c4b16b5c 100644
--- a/src/ltc/misc/crypt/crypt_sizes.c
+++ b/src/ltc/misc/crypt/crypt_sizes.c
@@ -183,6 +183,9 @@ static const crypt_size _crypt_sizes[] = {
#ifdef LTC_SOSEMANUK
_SZ_STRINGIFY_T(sosemanuk_state),
#endif
+#ifdef LTC_RABBIT
+ _SZ_STRINGIFY_T(rabbit_state),
+#endif
#ifdef LTC_RC4_STREAM
_SZ_STRINGIFY_T(rc4_state),
#endif
diff --git a/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c b/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c
index c552184c..2a674790 100644
--- a/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c
+++ b/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c
@@ -47,7 +47,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
/* store header (include bit padding count in length) */
x = 0;
- y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
+ y = ((inlen + 7) >> 3) + 1;
out[x++] = 0x03;
if (y < 128) {
diff --git a/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c b/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c
index 298c4e36..4101a1da 100644
--- a/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c
+++ b/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c
@@ -49,7 +49,7 @@ int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
/* store header (include bit padding count in length) */
x = 0;
- y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
+ y = ((inlen + 7) >> 3) + 1;
out[x++] = 0x03;
if (y < 128) {
diff --git a/src/ltc/pk/rsa/rsa_decrypt_key.c b/src/ltc/pk/rsa/rsa_decrypt_key.c
index 9e1bcede..9e1bcede 100755..100644
--- a/src/ltc/pk/rsa/rsa_decrypt_key.c
+++ b/src/ltc/pk/rsa/rsa_decrypt_key.c
diff --git a/src/ltc/pk/rsa/rsa_encrypt_key.c b/src/ltc/pk/rsa/rsa_encrypt_key.c
index ef066d2d..ef066d2d 100755..100644
--- a/src/ltc/pk/rsa/rsa_encrypt_key.c
+++ b/src/ltc/pk/rsa/rsa_encrypt_key.c
diff --git a/src/ltc/pk/rsa/rsa_export.c b/src/ltc/pk/rsa/rsa_export.c
index a9885de8..a9885de8 100755..100644
--- a/src/ltc/pk/rsa/rsa_export.c
+++ b/src/ltc/pk/rsa/rsa_export.c
diff --git a/src/ltc/pk/rsa/rsa_exptmod.c b/src/ltc/pk/rsa/rsa_exptmod.c
index 37f62d11..37f62d11 100755..100644
--- a/src/ltc/pk/rsa/rsa_exptmod.c
+++ b/src/ltc/pk/rsa/rsa_exptmod.c
diff --git a/src/ltc/pk/rsa/rsa_free.c b/src/ltc/pk/rsa/rsa_free.c
index 1e62f097..1e62f097 100755..100644
--- a/src/ltc/pk/rsa/rsa_free.c
+++ b/src/ltc/pk/rsa/rsa_free.c
diff --git a/src/ltc/pk/rsa/rsa_get_size.c b/src/ltc/pk/rsa/rsa_get_size.c
index 8c901947..8c901947 100755..100644
--- a/src/ltc/pk/rsa/rsa_get_size.c
+++ b/src/ltc/pk/rsa/rsa_get_size.c
diff --git a/src/ltc/pk/rsa/rsa_import.c b/src/ltc/pk/rsa/rsa_import.c
index 84cd6f65..84cd6f65 100755..100644
--- a/src/ltc/pk/rsa/rsa_import.c
+++ b/src/ltc/pk/rsa/rsa_import.c
diff --git a/src/ltc/pk/rsa/rsa_import_pkcs8.c b/src/ltc/pk/rsa/rsa_import_pkcs8.c
index 8e15e066..8e15e066 100755..100644
--- a/src/ltc/pk/rsa/rsa_import_pkcs8.c
+++ b/src/ltc/pk/rsa/rsa_import_pkcs8.c
diff --git a/src/ltc/pk/rsa/rsa_import_x509.c b/src/ltc/pk/rsa/rsa_import_x509.c
index 0f2d5f1c..0f2d5f1c 100755..100644
--- a/src/ltc/pk/rsa/rsa_import_x509.c
+++ b/src/ltc/pk/rsa/rsa_import_x509.c
diff --git a/src/ltc/pk/rsa/rsa_make_key.c b/src/ltc/pk/rsa/rsa_make_key.c
index c5c4c288..c5c4c288 100755..100644
--- a/src/ltc/pk/rsa/rsa_make_key.c
+++ b/src/ltc/pk/rsa/rsa_make_key.c
diff --git a/src/ltc/pk/rsa/rsa_sign_hash.c b/src/ltc/pk/rsa/rsa_sign_hash.c
index 05c7155d..05c7155d 100755..100644
--- a/src/ltc/pk/rsa/rsa_sign_hash.c
+++ b/src/ltc/pk/rsa/rsa_sign_hash.c
diff --git a/src/ltc/pk/rsa/rsa_sign_saltlen_get.c b/src/ltc/pk/rsa/rsa_sign_saltlen_get.c
index b217f94e..b217f94e 100755..100644
--- a/src/ltc/pk/rsa/rsa_sign_saltlen_get.c
+++ b/src/ltc/pk/rsa/rsa_sign_saltlen_get.c
diff --git a/src/ltc/pk/rsa/rsa_verify_hash.c b/src/ltc/pk/rsa/rsa_verify_hash.c
index b5846965..b5846965 100755..100644
--- a/src/ltc/pk/rsa/rsa_verify_hash.c
+++ b/src/ltc/pk/rsa/rsa_verify_hash.c
diff --git a/src/ltc/prngs/chacha20.c b/src/ltc/prngs/chacha20.c
index ac1f8a24..72a6d63d 100644
--- a/src/ltc/prngs/chacha20.c
+++ b/src/ltc/prngs/chacha20.c
@@ -139,6 +139,7 @@ int chacha20_prng_done(prng_state *prng)
prng->ready = 0;
err = chacha_done(&prng->chacha.s);
LTC_MUTEX_UNLOCK(&prng->lock);
+ LTC_MUTEX_DESTROY(&prng->lock);
return err;
}
diff --git a/src/ltc/prngs/fortuna.c b/src/ltc/prngs/fortuna.c
index 4a520d4a..7b1ecb65 100644
--- a/src/ltc/prngs/fortuna.c
+++ b/src/ltc/prngs/fortuna.c
@@ -318,6 +318,7 @@ LBL_UNLOCK:
zeromem(tmp, sizeof(tmp));
#endif
LTC_MUTEX_UNLOCK(&prng->lock);
+ LTC_MUTEX_DESTROY(&prng->lock);
return err;
}
diff --git a/src/ltc/prngs/rc4.c b/src/ltc/prngs/rc4.c
index 5ae91c4f..e2aa9217 100644
--- a/src/ltc/prngs/rc4.c
+++ b/src/ltc/prngs/rc4.c
@@ -142,6 +142,7 @@ int rc4_done(prng_state *prng)
prng->ready = 0;
err = rc4_stream_done(&prng->rc4.s);
LTC_MUTEX_UNLOCK(&prng->lock);
+ LTC_MUTEX_DESTROY(&prng->lock);
return err;
}
diff --git a/src/ltc/prngs/sober128.c b/src/ltc/prngs/sober128.c
index 00b1d617..8d95491b 100644
--- a/src/ltc/prngs/sober128.c
+++ b/src/ltc/prngs/sober128.c
@@ -141,6 +141,7 @@ int sober128_done(prng_state *prng)
prng->ready = 0;
err = sober128_stream_done(&prng->sober128.s);
LTC_MUTEX_UNLOCK(&prng->lock);
+ LTC_MUTEX_DESTROY(&prng->lock);
return err;
}
diff --git a/src/ltc/prngs/yarrow.c b/src/ltc/prngs/yarrow.c
index 1a77e7f0..e5988348 100644
--- a/src/ltc/prngs/yarrow.c
+++ b/src/ltc/prngs/yarrow.c
@@ -262,6 +262,7 @@ int yarrow_done(prng_state *prng)
err = ctr_done(&prng->yarrow.ctr);
LTC_MUTEX_UNLOCK(&prng->lock);
+ LTC_MUTEX_DESTROY(&prng->lock);
return err;
}
diff --git a/src/ltc/stream/rabbit/rabbit.c b/src/ltc/stream/rabbit/rabbit.c
new file mode 100644
index 00000000..cf6ec0b8
--- /dev/null
+++ b/src/ltc/stream/rabbit/rabbit.c
@@ -0,0 +1,446 @@
+/* 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.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes. Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes. Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * 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
+ * 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
+ *
+ * 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.
+ *
+ * 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
+ *
+ * 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.
+ *---------------------------------------------------------------------------
+ * 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
+ ******************************************************************************/
+
+
+#include "tomcrypt.h"
+
+#ifdef LTC_RABBIT
+
+/* local/private prototypes (NB: rabbit_ctx and rabbit_state are different) */
+static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x);
+static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance);
+static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
+
+/* -------------------------------------------------------------------------- */
+
+/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
+/* the upper 32 bits XOR the lower 32 bits */
+static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x)
+{
+ ulong32 a, b, h, l;
+
+ /* Construct high and low argument for squaring */
+ a = x & 0xFFFF;
+ b = x >> 16;
+
+ /* Calculate high and low result of squaring */
+ h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
+ l = x * x;
+
+ /* Return high XOR low */
+ return (ulong32)(h^l);
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* Calculate the next internal state */
+static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance)
+{
+ ulong32 g[8], c_old[8], i;
+
+ /* Save old counter values */
+ for (i=0; i<8; i++)
+ c_old[i] = p_instance->c[i];
+
+ /* Calculate new counter values */
+ p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
+ p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
+ p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
+ p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
+ p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
+ p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
+ p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
+ p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
+ p_instance->carry = (p_instance->c[7] < c_old[7]);
+
+ /* Calculate the g-values */
+ for (i=0;i<8;i++)
+ g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
+
+ /* Calculate new state values */
+ p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
+ p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
+ p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
+ p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
+ p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
+ p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
+ p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
+ p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
+{
+ ulong32 *ptr;
+
+ /* Iterate the work context once */
+ _rabbit_next_state(&(st->work_ctx));
+
+ /* Generate 16 bytes of pseudo-random data */
+ ptr = (ulong32*)&(st->work_ctx.x);
+ STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
+ STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
+ STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
+ 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)
+{
+ ulong32 k0, k1, k2, k3, i;
+ unsigned char tmpkey[16] = {0};
+
+ LTC_ARGCHK(st != NULL);
+ LTC_ARGCHK(key != NULL);
+ LTC_ARGCHK(keylen <= 16);
+
+ /* init state */
+ XMEMSET(st, 0, sizeof(rabbit_state));
+
+ /* pad key in tmpkey */
+ XMEMCPY(tmpkey, key, keylen);
+
+ /* Generate four subkeys */
+ LOAD32L(k0, tmpkey+ 0);
+ LOAD32L(k1, tmpkey+ 4);
+ LOAD32L(k2, tmpkey+ 8);
+ LOAD32L(k3, tmpkey+12);
+
+#ifdef LTC_CLEAN_STACK
+ /* done with tmpkey, wipe it */
+ zeromem(tmpkey, sizeof(tmpkey));
+#endif
+
+ /* Generate initial state variables */
+ st->master_ctx.x[0] = k0;
+ st->master_ctx.x[2] = k1;
+ st->master_ctx.x[4] = k2;
+ st->master_ctx.x[6] = k3;
+ st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
+ st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
+ st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
+ st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
+
+ /* Generate initial counter values */
+ st->master_ctx.c[0] = ROLc(k2, 16);
+ st->master_ctx.c[2] = ROLc(k3, 16);
+ st->master_ctx.c[4] = ROLc(k0, 16);
+ st->master_ctx.c[6] = ROLc(k1, 16);
+ st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
+ st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
+ st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
+ st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
+
+ /* Clear carry bit */
+ st->master_ctx.carry = 0;
+
+ /* Iterate the master context four times */
+ for (i=0; i<4; i++)
+ _rabbit_next_state(&(st->master_ctx));
+
+ /* Modify the counters */
+ for (i=0; i<8; i++)
+ st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
+
+ /* Copy master instance to work instance */
+ for (i=0; i<8; i++) {
+ st->work_ctx.x[i] = st->master_ctx.x[i];
+ st->work_ctx.c[i] = st->master_ctx.c[i];
+ }
+ st->work_ctx.carry = st->master_ctx.carry;
+ /* ...and prepare block for crypt() */
+ XMEMSET(&(st->block), 0, sizeof(st->block));
+ st->unused = 0;
+
+ return CRYPT_OK;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* IV setup */
+int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
+{
+ ulong32 i0, i1, i2, i3, i;
+ unsigned char tmpiv[8] = {0};
+
+ LTC_ARGCHK(st != NULL);
+ LTC_ARGCHK(iv != NULL || ivlen == 0);
+ LTC_ARGCHK(ivlen <= 8);
+
+ /* pad iv in tmpiv */
+ if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
+
+ /* Generate four subvectors */
+ LOAD32L(i0, tmpiv+0);
+ LOAD32L(i2, tmpiv+4);
+ i1 = (i0>>16) | (i2&0xFFFF0000);
+ i3 = (i2<<16) | (i0&0x0000FFFF);
+
+ /* Modify counter values */
+ st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
+ st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
+ st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
+ st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
+ st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
+ st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
+ st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
+ st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
+
+ /* Copy state variables */
+ for (i=0; i<8; i++)
+ st->work_ctx.x[i] = st->master_ctx.x[i];
+ st->work_ctx.carry = st->master_ctx.carry;
+
+ /* Iterate the work context four times */
+ for (i=0; i<4; i++)
+ _rabbit_next_state(&(st->work_ctx));
+
+ /* reset keystream buffer and unused count */
+ XMEMSET(&(st->block), 0, sizeof(st->block));
+ st->unused = 0;
+
+ return CRYPT_OK;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Crypt a chunk of any size (encrypt/decrypt) */
+int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
+{
+ unsigned char buf[16];
+ unsigned long i, j;
+
+ if (inlen == 0) return CRYPT_OK; /* nothing to do */
+
+ LTC_ARGCHK(st != NULL);
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(out != NULL);
+
+ if (st->unused > 0) {
+ j = MIN(st->unused, inlen);
+ for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
+ inlen -= j;
+ if (inlen == 0) return CRYPT_OK;
+ out += j;
+ in += j;
+ }
+ for (;;) {
+ /* gen a block for buf */
+ _rabbit_gen_1_block(st, buf);
+ if (inlen <= 16) {
+ /* XOR and send to out */
+ for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
+ st->unused = 16 - inlen;
+ /* copy remainder to block */
+ for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
+ return CRYPT_OK;
+ } else {
+ /* XOR entire buf and send to out */
+ for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
+ inlen -= 16;
+ out += 16;
+ in += 16;
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+int rabbit_keystream(rabbit_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 rabbit_crypt(st, out, outlen, out);
+}
+
+/* -------------------------------------------------------------------------- */
+
+int rabbit_done(rabbit_state *st)
+{
+ LTC_ARGCHK(st != NULL);
+
+ zeromem(st, sizeof(rabbit_state));
+ return CRYPT_OK;
+}
+
+/* -------------------------------------------------------------------------- */
+
+int rabbit_test(void)
+{
+#ifndef LTC_TEST
+ return CRYPT_NOP;
+#else
+ rabbit_state st;
+ int err;
+ unsigned char out[1000] = { 0 };
+ {
+ /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
+ http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
+ */
+
+ /* --- Test 1 (generate whole blocks) --------------------------------- */
+
+ {
+ unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
+ 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
+ unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
+ char pt[64] = { 0 };
+ unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
+ 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
+ 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
+ 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
+ 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
+ 0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
+ 0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
+ 0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
+ unsigned long ptlen = sizeof(pt);
+
+ /* crypt 64 nulls */
+ if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
+ if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
+ if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ /* --- Test 2 (generate unusual number of bytes each time) ------------ */
+
+ {
+ unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
+ 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
+ unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
+ char pt[39] = { 0 };
+ unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
+ 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
+ 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
+ 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
+ 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D };
+ unsigned long ptlen = sizeof(pt);
+
+ /* crypt piece by piece (hit at least one 16-byte boundary) */
+ if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
+ if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 11, out + 5)) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30, 2, out + 30)) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32, 7, out + 32)) != CRYPT_OK) return err;
+ if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ /* --- Test 3 (use non-null data) ------------------------------------- */
+
+ {
+ unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
+ 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
+ unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
+ char pt[] = "Kilroy was here, there, and everywhere!";
+ unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8, 0xf9, 0xd6, 0xd6, 0xbd,
+ 0xae, 0x59, 0x65, 0xf2, 0x75, 0x58, 0x1a, 0x54,
+ 0xea, 0xec, 0x34, 0x9d, 0x8f, 0xb4, 0x6b, 0x60,
+ 0x79, 0x1b, 0xea, 0x16, 0xcb, 0xef, 0x46, 0x87,
+ 0x60, 0xa6, 0x55, 0x14, 0xff, 0xca, 0xac };
+ unsigned long ptlen = strlen(pt);
+ unsigned char out2[1000] = { 0 };
+ unsigned char nulls[1000] = { 0 };
+
+ /* crypt piece by piece */
+ if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
+ if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 29, out + 5)) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34, 5, out + 34)) != CRYPT_OK) return err;
+ if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
+ /* use 'out' (ciphertext) in the next decryption test */
+
+ /* --- Test 4 (decrypt ciphertext) ------------------------------------ */
+
+ /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
+ if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
+ if ((err = rabbit_crypt(&st, out, ptlen, out2)) != CRYPT_OK) return err;
+ if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
+
+ /* --- Test 5 (wipe state, incl key) ---------------------------------- */
+
+ if ((err = rabbit_done(&st)) != CRYPT_OK) return err;
+ if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV5", 1)) return CRYPT_FAIL_TESTVECTOR;
+
+ }
+
+ return CRYPT_OK;
+ }
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/ltc/stream/sosemanuk/sosemanuk.c b/src/ltc/stream/sosemanuk/sosemanuk.c
index 6146a81f..c4450278 100644
--- a/src/ltc/stream/sosemanuk/sosemanuk.c
+++ b/src/ltc/stream/sosemanuk/sosemanuk.c
@@ -194,11 +194,11 @@
/* ======================================================================== */
/*
- * Key schedule: initialize the key context structure with the provided
- * secret key. The secret key is an array of 1 to 32 bytes.
+ * Initialize Sosemanuk's state by providing a key. The key is an array of
+ * 1 to 32 bytes.
* @param ss The Sosemanuk state
* @param key Key
- * @param keylen Length of key
+ * @param keylen Length of key in bytes
* @return CRYPT_OK on success
*/
int sosemanuk_setup(sosemanuk_state *ss, unsigned char *key, unsigned long keylen)
@@ -331,12 +331,14 @@ int sosemanuk_setup(sosemanuk_state *ss, unsigned char *key, unsigned long keyle
/*
- * Cipher initialization: the cipher internal state is initialized, using
- * the provided key context and IV. The IV length is up to 16 bytes. If
- * "ivlen" is 0 (no IV), then the "iv" parameter can be NULL.
+ * 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
+ * sosemanuk_done() has not been called, only sosemanuk_setiv() need be called
+ * to set the state.
* @param ss The Sosemanuk state
* @param iv Initialization vector
- * @param ivlen Length of iv
+ * @param ivlen Length of iv in bytes
* @return CRYPT_OK on success
*/
int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long ivlen)
@@ -380,7 +382,7 @@ int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long ivlen)
unsigned char ivtmp[16] = {0};
LTC_ARGCHK(ss != NULL);
- LTC_ARGCHK(ivlen >= 0 && ivlen <= 16);
+ LTC_ARGCHK(ivlen <= 16);
LTC_ARGCHK(iv != NULL || ivlen == 0);
if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
@@ -448,7 +450,7 @@ int sosemanuk_setiv(sosemanuk_state *ss, unsigned char *iv, unsigned long ivlen)
/*
* Multiplication by alpha: alpha * x = T32(x << 8) ^ mul_a[x >> 24]
*/
-static ulong32 mul_a[] = {
+static const ulong32 mul_a[] = {
0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835,
0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679,
0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD,
@@ -518,7 +520,7 @@ static ulong32 mul_a[] = {
/*
* Multiplication by 1/alpha: 1/alpha * x = (x >> 8) ^ mul_ia[x & 0xFF]
*/
-static ulong32 mul_ia[] = {
+static const ulong32 mul_ia[] = {
0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE,
0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998,
0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32,
@@ -743,12 +745,12 @@ static LTC_INLINE void _xorbuf(const unsigned char *in1, const unsigned char *in
* reference distinct buffers (no partial overlap is allowed).
* @param ss The Sosemanuk state
* @param in Data in
+ * @param inlen Length of data in bytes
* @param out Data out
- * @param datalen Length of data
* @return CRYPT_OK on success
*/
int sosemanuk_crypt(sosemanuk_state *ss,
- const unsigned char *in, unsigned long datalen, unsigned char *out)
+ const unsigned char *in, unsigned long inlen, unsigned char *out)
{
LTC_ARGCHK(ss != NULL);
LTC_ARGCHK(in != NULL);
@@ -757,37 +759,38 @@ int sosemanuk_crypt(sosemanuk_state *ss,
if (ss->ptr < (sizeof(ss->buf))) {
unsigned long rlen = (sizeof(ss->buf)) - ss->ptr;
- if (rlen > datalen)
- rlen = datalen;
+ if (rlen > inlen)
+ rlen = inlen;
_xorbuf(ss->buf + ss->ptr, in, out, rlen);
in += rlen;
out += rlen;
- datalen -= rlen;
+ inlen -= rlen;
ss->ptr += rlen;
}
- while (datalen > 0) {
+ while (inlen > 0) {
_sosemanuk_internal(ss);
- if (datalen >= sizeof(ss->buf)) {
+ if (inlen >= sizeof(ss->buf)) {
_xorbuf(ss->buf, in, out, sizeof(ss->buf));
in += sizeof(ss->buf);
out += sizeof(ss->buf);
- datalen -= sizeof(ss->buf);
+ inlen -= sizeof(ss->buf);
} else {
- _xorbuf(ss->buf, in, out, datalen);
- ss->ptr = datalen;
- datalen = 0;
+ _xorbuf(ss->buf, in, out, inlen);
+ ss->ptr = inlen;
+ inlen = 0;
}
}
return CRYPT_OK;
}
+
/*
* 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 out Data out
- * @param outlen Length of output
+ * @param outlen Length of output in bytes
* @return CRYPT_OK on success
*/
int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen)
@@ -801,7 +804,7 @@ int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long o
/*
* Terminate and clear Sosemanuk key context
- * @param kc The Sosemanuk key context
+ * @param ss The Sosemanuk state
* @return CRYPT_OK on success
*/
int sosemanuk_done(sosemanuk_state *ss)