diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.DigestAlgs.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.DigestAlgs.cs index 056092b0b333f9..2d49dc8ef68ec3 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.DigestAlgs.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.DigestAlgs.cs @@ -19,11 +19,6 @@ internal static partial class Crypto private static volatile IntPtr s_evpSha3_512; private static volatile IntPtr s_evpSha3_Shake128; private static volatile IntPtr s_evpSha3_Shake256; - private static volatile bool s_evpSha3_256Cached; - private static volatile bool s_evpSha3_384Cached; - private static volatile bool s_evpSha3_512Cached; - private static volatile bool s_evpSha3_Shake128Cached; - private static volatile bool s_evpSha3_Shake256Cached; [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpMd5(); @@ -58,99 +53,48 @@ private static IntPtr EvpSha512() => [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpSha3_256(); - private static IntPtr EvpSha3_256() - { - if (!s_evpSha3_256Cached) - { - s_evpSha3_256 = CryptoNative_EvpSha3_256(); - s_evpSha3_256Cached = true; - } - - return s_evpSha3_256; - } + private static IntPtr EvpSha3_256() => + s_evpSha3_256 != IntPtr.Zero ? s_evpSha3_256 : (s_evpSha3_256 = CryptoNative_EvpSha3_256()); [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpSha3_384(); - private static IntPtr EvpSha3_384() - { - if (!s_evpSha3_384Cached) - { - s_evpSha3_384 = CryptoNative_EvpSha3_384(); - s_evpSha3_384Cached = true; - } - - return s_evpSha3_384; - } + private static IntPtr EvpSha3_384() => + s_evpSha3_384 != IntPtr.Zero ? s_evpSha3_384 : (s_evpSha3_384 = CryptoNative_EvpSha3_384()); [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpSha3_512(); - private static IntPtr EvpSha3_512() - { - if (!s_evpSha3_512Cached) - { - s_evpSha3_512 = CryptoNative_EvpSha3_512(); - s_evpSha3_512Cached = true; - } - - return s_evpSha3_512; - } + private static IntPtr EvpSha3_512() => + s_evpSha3_512 != IntPtr.Zero ? s_evpSha3_512 : (s_evpSha3_512 = CryptoNative_EvpSha3_512()); [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpShake128(); - private static IntPtr EvpShake128() - { - if (!s_evpSha3_Shake128Cached) - { - s_evpSha3_Shake128 = CryptoNative_EvpShake128(); - s_evpSha3_Shake128Cached = true; - } - - return s_evpSha3_Shake128; - } + private static IntPtr EvpShake128() => + s_evpSha3_Shake128 != IntPtr.Zero ? s_evpSha3_Shake128 : (s_evpSha3_Shake128 = CryptoNative_EvpShake128()); [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpShake256(); - private static IntPtr EvpShake256() - { - if (!s_evpSha3_Shake256Cached) - { - s_evpSha3_Shake256 = CryptoNative_EvpShake256(); - s_evpSha3_Shake256Cached = true; - } - - return s_evpSha3_Shake256; - } + private static IntPtr EvpShake256() => + s_evpSha3_Shake256 != IntPtr.Zero ? s_evpSha3_Shake256 : (s_evpSha3_Shake256 = CryptoNative_EvpShake256()); internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) { - switch (hashAlgorithmId) + return hashAlgorithmId switch { - case HashAlgorithmNames.SHA1: return EvpSha1(); - case HashAlgorithmNames.SHA256: return EvpSha256(); - case HashAlgorithmNames.SHA384: return EvpSha384(); - case HashAlgorithmNames.SHA512: return EvpSha512(); - case HashAlgorithmNames.SHA3_256: - IntPtr sha3_256 = EvpSha3_256(); - return sha3_256 != 0 ? sha3_256 : throw new PlatformNotSupportedException(); - case HashAlgorithmNames.SHA3_384: - IntPtr sha3_384 = EvpSha3_384(); - return sha3_384 != 0 ? sha3_384 : throw new PlatformNotSupportedException(); - case HashAlgorithmNames.SHA3_512: - IntPtr sha3_512 = EvpSha3_512(); - return sha3_512 != 0 ? sha3_512 : throw new PlatformNotSupportedException(); - case HashAlgorithmNames.SHAKE128: - IntPtr shake128 = EvpShake128(); - return shake128 != 0 ? shake128 : throw new PlatformNotSupportedException(); - case HashAlgorithmNames.SHAKE256: - IntPtr shake256 = EvpShake256(); - return shake256 != 0 ? shake256 : throw new PlatformNotSupportedException(); - case nameof(HashAlgorithmName.MD5): return EvpMd5(); - default: - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); + HashAlgorithmNames.MD5 => EvpMd5(), + HashAlgorithmNames.SHA1 => EvpSha1(), + HashAlgorithmNames.SHA256 => EvpSha256(), + HashAlgorithmNames.SHA384 => EvpSha384(), + HashAlgorithmNames.SHA512 => EvpSha512(), + HashAlgorithmNames.SHA3_256 => EvpSha3_256(), + HashAlgorithmNames.SHA3_384 => EvpSha3_384(), + HashAlgorithmNames.SHA3_512 => EvpSha3_512(), + HashAlgorithmNames.SHAKE128 => EvpShake128(), + HashAlgorithmNames.SHAKE256 => EvpShake256(), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)), }; } @@ -163,17 +107,12 @@ internal static bool HashAlgorithmSupported(string hashAlgorithmId) case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: case HashAlgorithmNames.MD5: - return true; case HashAlgorithmNames.SHA3_256: - return EvpSha3_256() != 0; case HashAlgorithmNames.SHA3_384: - return EvpSha3_384() != 0; case HashAlgorithmNames.SHA3_512: - return EvpSha3_512() != 0; case HashAlgorithmNames.SHAKE128: - return EvpShake128() != 0; case HashAlgorithmNames.SHAKE256: - return EvpShake256() != 0; + return true; default: throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); } diff --git a/src/native/libs/System.Security.Cryptography.Native/configure.cmake b/src/native/libs/System.Security.Cryptography.Native/configure.cmake index 4b59e48bce9e68..89d4c6c4760a0a 100644 --- a/src/native/libs/System.Security.Cryptography.Native/configure.cmake +++ b/src/native/libs/System.Security.Cryptography.Native/configure.cmake @@ -14,11 +14,6 @@ check_function_exists( SSL_get0_alpn_selected HAVE_OPENSSL_ALPN) -check_function_exists( - EVP_sha3_256 - HAVE_OPENSSL_SHA3 -) - check_function_exists( EVP_DigestSqueeze HAVE_OPENSSL_SHA3_SQUEEZE diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index bc50d89b11d468..fc4cc6c0459e0f 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -245,17 +245,6 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void); #define EVP_CTRL_AEAD_SET_TAG 0x11 #endif -#if !HAVE_OPENSSL_SHA3 -#undef HAVE_OPENSSL_SHA3 -#define HAVE_OPENSSL_SHA3 1 -const EVP_MD *EVP_sha3_256(void); -const EVP_MD *EVP_sha3_384(void); -const EVP_MD *EVP_sha3_512(void); -const EVP_MD *EVP_shake128(void); -const EVP_MD *EVP_shake256(void); -int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); -#endif - #if !HAVE_OPENSSL_SHA3_SQUEEZE #undef HAVE_OPENSSL_SHA3_SQUEEZE #define HAVE_OPENSSL_SHA3_SQUEEZE 1 @@ -580,11 +569,11 @@ extern bool g_libSslUses32BitTime; REQUIRED_FUNCTION(EVP_sha256) \ REQUIRED_FUNCTION(EVP_sha384) \ REQUIRED_FUNCTION(EVP_sha512) \ - LIGHTUP_FUNCTION(EVP_sha3_256) \ - LIGHTUP_FUNCTION(EVP_sha3_384) \ - LIGHTUP_FUNCTION(EVP_sha3_512) \ - LIGHTUP_FUNCTION(EVP_shake128) \ - LIGHTUP_FUNCTION(EVP_shake256) \ + REQUIRED_FUNCTION(EVP_sha3_256) \ + REQUIRED_FUNCTION(EVP_sha3_384) \ + REQUIRED_FUNCTION(EVP_sha3_512) \ + REQUIRED_FUNCTION(EVP_shake128) \ + REQUIRED_FUNCTION(EVP_shake256) \ LIGHTUP_FUNCTION(EVP_SIGNATURE_fetch) \ LIGHTUP_FUNCTION(EVP_SIGNATURE_free) \ REQUIRED_FUNCTION(GENERAL_NAMES_free) \ diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in b/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in index 3664c96114b653..d09ed47fa02843 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in +++ b/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in @@ -3,7 +3,6 @@ #cmakedefine01 HAVE_OPENSSL_EC2M #cmakedefine01 HAVE_OPENSSL_ALPN #cmakedefine01 HAVE_OPENSSL_CHACHA20POLY1305 -#cmakedefine01 HAVE_OPENSSL_SHA3 #cmakedefine01 HAVE_OPENSSL_SHA3_SQUEEZE #cmakedefine01 HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT #cmakedefine01 HAVE_OPENSSL_ENGINE diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c index 6d707bb15edac5..bd24267b06e38a 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c @@ -33,30 +33,12 @@ pthread_once(&g_evpFetchInit##export, EnsureFetchEvpMd##export); \ return g_evpFetch##export; \ } -#define BUILD_MD_FETCH_LIGHTUP_SHA3(...) BUILD_MD_FETCH(__VA_ARGS__) #else #define BUILD_MD_FETCH(export, fn, name, query) \ const EVP_MD* export(void) \ { \ return fn(); \ } -#if HAVE_OPENSSL_SHA3 -#define BUILD_MD_FETCH_LIGHTUP_SHA3(export, fn, name, query) \ - const EVP_MD* export(void) \ - { \ - if (API_EXISTS(fn)) \ - { \ - return fn(); \ - } \ - \ - return NULL; \ - } -#else - const EVP_MD* export(void) \ - { \ - return NULL; \ - } -#endif #endif @@ -128,43 +110,31 @@ int32_t CryptoNative_EvpDigestFinalEx(EVP_MD_CTX* ctx, uint8_t* md, uint32_t* s) int32_t CryptoNative_EvpDigestFinalXOF(EVP_MD_CTX* ctx, uint8_t* md, uint32_t len) { - #if HAVE_OPENSSL_SHA3 - if (API_EXISTS(EVP_DigestFinalXOF)) - { - ERR_clear_error(); - - // https://github.com/openssl/openssl/issues/9431 - // EVP_DigestFinalXOF has a bug in some arch-optimized code paths where it cannot tolerate a zero length - // digest. - // If the caller asked for no bytes, use a temporary buffer to ask for 1 byte, then throw away the result. - // We don't want to skip calling FinalXOF entirely because we want to make sure the EVP_MD_CTX is in a - // finalized state regardless of the length of the digest. - // We can remove this work around when OpenSSL 3.0 is the minimum OpenSSL requirement. - if (len == 0) - { - uint8_t single[1] = { 0 }; - int result = EVP_DigestFinalXOF(ctx, single, 1); - OPENSSL_cleanse(single, sizeof(single)); - return result; - } - else if (!md) - { - // Length is not zero but we don't have a buffer to write to. - return -1; - } - else - { - return EVP_DigestFinalXOF(ctx, md, len); - } - } - #else - // Use each parameter to avoid unused parameter warnings. - (void)(ctx); - (void)(md); - (void)(len); - #endif + ERR_clear_error(); - return 0; + // https://github.com/openssl/openssl/issues/9431 + // EVP_DigestFinalXOF has a bug in some arch-optimized code paths where it cannot tolerate a zero length + // digest. + // If the caller asked for no bytes, use a temporary buffer to ask for 1 byte, then throw away the result. + // We don't want to skip calling FinalXOF entirely because we want to make sure the EVP_MD_CTX is in a + // finalized state regardless of the length of the digest. + // We can remove this work around when OpenSSL 3.0 is the minimum OpenSSL requirement. + if (len == 0) + { + uint8_t single[1] = { 0 }; + int result = EVP_DigestFinalXOF(ctx, single, 1); + OPENSSL_cleanse(single, sizeof(single)); + return result; + } + else if (!md) + { + // Length is not zero but we don't have a buffer to write to. + return -1; + } + else + { + return EVP_DigestFinalXOF(ctx, md, len); + } } EVP_MD_CTX* CryptoNative_EvpMdCtxCopyEx(const EVP_MD_CTX* ctx) @@ -322,11 +292,11 @@ BUILD_MD_FETCH(CryptoNative_EvpSha1, EVP_sha1, "SHA1", NULL) BUILD_MD_FETCH(CryptoNative_EvpSha256, EVP_sha256, "SHA256", NULL) BUILD_MD_FETCH(CryptoNative_EvpSha384, EVP_sha384, "SHA384", NULL) BUILD_MD_FETCH(CryptoNative_EvpSha512, EVP_sha512, "SHA512", NULL) -BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_256, EVP_sha3_256, "SHA3-256", NULL) -BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_384, EVP_sha3_384, "SHA3-384", NULL) -BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_512, EVP_sha3_512, "SHA3-512", NULL) -BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpShake128, EVP_shake128, "SHAKE-128", NULL) -BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpShake256, EVP_shake256, "SHAKE-256", NULL) +BUILD_MD_FETCH(CryptoNative_EvpSha3_256, EVP_sha3_256, "SHA3-256", NULL) +BUILD_MD_FETCH(CryptoNative_EvpSha3_384, EVP_sha3_384, "SHA3-384", NULL) +BUILD_MD_FETCH(CryptoNative_EvpSha3_512, EVP_sha3_512, "SHA3-512", NULL) +BUILD_MD_FETCH(CryptoNative_EvpShake128, EVP_shake128, "SHAKE-128", NULL) +BUILD_MD_FETCH(CryptoNative_EvpShake256, EVP_shake256, "SHAKE-256", NULL) int32_t CryptoNative_GetMaxMdSize(void) {