Explorar o código

Merge branch 'fix/135' into develop

Karel Miko %!s(int64=8) %!d(string=hai) anos
pai
achega
797031170d

+ 1 - 1
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 \\

+ 73 - 17
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,26 +60,30 @@ 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 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 < 8 || 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,11 +120,27 @@ 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.            *
 \**********************************************************************/
 /**
-  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 +218,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 +294,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)
@@ -284,18 +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[] = {
 
-   { 8,
+   { 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 },
+     { 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff }
+   },
+   { 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, 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 },
@@ -308,14 +356,22 @@ 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);
         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;
         }
 
@@ -345,7 +401,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;

+ 1 - 0
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);

+ 5 - 1
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$ */

+ 2 - 0
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);

+ 2 - 0
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;