diff options
author | Andreas Kretschmer <andreas.kretschmer@siemens.com> | 2019-09-05 13:21:03 +0200 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2019-09-14 10:26:02 +0100 |
commit | f3f3318a25e62f471a69e1e8dd117bf30191da20 (patch) | |
tree | 2d7b3d49465dfe40ee05fb145365c94bc17c4497 /crypto/crmf | |
parent | 7b6b194b5281649ad5c50ecead0f3725d2d2a6a0 (diff) |
fix CRMF symmetric key handling
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9774)
Diffstat (limited to 'crypto/crmf')
-rw-r--r-- | crypto/crmf/crmf_lib.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index e519c50677..2974341446 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -29,6 +29,7 @@ #include <openssl/asn1t.h> #include "crmf_int.h" +#include "internal/constant_time_locl.h" /* explicit #includes not strictly needed since implied by the above: */ #include <openssl/crmf.h> @@ -654,7 +655,9 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, X509 *cert = NULL; /* decrypted certificate */ EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */ unsigned char *ek = NULL; /* decrypted symmetric encryption key */ + size_t eksize = 0; /* size of decrypted symmetric encryption key */ const EVP_CIPHER *cipher = NULL; /* used cipher */ + int cikeysize = 0; /* key size from cipher */ unsigned char *iv = NULL; /* initial vector for symmetric encryption */ unsigned char *outbuf = NULL; /* decryption output buffer */ const unsigned char *p = NULL; /* needed for decoding ASN1 */ @@ -673,18 +676,31 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, CRMF_R_UNSUPPORTED_CIPHER); return NULL; } - + /* select symmetric cipher based on algorithm given in message */ + if ((cipher = EVP_get_cipherbynid(symmAlg)) == NULL) { + CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, + CRMF_R_UNSUPPORTED_CIPHER); + goto end; + } + cikeysize = EVP_CIPHER_key_length(cipher); /* first the symmetric key needs to be decrypted */ pkctx = EVP_PKEY_CTX_new(pkey, NULL); if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx)) { ASN1_BIT_STRING *encKey = ecert->encSymmKey; - size_t eksize = 0; + size_t failure; + int retval; - if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, encKey->data, encKey->length) - <= 0 - || (ek = OPENSSL_malloc(eksize)) == NULL - || EVP_PKEY_decrypt(pkctx, ek, &eksize, encKey->data, - encKey->length) <= 0) { + if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, + encKey->data, encKey->length) <= 0 + || (ek = OPENSSL_malloc(eksize)) == NULL) + goto oom; + 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) { CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY); goto end; @@ -692,13 +708,6 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, } else { goto oom; } - - /* select symmetric cipher based on algorithm given in message */ - if ((cipher = EVP_get_cipherbynid(symmAlg)) == NULL) { - CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, - CRMF_R_UNSUPPORTED_CIPHER); - goto end; - } if ((iv = OPENSSL_malloc(EVP_CIPHER_iv_length(cipher))) == NULL) goto oom; if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, @@ -743,7 +752,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, EVP_PKEY_CTX_free(pkctx); OPENSSL_free(outbuf); EVP_CIPHER_CTX_free(evp_ctx); - OPENSSL_free(ek); + OPENSSL_clear_free(ek, eksize); OPENSSL_free(iv); return cert; } |