From: herbenderbler Date: Fri, 13 Mar 2026 04:28:41 +0000 (-0600) Subject: Enforce mandatory cipher get_params at dispatch parse X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e730ce940d2c117249df4f206a328898cf331ba6;p=thirdparty%2Fopenssl.git 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 Reviewed-by: Eugene Syromiatnikov Reviewed-by: Paul Dale Reviewed-by: Matt Caswell 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 0d2c26052ed..1be9508ac61 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 679c35e0f9b..a7dea25fd3a 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 c5a7a565b70..0c69df85cc5 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 2cde0049e87..bcc7c59eb61 100644 --- a/test/evp_fetch_prov_test.c +++ b/test/evp_fetch_prov_test.c @@ -20,6 +20,7 @@ #include #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 2e24123a494..c98abb8462c 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 2322a1a8122..2306f29e4ed 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 ea7313a740a..54ccd6face0 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"