improve OAEP check
This commit is contained in:
parent
e1a4814cd4
commit
a9ed4da8eb
9
CHANGES
9
CHANGES
@ -12,11 +12,18 @@
|
|||||||
*) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7
|
*) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7
|
||||||
+) applies to 0.9.7 only
|
+) applies to 0.9.7 only
|
||||||
|
|
||||||
|
*) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid
|
||||||
|
'wristwatch attack' using huge encoding parameters (cf.
|
||||||
|
James H. Manger's CRYPTO 2001 paper). Note that the
|
||||||
|
RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use
|
||||||
|
encoding paramters and hence was not vulnerable.
|
||||||
|
[Bodo Moeller]
|
||||||
|
|
||||||
+) Add a "destroy" handler to ENGINEs that allows structural cleanup to
|
+) Add a "destroy" handler to ENGINEs that allows structural cleanup to
|
||||||
be done prior to destruction. Use this to unload error strings from
|
be done prior to destruction. Use this to unload error strings from
|
||||||
ENGINEs that load their own error strings. NB: This adds two new API
|
ENGINEs that load their own error strings. NB: This adds two new API
|
||||||
functions to "get" and "set" this destroy handler in an ENGINE.
|
functions to "get" and "set" this destroy handler in an ENGINE.
|
||||||
[Geoff]
|
[Geoff Thorpe]
|
||||||
|
|
||||||
+) Alter all existing ENGINE implementations (except "openssl" and
|
+) Alter all existing ENGINE implementations (except "openssl" and
|
||||||
"openbsd") to dynamically instantiate their own error strings. This
|
"openbsd") to dynamically instantiate their own error strings. This
|
||||||
|
@ -43,20 +43,20 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
|
|||||||
{
|
{
|
||||||
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
|
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
|
||||||
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
|
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
|
if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
|
||||||
{
|
{
|
||||||
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
|
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
|
dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
|
||||||
if (dbmask == NULL)
|
if (dbmask == NULL)
|
||||||
{
|
{
|
||||||
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
|
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
to[0] = 0;
|
to[0] = 0;
|
||||||
@ -69,7 +69,7 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
|
|||||||
db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
|
db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
|
||||||
memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
|
memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
|
||||||
if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
|
if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
|
||||||
return (0);
|
return 0;
|
||||||
#ifdef PKCS_TESTVECT
|
#ifdef PKCS_TESTVECT
|
||||||
memcpy(seed,
|
memcpy(seed,
|
||||||
"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
|
"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
|
||||||
@ -96,13 +96,26 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
|
|||||||
const unsigned char *maskeddb;
|
const unsigned char *maskeddb;
|
||||||
int lzero;
|
int lzero;
|
||||||
unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
|
unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
|
||||||
|
int bad = 0;
|
||||||
|
|
||||||
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
|
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
|
||||||
|
/* 'num' is the length of the modulus, i.e. does not depend on the
|
||||||
|
* particular ciphertext. */
|
||||||
goto decoding_err;
|
goto decoding_err;
|
||||||
|
|
||||||
lzero = num - flen;
|
lzero = num - flen;
|
||||||
if (lzero < 0)
|
if (lzero < 0)
|
||||||
goto decoding_err;
|
{
|
||||||
|
/* 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
|
||||||
|
* Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
|
||||||
|
* so we use a 'bad' flag */
|
||||||
|
bad = 1;
|
||||||
|
lzero = 0;
|
||||||
|
}
|
||||||
maskeddb = from - lzero + SHA_DIGEST_LENGTH;
|
maskeddb = from - lzero + SHA_DIGEST_LENGTH;
|
||||||
|
|
||||||
dblen = num - SHA_DIGEST_LENGTH;
|
dblen = num - SHA_DIGEST_LENGTH;
|
||||||
@ -110,7 +123,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
|
|||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
{
|
{
|
||||||
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
|
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
|
||||||
return (-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
|
MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
|
||||||
@ -123,7 +136,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
|
|||||||
|
|
||||||
EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1());
|
EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1());
|
||||||
|
|
||||||
if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0)
|
if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
|
||||||
goto decoding_err;
|
goto decoding_err;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -134,6 +147,8 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
|
|||||||
goto decoding_err;
|
goto decoding_err;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* everything looks OK */
|
||||||
|
|
||||||
mlen = dblen - i;
|
mlen = dblen - i;
|
||||||
if (tlen < mlen)
|
if (tlen < mlen)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user