From ff2eccbdf9541fc3491e8a5a302eb661208bb827 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 11 Jan 2022 12:43:19 +0200 Subject: [PATCH] OpenSSL: Load legacy provider when needed for OpenSSL 3.0 Number of the older algorithms have now been moved into a separate provider in OpenSSL 3.0 and they are not available by default. Explicitly load the legacy provider when such an algorithm is needed for the first time. In addition, at least for now, load the legacy providers when initiating TLS context to maintain existing functionality for various private key formats. Signed-off-by: Jouni Malinen --- src/crypto/crypto_openssl.c | 28 ++++++++++++++++++++++++++++ src/crypto/tls_openssl.c | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index bac260e11..0372fc3f7 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -24,6 +24,9 @@ #include #include #endif /* CONFIG_ECC */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif /* OpenSSL version >= 3.0 */ #include "common.h" #include "utils/const_time.h" @@ -117,6 +120,26 @@ static const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x) } #endif /* OpenSSL version < 1.1.0 */ + +void openssl_load_legacy_provider(void) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + static bool loaded = false; + OSSL_PROVIDER *legacy; + + if (loaded) + return; + + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + + if (legacy) { + OSSL_PROVIDER_load(NULL, "default"); + loaded = true; + } +#endif /* OpenSSL version >= 3.0 */ +} + + static BIGNUM * get_group5_prime(void) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ @@ -223,6 +246,7 @@ static int openssl_digest_vector(const EVP_MD *type, size_t num_elem, #ifndef CONFIG_FIPS int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { + openssl_load_legacy_provider(); return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac); } #endif /* CONFIG_FIPS */ @@ -234,6 +258,8 @@ int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) int i, plen, ret = -1; EVP_CIPHER_CTX *ctx; + openssl_load_legacy_provider(); + /* Add parity bits to the key */ next = 0; for (i = 0; i < 7; i++) { @@ -271,6 +297,8 @@ int rc4_skip(const u8 *key, size_t keylen, size_t skip, int res = -1; unsigned char skip_buf[16]; + openssl_load_legacy_provider(); + ctx = EVP_CIPHER_CTX_new(); if (!ctx || !EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, 1) || diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 203b0f781..ad651bdc8 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -957,6 +957,10 @@ void * tls_init(const struct tls_config *conf) const char *ciphers; if (tls_openssl_ref_count == 0) { + void openssl_load_legacy_provider(void); + + openssl_load_legacy_provider(); + tls_global = context = tls_context_new(conf); if (context == NULL) return NULL;