Browse Source

added libtomcrypt-0.97a

Tom St Denis 21 years ago
parent
commit
e9c1c530b4
15 changed files with 132 additions and 80 deletions
  1. 15 0
      changes
  2. 1 1
      crypt.tex
  3. 73 36
      demos/test/rsa_test.c
  4. 3 3
      des.c
  5. BIN
      doc/crypt.pdf
  6. 1 1
      ltc_tommath.h
  7. 1 1
      makefile
  8. 2 2
      mycrypt.h
  9. 1 1
      mycrypt_hash.h
  10. 22 22
      mycrypt_macros.h
  11. 1 1
      pkcs_1_oaep_decode.c
  12. 1 2
      pkcs_1_oaep_encode.c
  13. 1 0
      pkcs_1_pss_decode.c
  14. 1 1
      rsa_decrypt_key.c
  15. 9 9
      tiger.c

+ 15 - 0
changes

@@ -1,3 +1,18 @@
+June 23rd, 2004
+v0.97a ++ Fixed several potentially crippling bugs... [read on]
+       -- Fixed bug in OAEP decoder that would incorrectly report 
+          buffer overflows. [Zhi Chen]
+       -- Fixed headers which had various C++ missing [extern "C"]'s
+       -- Added "extern" to sha384_desc descriptor which I removed by mistake
+       -- Fixed bugs in ENDIAN_BIG macros using the wrong byte order [Matt Johnston]
+       -- Updated tiger.c and des.c to not shadow "round" which is intrinsic on
+          some C compilers.
+       -- Updated demos/test/rsa_test.c to test the RSA functionality better
+       ++ This update has been tested with GCC [v3.3.3], ICC [v8] and MSVC [v6+SP6] 
+          all on a x86 P4  [GCC/ICC tested in Gentoo Linux, MSVC in WinXP]
+       ++ Outcome: The bug Zhi Chen pointed out has been fixed.  So have the bugs
+          that Matt Johnston found.  
+
 June 19th, 2004
 v0.97  -- Removed spurious unused files [arrg!]
        -- Patched buffer overflow in tim_exptmod()

+ 1 - 1
crypt.tex

@@ -47,7 +47,7 @@
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \begin{document}
-\title{LibTomCrypt \\ Version 0.97}
+\title{LibTomCrypt \\ Version 0.97a}
 \author{Tom St Denis \\
 \\
 [email protected] \\

+ 73 - 36
demos/test/rsa_test.c

@@ -1,11 +1,14 @@
 #include "test.h"
 
+#define RSA_MSGSIZE 78
+
+
 int rsa_test(void)
 {
    unsigned char in[1024], out[1024], tmp[1024];
    rsa_key       key;
    int           hash_idx, prng_idx, stat, stat2;
-   unsigned long len, len2;
+   unsigned long rsa_msgsize, len, len2;
    static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
       
    hash_idx = find_hash("sha1");
@@ -15,48 +18,82 @@ int rsa_test(void)
       return 1;
    }
    
-   /* make a random key/msg */
-   yarrow_read(in, 20, &test_yarrow);
-   
    /* make a random key */
    DO(rsa_make_key(&test_yarrow, prng_idx, 1024/8, 65537, &key));
    
    /* encrypt the key (without lparam) */
-   len  = sizeof(out);
-   len2 = sizeof(tmp);
-   DO(rsa_encrypt_key(in, 20, out, &len, NULL, 0, &test_yarrow, prng_idx, hash_idx, &key));
-   /* change a byte */
-   out[0] ^= 1;
-   DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat2, &key));
-   /* change a byte back */
-   out[0] ^= 1;
-   DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat, &key));
-   if (!(stat == 1 && stat2 == 0)) {
-      printf("rsa_decrypt_key failed");
-      return 1;
-   }
-   if (len2 != 20 || memcmp(tmp, in, 20)) {
-      printf("rsa_decrypt_key mismatch len %lu", len2);
-      return 1;
+   for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) {
+      /* make a random key/msg */
+      yarrow_read(in, rsa_msgsize, &test_yarrow);
+
+      len  = sizeof(out);
+      len2 = rsa_msgsize;
+   
+      DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &test_yarrow, prng_idx, hash_idx, &key));
+      /* change a byte */
+      out[8] ^= 1;
+      DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat2, &key));
+      /* change a byte back */
+      out[8] ^= 1;
+      if (len2 != rsa_msgsize) {
+         printf("\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2);
+         return 1;
+      }
+
+      len2 = rsa_msgsize;
+      DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat, &key));
+      if (!(stat == 1 && stat2 == 0)) {
+         printf("rsa_decrypt_key failed");
+         return 1;
+      }
+      if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) {
+         int x;
+         printf("\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2);
+         printf("Original contents: \n"); 
+         for (x = 0; x < rsa_msgsize; ) {
+             printf("%02x ", in[x]);
+             if (!(++x % 16)) {
+                printf("\n");
+             }
+         }
+         printf("\n");
+         printf("Output contents: \n"); 
+         for (x = 0; x < rsa_msgsize; ) {
+             printf("%02x ", out[x]);
+             if (!(++x % 16)) {
+                printf("\n");
+             }
+         }     
+         printf("\n");
+         return 1;
+      }
    }
 
    /* encrypt the key (with lparam) */
