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);