[PATCH v2] Add support for OpenSSL Provider API
Eddie Kovsky
ekovsky at redhat.com
Fri Nov 21 19:16:34 CET 2025
Hi Quentin
On 11/17/25, Quentin Schulz wrote:
> Hi Eddie,
>
> On 10/27/25 8:58 PM, Eddie Kovsky wrote:
> > [You don't often get email from ekovsky at redhat.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> >
> > The Engine API has been deprecated since the release of OpenSSL 3.0. End
> > users have been advised to migrate to the new Provider interface.
> > Several distributions have already removed support for engines, which is
> > preventing U-Boot from being compiled in those environments.
> >
>
> Which ones? How do I reproduce?
>
As you are probably aware, OpenSSL deprecated the Engine API with the
3.0 release, and engines are likely to be removed entirely when
OpenSSL 4.0 is released in 2026. [1][2]
[1] https://docs.openssl.org/3.0/man7/migration_guide/#engines-and-method-apis
[2] https://github.com/openssl/openssl/discussions/21832
I don't have a comprehensive list of all distros. Fedora, RHEL 10,
Arch, and Debian 13 are all shipping OpenSSL 3.5. If you try to build
U-Boot in those environments the compiler will not be able to resolve the
engine API symbols and the build will fail.
Fedora is currently providing a bridge package openssl-devel-engine [3] to
help make the API transition easier, but that is only a temporary
solution. (I think Debian is currently doing something similar.)
[3] https://packages.fedoraproject.org/pkgs/openssl/openssl-devel-engine/
> > The Kconfig option OPENSSL_NO_DEPRECATED introduces support for the
>
> Please consider renaming this, OpenSSL itself uses OPENSSL_NO_DEPRECATED
> constants for many things. I would recommend simply renaming to
> OPENSSL_NO_ENGINE which is also the symbol OpenSSL is using. If there comes
> a time we have more OPENSSL_NO_ options, we can always have a "virtual"
> symbol called OPENSSL_NO_DEPRECATED which would select them all if one
> wanted for example.
>
I did give some thought to using a different name because I don't
like the double negative that comes from this construct:
#ifndef CONFIG_OPENSSL_NO_DEPRECATED
But I kept it because the name is advantageous precisely because it's
already recognized by the OpenSSL API. OPENSSL_NO_DEPRECATED is a
user-defined macro.[4] When combined with the OPENSSL_API_COMPAT macro,
which is already defined in lib/rsa/rsa-sign.c, we can ensure that
deprecated symbols won't be available in sections where
OPENSSL_NO_DEPRECATED is defined.
[4] https://docs.openssl.org/3.0/man7/openssl_user_macros/
> > Provider API while continuing to use the existing Engine API on distros
> > shipping older releases of OpenSSL.
> >
>
> One can use org.openssl.engine: as prefix for provider arguments when one
> wants to use an engine still.
>
Sorry, but it's not clear what you are referring to here.
> > This is based on similar work contributed by Jan Stancek updating Linux
> > to use the Provider interface.
> >
> > commit 558bdc45dfb2669e1741384a0c80be9c82fa052c
> > Author: Jan Stancek <jstancek at redhat.com>
> > Date: Fri Sep 20 19:52:48 2024 +0300
> >
> > sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3
> >
> > The changes have been tested with the FIT signature verification vboot
> > tests on Fedora 42 and Debian 13. All 30 tests pass with both the legacy
> > Engine library installed and with the Provider API.
> >
>
> Are there actually tests using an OpenSSL engine? Because otherwise it's
> simply checking that local keys are still working... which isn't that much
> different from what we currently have with engines when not using engines.
>
> I'm implementing FIT images signing with OpenSSL engines, and it'd be nice
> if we could have something that doesn't require changes to support providers
> (or if it does, not in a confusing manner for example).
>
> https://lore.kernel.org/u-boot/20251031-binman-engine-v1-0-c13c1b5dac43@cherry.de/T/#t
> for the v1, I'll soon (next hours or tomorrow) post a v2 and Cc you if you
> don't mind.
>
> [...]
>
As mentioned above, the motivation for this patch is that the Engine
API has already been deprecated. Projects that depend on OpenSSL will
need to move to the new Provider API in order to continue to function.
The FIT Signature Verification tests I used to exercise both APIs are
documented here.[5]
[5] https://docs.u-boot.org/en/latest/usage/fit/signature.html#u-boot-fit-signature-verification
> > diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
> > index 9033384e60a3..1bf0ac96d598 100644
> > --- a/lib/rsa/Kconfig
> > +++ b/lib/rsa/Kconfig
> > @@ -20,6 +20,13 @@ config SPL_RSA
> > bool "Use RSA Library within SPL"
> > depends on SPL
> >
> > +config OPENSSL_NO_DEPRECATED
> > + bool "Build U-Boot without support for OpenSSL Engine"
> > + help
> > + Add support for the OpenSSL Provider API, which is the officially
> > + supported mechanism in OpenSSL 3.x and later releases for accessing
> > + hardware and software cryptography.
> > +
>
> mmmm Cannot we use providers for something else than RSA? In which case it's
> a bit odd to have it in lib/rsa/Kconfig (but I have no better suggestion).
>
To the best of my knowledge, the only areas in the U-Boot source that
are using the Engine API are the RSA and AES libraries. All other uses
in U-Boot are clients of these two libraries.
> > config SPL_RSA_VERIFY
> > bool
> > depends on SPL_RSA
>
> [...]
>
> > @@ -207,6 +247,37 @@ static int rsa_pem_get_priv_key(const char *keydir, const char *name,
> > return -ENOENT;
> > }
> >
> > +#ifdef CONFIG_OPENSSL_NO_DEPRECATED
> > + EVP_PKEY *private_key = NULL;
> > + OSSL_STORE_CTX *store;
> > +
> > + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true))
> > + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)");
> > + if (!OSSL_PROVIDER_try_load(NULL, "default", true))
> > + ERR(1, "OSSL_PROVIDER_try_load(default)");
> > +
> > + store = OSSL_STORE_open(path, NULL, NULL, NULL, NULL);
> > + ERR(!store, "OSSL_STORE_open");
> > +
> > + while (!OSSL_STORE_eof(store)) {
> > + OSSL_STORE_INFO *info = OSSL_STORE_load(store);
> > +
> > + if (!info) {
> > + drain_openssl_errors(__LINE__, 0);
> > + continue;
> > + }
> > + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
> > + private_key = OSSL_STORE_INFO_get1_PKEY(info);
> > + ERR(!private_key, "OSSL_STORE_INFO_get1_PKEY");
> > + }
> > + OSSL_STORE_INFO_free(info);
> > + if (private_key)
> > + break;
> > + }
> > + OSSL_STORE_close(store);
> > +
> > + *evpp = private_key;
> > +#else
>
> Wondering if it really makes sense to have the provider API implemented as
> an #ifdef to save like 10 common lines between key-based and provider-based
> implems.
>
> On another topic, my first reading of the code makes me a bit worried by the
> fact that there's seemingly no way to select whether we want to use a local
> key or a provider key. Also, I see "pkcs11" and "default" here, but how do I
> select which provider I want to use (e.g. my custom one). If I somehow
> manage to have a key named the same locally and in one or more providers,
> how do I make sure the proper one is selected? I'm wondering whether we
> should be reusing the engine parameter to select a provider?
>
> I have 0 security or crypto background, don't hesitate to be verbose in your
> answer.
>
> Cheers,
> Quentin
>
It's not the prettiest code. But I'm trying to be very conservative
in making these changes so that no one's workflow is disrupted.
Developers should be able to build U-Boot with the latest OpenSSL
without impacting developers who are in environments utilizing the
Engine API. The goal here is to preserve feature parity between the two
APIs. Adding support for custom Providers is outside the scope of this
change, but could certainly be added later.
Eddie
More information about the U-Boot
mailing list