From 344620a0e74775fde51c57e76b5cd315b35c12d1 Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Tue, 21 Feb 2017 20:23:10 +0100 Subject: [PATCH 1/6] fixes #135 RC2 min keylen 40bit (was 64bit) --- crypt.tex | 2 +- src/ciphers/rc2.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypt.tex b/crypt.tex index 7e854a7..041baac 100644 --- a/crypt.tex +++ b/crypt.tex @@ -609,7 +609,7 @@ As of this release the current cipher\_descriptors elements are the following: \hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Block Size} & \textbf{Key Range} & \textbf{Rounds} \\ \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\ \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\ - \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\ + \hline RC2 & rc2\_desc & 8 & 5 $\ldots$ 128 & 16 \\ \hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\ \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\ \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\ diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index a778535..2520b83 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -77,7 +77,7 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); - if (keylen < 8 || keylen > 128) { + if (keylen < 5 || keylen > 128) { return CRYPT_INVALID_KEYSIZE; } @@ -345,7 +345,7 @@ void rc2_done(symmetric_key *skey) int rc2_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); - if (*keysize < 8) { + if (*keysize < 5) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 128) { *keysize = 128; From 19c81bbbee89c56a261cf0d40642c6fc2b4d9657 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Sat, 18 Feb 2017 14:41:54 +0100 Subject: [PATCH 2/6] fix typo --- src/ciphers/rc2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 2520b83..222eda4 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -22,7 +22,7 @@ /** @file rc2.c - Implementation of LTC_RC2 + Implementation of RC2 with fixed effective key length of 64bits */ #ifdef LTC_RC2 @@ -60,7 +60,7 @@ static const unsigned char permute[256] = { }; /** - Initialize the LTC_RC2 block cipher + Initialize the RC2 block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @@ -121,7 +121,7 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke * Encrypt an 8-byte block of plaintext using the given key. * \**********************************************************************/ /** - Encrypts a block of text with LTC_RC2 + Encrypts a block of text with RC2 @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @@ -199,7 +199,7 @@ int rc2_ecb_encrypt( const unsigned char *pt, * Decrypt an 8-byte block of ciphertext using the given key. * \**********************************************************************/ /** - Decrypts a block of text with LTC_RC2 + Decrypts a block of text with RC2 @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @@ -275,7 +275,7 @@ int rc2_ecb_decrypt( const unsigned char *ct, #endif /** - Performs a self-test of the LTC_RC2 block cipher + Performs a self-test of the RC2 block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int rc2_test(void) From 952caf3cd7004a582726a372299ad32dbfae8bd0 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Mon, 27 Feb 2017 20:11:20 +0100 Subject: [PATCH 3/6] add testvectors for smaller RC2 keysizes originates from rfc2268 1 byte keylen is commented --- src/ciphers/rc2.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 222eda4..2eebde2 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -288,12 +288,25 @@ int rc2_test(void) unsigned char key[16], pt[8], ct[8]; } tests[] = { +#if 0 + { 1, + { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 } + }, +#endif + { 7, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f } + }, { 8, { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } - }, { 16, { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, @@ -315,7 +328,8 @@ int rc2_test(void) rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); rc2_ecb_decrypt(tmp[0], tmp[1], &skey); - if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) { + if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) != 0 || + compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x) != 0) { return CRYPT_FAIL_TESTVECTOR; } From 43c50423ade4f9c639b7aa28e7302bd2c903a490 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Mon, 27 Feb 2017 20:52:16 +0100 Subject: [PATCH 4/6] add yet another testvector --- src/ciphers/rc2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 2eebde2..8253e87 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -302,6 +302,12 @@ int rc2_test(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f } }, + { 8, + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + { 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 } + }, { 8, { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, From 9a29428f8e10c8b42747832c5b2ed8c5c0b284a4 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Mon, 27 Feb 2017 22:30:18 +0100 Subject: [PATCH 5/6] Add secondary rc2 setup function ...to be able to pass the effective key length. --- src/ciphers/rc2.c | 78 +++++++++++++++++++++++++---------- src/headers/tomcrypt_cipher.h | 1 + 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 8253e87..46a916b 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -63,23 +63,27 @@ static const unsigned char permute[256] = { Initialize the RC2 block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes + @param bits The effective key length in bits @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ -int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey) { unsigned *xkey = skey->rc2.xkey; unsigned char tmp[128]; unsigned T8, TM; - int i, bits; + int i; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); - if (keylen < 5 || keylen > 128) { + if (keylen == 0 || keylen > 128 || bits > 1024) { return CRYPT_INVALID_KEYSIZE; } + if (bits == 0) { + bits = 1024; + } if (num_rounds != 0 && num_rounds != 16) { return CRYPT_INVALID_ROUNDS; @@ -97,7 +101,6 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke } /* Phase 2 - reduce effective key size to "bits" */ - bits = keylen<<3; T8 = (unsigned)(bits+7)>>3; TM = (255 >> (unsigned)(7 & -bits)); tmp[128 - T8] = permute[tmp[128 - T8] & TM]; @@ -117,6 +120,22 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke return CRYPT_OK; } +/** + Initialize the RC2 block cipher + + The effective key length is here always keylen * 8 + + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful +*/ +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + return rc2_setup_ex(key, keylen, keylen * 8, num_rounds, skey); +} + /**********************************************************************\ * Encrypt an 8-byte block of plaintext using the given key. * \**********************************************************************/ @@ -284,37 +303,47 @@ int rc2_test(void) return CRYPT_NOP; #else static const struct { - int keylen; + int keylen, bits; unsigned char key[16], pt[8], ct[8]; } tests[] = { -#if 0 - { 1, - { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + { 8, 63, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 } + { 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff } }, -#endif - { 7, - { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f } - }, - { 8, + { 8, 64, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, { 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 } }, - { 8, + { 8, 64, { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } }, - { 16, + { 1, 64, + { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 } + }, + { 7, 64, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f } + }, + { 16, 64, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1 } + }, + { 16, 128, { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -327,8 +356,15 @@ int rc2_test(void) for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { zeromem(tmp, sizeof(tmp)); - if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { - return err; + if (tests[x].bits == (tests[x].keylen * 8)) { + if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + } + else { + if ((err = rc2_setup_ex(tests[x].key, tests[x].keylen, tests[x].bits, 0, &skey)) != CRYPT_OK) { + return err; + } } rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index da3a6b7..c9c6832 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -617,6 +617,7 @@ extern const struct ltc_cipher_descriptor rc6_desc; #ifdef LTC_RC2 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey); int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc2_test(void); From 03f0674985806efe55791511d3f30ce9cc6ec7f5 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 28 Feb 2017 01:29:45 +0100 Subject: [PATCH 6/6] add compare_testvector() prototype to tomcrypt_misc.h --- src/headers/tomcrypt_misc.h | 6 +++++- testprof/tomcrypt_test.h | 2 ++ testprof/x86_prof.c | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/headers/tomcrypt_misc.h b/src/headers/tomcrypt_misc.h index 4f5e8fa..91f87c5 100644 --- a/src/headers/tomcrypt_misc.h +++ b/src/headers/tomcrypt_misc.h @@ -101,7 +101,11 @@ int crc32_test(void); /* yeah it's not exactly in misc in the library, but in testprof/x86_prof.c */ #if defined(LTC_TEST) && defined(LTC_TEST_DBG) -void print_hex(const char* what, const void* p, const unsigned long l); +void print_hex(const char* what, const void* v, const unsigned long l); +int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); +#else +#define compare_testvector(is, is_len, should, should_len, what, which) \ + (((is_len) != (should_len)) || (XMEMCMP((is), (should), (is_len)) != 0)) #endif /* $Source$ */ diff --git a/testprof/tomcrypt_test.h b/testprof/tomcrypt_test.h index 776580e..ce9bfeb 100644 --- a/testprof/tomcrypt_test.h +++ b/testprof/tomcrypt_test.h @@ -81,7 +81,9 @@ extern const struct ltc_prng_descriptor no_prng_desc; #endif void print_hex(const char* what, const void* v, const unsigned long l); +#ifndef compare_testvector int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); +#endif int sorter(const void *a, const void *b); void tally_results(int type); ulong64 rdtsc (void); diff --git a/testprof/x86_prof.c b/testprof/x86_prof.c index 3d8787c..46ae43a 100644 --- a/testprof/x86_prof.c +++ b/testprof/x86_prof.c @@ -35,6 +35,7 @@ void print_hex(const char* what, const void* v, const unsigned long l) } } +#ifndef compare_testvector int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which) { int res = 0; @@ -51,6 +52,7 @@ int compare_testvector(const void* is, const unsigned long is_len, const void* s return res; } +#endif struct list results[100]; int no_results;