summaryrefslogtreecommitdiffstats
path: root/crypto/crmf
diff options
context:
space:
mode:
authorAndreas Kretschmer <andreas.kretschmer@siemens.com>2019-09-05 13:21:03 +0200
committerMatt Caswell <matt@openssl.org>2019-09-14 10:26:02 +0100
commitf3f3318a25e62f471a69e1e8dd117bf30191da20 (patch)
tree2d7b3d49465dfe40ee05fb145365c94bc17c4497 /crypto/crmf
parent7b6b194b5281649ad5c50ecead0f3725d2d2a6a0 (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.c39
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;
}