Skip to content

Commit 4562739

Browse files
authored
Make SHA-3 required with OpenSSL
This makes SHA-3 required for OpenSSL, effectively making our OpenSSL minimum 1.1.1.
1 parent 0c54c06 commit 4562739

File tree

5 files changed

+57
-165
lines changed

5 files changed

+57
-165
lines changed

src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.DigestAlgs.cs

Lines changed: 23 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ internal static partial class Crypto
1919
private static volatile IntPtr s_evpSha3_512;
2020
private static volatile IntPtr s_evpSha3_Shake128;
2121
private static volatile IntPtr s_evpSha3_Shake256;
22-
private static volatile bool s_evpSha3_256Cached;
23-
private static volatile bool s_evpSha3_384Cached;
24-
private static volatile bool s_evpSha3_512Cached;
25-
private static volatile bool s_evpSha3_Shake128Cached;
26-
private static volatile bool s_evpSha3_Shake256Cached;
2722

2823
[LibraryImport(Libraries.CryptoNative)]
2924
private static partial IntPtr CryptoNative_EvpMd5();
@@ -58,99 +53,48 @@ private static IntPtr EvpSha512() =>
5853
[LibraryImport(Libraries.CryptoNative)]
5954
private static partial IntPtr CryptoNative_EvpSha3_256();
6055

61-
private static IntPtr EvpSha3_256()
62-
{
63-
if (!s_evpSha3_256Cached)
64-
{
65-
s_evpSha3_256 = CryptoNative_EvpSha3_256();
66-
s_evpSha3_256Cached = true;
67-
}
68-
69-
return s_evpSha3_256;
70-
}
56+
private static IntPtr EvpSha3_256() =>
57+
s_evpSha3_256 != IntPtr.Zero ? s_evpSha3_256 : (s_evpSha3_256 = CryptoNative_EvpSha3_256());
7158

7259
[LibraryImport(Libraries.CryptoNative)]
7360
private static partial IntPtr CryptoNative_EvpSha3_384();
7461

75-
private static IntPtr EvpSha3_384()
76-
{
77-
if (!s_evpSha3_384Cached)
78-
{
79-
s_evpSha3_384 = CryptoNative_EvpSha3_384();
80-
s_evpSha3_384Cached = true;
81-
}
82-
83-
return s_evpSha3_384;
84-
}
62+
private static IntPtr EvpSha3_384() =>
63+
s_evpSha3_384 != IntPtr.Zero ? s_evpSha3_384 : (s_evpSha3_384 = CryptoNative_EvpSha3_384());
8564

8665
[LibraryImport(Libraries.CryptoNative)]
8766
private static partial IntPtr CryptoNative_EvpSha3_512();
8867

89-
private static IntPtr EvpSha3_512()
90-
{
91-
if (!s_evpSha3_512Cached)
92-
{
93-
s_evpSha3_512 = CryptoNative_EvpSha3_512();
94-
s_evpSha3_512Cached = true;
95-
}
96-
97-
return s_evpSha3_512;
98-
}
68+
private static IntPtr EvpSha3_512() =>
69+
s_evpSha3_512 != IntPtr.Zero ? s_evpSha3_512 : (s_evpSha3_512 = CryptoNative_EvpSha3_512());
9970

10071
[LibraryImport(Libraries.CryptoNative)]
10172
private static partial IntPtr CryptoNative_EvpShake128();
10273

103-
private static IntPtr EvpShake128()
104-
{
105-
if (!s_evpSha3_Shake128Cached)
106-
{
107-
s_evpSha3_Shake128 = CryptoNative_EvpShake128();
108-
s_evpSha3_Shake128Cached = true;
109-
}
110-
111-
return s_evpSha3_Shake128;
112-
}
74+
private static IntPtr EvpShake128() =>
75+
s_evpSha3_Shake128 != IntPtr.Zero ? s_evpSha3_Shake128 : (s_evpSha3_Shake128 = CryptoNative_EvpShake128());
11376

11477
[LibraryImport(Libraries.CryptoNative)]
11578
private static partial IntPtr CryptoNative_EvpShake256();
11679

