Commit e83ac40259 for openssl.org
commit e83ac4025934d1db7b4bf8c835ed1dd1abc3da92
Author: Martin Mirchev <mirchevmartin2203@gmail.com>
Date: Sun Oct 18 14:16:27 2026 +0800
providers/../ciphercommon_ccm.c: fix CCM IV getters with oversized buffers
Previously, the provider used the caller's destination capacity
as the copy length, which could read beyond the cipher context
and overwrite the caller's buffer past the IV. Use the actual CCM IV
length when returning the original or updated IV.
Fixes: 7cc5e0d28380 "Allow oversized buffers for provider cipher IV fetch"
Fixes: 8489026850b3 "Support cipher provider "iv state""
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Martin Mirchev <mirchevmartin2203@gmail.com>
Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Merge-date: Fri Nov 6 11:56:27 2026
Merged-from: https://github.com/openssl/openssl/pull/33322
diff --git a/providers/implementations/ciphers/ciphercommon_ccm.c b/providers/implementations/ciphers/ciphercommon_ccm.c
index 3ed25e4a8e..3ff56ba537 100644
--- a/providers/implementations/ciphers/ciphercommon_ccm.c
+++ b/providers/implementations/ciphers/ciphercommon_ccm.c
@@ -174,7 +174,7 @@ int ossl_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[])
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
return 0;
}
- if (!OSSL_PARAM_set_octet_string_or_ptr(p.iv, ctx->iv, p.iv->data_size)) {
+ if (!OSSL_PARAM_set_octet_string_or_ptr(p.iv, ctx->iv, ccm_get_ivlen(ctx))) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
@@ -185,7 +185,7 @@ int ossl_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[])
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
return 0;
}
- if (!OSSL_PARAM_set_octet_string_or_ptr(p.updiv, ctx->iv, p.updiv->data_size)) {
+ if (!OSSL_PARAM_set_octet_string_or_ptr(p.updiv, ctx->iv, ccm_get_ivlen(ctx))) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 688d51a69a..23da81f1b1 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -7424,6 +7424,53 @@ err:
return testresult;
}
+static int test_ccm_get_iv_with_large_buffer(void)
+{
+ static const unsigned char key[16] = { 0 };
+ static const unsigned char iv[12] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b
+ };
+ unsigned char expected[EVP_MAX_IV_LENGTH];
+ unsigned char actual[EVP_MAX_IV_LENGTH];
+ EVP_CIPHER_CTX *ctx = NULL;
+ EVP_CIPHER *cipher = NULL;
+ int testresult = 0;
+
+ if (!TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, "AES-128-CCM", testpropq))) {
+ TEST_skip("AES-128-CCM is not supported");
+ testresult = 1;
+ goto err;
+ }
+
+ memset(expected, 0xa5, sizeof(expected));
+ memcpy(expected, iv, sizeof(iv));
+
+ if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+ || !TEST_true(EVP_EncryptInit_ex2(ctx, cipher, NULL, NULL, NULL))
+ || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
+ sizeof(iv), NULL),
+ 0)
+ || !TEST_true(EVP_EncryptInit_ex2(ctx, NULL, key, iv, NULL)))
+ goto err;
+
+ memset(actual, 0xa5, sizeof(actual));
+ if (!TEST_true(EVP_CIPHER_CTX_get_original_iv(ctx, actual, sizeof(actual)))
+ || !TEST_mem_eq(actual, sizeof(actual), expected, sizeof(expected)))
+ goto err;
+
+ memset(actual, 0xa5, sizeof(actual));
+ if (!TEST_true(EVP_CIPHER_CTX_get_updated_iv(ctx, actual, sizeof(actual)))
+ || !TEST_mem_eq(actual, sizeof(actual), expected, sizeof(expected)))
+ goto err;
+
+ testresult = 1;
+err:
+ EVP_CIPHER_CTX_free(ctx);
+ EVP_CIPHER_free(cipher);
+ return testresult;
+}
+
static const char *ivlen_change_ciphers[] = {
"AES-256-GCM",
#ifndef OPENSSL_NO_OCB
@@ -10403,6 +10450,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_aes_cbc_decrypt, OSSL_NELEM(aes_cbc_decrypt_ciphers));
ADD_ALL_TESTS(test_evp_reinit_seq, OSSL_NELEM(evp_reinit_tests));
ADD_ALL_TESTS(test_evp_updated_iv, OSSL_NELEM(evp_updated_iv_tests));
+ ADD_TEST(test_ccm_get_iv_with_large_buffer);
ADD_ALL_TESTS(test_ivlen_change, OSSL_NELEM(ivlen_change_ciphers));
ADD_ALL_TESTS(test_iv_reuse, OSSL_NELEM(iv_state_ciphers));