From ff736a61bb39d2f94b9efef5b92b6761d1b06741 Mon Sep 17 00:00:00 2001 From: Jonathan Herzog Date: Sun, 20 Jan 2008 21:57:25 -0800 Subject: [PATCH] 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. --- src/headers/tomcrypt.h | 4 +++- src/headers/tomcrypt_hash.h | 3 +++ src/misc/error_to_string.c | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index 51299af..d38a7c7 100644 --- a/src/headers/tomcrypt.h +++ b/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 diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index 146dcbc..e750cb8 100644 --- a/src/headers/tomcrypt_hash.h +++ b/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) { \ diff --git a/src/misc/error_to_string.c b/src/misc/error_to_string.c index 034cd18..19f8781 100644 --- a/src/misc/error_to_string.c +++ b/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.", }; /**