117-
private static IntPtr EvpShake256()
118-
{
119-
if (!s_evpSha3_Shake256Cached)
120-
{
121-
s_evpSha3_Shake256 = CryptoNative_EvpShake256();
122-
s_evpSha3_Shake256Cached = true;
123-
}
124-
125-
return s_evpSha3_Shake256;
126-
}
80+
private static IntPtr EvpShake256() =>
81+
s_evpSha3_Shake256 != IntPtr.Zero ? s_evpSha3_Shake256 : (s_evpSha3_Shake256 = CryptoNative_EvpShake256());
12782

12883
internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId)
12984
{
130-
switch (hashAlgorithmId)
85+
return hashAlgorithmId switch
13186
{
132-
case HashAlgorithmNames.SHA1: return EvpSha1();
133-
case HashAlgorithmNames.SHA256: return EvpSha256();
134-
case HashAlgorithmNames.SHA384: return EvpSha384();
135-
case HashAlgorithmNames.SHA512: return EvpSha512();
136-
case HashAlgorithmNames.SHA3_256:
137-
IntPtr sha3_256 = EvpSha3_256();
138-
return sha3_256 != 0 ? sha3_256 : throw new PlatformNotSupportedException();
139-
case HashAlgorithmNames.SHA3_384:
140-
IntPtr sha3_384 = EvpSha3_384();
141-
return sha3_384 != 0 ? sha3_384 : throw new PlatformNotSupportedException();
142-
case HashAlgorithmNames.SHA3_512:
143-
IntPtr sha3_512 = EvpSha3_512();
144-
return sha3_512 != 0 ? sha3_512 : throw new PlatformNotSupportedException();
145-
case HashAlgorithmNames.SHAKE128:
146-
IntPtr shake128 = EvpShake128();
147-
return shake128 != 0 ? shake128 : throw new PlatformNotSupportedException();
148-
case HashAlgorithmNames.SHAKE256:
149-
IntPtr shake256 = EvpShake256();
150-
return shake256 != 0 ? shake256 : throw new PlatformNotSupportedException();
151-
case nameof(HashAlgorithmName.MD5): return EvpMd5();
152-
default:
153-
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
87+
HashAlgorithmNames.MD5 => EvpMd5(),
88+
HashAlgorithmNames.SHA1 => EvpSha1(),
89+
HashAlgorithmNames.SHA256 => EvpSha256(),
90+
HashAlgorithmNames.SHA384 => EvpSha384(),
91+
HashAlgorithmNames.SHA512 => EvpSha512(),
92+
HashAlgorithmNames.SHA3_256 => EvpSha3_256(),
93+
HashAlgorithmNames.SHA3_384 => EvpSha3_384(),
94+
HashAlgorithmNames.SHA3_512 => EvpSha3_512(),
95+
HashAlgorithmNames.SHAKE128 => EvpShake128(),
96+
HashAlgorithmNames.SHAKE256 => EvpShake256(),
97+
_ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)),
15498
};
15599
}
156100

@@ -163,17 +107,12 @@ internal static bool HashAlgorithmSupported(string hashAlgorithmId)
163107
case HashAlgorithmNames.SHA384:
164108
case HashAlgorithmNames.SHA512:
165109
case HashAlgorithmNames.MD5:
166-
return true;
167110
case HashAlgorithmNames.SHA3_256:
168-
return EvpSha3_256() != 0;
169111
case HashAlgorithmNames.SHA3_384:
170-
return EvpSha3_384() != 0;
171112
case HashAlgorithmNames.SHA3_512:
172-
return EvpSha3_512() != 0;
173113
case HashAlgorithmNames.SHAKE128:
174-
return EvpShake128() != 0;
175114
case HashAlgorithmNames.SHAKE256:
176-
return EvpShake256() != 0;
115+
return true;
177116
default:
178117
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
179118
}

src/native/libs/System.Security.Cryptography.Native/configure.cmake

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ check_function_exists(
1414
SSL_get0_alpn_selected
1515
HAVE_OPENSSL_ALPN)
1616

