Commit de80bb1250 for openssl.org
commit de80bb12501c32bd92cfd02b56da778925da992c
Author: unjuno <unjuno.org@unjuno.org>
Date: Tue Aug 11 21:46:40 2026 +0900
cms: clear temporary key buffers on failure
Use OPENSSL_clear_free() with the original allocation length on the
KARI, KEKRI, and PWRI failure paths. This is defense-in-depth
hardening at the CMS/provider boundary.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Fri Aug 14 06:38:29 2026
Merged-from: https://github.com/openssl/openssl/pull/32303
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index f03fea6f75..7d8af68b3c 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -958,6 +958,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
CMS_EncryptedContentInfo *ec;
CMS_KEKRecipientInfo *kekri;
unsigned char *ukey = NULL;
+ size_t ukey_alloc_len = 0;
int ukeylen;
int r = 0, wrap_nid;
EVP_CIPHER *cipher = NULL;
@@ -995,7 +996,8 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
goto err;
}
- ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
+ ukey_alloc_len = (size_t)kekri->encryptedKey->length - 8;
+ ukey = OPENSSL_malloc(ukey_alloc_len);
if (ukey == NULL)
goto err;
@@ -1024,7 +1026,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
err:
EVP_CIPHER_free(cipher);
if (!r)
- OPENSSL_free(ukey);
+ OPENSSL_clear_free(ukey, ukey_alloc_len);
EVP_CIPHER_CTX_free(ctx);
return r;
diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c
index e6f6e16790..bae78b45da 100644
--- a/crypto/cms/cms_kari.c
+++ b/crypto/cms/cms_kari.c
@@ -210,6 +210,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
size_t keklen;
int rv = 0;
unsigned char *out = NULL;
+ size_t out_alloc_len = 0;
int outlen;
keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx);
@@ -227,6 +228,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
out = OPENSSL_malloc(outlen);
if (out == NULL)
goto err;
+ out_alloc_len = (size_t)outlen;
if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, (int)inlen))
goto err;
*pout = out;
@@ -236,7 +238,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
err:
OPENSSL_cleanse(kek, keklen);
if (!rv)
- OPENSSL_free(out);
+ OPENSSL_clear_free(out, out_alloc_len);
EVP_CIPHER_CTX_reset(kari->ctx);
/* FIXME: WHY IS kari->pctx freed here? /RL */
EVP_PKEY_CTX_free(kari->pctx);
diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c
index 2cdac56fcf..61656c30da 100644
--- a/crypto/cms/cms_pwri.c
+++ b/crypto/cms/cms_pwri.c
@@ -316,6 +316,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
EVP_CIPHER *kekcipher;
unsigned char *key = NULL;
size_t keylen;
+ size_t key_alloc_len = 0;
const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
ec = ossl_cms_get0_env_enc_content(cms);
@@ -392,6 +393,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
if (key == NULL)
goto err;
+ key_alloc_len = keylen;
if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
goto err;
@@ -401,6 +403,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
key = OPENSSL_malloc(pwri->encryptedKey->length);
if (key == NULL)
goto err;
+ key_alloc_len = (size_t)pwri->encryptedKey->length;
if (!kek_unwrap_key(key, &keylen,
pwri->encryptedKey->data,
pwri->encryptedKey->length, kekctx)) {
@@ -420,7 +423,7 @@ err:
EVP_CIPHER_CTX_free(kekctx);
if (!r)
- OPENSSL_free(key);
+ OPENSSL_clear_free(key, key_alloc_len);
X509_ALGOR_free(kekalg);
return r;