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;