17-
check_function_exists(
18-
EVP_sha3_256
19-
HAVE_OPENSSL_SHA3
20-
)
21-
2217
check_function_exists(
2318
EVP_DigestSqueeze
2419
HAVE_OPENSSL_SHA3_SQUEEZE

src/native/libs/System.Security.Cryptography.Native/opensslshim.h

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -245,17 +245,6 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
245245
#define EVP_CTRL_AEAD_SET_TAG 0x11
246246
#endif
247247

248-
#if !HAVE_OPENSSL_SHA3
249-
#undef HAVE_OPENSSL_SHA3
250-
#define HAVE_OPENSSL_SHA3 1
251-
const EVP_MD *EVP_sha3_256(void);
252-
const EVP_MD *EVP_sha3_384(void);
253-
const EVP_MD *EVP_sha3_512(void);
254-
const EVP_MD *EVP_shake128(void);
255-
const EVP_MD *EVP_shake256(void);
256-
int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len);
257-
#endif
258-
259248
#if !HAVE_OPENSSL_SHA3_SQUEEZE
260249
#undef HAVE_OPENSSL_SHA3_SQUEEZE
261250
#define HAVE_OPENSSL_SHA3_SQUEEZE 1
@@ -580,11 +569,11 @@ extern bool g_libSslUses32BitTime;
580569
REQUIRED_FUNCTION(EVP_sha256) \
581570
REQUIRED_FUNCTION(EVP_sha384) \
582571
REQUIRED_FUNCTION(EVP_sha512) \
583-
LIGHTUP_FUNCTION(EVP_sha3_256) \
584-
LIGHTUP_FUNCTION(EVP_sha3_384) \
585-
LIGHTUP_FUNCTION(EVP_sha3_512) \
586-
LIGHTUP_FUNCTION(EVP_shake128) \
587-
LIGHTUP_FUNCTION(EVP_shake256) \
572+
REQUIRED_FUNCTION(EVP_sha3_256) \
573+
REQUIRED_FUNCTION(EVP_sha3_384) \
574+
REQUIRED_FUNCTION(EVP_sha3_512) \
575+
REQUIRED_FUNCTION(EVP_shake128) \
576+
REQUIRED_FUNCTION(EVP_shake256) \
588577
LIGHTUP_FUNCTION(EVP_SIGNATURE_fetch) \
589578
LIGHTUP_FUNCTION(EVP_SIGNATURE_free) \
590579
REQUIRED_FUNCTION(GENERAL_NAMES_free) \

src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#cmakedefine01 HAVE_OPENSSL_EC2M
44
#cmakedefine01 HAVE_OPENSSL_ALPN
55
#cmakedefine01 HAVE_OPENSSL_CHACHA20POLY1305
6-
#cmakedefine01 HAVE_OPENSSL_SHA3
76
#cmakedefine01 HAVE_OPENSSL_SHA3_SQUEEZE
87
#cmakedefine01 HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT
98
#cmakedefine01 HAVE_OPENSSL_ENGINE

src/native/libs/System.Security.Cryptography.Native/pal_evp.c

Lines changed: 29 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,12 @@
3333
pthread_once(&g_evpFetchInit##export, EnsureFetchEvpMd##export); \
3434
return g_evpFetch##export; \
3535
}
36-
#define BUILD_MD_FETCH_LIGHTUP_SHA3(...) BUILD_MD_FETCH(__VA_ARGS__)
3736
#else
3837
#define BUILD_MD_FETCH(export, fn, name, query) \
3938
const EVP_MD* export(void) \
4039
{ \
4140
return fn(); \
4241
}
43-
#if HAVE_OPENSSL_SHA3
44-
#define BUILD_MD_FETCH_LIGHTUP_SHA3(export, fn, name, query) \
45-
const EVP_MD* export(void) \
46-
{ \
47-
if (API_EXISTS(fn)) \
48-
{ \
49-
return fn(); \
50-
} \
51-
\
52-
return NULL; \
53-
}
54-
#else
55-
const EVP_MD* export(void) \
56-
{ \
57-
return NULL; \
58-
}
59-
#endif
6042
#endif
6143

6244

@@ -128,43 +110,31 @@ int32_t CryptoNative_EvpDigestFinalEx(EVP_MD_CTX* ctx, uint8_t* md, uint32_t* s)
128110

