diff options
author | gregor herrmann <gregoa@debian.org> | 2018-01-03 20:36:37 +0100 |
---|---|---|
committer | gregor herrmann <gregoa@debian.org> | 2018-01-03 20:36:37 +0100 |
commit | 5b7253046b660592f2e7db7afd2857c8ac517621 (patch) | |
tree | 0bb309447b14b81de91bc8542da855a8083732b9 /src/ltc | |
parent | b3d0c9e280ed278158bcf1d15963b7c6f66057df (diff) | |
parent | 6e8abedfd93462d12874c2ba837012f2ab5eaaf9 (diff) |
New upstream version 0.056
Diffstat (limited to 'src/ltc')
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) |