Fix two invalid memory reads in RSA OAEP mode.

Submitted by: Ivan Nestlerode <inestlerode@us.ibm.com>
Reviewed by: steve
This commit is contained in:
Dr. Stephen Henson 2008-05-19 21:33:55 +00:00
parent 4bd4afa34e
commit 94fd382f8b
2 changed files with 23 additions and 8 deletions

View File

@ -686,6 +686,14 @@
Changes between 0.9.8g and 0.9.8h [xx XXX xxxx]
*) RSA OAEP patches to fix two separate invalid memory reads.
The first one involves inputs when 'lzero' is greater than
'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes
before the beginning of from). The second one involves inputs where
the 'db' section contains nothing but zeroes (there is a one-byte
invalid read after the end of 'db').
[Ivan Nesterlode <inestlerode@us.ibm.com>]
*) Add TLS session ticket callback. This allows an application to set
TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
values. This is useful for key rollover for example where several key

View File

@ -96,6 +96,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
const unsigned char *maskeddb;
int lzero;
unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
unsigned char *padded_from;
int bad = 0;
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
@ -106,8 +107,6 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
lzero = num - flen;
if (lzero < 0)
{
/* lzero == -1 */
/* signalling this error immediately after detection might allow
* for side-channel attacks (e.g. timing if 'plen' is huge
* -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
@ -115,20 +114,28 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
* so we use a 'bad' flag */
bad = 1;
lzero = 0;
flen = num; /* don't overflow the memcpy to padded_from */
}
maskeddb = from - lzero + SHA_DIGEST_LENGTH;
dblen = num - SHA_DIGEST_LENGTH;
db = OPENSSL_malloc(dblen);
db = OPENSSL_malloc(dblen + num);
if (db == NULL)
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
return -1;
}
/* Always do this zero-padding copy (even when lzero == 0)
* to avoid leaking timing info about the value of lzero. */
padded_from = db + dblen;
memset(padded_from, 0, lzero);
memcpy(padded_from + lzero, from, flen);
maskeddb = padded_from + SHA_DIGEST_LENGTH;
MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
seed[i] ^= from[i - lzero];
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
seed[i] ^= padded_from[i];
MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
for (i = 0; i < dblen; i++)
@ -143,13 +150,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
if (db[i] != 0x00)
break;
if (db[i] != 0x01 || i++ >= dblen)
if (i == dblen || db[i] != 0x01)
goto decoding_err;
else
{
/* everything looks OK */
mlen = dblen - i;
mlen = dblen - ++i;
if (tlen < mlen)
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);