-   len  = sizeof(out);
-   len2 = sizeof(tmp);
-   DO(rsa_encrypt_key(in, 20, out, &len, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &key));
-   /* change a byte */
-   out[0] ^= 1;
-   DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat2, &key));
-   /* change a byte back */
-   out[0] ^= 1;
-   DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat, &key));
-   if (!(stat == 1 && stat2 == 0)) {
-      printf("rsa_decrypt_key failed");
-      return 1;
-   }
-   if (len2 != 20 || memcmp(tmp, in, 20)) {
-      printf("rsa_decrypt_key mismatch len %lu", len2);
-      return 1;
+   for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) {
+      len  = sizeof(out);
+      len2 = rsa_msgsize;
+      DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &key));
+      /* change a byte */
+      out[8] ^= 1;
+      DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat2, &key));
+      if (len2 != rsa_msgsize) {
+         printf("\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2);
+         return 1;
+      }
+      /* change a byte back */
+      out[8] ^= 1;
+
+      len2 = rsa_msgsize;
+      DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat, &key));
+      if (!(stat == 1 && stat2 == 0)) {
+         printf("rsa_decrypt_key failed");
+         return 1;
+      }
+      if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) {
+         printf("rsa_decrypt_key mismatch len %lu", len2);
+         return 1;
+      }
    }
 
    /* sign a message (unsalted, lower cholestorol and Atkins approved) now */

+ 3 - 3
des.c

@@ -1395,7 +1395,7 @@ static void _desfunc(ulong32 *block, const ulong32 *keys)
 #endif
 {
     ulong32 work, right, leftt;
-    int round;
+    int cur_round;
 
     leftt = block[0];
     right = block[1];
@@ -1439,7 +1439,7 @@ static void _desfunc(ulong32 *block, const ulong32 *keys)
    }
 #endif
 
