diff options
-rw-r--r-- | crypto/cms/cms_env.c | 19 | ||||
-rw-r--r-- | crypto/crmf/crmf_lib.c | 28 | ||||
-rw-r--r-- | crypto/evp/asymcipher.c | 18 | ||||
-rw-r--r-- | crypto/pkcs7/pk7_doit.c | 19 | ||||
-rw-r--r-- | include/crypto/evp.h | 4 |
5 files changed, 35 insertions, 53 deletions
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index c55511011f..2b06da468e 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -615,24 +615,11 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, * disable implicit rejection for RSA keys */ EVP_PKEY_CTX_ctrl_str(ktri->pctx, "rsa_pkcs1_implicit_rejection", "0"); - if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) + if (evp_pkey_decrypt_alloc(ktri->pctx, &ek, &eklen, fixlen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) goto err; - ek = OPENSSL_malloc(eklen); - if (ek == NULL) - goto err; - - if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0 - || eklen == 0 - || (fixlen != 0 && eklen != fixlen)) { - ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB); - goto err; - } - ret = 1; OPENSSL_clear_free(ec->key, ec->keylen); diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 6fc7c91095..12939b9920 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -29,8 +29,8 @@ #include <openssl/asn1t.h> #include "crmf_local.h" -#include "internal/constant_time.h" #include "internal/sizes.h" +#include "crypto/evp.h" #include "crypto/x509.h" /* explicit #includes not strictly needed since implied by the above: */ @@ -661,28 +661,12 @@ X509 cikeysize = EVP_CIPHER_get_key_length(cipher); /* first the symmetric key needs to be decrypted */ pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); - if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx) > 0) { - ASN1_BIT_STRING *encKey = ecert->encSymmKey; - size_t failure; - int retval; - - if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, - encKey->data, encKey->length) <= 0 - || (ek = OPENSSL_malloc(eksize)) == NULL) - goto end; - retval = EVP_PKEY_decrypt(pkctx, ek, &eksize, - encKey->data, encKey->length); - ERR_clear_error(); /* error state may have sensitive information */ - failure = ~constant_time_is_zero_s(constant_time_msb(retval) - | constant_time_is_zero(retval)); - failure |= ~constant_time_eq_s(eksize, (size_t)cikeysize); - if (failure) { - ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY); - goto end; - } - } else { + if (pkctx == NULL || EVP_PKEY_decrypt_init(pkctx) <= 0 + || evp_pkey_decrypt_alloc(pkctx, &ek, &eksize, (size_t)cikeysize, + ecert->encSymmKey->data, + ecert->encSymmKey->length) <= 0) goto end; - } + if ((iv = OPENSSL_malloc(EVP_CIPHER_get_iv_length(cipher))) == NULL) goto end; if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, diff --git a/crypto/evp/asymcipher.c b/crypto/evp/asymcipher.c index 3acf4d1dfd..ca2a8ebdf2 100644 --- a/crypto/evp/asymcipher.c +++ b/crypto/evp/asymcipher.c @@ -298,6 +298,24 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); } +/* decrypt to new buffer of dynamic size, checking any pre-determined size */ +int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, + size_t *outlenp, size_t expected_outlen, + const unsigned char *in, size_t inlen) +{ + if (EVP_PKEY_decrypt(ctx, NULL, outlenp, in, inlen) <= 0 + || (*outp = OPENSSL_malloc(*outlenp)) == NULL) + return -1; + if (EVP_PKEY_decrypt(ctx, *outp, outlenp, in, inlen) <= 0 + || *outlenp == 0 + || (expected_outlen != 0 && *outlenp != expected_outlen)) { + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); + OPENSSL_clear_free(*outp, *outlenp); + *outp = NULL; + return 0; + } + return 1; +} static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov) { diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index e39821a205..d3f65adb66 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -15,6 +15,7 @@ #include <openssl/err.h> #include "internal/cryptlib.h" #include "internal/sizes.h" +#include "crypto/evp.h" #include "pk7_local.h" static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, @@ -174,23 +175,11 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, * disable implicit rejection for RSA keys */ EVP_PKEY_CTX_ctrl_str(pctx, "rsa_pkcs1_implicit_rejection", "0"); - if (EVP_PKEY_decrypt(pctx, NULL, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) + ret = evp_pkey_decrypt_alloc(pctx, &ek, &eklen, fixlen, + ri->enc_key->data, ri->enc_key->length); + if (ret <= 0) goto err; - ek = OPENSSL_malloc(eklen); - if (ek == NULL) - goto err; - - if (EVP_PKEY_decrypt(pctx, ek, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0 - || eklen == 0 - || (fixlen != 0 && eklen != fixlen)) { - ret = 0; - ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); - goto err; - } - ret = 1; OPENSSL_clear_free(*pek, *peklen); diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 4f7f0c6eea..4e9cf7bb6d 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -952,4 +952,8 @@ int evp_md_get_number(const EVP_MD *md); int evp_rand_get_number(const EVP_RAND *rand); int evp_signature_get_number(const EVP_SIGNATURE *signature); +int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, + size_t *outlenp, size_t expected_outlen, + const unsigned char *in, size_t inlen); + #endif /* OSSL_CRYPTO_EVP_H */ |