[PATCH v2] Add support for OpenSSL Provider API
Mattijs Korpershoek
mkorpershoek at kernel.org
Thu Dec 11 09:23:11 CET 2025
Hi Eddie,
Thank you for working on this. It would be really nice if we could build
U-Boot on more recent Linux distros without bridge packages such as
openssl-devel-engine.
On Fri, Nov 21, 2025 at 11:16, Eddie Kovsky <ekovsky at redhat.com> wrote:
> 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.
I also don't linke this double negative.
As you already shared, Linux solved this via:
#if OPENSSL_VERSION_MAJOR >= 3
Why can't we have something similar?
See: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=558bdc45dfb2669e1741384a0c80be9c82fa052c
>
> [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.
I'd be in favor to drop CONFIG_OPENSSL_NO_DEPRECATED all together and
just use "#if OPENSSL_VERSION_MAJOR >= 3".
Tom, or anyone else, is there a particular` reason for gating this in a
Kconfig ?
The oldest Ubuntu version that seems supported (22.04) already has
OpenSSL version 3:
$ podman run -it /bin/bash ubuntu:22.04
root at 6dc347676b8a:~# apt update && apt install -y openssl
root at 6dc347676b8a:~# openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
>
> Eddie
More information about the U-Boot
mailing list