Browse Source

Hash functions now check for input-length overflow.

Because many of the hash-functions implemented by LTC use the length
of the input when padding the input out to a block-length, LTC keeps
track of the input length in a 64-bit integer. However, it did not
previously test for overflow of this value. Since many of the
hash-functions implemented by LTC are defined for inputs of length
2^128 bits or more, this means that LTC was incorrectly implementing
these hash functions for extremely long inputs. Also, this might have
been a minor security problem: A clever attacker might have been able
to take a message with a known hash and find another message (longer
by 2^64 bits) that would be hashed to the same value by LTC.

Fortunately, LTC uses a pre-processor macro to make the actual code
for hashing, and so this problem could be fixed by adding an
overflow-check to that macro.
Jonathan Herzog 17 years ago
parent
commit
ff736a61bb
3 changed files with 9 additions and 1 deletions
  1. 3 1
      src/headers/tomcrypt.h
  2. 3 0
      src/headers/tomcrypt_hash.h
  3. 3 0
      src/misc/error_to_string.c

+ 3 - 1
src/headers/tomcrypt.h

@@ -61,7 +61,9 @@ enum {
    CRYPT_PK_INVALID_SIZE,  /* Invalid size input for PK parameters */
 
    CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
-   CRYPT_PK_INVALID_PADDING /* Invalid padding on input */
+   CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */
+
+   CRYPT_HASH_OVERFLOW      /* Hash applied to too many bits */
 };
 
 #include <tomcrypt_cfg.h>

+ 3 - 0
src/headers/tomcrypt_hash.h

@@ -351,6 +351,9 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)
     if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
        return CRYPT_INVALID_ARG;                                                            \
     }                                                                                       \
+    if ((md-> state_var .length + inlen) < md-> state_var .length) {	                    \
+      return CRYPT_HASH_OVERFLOW;                                                           \
+    }                                                                                       \
     while (inlen > 0) {                                                                     \
         if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
            if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) {               \

+ 3 - 0
src/misc/error_to_string.c

@@ -52,6 +52,9 @@ static const char *err_2_str[] =
 
    "Invalid size for prime.",
 
+   "Invalid padding.",
+
+   "Hash applied to too many bits.",
 };
 
 /**