-    for (round = 0; round < 8; round++) {
+    for (cur_round = 0; cur_round < 8; cur_round++) {
         work  = ROR(right, 4) ^ *keys++;
         leftt ^= SP7[work        & 0x3fL]
               ^ SP5[(work >>  8) & 0x3fL]
@@ -1534,7 +1534,7 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
     _ARGCHK(key != NULL);
     _ARGCHK(skey != NULL);
 
-    if( num_rounds != 0 && num_rounds != 16) {
+    if(num_rounds != 0 && num_rounds != 16) {
         return CRYPT_INVALID_ROUNDS;
     }
 

BIN
doc/crypt.pdf


+ 1 - 1
ltc_tommath.h

@@ -27,7 +27,7 @@
 #define MAX(x,y) ((x)>(y)?(x):(y))
 
 #ifdef __cplusplus
- "C" {
+extern "C" {
 
 /* C++ compilers don't like assigning void * to mp_digit * */
 #define  OPT_CAST(x)  (x *)

+ 1 - 1
makefile

@@ -4,7 +4,7 @@
 # Modified by Clay Culver
 
 # The version
-VERSION=0.97
+VERSION=0.97a
 
 # Compiler and Linker Names
 #CC=gcc

+ 2 - 2
mycrypt.h

@@ -12,12 +12,12 @@
 #include <mycrypt_custom.h>
 
 #ifdef __cplusplus
- "C" {
+extern "C" {
 #endif
 
 /* version */
 #define CRYPT   0x0097
-#define SCRYPT  "0.97"
+#define SCRYPT  "0.97a"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE  64

+ 1 - 1
mycrypt_hash.h

@@ -149,7 +149,7 @@ extern  struct _hash_descriptor {
 #define sha384_process sha512_process
  int sha384_done(hash_state * md, unsigned char *hash);
  int  sha384_test(void);
- const struct _hash_descriptor sha384_desc;
+ extern const struct _hash_descriptor sha384_desc;
 #endif
 
 #ifdef SHA256

+ 22 - 22
mycrypt_macros.h

@@ -125,26 +125,26 @@ typedef unsigned long ulong32;
 
 #ifdef ENDIAN_BIG
 #define STORE32L(x, y)                                                                     \
-     { (y)[z0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
-       (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
+     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
+       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
 
 #define LOAD32L(x, y)                            \
-     { x = ((unsigned long)((y)[0] & 255)<<24) | \
-           ((unsigned long)((y)[1] & 255)<<16) | \
-           ((unsigned long)((y)[2] & 255)<<8)  | \
-           ((unsigned long)((y)[3] & 255)); }
+     { x = ((unsigned long)((y)[3] & 255)<<24) | \
+           ((unsigned long)((y)[2] & 255)<<16) | \
+           ((unsigned long)((y)[1] & 255)<<8)  | \
+           ((unsigned long)((y)[0] & 255)); }
 
 #define STORE64L(x, y)                                                                     \
-   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
-     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
-     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
-     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
+   { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);     \
+     (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);     \
+     (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);     \
+     (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
 
 #define LOAD64L(x, y)                                                      \
-   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
-         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
-         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
-         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
+   { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
+         (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
+         (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
+         (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
 
 #ifdef ENDIAN_32BITWORD 
 
@@ -155,16 +155,16 @@ typedef unsigned long ulong32;
      memcpy(&(x), y, 4);
 
 #define STORE64H(x, y)                                                                     \
-     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
-       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
-       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
-       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
+     { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \
+       (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);   \
+       (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);   \
+       (y)[6] = (unsigned char)(((x)>>8)&255);  (y)[7] = (unsigned char)((x)&255); }
 
 #define LOAD64H(x, y)                                                       \
-     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
-           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
-           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
-           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
+     { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
+           (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
+           (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
+           (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
 
 #else /* 64-bit words then  */
 

+ 1 - 1
pkcs_1_oaep_decode.c

@@ -140,7 +140,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    }
 
    /* rest is the message (and skip 0x01) */
-   if (msglen - ++x > *outlen) {
+   if ((modulus_len - hLen - 1) - ++x > *outlen) {
       err = CRYPT_BUFFER_OVERFLOW;
       goto __ERR;
    }

+ 1 - 2
pkcs_1_oaep_encode.c

@@ -58,7 +58,6 @@ int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
       return CRYPT_MEM;
    }
 
-
    /* test message size */
    if (msglen > (modulus_len - 2*hLen - 2)) {
       err = CRYPT_PK_INVALID_SIZE;
@@ -66,7 +65,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
    }
 
    /* get lhash */
-// DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes
+   /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
    x = modulus_len;
    if (lparam != NULL) {
       if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) {

+ 1 - 0
pkcs_1_pss_decode.c

@@ -111,6 +111,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
        }
    }
 
+   /* check for the 0x01 */
    if (DB[x++] != 0x01) {
       err = CRYPT_OK;
       goto __ERR;

+ 1 - 1
rsa_decrypt_key.c

@@ -29,7 +29,7 @@ int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
   _ARGCHK(keylen != NULL);
   _ARGCHK(key    != NULL);
   _ARGCHK(res    != NULL);
-  
+
   /* valid hash ? */
   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
      return err;

+ 9 - 9
tiger.c

@@ -558,7 +558,7 @@ static const ulong64 table[4*256] = {
 #endif   
 
 /* one round of the hash function */
-INLINE static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
+INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
 {
     ulong64 tmp;
     tmp = (*c ^= x); 
@@ -574,14 +574,14 @@ INLINE static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
 /* one complete pass */
 static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul)
 {
-   round(a,b,c,x[0],mul); 
-   round(b,c,a,x[1],mul); 
-   round(c,a,b,x[2],mul); 
-   round(a,b,c,x[3],mul); 
-   round(b,c,a,x[4],mul); 
-   round(c,a,b,x[5],mul); 
-   round(a,b,c,x[6],mul); 
-   round(b,c,a,x[7],mul);          
+   tiger_round(a,b,c,x[0],mul); 
+   tiger_round(b,c,a,x[1],mul); 
+   tiger_round(c,a,b,x[2],mul); 
+   tiger_round(a,b,c,x[3],mul); 
+   tiger_round(b,c,a,x[4],mul); 
+   tiger_round(c,a,b,x[5],mul); 
+   tiger_round(a,b,c,x[6],mul); 
+   tiger_round(b,c,a,x[7],mul);          
 }   
 
 /* The key mixing schedule */