129111
int32_t CryptoNative_EvpDigestFinalXOF(EVP_MD_CTX* ctx, uint8_t* md, uint32_t len)
130112
{
131-
#if HAVE_OPENSSL_SHA3
132-
if (API_EXISTS(EVP_DigestFinalXOF))
133-
{
134-
ERR_clear_error();
135-
136-
// https://github.com/openssl/openssl/issues/9431
137-
// EVP_DigestFinalXOF has a bug in some arch-optimized code paths where it cannot tolerate a zero length
138-
// digest.
139-
// If the caller asked for no bytes, use a temporary buffer to ask for 1 byte, then throw away the result.
140-
// We don't want to skip calling FinalXOF entirely because we want to make sure the EVP_MD_CTX is in a
141-
// finalized state regardless of the length of the digest.
142-
// We can remove this work around when OpenSSL 3.0 is the minimum OpenSSL requirement.
143-
if (len == 0)
144-
{
145-
uint8_t single[1] = { 0 };
146-
int result = EVP_DigestFinalXOF(ctx, single, 1);
147-
OPENSSL_cleanse(single, sizeof(single));
148-
return result;
149-
}
150-
else if (!md)
151-
{
152-
// Length is not zero but we don't have a buffer to write to.
153-
return -1;
154-
}
155-
else
156-
{
157-
return EVP_DigestFinalXOF(ctx, md, len);
158-
}
159-
}
160-
#else
161-
// Use each parameter to avoid unused parameter warnings.
162-
(void)(ctx);
163-
(void)(md);
164-
(void)(len);
165-
#endif
113+
ERR_clear_error();
166114

167-
return 0;
115+
// https://github.com/openssl/openssl/issues/9431
116+
// EVP_DigestFinalXOF has a bug in some arch-optimized code paths where it cannot tolerate a zero length
117+
// digest.
118+
// If the caller asked for no bytes, use a temporary buffer to ask for 1 byte, then throw away the result.
119+
// We don't want to skip calling FinalXOF entirely because we want to make sure the EVP_MD_CTX is in a
120+
// finalized state regardless of the length of the digest.
121+
// We can remove this work around when OpenSSL 3.0 is the minimum OpenSSL requirement.
122+
if (len == 0)
123+
{
124+
uint8_t single[1] = { 0 };
125+
int result = EVP_DigestFinalXOF(ctx, single, 1);
126+
OPENSSL_cleanse(single, sizeof(single));
127+
return result;
128+
}
129+
else if (!md)
130+
{
131+
// Length is not zero but we don't have a buffer to write to.
132+
return -1;
133+
}
134+
else
135+
{
136+
return EVP_DigestFinalXOF(ctx, md, len);
137+
}
168138
}
169139

170140
EVP_MD_CTX* CryptoNative_EvpMdCtxCopyEx(const EVP_MD_CTX* ctx)
@@ -322,11 +292,11 @@ BUILD_MD_FETCH(CryptoNative_EvpSha1, EVP_sha1, "SHA1", NULL)
322292
BUILD_MD_FETCH(CryptoNative_EvpSha256, EVP_sha256, "SHA256", NULL)
323293
BUILD_MD_FETCH(CryptoNative_EvpSha384, EVP_sha384, "SHA384", NULL)
324294
BUILD_MD_FETCH(CryptoNative_EvpSha512, EVP_sha512, "SHA512", NULL)
325-
BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_256, EVP_sha3_256, "SHA3-256", NULL)
326-
BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_384, EVP_sha3_384, "SHA3-384", NULL)
327-
BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_512, EVP_sha3_512, "SHA3-512", NULL)
328-
BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpShake128, EVP_shake128, "SHAKE-128", NULL)
329-
BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpShake256, EVP_shake256, "SHAKE-256", NULL)
295+
BUILD_MD_FETCH(CryptoNative_EvpSha3_256, EVP_sha3_256, "SHA3-256", NULL)
296+
BUILD_MD_FETCH(CryptoNative_EvpSha3_384, EVP_sha3_384, "SHA3-384", NULL)
297+
BUILD_MD_FETCH(CryptoNative_EvpSha3_512, EVP_sha3_512, "SHA3-512", NULL)
298+
BUILD_MD_FETCH(CryptoNative_EvpShake128, EVP_shake128, "SHAKE-128", NULL)
299+
BUILD_MD_FETCH(CryptoNative_EvpShake256, EVP_shake256, "SHAKE-256", NULL)
330300

331301
int32_t CryptoNative_GetMaxMdSize(void)
332302
{

0 commit comments

Comments
 (0)