|
|
5820f5 |
Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness
|
|
|
5820f5 |
in PKCS7 code. When RSA decryption fails use a random key for
|
|
|
5820f5 |
content decryption and always return the same error.
|
|
|
5820f5 |
diff -up openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c.pk7-mma openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c
|
|
|
5820f5 |
--- openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c.pk7-mma 2007-02-03 10:51:58.000000000 +0100
|
|
|
5820f5 |
+++ openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c 2012-03-19 17:51:35.879037258 +0100
|
|
|
5820f5 |
@@ -423,6 +423,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
|
|
|
5820f5 |
int max;
|
|
|
5820f5 |
X509_OBJECT ret;
|
|
|
5820f5 |
#endif
|
|
|
5820f5 |
+ unsigned char *tkey = NULL;
|
|
|
5820f5 |
+ int tkeylen;
|
|
|
5820f5 |
int jj;
|
|
|
5820f5 |
|
|
|
5820f5 |
if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
|
|
|
5820f5 |
@@ -464,36 +466,42 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
|
|
|
5820f5 |
|
|
|
5820f5 |
if (pcert == NULL)
|
|
|
5820f5 |
{
|
|
|
5820f5 |
+ /* Temporary storage in case EVP_PKEY_decrypt
|
|
|
5820f5 |
+ * overwrites output buffer on error.
|
|
|
5820f5 |
+ */
|
|
|
5820f5 |
+ unsigned char *tmp2;
|
|
|
5820f5 |
+ tmp2 = OPENSSL_malloc(jj);
|
|
|
5820f5 |
+ if (!tmp2)
|
|
|
5820f5 |
+ goto err;
|
|
|
5820f5 |
+ jj = -1;
|
|
|
5820f5 |
+ /* Always attempt to decrypt all cases to avoid
|
|
|
5820f5 |
+ * leaking timing information about a successful
|
|
|
5820f5 |
+ * decrypt.
|
|
|
5820f5 |
+ */
|
|
|
5820f5 |
for (i=0; i
|
|
|
5820f5 |
{
|
|
|
5820f5 |
+ int tret;
|
|
|
5820f5 |
ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
|
|
|
5820f5 |
- jj=EVP_PKEY_decrypt(tmp,
|
|
|
5820f5 |
+ tret=EVP_PKEY_decrypt(tmp2,
|
|
|
5820f5 |
M_ASN1_STRING_data(ri->enc_key),
|
|
|
5820f5 |
M_ASN1_STRING_length(ri->enc_key),
|
|
|
5820f5 |
pkey);
|
|
|
5820f5 |
- if (jj > 0)
|
|
|
5820f5 |
- break;
|
|
|
5820f5 |
+ if (tret > 0)
|
|
|
5820f5 |
+ {
|
|
|
5820f5 |
+ memcpy(tmp, tmp2, tret);
|
|
|
5820f5 |
+ OPENSSL_cleanse(tmp2, tret);
|
|
|
5820f5 |
+ jj = tret;
|
|
|
5820f5 |
+ }
|
|
|
5820f5 |
ERR_clear_error();
|
|
|
5820f5 |
- ri = NULL;
|
|
|
5820f5 |
- }
|
|
|
5820f5 |
- if (ri == NULL)
|
|
|
5820f5 |
- {
|
|
|
5820f5 |
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,
|
|
|
5820f5 |
- PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
|
|
|
5820f5 |
- goto err;
|
|
|
5820f5 |
}
|
|
|
5820f5 |
+ OPENSSL_free(tmp2);
|
|
|
5820f5 |
}
|
|
|
5820f5 |
else
|
|
|
5820f5 |
{
|
|
|
5820f5 |
jj=EVP_PKEY_decrypt(tmp,
|
|
|
5820f5 |
M_ASN1_STRING_data(ri->enc_key),
|
|
|
5820f5 |
M_ASN1_STRING_length(ri->enc_key), pkey);
|
|
|
5820f5 |
- if (jj <= 0)
|
|
|
5820f5 |
- {
|
|
|
5820f5 |
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,
|
|
|
5820f5 |
- ERR_R_EVP_LIB);
|
|
|
5820f5 |
- goto err;
|
|
|
5820f5 |
- }
|
|
|
5820f5 |
+ ERR_clear_error();
|
|
|
5820f5 |
}
|
|
|
5820f5 |
|
|
|
5820f5 |
evp_ctx=NULL;
|
|
|
5820f5 |
@@ -502,24 +510,49 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
|
|
|
5820f5 |
goto err;
|
|
|
5820f5 |
if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
|
|
|
5820f5 |
goto err;
|
|
|
5820f5 |
+ /* Generate random key to counter MMA */
|
|
|
5820f5 |
+ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
|
|
|
5820f5 |
+ tkey = OPENSSL_malloc(tkeylen);
|
|
|
5820f5 |
+ if (!tkey)
|
|
|
5820f5 |
+ goto err;
|
|
|
5820f5 |
+ if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
|
|
|
5820f5 |
+ goto err;
|
|
|
5820f5 |
+ /* If we have no key use random key */
|
|
|
5820f5 |
+ if (jj <= 0)
|
|
|
5820f5 |
+ {
|
|
|
5820f5 |
+ OPENSSL_free(tmp);
|
|
|
5820f5 |
+ jj = tkeylen;
|
|
|
5820f5 |
+ tmp = tkey;
|
|
|
5820f5 |
+ tkey = NULL;
|
|
|
5820f5 |
+ }
|
|
|
5820f5 |
|
|
|
5820f5 |
- if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
|
|
|
5820f5 |
+ if (jj != tkeylen) {
|
|
|
5820f5 |
/* Some S/MIME clients don't use the same key
|
|
|
5820f5 |
* and effective key length. The key length is
|
|
|
5820f5 |
* determined by the size of the decrypted RSA key.
|
|
|
5820f5 |
*/
|
|
|
5820f5 |
if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
|
|
|
5820f5 |
{
|
|
|
5820f5 |
- PKCS7err(PKCS7_F_PKCS7_DATADECODE,
|
|
|
5820f5 |
- PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
|
|
|
5820f5 |
- goto err;
|
|
|
5820f5 |
+ /* As MMA defence use random key instead */
|
|
|
5820f5 |
+ OPENSSL_cleanse(tmp, jj);
|
|
|
5820f5 |
+ OPENSSL_free(tmp);
|
|
|
5820f5 |
+ jj = tkeylen;
|
|
|
5820f5 |
+ tmp = tkey;
|
|
|
5820f5 |
+ tkey = NULL;
|
|
|
5820f5 |
}
|
|
|
5820f5 |
}
|
|
|
5820f5 |
+ ERR_clear_error();
|
|
|
5820f5 |
if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
|
|
|
5820f5 |
goto err;
|
|
|
5820f5 |
|
|
|
5820f5 |
OPENSSL_cleanse(tmp,jj);
|
|
|
5820f5 |
|
|
|
5820f5 |
+ if (tkey)
|
|
|
5820f5 |
+ {
|
|
|
5820f5 |
+ OPENSSL_cleanse(tkey, tkeylen);
|
|
|
5820f5 |
+ OPENSSL_free(tkey);
|
|
|
5820f5 |
+ }
|
|
|
5820f5 |
+
|
|
|
5820f5 |
if (out == NULL)
|
|
|
5820f5 |
out=etmp;
|
|
|
5820f5 |
else
|