/* Provenance: openssl/openssl cms_kek_cipher (fixed). * repo: openssl/openssl * commit: 2a3dac874c8057c1f0186849bf1ede1ae7b6b756 * parent: 1951c3cbd9d5101e027a1eb126f26c3c758f6cc0 * commit_url: https://github.com/openssl/openssl/commit/2a3dac874c8057c1f0186849bf1ede1ae7b6b756 * cve: CVE-2026-63072 * license: Apache-2.0 * function: cms_kek_cipher * relpath: crypto/cms/cms_kemri.c */ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, const unsigned char *ss, size_t sslen, const unsigned char *in, size_t inlen, CMS_KEMRecipientInfo *kemri, int enc) { /* Key encryption key */ unsigned char kek[EVP_MAX_KEY_LENGTH]; size_t keklen = kemri->kekLength; unsigned char *out = NULL; int outlen = 0; int rv = 0; size_t outsize; if (keklen > sizeof(kek)) { ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); return 0; } if (inlen > INT_MAX) return 0; if (!kdf_derive(kek, keklen, ss, sslen, kemri)) goto err; /* Set KEK in context */ if (!EVP_CipherInit_ex(kemri->ctx, NULL, NULL, kek, NULL, enc)) goto err; /* obtain output length of ciphered key */ if (!EVP_CipherUpdate(kemri->ctx, NULL, &outlen, in, (int)inlen)) goto err; /* * On its integrity-failure paths that primitive writes and cleanses up to * inlen bytes of the output buffer. Size the buffer for that worst case so * a failed unwrap cannot write past the allocation. */ outsize = (size_t)outlen < inlen ? inlen : (size_t)outlen; out = OPENSSL_malloc(outsize); if (out == NULL) goto err; if (!EVP_CipherUpdate(kemri->ctx, out, &outlen, in, (int)inlen)) goto err; *pout = out; out = NULL; *poutlen = (size_t)outlen; rv = 1; err: OPENSSL_free(out); OPENSSL_cleanse(kek, sizeof(kek)); EVP_CIPHER_CTX_reset(kemri->ctx); EVP_PKEY_CTX_free(kemri->pctx); kemri->pctx = NULL; return rv; }