Commit e730ce940d for openssl.org
commit e730ce940d2c117249df4f206a328898cf331ba6
Author: herbenderbler <johnclaus@gmail.com>
Date: Thu Mar 12 22:28:41 2026 -0600
Enforce mandatory cipher get_params at dispatch parse
Reject provider ciphers that lack get_params when unpacking the dispatch
table in evp_cipher_from_algorithm(), failing with
EVP_R_INVALID_PROVIDER_FUNCTIONS instead of later with
EVP_R_CACHE_CONSTANTS_FAILED.
Revert the optional-functions sentence in provider-cipher.pod to "All
other functions are optional." so the doc does not imply only
get_params, newctx, and freectx are required; a consistent
encrypt/decrypt set is also required as described in the prior paragraph.
Move test_cipher_no_getparams from evp_skey_test.c to evp_fetch_prov_test.c
and add fake_cipherprov.c to the evp_fetch_prov_test build.
Drop the redundant newctx/freectx/get_params line from the
evp_cipher_from_algorithm() comment.
Fixes #19110
Made-with: Cursor
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Mon Mar 16 11:22:05 2026
(Merged from https://github.com/openssl/openssl/pull/30383)
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 0d2c26052e..1be9508ac6 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -1478,12 +1478,12 @@ static void *evp_cipher_from_algorithm(const int name_id,
if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
|| (fnciphcnt == 0 && cipher->ccipher == NULL && fnpipecnt == 0)
|| (fnpipecnt != 0 && (fnpipecnt < 3 || cipher->p_cupdate == NULL || cipher->p_cfinal == NULL))
- || fnctxcnt != 2) {
+ || fnctxcnt != 2
+ || cipher->get_params == NULL) {
/*
* In order to be a consistent set of functions we must have at least
* a complete set of "encrypt" functions, or a complete set of "decrypt"
- * functions, or a single "cipher" function. In all cases we need both
- * the "newctx" and "freectx" functions.
+ * functions, or a single "cipher" function.
*/
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
goto err;
diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod
index 679c35e0f9..a7dea25fd3 100644
--- a/doc/man7/provider-cipher.pod
+++ b/doc/man7/provider-cipher.pod
@@ -294,7 +294,7 @@ OSSL_FUNC_cipher_decrypt_skey_init() were introduced in OpenSSL 3.5.
=head1 COPYRIGHT
-Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
diff --git a/test/build.info b/test/build.info
index c5a7a565b7..0c69df85cc 100644
--- a/test/build.info
+++ b/test/build.info
@@ -248,7 +248,7 @@ IF[{- !$disabled{tests} -}]
INCLUDE[evp_libctx_test]=../include ../apps/include
DEPEND[evp_libctx_test]=../libcrypto.a libtestutil.a
- SOURCE[evp_fetch_prov_test]=evp_fetch_prov_test.c
+ SOURCE[evp_fetch_prov_test]=evp_fetch_prov_test.c fake_cipherprov.c
INCLUDE[evp_fetch_prov_test]=../include ../apps/include
DEPEND[evp_fetch_prov_test]=../libcrypto libtestutil.a
diff --git a/test/evp_fetch_prov_test.c b/test/evp_fetch_prov_test.c
index 2cde0049e8..bcc7c59eb6 100644
--- a/test/evp_fetch_prov_test.c
+++ b/test/evp_fetch_prov_test.c
@@ -20,6 +20,7 @@
#include <openssl/provider.h>
#include "internal/sizes.h"
#include "testutil.h"
+#include "fake_cipherprov.h"
static char *config_file = NULL;
static char *alg = "digest";
@@ -340,6 +341,36 @@ static int test_explicit_EVP_CIPHER_fetch_by_name(void)
return test_explicit_EVP_CIPHER_fetch("AES-128-CBC");
}
+/*
+ * Test that a provider cipher without get_params fails to fetch.
+ */
+static int test_cipher_no_getparams(void)
+{
+ int ret = 0;
+ OSSL_LIB_CTX *ctx = NULL;
+ OSSL_PROVIDER *fake_prov = NULL;
+ EVP_CIPHER *cipher = NULL;
+
+ ctx = OSSL_LIB_CTX_new();
+ if (!TEST_ptr(ctx))
+ return 0;
+
+ if (!TEST_ptr(fake_prov = fake_cipher_start(ctx)))
+ goto end;
+
+ /* Fetch must fail for a cipher that has no get_params */
+ cipher = EVP_CIPHER_fetch(ctx, FAKE_CIPHER_NO_GETPARAMS, FAKE_CIPHER_FETCH_PROPS);
+ if (!TEST_ptr_null(cipher))
+ goto end;
+
+ ret = 1;
+end:
+ EVP_CIPHER_free(cipher);
+ fake_cipher_finish(fake_prov);
+ OSSL_LIB_CTX_free(ctx);
+ return ret;
+}
+
/*
* idx 0: Allow names from OBJ_obj2txt()
* idx 1: Force an OID in text form from OBJ_obj2txt()
@@ -408,6 +439,7 @@ int setup_tests(void)
} else {
ADD_TEST(test_implicit_EVP_CIPHER_fetch);
ADD_TEST(test_explicit_EVP_CIPHER_fetch_by_name);
+ ADD_TEST(test_cipher_no_getparams);
ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR, 2);
}
return 1;
diff --git a/test/evp_skey_test.c b/test/evp_skey_test.c
index 2e24123a49..c98abb8462 100644
--- a/test/evp_skey_test.c
+++ b/test/evp_skey_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
diff --git a/test/fake_cipherprov.c b/test/fake_cipherprov.c
index 2322a1a812..2306f29e4e 100644
--- a/test/fake_cipherprov.c
+++ b/test/fake_cipherprov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -267,8 +267,18 @@ static const OSSL_DISPATCH ossl_fake_functions[] = {
OSSL_DISPATCH_END
};
+static const OSSL_DISPATCH ossl_fake_no_getparams_functions[] = {
+ { OSSL_FUNC_CIPHER_NEWCTX,
+ (void (*)(void))fake_newctx },
+ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))fake_freectx },
+ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))fake_cipher },
+ OSSL_DISPATCH_END
+};
+
static const OSSL_ALGORITHM fake_cipher_algs[] = {
{ "fake_cipher", FAKE_CIPHER_FETCH_PROPS, ossl_fake_functions },
+ { FAKE_CIPHER_NO_GETPARAMS, FAKE_CIPHER_FETCH_PROPS,
+ ossl_fake_no_getparams_functions },
{ NULL, NULL, NULL }
};
diff --git a/test/fake_cipherprov.h b/test/fake_cipherprov.h
index ea7313a740..54ccd6face 100644
--- a/test/fake_cipherprov.h
+++ b/test/fake_cipherprov.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -16,4 +16,5 @@ void fake_cipher_finish(OSSL_PROVIDER *p);
#define FAKE_PROV_NAME "fake-cipher"
#define FAKE_CIPHER_FETCH_PROPS "provider=fake-cipher"
+#define FAKE_CIPHER_NO_GETPARAMS "fake_cipher_no_getparams"
#define FAKE_CIPHER_PARAM_KEY_NAME "key_name"