From ef69307f061debcd1d51c69f44a6581610782e1e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sun, 19 Mar 2023 15:39:40 -0400 Subject: [PATCH 01/47] Initial SHA3 bringup on Linux --- .../Interop.Evp.DigestAlgs.cs | 4 + .../Interop.EVP.DigestAlgs.cs | 68 +++- .../Cryptography/HashOneShotHelpers.cs | 36 ++ .../src/System/Security/Cryptography/Oids.cs | 11 + .../ECDsa/ECDsaTests.NistValidation.cs | 106 +++++ .../RSA/EncryptDecrypt.cs | 33 +- .../RSA/RSAFactory.cs | 3 + .../TestUtilities/System/PlatformDetection.cs | 23 ++ .../tests/RSACngProvider.cs | 2 + .../tests/RSACryptoServiceProviderProvider.cs | 2 + .../tests/RSAOpenSslProvider.cs | 2 + .../ref/System.Security.Cryptography.cs | 149 +++++++ .../src/System.Security.Cryptography.csproj | 6 + .../src/System/Security/Cryptography/HKDF.cs | 12 + .../Security/Cryptography/HMACCommon.cs | 3 + .../Security/Cryptography/HMACSHA3_256.cs | 378 ++++++++++++++++++ .../Security/Cryptography/HMACSHA3_384.cs | 378 ++++++++++++++++++ .../Security/Cryptography/HMACSHA3_512.cs | 378 ++++++++++++++++++ .../Cryptography/HashAlgorithmName.cs | 24 ++ .../Cryptography/HashAlgorithmNames.cs | 4 + .../HashProviderDispenser.Apple.cs | 15 + .../HashProviderDispenser.Browser.cs | 14 + .../HashProviderDispenser.OpenSsl.cs | 5 + .../HashProviderDispenser.Windows.cs | 17 + .../Cryptography/RSAEncryptionPadding.cs | 31 +- .../Rfc2898DeriveBytes.OneShot.cs | 5 +- .../Cryptography/Rfc2898DeriveBytes.cs | 5 +- .../System/Security/Cryptography/SHA3_256.cs | 346 ++++++++++++++++ .../System/Security/Cryptography/SHA3_384.cs | 325 +++++++++++++++ .../System/Security/Cryptography/SHA3_512.cs | 325 +++++++++++++++ .../ECDsaX509SignatureGenerator.cs | 12 + .../RSAPkcs1X509SignatureGenerator.cs | 12 + .../tests/DefaultRSAProvider.cs | 2 + .../tests/HashAlgorithmNameTests.cs | 3 + .../tests/HmacSha3_256Tests.cs | 213 ++++++++++ .../tests/HmacSha3_384Tests.cs | 221 ++++++++++ .../tests/HmacSha3_512Tests.cs | 227 +++++++++++ .../tests/HmacTests.cs | 8 +- .../tests/IncrementalHashTests.cs | 15 + .../tests/Rfc2898OneShotTests.cs | 103 ++++- .../tests/Rfc2898Tests.cs | 36 ++ .../tests/Sha3_256Tests.cs | 196 +++++++++ .../tests/Sha3_384Tests.cs | 164 ++++++++ .../tests/Sha3_512Tests.cs | 132 ++++++ .../System.Security.Cryptography.Tests.csproj | 6 + .../ECDsaX509SignatureGeneratorTests.cs | 65 ++- .../RSAPkcs1X509SignatureGeneratorTests.cs | 80 ++-- .../RSAPssX509SignatureGeneratorTests.cs | 3 + .../configure.cmake | 5 + .../entrypoints.c | 3 + .../opensslshim.h | 14 + .../pal_crypto_config.h.in | 1 + .../pal_evp.c | 39 ++ .../pal_evp.h | 24 ++ 54 files changed, 4210 insertions(+), 84 deletions(-) create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs create mode 100644 src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs create mode 100644 src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs create mode 100644 src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs create mode 100644 src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs create mode 100644 src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs create mode 100644 src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs index 8ba0658735a297..32bba680d8298d 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs @@ -52,6 +52,10 @@ internal static IntPtr EvpSha512() => nameof(HashAlgorithmName.SHA384) => EvpSha384(), nameof(HashAlgorithmName.SHA512) => EvpSha512(), nameof(HashAlgorithmName.MD5) => EvpMd5(), + + nameof(HashAlgorithmName.SHA3_256) or + nameof(HashAlgorithmName.SHA3_384) or + nameof(HashAlgorithmName.SHA3_512) => throw new PlatformNotSupportedException(), _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)) }; } 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 abaefab1dab6fc..7ebc6fb545438a 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 @@ -14,45 +14,79 @@ internal static partial class Crypto private static volatile IntPtr s_evpSha256; private static volatile IntPtr s_evpSha384; private static volatile IntPtr s_evpSha512; + private static volatile IntPtr s_evpSha3_256 = -1; + private static volatile IntPtr s_evpSha3_384 = -1; + private static volatile IntPtr s_evpSha3_512 = -1; [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpMd5(); - internal static IntPtr EvpMd5() => + private static IntPtr EvpMd5() => s_evpMd5 != IntPtr.Zero ? s_evpMd5 : (s_evpMd5 = CryptoNative_EvpMd5()); [LibraryImport(Libraries.CryptoNative)] - internal static partial IntPtr CryptoNative_EvpSha1(); + private static partial IntPtr CryptoNative_EvpSha1(); - internal static IntPtr EvpSha1() => + private static IntPtr EvpSha1() => s_evpSha1 != IntPtr.Zero ? s_evpSha1 : (s_evpSha1 = CryptoNative_EvpSha1()); [LibraryImport(Libraries.CryptoNative)] - internal static partial IntPtr CryptoNative_EvpSha256(); + private static partial IntPtr CryptoNative_EvpSha256(); - internal static IntPtr EvpSha256() => + private static IntPtr EvpSha256() => s_evpSha256 != IntPtr.Zero ? s_evpSha256 : (s_evpSha256 = CryptoNative_EvpSha256()); [LibraryImport(Libraries.CryptoNative)] - internal static partial IntPtr CryptoNative_EvpSha384(); + private static partial IntPtr CryptoNative_EvpSha384(); - internal static IntPtr EvpSha384() => + private static IntPtr EvpSha384() => s_evpSha384 != IntPtr.Zero ? s_evpSha384 : (s_evpSha384 = CryptoNative_EvpSha384()); [LibraryImport(Libraries.CryptoNative)] - internal static partial IntPtr CryptoNative_EvpSha512(); + private static partial IntPtr CryptoNative_EvpSha512(); - internal static IntPtr EvpSha512() => + private static IntPtr EvpSha512() => s_evpSha512 != IntPtr.Zero ? s_evpSha512 : (s_evpSha512 = CryptoNative_EvpSha512()); - internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) => hashAlgorithmId switch + [LibraryImport(Libraries.CryptoNative)] + private static partial IntPtr CryptoNative_EvpSha3_256(); + + private static IntPtr EvpSha3_256() => + s_evpSha3_256 != -1 ? s_evpSha3_256 : (s_evpSha3_256 = CryptoNative_EvpSha3_256()); + + [LibraryImport(Libraries.CryptoNative)] + private static partial IntPtr CryptoNative_EvpSha3_384(); + + private static IntPtr EvpSha3_384() => + s_evpSha3_384 != -1 ? s_evpSha3_384 : (s_evpSha3_384 = CryptoNative_EvpSha3_384()); + + [LibraryImport(Libraries.CryptoNative)] + private static partial IntPtr CryptoNative_EvpSha3_512(); + + private static IntPtr EvpSha3_512() => + s_evpSha3_512 != -1 ? s_evpSha3_512 : (s_evpSha3_512 = CryptoNative_EvpSha3_512()); + + internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) { - nameof(HashAlgorithmName.SHA1) => EvpSha1(), - nameof(HashAlgorithmName.SHA256) => EvpSha256(), - nameof(HashAlgorithmName.SHA384) => EvpSha384(), - nameof(HashAlgorithmName.SHA512) => EvpSha512(), - nameof(HashAlgorithmName.MD5) => EvpMd5(), - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)) - }; + switch (hashAlgorithmId) + { + case nameof(HashAlgorithmName.SHA1): return EvpSha1(); + case nameof(HashAlgorithmName.SHA256): return EvpSha256(); + case nameof(HashAlgorithmName.SHA384): return EvpSha384(); + case nameof(HashAlgorithmName.SHA512): return EvpSha512(); + case nameof(HashAlgorithmName.SHA3_256): + IntPtr sha3_256 = EvpSha3_256(); + return sha3_256 != 0 ? sha3_256 : throw new PlatformNotSupportedException(); + case nameof(HashAlgorithmName.SHA3_384): + IntPtr sha3_384 = EvpSha3_384(); + return sha3_384 != 0 ? sha3_384 : throw new PlatformNotSupportedException(); + case nameof(HashAlgorithmName.SHA3_512): + IntPtr sha3_512 = EvpSha3_512(); + return sha3_512 != 0 ? sha3_512 : throw new PlatformNotSupportedException(); + case nameof(HashAlgorithmName.MD5): return EvpMd5(); + default: + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); + }; + } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs index debc16c329b1e5..89d60020ff3a9f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs @@ -28,6 +28,18 @@ internal static byte[] HashData(HashAlgorithmName hashAlgorithm, ReadOnlySpan public void RsaCryptRoundtrip_OaepSHA512() => RsaCryptRoundtrip(RSAEncryptionPadding.OaepSHA512, RSAFactory.SupportsSha2Oaep); - private void RsaCryptRoundtrip(RSAEncryptionPadding paddingMode, bool expectSuccess=true) + [Fact] + public void RsaCryptRoundtrip_OaepSHA3_256() => + RsaCryptRoundtrip(RSAEncryptionPadding.OaepSHA3_256, RSAFactory.SupportsSha3); + + [Fact] + public void RsaCryptRoundtrip_OaepSHA3_384() => + RsaCryptRoundtrip(RSAEncryptionPadding.OaepSHA3_384, RSAFactory.SupportsSha3); + + [Fact] + public void RsaCryptRoundtrip_OaepSHA3_512() => + RsaCryptRoundtrip(RSAEncryptionPadding.OaepSHA3_512, RSAFactory.SupportsSha3); + + private void RsaCryptRoundtrip(RSAEncryptionPadding paddingMode, bool expectSuccess = true) { byte[] crypt; byte[] output; @@ -324,9 +336,12 @@ private void RsaCryptRoundtrip(RSAEncryptionPadding paddingMode, bool expectSucc { if (!expectSuccess) { - Assert.ThrowsAny( + Exception ex = Assert.ThrowsAny( () => Encrypt(rsa, TestData.HelloBytes, paddingMode)); + Assert.True(ex is CryptographicException or PlatformNotSupportedException, + "exception is CryptographicException or PlatformNotSupportedException"); + return; } @@ -370,6 +385,13 @@ void RoundtripEmpty(RSAEncryptionPadding paddingMode) RoundtripEmpty(RSAEncryptionPadding.OaepSHA384); RoundtripEmpty(RSAEncryptionPadding.OaepSHA512); } + + if (RSAFactory.SupportsSha3) + { + RoundtripEmpty(RSAEncryptionPadding.OaepSHA3_256); + RoundtripEmpty(RSAEncryptionPadding.OaepSHA3_384); + RoundtripEmpty(RSAEncryptionPadding.OaepSHA3_512); + } } } @@ -715,6 +737,13 @@ public static IEnumerable OaepPaddingModes yield return new object[] { RSAEncryptionPadding.OaepSHA384 }; yield return new object[] { RSAEncryptionPadding.OaepSHA512 }; } + + if (RSAFactory.SupportsSha3) + { + yield return new object[] { RSAEncryptionPadding.OaepSHA3_256 }; + yield return new object[] { RSAEncryptionPadding.OaepSHA3_384 }; + yield return new object[] { RSAEncryptionPadding.OaepSHA3_512 }; + } } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs index 9a4b27348ab4a0..3d2354ea88a3cc 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs @@ -12,6 +12,7 @@ public interface IRSAProvider bool SupportsSha2Oaep { get; } bool SupportsPss { get; } bool SupportsSha1Signatures { get; } + bool SupportsSha3 { get; } } public static partial class RSAFactory @@ -42,5 +43,7 @@ public static RSA Create(RSAParameters rsaParameters) public static bool SupportsPss => s_provider.SupportsPss; public static bool SupportsSha1Signatures => s_provider.SupportsSha1Signatures; + + public static bool SupportsSha3 => s_provider.SupportsSha3; } } diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 6e43ad25bc6b50..8ca81264a2dc66 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -303,6 +303,7 @@ private static bool GetAlpnSupport() private static readonly Lazy s_supportsTls12 = new Lazy(GetTls12Support); private static readonly Lazy s_supportsTls13 = new Lazy(GetTls13Support); private static readonly Lazy s_sendsCAListByDefault = new Lazy(GetSendsCAListByDefault); + private static readonly Lazy s_supportsSha3 = new Lazy(GetSupportsSha3); public static bool SupportsTls10 => s_supportsTls10.Value; public static bool SupportsTls11 => s_supportsTls11.Value; @@ -310,6 +311,8 @@ private static bool GetAlpnSupport() public static bool SupportsTls13 => s_supportsTls13.Value; public static bool SendsCAListByDefault => s_sendsCAListByDefault.Value; public static bool SupportsSendingCustomCANamesInTls => UsesAppleCrypto || IsOpenSslSupported || (PlatformDetection.IsWindows8xOrLater && SendsCAListByDefault); + public static bool SupportsSha3 => s_supportsSha3.Value; + public static bool DoesNotSupportSha3 => !s_supportsSha3.Value; private static readonly Lazy s_largeArrayIsNotSupported = new Lazy(IsLargeArrayNotSupported); @@ -645,5 +648,25 @@ private static bool AssemblyConfigurationEquals(string configuration) return assemblyConfigurationAttribute != null && string.Equals(assemblyConfigurationAttribute.Configuration, configuration, StringComparison.InvariantCulture); } + + private static bool GetSupportsSha3() + { + if (IsOpenSslSupported) + { + if (OpenSslVersion.Major >= 3) + { + return true; + } + + return OpenSslVersion.Major == 1 && OpenSslVersion.Minor >= 1 && OpenSslVersion.Build >= 1; + } + + if (IsWindowsVersionOrLater(11, 0, 0)) // TODO: what is the right version here? + { + return true; + } + + return false; + } } } diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/RSACngProvider.cs b/src/libraries/System.Security.Cryptography.Cng/tests/RSACngProvider.cs index 963bd925d800c7..d41df34b61404b 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/RSACngProvider.cs +++ b/src/libraries/System.Security.Cryptography.Cng/tests/RSACngProvider.cs @@ -36,6 +36,8 @@ public bool Supports384PrivateKey public bool SupportsPss => true; public bool SupportsSha1Signatures => true; + + public bool SupportsSha3 { get; } = SHA3_256.IsSupported; // If SHA3_256 is supported, assume 384 and 512 are, too. } public partial class RSAFactory diff --git a/src/libraries/System.Security.Cryptography.Csp/tests/RSACryptoServiceProviderProvider.cs b/src/libraries/System.Security.Cryptography.Csp/tests/RSACryptoServiceProviderProvider.cs index 7f4f3eb5b7d462..7cd358cd5d1213 100644 --- a/src/libraries/System.Security.Cryptography.Csp/tests/RSACryptoServiceProviderProvider.cs +++ b/src/libraries/System.Security.Cryptography.Csp/tests/RSACryptoServiceProviderProvider.cs @@ -23,6 +23,8 @@ public class RSACryptoServiceProviderProvider : IRSAProvider public bool SupportsPss => false; public bool SupportsSha1Signatures => _supportsSha1Signatures ??= SignatureSupport.CanProduceSha1Signature(Create()); + + public bool SupportsSha3 => false; } public partial class RSAFactory diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs index deeecbe7cb18bd..0adcda4bfad5ec 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs @@ -22,6 +22,8 @@ public class RSAOpenSslProvider : IRSAProvider public bool SupportsPss => true; public bool SupportsSha1Signatures => _supportsSha1Signatures ??= SignatureSupport.CanProduceSha1Signature(Create()); + + public bool SupportsSha3 => SHA3_256.IsSupported; // If SHA3_256 is supported, assume 384 and 512 are, too. } public partial class RSAFactory diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index 8b9691bf9e6dd4..ff2ea254ac07d8 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -1314,6 +1314,9 @@ protected virtual void HashCore(System.ReadOnlySpan source) { } public static System.Security.Cryptography.HashAlgorithmName SHA1 { get { throw null; } } public static System.Security.Cryptography.HashAlgorithmName SHA256 { get { throw null; } } public static System.Security.Cryptography.HashAlgorithmName SHA384 { get { throw null; } } + public static System.Security.Cryptography.HashAlgorithmName SHA3_256 { get { throw null; } } + public static System.Security.Cryptography.HashAlgorithmName SHA3_384 { get { throw null; } } + public static System.Security.Cryptography.HashAlgorithmName SHA3_512 { get { throw null; } } public static System.Security.Cryptography.HashAlgorithmName SHA512 { get { throw null; } } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(System.Security.Cryptography.HashAlgorithmName other) { throw null; } @@ -1464,6 +1467,81 @@ public override void Initialize() { } public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } } + public partial class HMACSHA3_256 : System.Security.Cryptography.HMAC + { + public const int HashSizeInBits = 256; + public const int HashSizeInBytes = 32; + public HMACSHA3_256() { } + public HMACSHA3_256(byte[] key) { } + public static bool IsSupported { get { throw null; } } + public override byte[] Key { get { throw null; } set { } } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] rgb, int ib, int cb) { } + protected override void HashCore(System.ReadOnlySpan source) { } + public static byte[] HashData(byte[] key, byte[] source) { throw null; } + public static byte[] HashData(byte[] key, System.IO.Stream source) { throw null; } + public static byte[] HashData(System.ReadOnlySpan key, System.IO.Stream source) { throw null; } + public static int HashData(System.ReadOnlySpan key, System.IO.Stream source, System.Span destination) { throw null; } + public static byte[] HashData(System.ReadOnlySpan key, System.ReadOnlySpan source) { throw null; } + public static int HashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(byte[] key, System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.ReadOnlyMemory key, System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.ReadOnlyMemory key, System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } + public partial class HMACSHA3_384 : System.Security.Cryptography.HMAC + { + public const int HashSizeInBits = 384; + public const int HashSizeInBytes = 48; + public HMACSHA3_384() { } + public HMACSHA3_384(byte[] key) { } + public static bool IsSupported { get { throw null; } } + public override byte[] Key { get { throw null; } set { } } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] rgb, int ib, int cb) { } + protected override void HashCore(System.ReadOnlySpan source) { } + public static byte[] HashData(byte[] key, byte[] source) { throw null; } + public static byte[] HashData(byte[] key, System.IO.Stream source) { throw null; } + public static byte[] HashData(System.ReadOnlySpan key, System.IO.Stream source) { throw null; } + public static int HashData(System.ReadOnlySpan key, System.IO.Stream source, System.Span destination) { throw null; } + public static byte[] HashData(System.ReadOnlySpan key, System.ReadOnlySpan source) { throw null; } + public static int HashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(byte[] key, System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.ReadOnlyMemory key, System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.ReadOnlyMemory key, System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } + public partial class HMACSHA3_512 : System.Security.Cryptography.HMAC + { + public const int HashSizeInBits = 512; + public const int HashSizeInBytes = 64; + public HMACSHA3_512() { } + public HMACSHA3_512(byte[] key) { } + public static bool IsSupported { get { throw null; } } + public override byte[] Key { get { throw null; } set { } } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] rgb, int ib, int cb) { } + protected override void HashCore(System.ReadOnlySpan source) { } + public static byte[] HashData(byte[] key, byte[] source) { throw null; } + public static byte[] HashData(byte[] key, System.IO.Stream source) { throw null; } + public static byte[] HashData(System.ReadOnlySpan key, System.IO.Stream source) { throw null; } + public static int HashData(System.ReadOnlySpan key, System.IO.Stream source, System.Span destination) { throw null; } + public static byte[] HashData(System.ReadOnlySpan key, System.ReadOnlySpan source) { throw null; } + public static int HashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(byte[] key, System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.ReadOnlyMemory key, System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.ReadOnlyMemory key, System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } public partial class HMACSHA512 : System.Security.Cryptography.HMAC { public const int HashSizeInBits = 512; @@ -1999,6 +2077,9 @@ internal RSAEncryptionPadding() { } public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA1 { get { throw null; } } public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA256 { get { throw null; } } public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA384 { get { throw null; } } + public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA3_256 { get { throw null; } } + public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA3_384 { get { throw null; } } + public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA3_512 { get { throw null; } } public static System.Security.Cryptography.RSAEncryptionPadding OaepSHA512 { get { throw null; } } public static System.Security.Cryptography.RSAEncryptionPadding Pkcs1 { get { throw null; } } public static System.Security.Cryptography.RSAEncryptionPadding CreateOaep(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } @@ -2285,6 +2366,74 @@ protected sealed override void HashCore(System.ReadOnlySpan source) { } public sealed override void Initialize() { } protected sealed override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } } + public abstract partial class SHA3_256 : System.Security.Cryptography.HashAlgorithm + { + public const int HashSizeInBits = 256; + public const int HashSizeInBytes = 32; + protected SHA3_256() { } + [System.Runtime.Versioning.SupportedOSPlatformGuardAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformGuardAttribute("windows")] + public static bool IsSupported { get { throw null; } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static new System.Security.Cryptography.SHA3_256 Create() { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static byte[] HashData(byte[] source) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static byte[] HashData(System.IO.Stream source) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static byte[] HashData(System.ReadOnlySpan source) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + } + public abstract partial class SHA3_384 : System.Security.Cryptography.HashAlgorithm + { + public const int HashSizeInBits = 384; + public const int HashSizeInBytes = 48; + protected SHA3_384() { } + public static bool IsSupported { get { throw null; } } + public static new System.Security.Cryptography.SHA3_384 Create() { throw null; } + public static byte[] HashData(byte[] source) { throw null; } + public static byte[] HashData(System.IO.Stream source) { throw null; } + public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } + public static byte[] HashData(System.ReadOnlySpan source) { throw null; } + public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + } + public abstract partial class SHA3_512 : System.Security.Cryptography.HashAlgorithm + { + public const int HashSizeInBits = 512; + public const int HashSizeInBytes = 64; + protected SHA3_512() { } + public static bool IsSupported { get { throw null; } } + public static new System.Security.Cryptography.SHA3_512 Create() { throw null; } + public static byte[] HashData(byte[] source) { throw null; } + public static byte[] HashData(System.IO.Stream source) { throw null; } + public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } + public static byte[] HashData(System.ReadOnlySpan source) { throw null; } + public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + } public abstract partial class SHA512 : System.Security.Cryptography.HashAlgorithm { public const int HashSizeInBits = 512; diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj index 197dba5072bf5d..e572f791bf1b67 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -352,6 +352,9 @@ + + + @@ -412,6 +415,9 @@ + + + diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs index abb85e9a972e8c..1de6138cc1ec92 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs @@ -286,6 +286,18 @@ private static int HashLength(HashAlgorithmName hashAlgorithmName) { return HMACSHA512.HashSizeInBytes; } + else if (hashAlgorithmName == HashAlgorithmName.SHA3_256) + { + return HMACSHA3_256.HashSizeInBytes; + } + else if (hashAlgorithmName == HashAlgorithmName.SHA3_384) + { + return HMACSHA3_384.HashSizeInBytes; + } + else if (hashAlgorithmName == HashAlgorithmName.SHA3_512) + { + return HMACSHA3_512.HashSizeInBytes; + } else if (hashAlgorithmName == HashAlgorithmName.MD5) { return HMACMD5.HashSizeInBytes; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs index fec3c37cd3c620..d0d6da13ba1643 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs @@ -62,6 +62,9 @@ public void ChangeKey(byte[] key) HashAlgorithmNames.SHA256 => SHA256.HashData(key), HashAlgorithmNames.SHA384 => SHA384.HashData(key), HashAlgorithmNames.SHA512 => SHA512.HashData(key), + HashAlgorithmNames.SHA3_256 when SHA3_256.IsSupported => SHA3_256.HashData(key), + HashAlgorithmNames.SHA3_384 when SHA3_384.IsSupported => SHA3_384.HashData(key), + HashAlgorithmNames.SHA3_512 when SHA3_512.IsSupported => SHA3_512.HashData(key), HashAlgorithmNames.SHA1 => SHA1.HashData(key), HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(key), _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, _hashAlgorithmId)), diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs new file mode 100644 index 00000000000000..284949d4ba9e16 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.Diagnostics; +using System.IO; +using System.Runtime.Versioning; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Security.Cryptography +{ + /// + /// Computes a Hash-based Message Authentication Code (HMAC) by using the SHA3-256 hash function. + /// + public class HMACSHA3_256 : HMAC + { + private HMACCommon _hMacCommon; + private const int BlockSize = 136; // FIPS 202 Table 3. + + /// + /// The hash size produced by the HMAC SHA3-256 algorithm, in bits. + /// + public const int HashSizeInBits = 256; + + /// + /// The hash size produced by the HMAC SHA3-256 algorithm, in bytes. + /// + public const int HashSizeInBytes = HashSizeInBits / 8; + + /// + /// Initializes a new instance of the class with a randomly generated key. + /// + /// + /// + /// is a type of keyed hash algorithm that is constructed from the SHA3-256 hash + /// function and used as a Hash-based Message Authentication Code (HMAC). The HMAC process mixes a secret key + /// with the message data, hashes the result with the hash function, mixes that hash value with the secret key + /// again, and then applies the hash function a second time. The output hash is 256 bits in length. + /// + /// + /// This constructor uses a 136-byte, randomly generated key. + /// + /// + public HMACSHA3_256() + : this(RandomNumberGenerator.GetBytes(BlockSize)) + { + } + + /// + /// Initializes a new instance of the class with the specified key data. + /// + /// + /// The secret key for . The key can be any length. + /// + /// + /// is . + /// + public HMACSHA3_256(byte[] key) + { + ArgumentNullException.ThrowIfNull(key); + + this.HashName = HashAlgorithmNames.SHA3_256; + _hMacCommon = new HMACCommon(HashAlgorithmNames.SHA3_256, key, BlockSize); + base.Key = _hMacCommon.ActualKey!; + BlockSizeValue = BlockSize; + HashSizeValue = HashSizeInBits; + Debug.Assert(HashSizeValue == _hMacCommon.HashSizeInBits); + } + + /// + /// Gets a value that indicates whether the algorithm is supported on the current platform. + /// + /// + /// if the algorithm is supported; otherwise, . + /// + public static bool IsSupported => SHA3_256.IsSupported; + + /// + public override byte[] Key + { + get + { + return base.Key; + } + set + { + ArgumentNullException.ThrowIfNull(value); + _hMacCommon.ChangeKey(value); + base.Key = _hMacCommon.ActualKey!; + } + } + + /// + protected override void HashCore(byte[] rgb, int ib, int cb) => + _hMacCommon.AppendHashData(rgb, ib, cb); + + /// + protected override void HashCore(ReadOnlySpan source) => + _hMacCommon.AppendHashData(source); + + /// + protected override byte[] HashFinal() => + _hMacCommon.FinalizeHashAndReset(); + + /// + protected override bool TryHashFinal(Span destination, out int bytesWritten) => + _hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten); + + /// + public override void Initialize() => _hMacCommon.Reset(); + + /// + /// Computes the HMAC of data using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The HMAC of the data. + /// + /// or is . + /// + public static byte[] HashData(byte[] key, byte[] source) + { + ArgumentNullException.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(source); + + return HashData(new ReadOnlySpan(key), new ReadOnlySpan(source)); + } + + /// + /// Computes the HMAC of data using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The HMAC of the data. + public static byte[] HashData(ReadOnlySpan key, ReadOnlySpan source) + { + byte[] buffer = new byte[HashSizeInBytes]; + + int written = HashData(key, source, buffer.AsSpan()); + Debug.Assert(written == buffer.Length); + + return buffer; + } + + /// + /// Computes the HMAC of data using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The buffer to receive the HMAC value. + /// The total number of bytes written to . + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-256 algorithm always produces a 256-bit HMAC, or 32 bytes. + /// + public static int HashData(ReadOnlySpan key, ReadOnlySpan source, Span destination) + { + if (!TryHashData(key, source, destination, out int bytesWritten)) + { + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + } + + return bytesWritten; + } + + /// + /// Attempts to compute the HMAC of data using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The buffer to receive the HMAC value. + /// + /// When this method returns, the total number of bytes written into . + /// + /// + /// if is too small to hold the + /// calculated hash, otherwise. + /// + public static bool TryHashData(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int bytesWritten) + { + if (destination.Length < HashSizeInBytes) + { + bytesWritten = 0; + return false; + } + + bytesWritten = HashProviderDispenser.OneShotHashProvider.MacData(HashAlgorithmNames.SHA3_256, key, source, destination); + Debug.Assert(bytesWritten == HashSizeInBytes); + + return true; + } + + /// + /// Computes the HMAC of a stream using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The buffer to receive the HMAC value. + /// The total number of bytes written to . + /// + /// is . + /// + /// + /// + /// The buffer in is too small to hold the calculated HMAC + /// size. The SHA3-256 algorithm always produces a 256-bit HMAC, or 32 bytes. + /// + /// -or- + /// + /// does not support reading. + /// + /// + public static int HashData(ReadOnlySpan key, Stream source, Span destination) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_256, key, source, destination); + } + + /// + /// Computes the HMAC of a stream using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The HMAC of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + public static byte[] HashData(ReadOnlySpan key, Stream source) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_256, HashSizeInBytes, key, source); + } + + /// + /// Computes the HMAC of a stream using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The HMAC of the data. + /// + /// or is . + /// + /// + /// does not support reading. + /// + public static byte[] HashData(byte[] key, Stream source) + { + ArgumentNullException.ThrowIfNull(key); + + return HashData(new ReadOnlySpan(key), source); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The HMAC of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + public static ValueTask HashDataAsync(ReadOnlyMemory key, Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStreamAsync(HashAlgorithmNames.SHA3_256, key.Span, source, cancellationToken); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The HMAC of the data. + /// + /// or is . + /// + /// + /// does not support reading. + /// + public static ValueTask HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(key); + + return HashDataAsync(new ReadOnlyMemory(key), source, cancellationToken); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-256 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The buffer to receive the HMAC value. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The total number of bytes written to . + /// + /// is . + /// + /// + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-256 algorithm always produces a 256-bit hash, or 32 bytes. + /// + /// -or- + /// + /// does not support reading. + /// + /// + public static ValueTask HashDataAsync( + ReadOnlyMemory key, + Stream source, + Memory destination, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStreamAsync( + HashAlgorithmNames.SHA3_256, + key.Span, + source, + destination, + cancellationToken); + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + HMACCommon hMacCommon = _hMacCommon; + if (hMacCommon != null) + { + _hMacCommon = null!; + hMacCommon.Dispose(disposing); + } + } + base.Dispose(disposing); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs new file mode 100644 index 00000000000000..19979b8c7bf235 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.Diagnostics; +using System.IO; +using System.Runtime.Versioning; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Security.Cryptography +{ + /// + /// Computes a Hash-based Message Authentication Code (HMAC) by using the SHA3-384 hash function. + /// + public class HMACSHA3_384 : HMAC + { + private HMACCommon _hMacCommon; + private const int BlockSize = 104; // FIPS 202 Table 3. + + /// + /// The hash size produced by the HMAC SHA3-384 algorithm, in bits. + /// + public const int HashSizeInBits = 384; + + /// + /// The hash size produced by the HMAC SHA3-384 algorithm, in bytes. + /// + public const int HashSizeInBytes = HashSizeInBits / 8; + + /// + /// Initializes a new instance of the class with a randomly generated key. + /// + /// + /// + /// is a type of keyed hash algorithm that is constructed from the SHA3-384 hash + /// function and used as a Hash-based Message Authentication Code (HMAC). The HMAC process mixes a secret key + /// with the message data, hashes the result with the hash function, mixes that hash value with the secret key + /// again, and then applies the hash function a second time. The output hash is 384 bits in length. + /// + /// + /// This constructor uses a 104-byte, randomly generated key. + /// + /// + public HMACSHA3_384() + : this(RandomNumberGenerator.GetBytes(BlockSize)) + { + } + + /// + /// Initializes a new instance of the class with the specified key data. + /// + /// + /// The secret key for . The key can be any length. + /// + /// + /// is . + /// + public HMACSHA3_384(byte[] key) + { + ArgumentNullException.ThrowIfNull(key); + + this.HashName = HashAlgorithmNames.SHA3_384; + _hMacCommon = new HMACCommon(HashAlgorithmNames.SHA3_384, key, BlockSize); + base.Key = _hMacCommon.ActualKey!; + BlockSizeValue = BlockSize; + HashSizeValue = HashSizeInBits; + Debug.Assert(HashSizeValue == _hMacCommon.HashSizeInBits); + } + + /// + /// Gets a value that indicates whether the algorithm is supported on the current platform. + /// + /// + /// if the algorithm is supported; otherwise, . + /// + public static bool IsSupported => SHA3_384.IsSupported; + + /// + public override byte[] Key + { + get + { + return base.Key; + } + set + { + ArgumentNullException.ThrowIfNull(value); + _hMacCommon.ChangeKey(value); + base.Key = _hMacCommon.ActualKey!; + } + } + + /// + protected override void HashCore(byte[] rgb, int ib, int cb) => + _hMacCommon.AppendHashData(rgb, ib, cb); + + /// + protected override void HashCore(ReadOnlySpan source) => + _hMacCommon.AppendHashData(source); + + /// + protected override byte[] HashFinal() => + _hMacCommon.FinalizeHashAndReset(); + + /// + protected override bool TryHashFinal(Span destination, out int bytesWritten) => + _hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten); + + /// + public override void Initialize() => _hMacCommon.Reset(); + + /// + /// Computes the HMAC of data using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The HMAC of the data. + /// + /// or is . + /// + public static byte[] HashData(byte[] key, byte[] source) + { + ArgumentNullException.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(source); + + return HashData(new ReadOnlySpan(key), new ReadOnlySpan(source)); + } + + /// + /// Computes the HMAC of data using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The HMAC of the data. + public static byte[] HashData(ReadOnlySpan key, ReadOnlySpan source) + { + byte[] buffer = new byte[HashSizeInBytes]; + + int written = HashData(key, source, buffer.AsSpan()); + Debug.Assert(written == buffer.Length); + + return buffer; + } + + /// + /// Computes the HMAC of data using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The buffer to receive the HMAC value. + /// The total number of bytes written to . + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-384 algorithm always produces a 384-bit HMAC, or 48 bytes. + /// + public static int HashData(ReadOnlySpan key, ReadOnlySpan source, Span destination) + { + if (!TryHashData(key, source, destination, out int bytesWritten)) + { + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + } + + return bytesWritten; + } + + /// + /// Attempts to compute the HMAC of data using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The buffer to receive the HMAC value. + /// + /// When this method returns, the total number of bytes written into . + /// + /// + /// if is too small to hold the + /// calculated hash, otherwise. + /// + public static bool TryHashData(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int bytesWritten) + { + if (destination.Length < HashSizeInBytes) + { + bytesWritten = 0; + return false; + } + + bytesWritten = HashProviderDispenser.OneShotHashProvider.MacData(HashAlgorithmNames.SHA3_384, key, source, destination); + Debug.Assert(bytesWritten == HashSizeInBytes); + + return true; + } + + /// + /// Computes the HMAC of a stream using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The buffer to receive the HMAC value. + /// The total number of bytes written to . + /// + /// is . + /// + /// + /// + /// The buffer in is too small to hold the calculated HMAC + /// size. The SHA3-384 algorithm always produces a 384-bit HMAC, or 48 bytes. + /// + /// -or- + /// + /// does not support reading. + /// + /// + public static int HashData(ReadOnlySpan key, Stream source, Span destination) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_384, key, source, destination); + } + + /// + /// Computes the HMAC of a stream using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The HMAC of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + public static byte[] HashData(ReadOnlySpan key, Stream source) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_384, HashSizeInBytes, key, source); + } + + /// + /// Computes the HMAC of a stream using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The HMAC of the data. + /// + /// or is . + /// + /// + /// does not support reading. + /// + public static byte[] HashData(byte[] key, Stream source) + { + ArgumentNullException.ThrowIfNull(key); + + return HashData(new ReadOnlySpan(key), source); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The HMAC of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + public static ValueTask HashDataAsync(ReadOnlyMemory key, Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStreamAsync(HashAlgorithmNames.SHA3_384, key.Span, source, cancellationToken); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The HMAC of the data. + /// + /// or is . + /// + /// + /// does not support reading. + /// + public static ValueTask HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(key); + + return HashDataAsync(new ReadOnlyMemory(key), source, cancellationToken); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-384 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The buffer to receive the HMAC value. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The total number of bytes written to . + /// + /// is . + /// + /// + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-384 algorithm always produces a 384-bit hash, or 48 bytes. + /// + /// -or- + /// + /// does not support reading. + /// + /// + public static ValueTask HashDataAsync( + ReadOnlyMemory key, + Stream source, + Memory destination, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStreamAsync( + HashAlgorithmNames.SHA3_384, + key.Span, + source, + destination, + cancellationToken); + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + HMACCommon hMacCommon = _hMacCommon; + if (hMacCommon != null) + { + _hMacCommon = null!; + hMacCommon.Dispose(disposing); + } + } + base.Dispose(disposing); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs new file mode 100644 index 00000000000000..48e7c3635323de --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.Diagnostics; +using System.IO; +using System.Runtime.Versioning; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Security.Cryptography +{ + /// + /// Computes a Hash-based Message Authentication Code (HMAC) by using the SHA3-512 hash function. + /// + public class HMACSHA3_512 : HMAC + { + private HMACCommon _hMacCommon; + private const int BlockSize = 72; // FIPS 202 Table 3. + + /// + /// The hash size produced by the HMAC SHA3-512 algorithm, in bits. + /// + public const int HashSizeInBits = 512; + + /// + /// The hash size produced by the HMAC SHA3-512 algorithm, in bytes. + /// + public const int HashSizeInBytes = HashSizeInBits / 8; + + /// + /// Initializes a new instance of the class with a randomly generated key. + /// + /// + /// + /// is a type of keyed hash algorithm that is constructed from the SHA3-512 hash + /// function and used as a Hash-based Message Authentication Code (HMAC). The HMAC process mixes a secret key + /// with the message data, hashes the result with the hash function, mixes that hash value with the secret key + /// again, and then applies the hash function a second time. The output hash is 512 bits in length. + /// + /// + /// This constructor uses a 72-byte, randomly generated key. + /// + /// + public HMACSHA3_512() + : this(RandomNumberGenerator.GetBytes(BlockSize)) + { + } + + /// + /// Initializes a new instance of the class with the specified key data. + /// + /// + /// The secret key for . The key can be any length. + /// + /// + /// is . + /// + public HMACSHA3_512(byte[] key) + { + ArgumentNullException.ThrowIfNull(key); + + this.HashName = HashAlgorithmNames.SHA3_512; + _hMacCommon = new HMACCommon(HashAlgorithmNames.SHA3_512, key, BlockSize); + base.Key = _hMacCommon.ActualKey!; + BlockSizeValue = BlockSize; + HashSizeValue = HashSizeInBits; + Debug.Assert(HashSizeValue == _hMacCommon.HashSizeInBits); + } + + /// + /// Gets a value that indicates whether the algorithm is supported on the current platform. + /// + /// + /// if the algorithm is supported; otherwise, . + /// + public static bool IsSupported => SHA3_512.IsSupported; + + /// + public override byte[] Key + { + get + { + return base.Key; + } + set + { + ArgumentNullException.ThrowIfNull(value); + _hMacCommon.ChangeKey(value); + base.Key = _hMacCommon.ActualKey!; + } + } + + /// + protected override void HashCore(byte[] rgb, int ib, int cb) => + _hMacCommon.AppendHashData(rgb, ib, cb); + + /// + protected override void HashCore(ReadOnlySpan source) => + _hMacCommon.AppendHashData(source); + + /// + protected override byte[] HashFinal() => + _hMacCommon.FinalizeHashAndReset(); + + /// + protected override bool TryHashFinal(Span destination, out int bytesWritten) => + _hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten); + + /// + public override void Initialize() => _hMacCommon.Reset(); + + /// + /// Computes the HMAC of data using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The HMAC of the data. + /// + /// or is . + /// + public static byte[] HashData(byte[] key, byte[] source) + { + ArgumentNullException.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(source); + + return HashData(new ReadOnlySpan(key), new ReadOnlySpan(source)); + } + + /// + /// Computes the HMAC of data using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The HMAC of the data. + public static byte[] HashData(ReadOnlySpan key, ReadOnlySpan source) + { + byte[] buffer = new byte[HashSizeInBytes]; + + int written = HashData(key, source, buffer.AsSpan()); + Debug.Assert(written == buffer.Length); + + return buffer; + } + + /// + /// Computes the HMAC of data using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The buffer to receive the HMAC value. + /// The total number of bytes written to . + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-512 algorithm always produces a 512-bit HMAC, or 64 bytes. + /// + public static int HashData(ReadOnlySpan key, ReadOnlySpan source, Span destination) + { + if (!TryHashData(key, source, destination, out int bytesWritten)) + { + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + } + + return bytesWritten; + } + + /// + /// Attempts to compute the HMAC of data using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The data to HMAC. + /// The buffer to receive the HMAC value. + /// + /// When this method returns, the total number of bytes written into . + /// + /// + /// if is too small to hold the + /// calculated hash, otherwise. + /// + public static bool TryHashData(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int bytesWritten) + { + if (destination.Length < HashSizeInBytes) + { + bytesWritten = 0; + return false; + } + + bytesWritten = HashProviderDispenser.OneShotHashProvider.MacData(HashAlgorithmNames.SHA3_512, key, source, destination); + Debug.Assert(bytesWritten == HashSizeInBytes); + + return true; + } + + /// + /// Computes the HMAC of a stream using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The buffer to receive the HMAC value. + /// The total number of bytes written to . + /// + /// is . + /// + /// + /// + /// The buffer in is too small to hold the calculated HMAC + /// size. The SHA3-512 algorithm always produces a 512-bit HMAC, or 64 bytes. + /// + /// -or- + /// + /// does not support reading. + /// + /// + public static int HashData(ReadOnlySpan key, Stream source, Span destination) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_512, key, source, destination); + } + + /// + /// Computes the HMAC of a stream using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The HMAC of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + public static byte[] HashData(ReadOnlySpan key, Stream source) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_512, HashSizeInBytes, key, source); + } + + /// + /// Computes the HMAC of a stream using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The HMAC of the data. + /// + /// or is . + /// + /// + /// does not support reading. + /// + public static byte[] HashData(byte[] key, Stream source) + { + ArgumentNullException.ThrowIfNull(key); + + return HashData(new ReadOnlySpan(key), source); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The HMAC of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + public static ValueTask HashDataAsync(ReadOnlyMemory key, Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStreamAsync(HashAlgorithmNames.SHA3_512, key.Span, source, cancellationToken); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The HMAC of the data. + /// + /// or is . + /// + /// + /// does not support reading. + /// + public static ValueTask HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(key); + + return HashDataAsync(new ReadOnlyMemory(key), source, cancellationToken); + } + + /// + /// Asynchronously computes the HMAC of a stream using the SHA3-512 algorithm. + /// + /// The HMAC key. + /// The stream to HMAC. + /// The buffer to receive the HMAC value. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The total number of bytes written to . + /// + /// is . + /// + /// + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-512 algorithm always produces a 512-bit hash, or 64 bytes. + /// + /// -or- + /// + /// does not support reading. + /// + /// + public static ValueTask HashDataAsync( + ReadOnlyMemory key, + Stream source, + Memory destination, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + return LiteHashProvider.HmacStreamAsync( + HashAlgorithmNames.SHA3_512, + key.Span, + source, + destination, + cancellationToken); + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + HMACCommon hMacCommon = _hMacCommon; + if (hMacCommon != null) + { + _hMacCommon = null!; + hMacCommon.Dispose(disposing); + } + } + base.Dispose(disposing); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs index f7df0f24280251..22fa837a17e59b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs @@ -52,6 +52,21 @@ namespace System.Security.Cryptography /// public static HashAlgorithmName SHA512 { get { return new HashAlgorithmName("SHA512"); } } + /// + /// Gets a representing "SHA3-256" + /// + public static HashAlgorithmName SHA3_256 => new HashAlgorithmName("SHA3_256"); + + /// + /// Gets a representing "SHA3-384" + /// + public static HashAlgorithmName SHA3_384 => new HashAlgorithmName("SHA3_384"); + + /// + /// Gets a representing "SHA3-512" + /// + public static HashAlgorithmName SHA3_512 => new HashAlgorithmName("SHA3_512"); + private readonly string? _name; /// @@ -142,6 +157,15 @@ public static bool TryFromOid(string oidValue, out HashAlgorithmName value) case Oids.Sha512: value = SHA512; return true; + case Oids.Sha3_256: + value = SHA3_256; + return true; + case Oids.Sha3_384: + value = SHA3_384; + return true; + case Oids.Sha3_512: + value = SHA3_512; + return true; default: value = default; return false; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index 1b8f225ce4b7a1..6f7cd248807171 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -14,6 +14,10 @@ internal static partial class HashAlgorithmNames public const string SHA384 = "SHA384"; public const string SHA512 = "SHA512"; + public const string SHA3_256 = "SHA3_256"; + public const string SHA3_384 = "SHA3_384"; + public const string SHA3_512 = "SHA3_512"; + /// /// Map HashAlgorithm type to string; .NET Framework uses CryptoConfig functionality. /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs index 296cafef903597..c4082d78713f39 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs @@ -21,6 +21,21 @@ public static HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlySpa return new AppleHmacProvider(hashAlgorithmId, key); } + internal static bool HashSupported(string hashAlgorithmId) + { + switch (hashAlgorithmId) + { + case HashAlgorithmNames.MD5: + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + case HashAlgorithmNames.SHA384: + case HashAlgorithmNames.SHA512: + return true; + default: + return false; + } + } + internal static class OneShotHashProvider { public static unsafe int MacData( diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs index 8bae776c7ac933..7e97eb1b30bd59 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs @@ -5,6 +5,20 @@ namespace System.Security.Cryptography { internal static partial class HashProviderDispenser { + internal static bool HashSupported(string hashAlgorithmId) + { + switch (hashAlgorithmId) + { + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + case HashAlgorithmNames.SHA384: + case HashAlgorithmNames.SHA512: + return true; + default: + return false; + } + } + public static HashProvider CreateHashProvider(string hashAlgorithmId) { switch (hashAlgorithmId) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs index 32cdc7dd93b1cc..52778f04b5094d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs @@ -22,6 +22,11 @@ internal static HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlyS return new HmacHashProvider(hashAlgorithmId, key); } + internal static bool HashSupported(string hashAlgorithmId) + { + return Interop.Crypto.HashAlgorithmToEvp(hashAlgorithmId) != IntPtr.Zero; + } + internal static class OneShotHashProvider { public static int MacData( diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs index e195a153393924..dcbeb7763f7ca3 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs @@ -27,6 +27,23 @@ public static HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlySpa return new HashProviderCng(hashAlgorithmId, key, isHmac: true); } + internal static bool HashSupported(string hashAlgorithmId) + { + + //TODO: This needs to ask CNG. + switch (hashAlgorithmId) + { + case HashAlgorithmNames.MD5: + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + case HashAlgorithmNames.SHA384: + case HashAlgorithmNames.SHA512: + return true; + default: + return false; + } + } + public static class OneShotHashProvider { public static unsafe int MacData( diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAEncryptionPadding.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAEncryptionPadding.cs index c31f665ad40008..9a2feee6dac982 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAEncryptionPadding.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAEncryptionPadding.cs @@ -10,36 +10,45 @@ namespace System.Security.Cryptography /// public sealed class RSAEncryptionPadding : IEquatable { - private static readonly RSAEncryptionPadding s_pkcs1 = new RSAEncryptionPadding(RSAEncryptionPaddingMode.Pkcs1, default(HashAlgorithmName)); - private static readonly RSAEncryptionPadding s_oaepSHA1 = CreateOaep(HashAlgorithmName.SHA1); - private static readonly RSAEncryptionPadding s_oaepSHA256 = CreateOaep(HashAlgorithmName.SHA256); - private static readonly RSAEncryptionPadding s_oaepSHA384 = CreateOaep(HashAlgorithmName.SHA384); - private static readonly RSAEncryptionPadding s_oaepSHA512 = CreateOaep(HashAlgorithmName.SHA512); - /// /// mode. /// - public static RSAEncryptionPadding Pkcs1 { get { return s_pkcs1; } } + public static RSAEncryptionPadding Pkcs1 { get; } = new RSAEncryptionPadding(RSAEncryptionPaddingMode.Pkcs1, default); /// /// mode with SHA1 hash algorithm. /// - public static RSAEncryptionPadding OaepSHA1 { get { return s_oaepSHA1; } } + public static RSAEncryptionPadding OaepSHA1 { get; } = CreateOaep(HashAlgorithmName.SHA1); /// /// mode with SHA256 hash algorithm. /// - public static RSAEncryptionPadding OaepSHA256 { get { return s_oaepSHA256; } } + public static RSAEncryptionPadding OaepSHA256 { get; } = CreateOaep(HashAlgorithmName.SHA256); /// /// mode with SHA384 hash algorithm. /// - public static RSAEncryptionPadding OaepSHA384 { get { return s_oaepSHA384; } } + public static RSAEncryptionPadding OaepSHA384 { get; } = CreateOaep(HashAlgorithmName.SHA384); /// /// mode with SHA512 hash algorithm. /// - public static RSAEncryptionPadding OaepSHA512 { get { return s_oaepSHA512; } } + public static RSAEncryptionPadding OaepSHA512 { get; } = CreateOaep(HashAlgorithmName.SHA512); + + /// + /// mode with SHA3-256 hash algorithm. + /// + public static RSAEncryptionPadding OaepSHA3_256 { get; } = CreateOaep(HashAlgorithmName.SHA3_256); + + /// + /// mode with SHA3-384 hash algorithm. + /// + public static RSAEncryptionPadding OaepSHA3_384 { get; } = CreateOaep(HashAlgorithmName.SHA3_384); + + /// + /// mode with SHA3-512 hash algorithm. + /// + public static RSAEncryptionPadding OaepSHA3_512 { get; } = CreateOaep(HashAlgorithmName.SHA3_512); private readonly RSAEncryptionPaddingMode _mode; private readonly HashAlgorithmName _oaepHashAlgorithm; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs index 88ca89094e3da0..0486220680f4cd 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs @@ -326,7 +326,10 @@ private static void ValidateHashAlgorithm(HashAlgorithmName hashAlgorithm) if (hashAlgorithmName != HashAlgorithmName.SHA1.Name && hashAlgorithmName != HashAlgorithmName.SHA256.Name && hashAlgorithmName != HashAlgorithmName.SHA384.Name && - hashAlgorithmName != HashAlgorithmName.SHA512.Name) + hashAlgorithmName != HashAlgorithmName.SHA512.Name && + hashAlgorithmName != HashAlgorithmName.SHA3_256.Name && + hashAlgorithmName != HashAlgorithmName.SHA3_384.Name && + hashAlgorithmName != HashAlgorithmName.SHA3_512.Name) { throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName)); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs index 736fc089ee9041..4c1ee1acc8663f 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs @@ -252,7 +252,10 @@ private IncrementalHash OpenHmac(ReadOnlySpan password) if (hashAlgorithm != HashAlgorithmName.SHA1 && hashAlgorithm != HashAlgorithmName.SHA256 && hashAlgorithm != HashAlgorithmName.SHA384 && - hashAlgorithm != HashAlgorithmName.SHA512) + hashAlgorithm != HashAlgorithmName.SHA512 && + hashAlgorithm != HashAlgorithmName.SHA3_256 && + hashAlgorithm != HashAlgorithmName.SHA3_384 && + hashAlgorithm != HashAlgorithmName.SHA3_512) { throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs new file mode 100644 index 00000000000000..0a0daff805bbe5 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs @@ -0,0 +1,346 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.Versioning; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Security.Cryptography +{ + /// + /// Computes the SHA3-256 hash for the input data. + /// + /// + /// This algorithm is specified by FIPS 202. + /// + public abstract class SHA3_256 : HashAlgorithm + { + /// + /// The hash size produced by the SHA3-256 algorithm, in bits. + /// + public const int HashSizeInBits = 256; + + /// + /// The hash size produced by the SHA3-256 algorithm, in bytes. + /// + public const int HashSizeInBytes = HashSizeInBits / 8; + + /// + /// Initializes a new instance of . + /// + protected SHA3_256() + { + HashSizeValue = HashSizeInBits; + } + + /// + /// Gets a value that indicates whether the algorithm is supported on the current platform. + /// + /// + /// if the algorithm is supported; otherwise, . + /// + [SupportedOSPlatformGuard("windows")] + [SupportedOSPlatformGuard("linux")] + public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_256); + + /// + /// Creates an instance of the default implementation of . + /// + /// + /// A new instance of . + /// + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static new SHA3_256 Create() + { + CheckSha3Support(); + return new Implementation(); + } + + /// + /// Computes the hash of data using the SHA3-256 algorithm. + /// + /// The data to hash. + /// The hash of the data. + /// + /// is . + /// + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static byte[] HashData(byte[] source) + { + ArgumentNullException.ThrowIfNull(source); + + return HashData(new ReadOnlySpan(source)); + } + + /// + /// Computes the hash of data using the SHA3-256 algorithm. + /// + /// The data to hash. + /// The hash of the data. + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static byte[] HashData(ReadOnlySpan source) + { + byte[] buffer = new byte[HashSizeInBytes]; + + int written = HashData(source, buffer.AsSpan()); + Debug.Assert(written == buffer.Length); + + return buffer; + } + + /// + /// Computes the hash of data using the SHA3-256 algorithm. + /// + /// The data to hash. + /// The buffer to receive the hash value. + /// The total number of bytes written to . + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-256 algorithm always produces a 256-bit hash, or 32 bytes. + /// + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static int HashData(ReadOnlySpan source, Span destination) + { + if (!TryHashData(source, destination, out int bytesWritten)) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + return bytesWritten; + } + + + /// + /// Attempts to compute the hash of data using the SHA3-256 algorithm. + /// + /// The data to hash. + /// The buffer to receive the hash value. + /// + /// When this method returns, the total number of bytes written into . + /// + /// + /// if is too small to hold the + /// calculated hash, otherwise. + /// + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) + { + CheckSha3Support(); + + if (destination.Length < HashSizeInBytes) + { + bytesWritten = 0; + return false; + } + + bytesWritten = HashProviderDispenser.OneShotHashProvider.HashData(HashAlgorithmNames.SHA3_256, source, destination); + Debug.Assert(bytesWritten == HashSizeInBytes); + + return true; + } + + /// + /// Computes the hash of a stream using the SHA3-256 algorithm. + /// + /// The stream to hash. + /// The buffer to receive the hash value. + /// The total number of bytes written to . + /// + /// is . + /// + /// + ///

+ /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-256 algorithm always produces a 256-bit hash, or 32 bytes. + ///

+ ///

-or-

+ ///

+ /// does not support reading. + ///

+ ///
+ /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static int HashData(Stream source, Span destination) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStream(HashAlgorithmNames.SHA3_256, source, destination); + } + + /// + /// Computes the hash of a stream using the SHA3-256 algorithm. + /// + /// The stream to hash. + /// The hash of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static byte[] HashData(Stream source) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStream(HashAlgorithmNames.SHA3_256, HashSizeInBytes, source); + } + + /// + /// Asynchronously computes the hash of a stream using the SHA3-256 algorithm. + /// + /// The stream to hash. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The hash of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStreamAsync(HashAlgorithmNames.SHA3_256, source, cancellationToken); + } + + /// + /// Asynchronously computes the hash of a stream using the SHA3-256 algorithm. + /// + /// The stream to hash. + /// The buffer to receive the hash value. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The total number of bytes written to . + /// + /// is . + /// + /// + ///

+ /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-256 algorithm always produces a 256-bit hash, or 32 bytes. + ///

+ ///

-or-

+ ///

+ /// does not support reading. + ///

+ ///
+ /// + /// The platform does not support SHA3-256. + /// + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + public static ValueTask HashDataAsync( + Stream source, + Memory destination, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStreamAsync( + HashAlgorithmNames.SHA3_256, + source, + destination, + cancellationToken); + } + + private static void CheckSha3Support() + { + if (!IsSupported) + throw new PlatformNotSupportedException(); + } + + private sealed class Implementation : SHA3_256 + { + private readonly HashProvider _hashProvider; + + public Implementation() + { + _hashProvider = HashProviderDispenser.CreateHashProvider(HashAlgorithmNames.SHA3_256); + HashSizeValue = _hashProvider.HashSizeInBytes * 8; + } + + protected sealed override void HashCore(byte[] array, int ibStart, int cbSize) => + _hashProvider.AppendHashData(array, ibStart, cbSize); + + protected sealed override void HashCore(ReadOnlySpan source) => + _hashProvider.AppendHashData(source); + + protected sealed override byte[] HashFinal() => + _hashProvider.FinalizeHashAndReset(); + + protected sealed override bool TryHashFinal(Span destination, out int bytesWritten) => + _hashProvider.TryFinalizeHashAndReset(destination, out bytesWritten); + + public sealed override void Initialize() => _hashProvider.Reset(); + + protected sealed override void Dispose(bool disposing) + { + _hashProvider.Dispose(disposing); + base.Dispose(disposing); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs new file mode 100644 index 00000000000000..97ad591e97a62e --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs @@ -0,0 +1,325 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Security.Cryptography +{ + /// + /// Computes the SHA3-384 hash for the input data. + /// + /// + /// This algorithm is specified by FIPS 202. + /// + public abstract class SHA3_384 : HashAlgorithm + { + /// + /// The hash size produced by the SHA3-384 algorithm, in bits. + /// + public const int HashSizeInBits = 384; + + /// + /// The hash size produced by the SHA3-384 algorithm, in bytes. + /// + public const int HashSizeInBytes = HashSizeInBits / 8; + + /// + /// Initializes a new instance of . + /// + protected SHA3_384() + { + HashSizeValue = HashSizeInBits; + } + + /// + /// Gets a value that indicates whether the algorithm is supported on the current platform. + /// + /// + /// if the algorithm is supported; otherwise, . + /// + public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_384); + + /// + /// Creates an instance of the default implementation of . + /// + /// + /// A new instance of . + /// + /// + /// The platform does not support SHA3-384. + /// + public static new SHA3_384 Create() + { + CheckSha3Support(); + return new Implementation(); + } + + /// + /// Computes the hash of data using the SHA3-384 algorithm. + /// + /// The data to hash. + /// The hash of the data. + /// + /// is . + /// + /// + /// The platform does not support SHA3-384. + /// + public static byte[] HashData(byte[] source) + { + ArgumentNullException.ThrowIfNull(source); + + return HashData(new ReadOnlySpan(source)); + } + + /// + /// Computes the hash of data using the SHA3-384 algorithm. + /// + /// The data to hash. + /// The hash of the data. + /// + /// The platform does not support SHA3-384. + /// + public static byte[] HashData(ReadOnlySpan source) + { + byte[] buffer = new byte[HashSizeInBytes]; + + int written = HashData(source, buffer.AsSpan()); + Debug.Assert(written == buffer.Length); + + return buffer; + } + + /// + /// Computes the hash of data using the SHA3-384 algorithm. + /// + /// The data to hash. + /// The buffer to receive the hash value. + /// The total number of bytes written to . + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-384 algorithm always produces a 384-bit hash, or 48 bytes. + /// + /// + /// The platform does not support SHA3-384. + /// + public static int HashData(ReadOnlySpan source, Span destination) + { + if (!TryHashData(source, destination, out int bytesWritten)) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + return bytesWritten; + } + + + /// + /// Attempts to compute the hash of data using the SHA3-384 algorithm. + /// + /// The data to hash. + /// The buffer to receive the hash value. + /// + /// When this method returns, the total number of bytes written into . + /// + /// + /// if is too small to hold the + /// calculated hash, otherwise. + /// + /// + /// The platform does not support SHA3-384. + /// + public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) + { + CheckSha3Support(); + + if (destination.Length < HashSizeInBytes) + { + bytesWritten = 0; + return false; + } + + bytesWritten = HashProviderDispenser.OneShotHashProvider.HashData(HashAlgorithmNames.SHA3_384, source, destination); + Debug.Assert(bytesWritten == HashSizeInBytes); + + return true; + } + + /// + /// Computes the hash of a stream using the SHA3-384 algorithm. + /// + /// The stream to hash. + /// The buffer to receive the hash value. + /// The total number of bytes written to . + /// + /// is . + /// + /// + ///

+ /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-384 algorithm always produces a 384-bit hash, or 48 bytes. + ///

+ ///

-or-

+ ///

+ /// does not support reading. + ///

+ ///
+ /// + /// The platform does not support SHA3-384. + /// + public static int HashData(Stream source, Span destination) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStream(HashAlgorithmNames.SHA3_384, source, destination); + } + + /// + /// Computes the hash of a stream using the SHA3-384 algorithm. + /// + /// The stream to hash. + /// The hash of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + /// + /// The platform does not support SHA3-384. + /// + public static byte[] HashData(Stream source) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStream(HashAlgorithmNames.SHA3_384, HashSizeInBytes, source); + } + + /// + /// Asynchronously computes the hash of a stream using the SHA3-384 algorithm. + /// + /// The stream to hash. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The hash of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + /// + /// The platform does not support SHA3-384. + /// + public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStreamAsync(HashAlgorithmNames.SHA3_384, source, cancellationToken); + } + + /// + /// Asynchronously computes the hash of a stream using the SHA3-384 algorithm. + /// + /// The stream to hash. + /// The buffer to receive the hash value. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The total number of bytes written to . + /// + /// is . + /// + /// + ///

+ /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-384 algorithm always produces a 384-bit hash, or 48 bytes. + ///

+ ///

-or-

+ ///

+ /// does not support reading. + ///

+ ///
+ /// + /// The platform does not support SHA3-384. + /// + public static ValueTask HashDataAsync( + Stream source, + Memory destination, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStreamAsync( + HashAlgorithmNames.SHA3_384, + source, + destination, + cancellationToken); + } + + private static void CheckSha3Support() + { + if (!IsSupported) + throw new PlatformNotSupportedException(); + } + + private sealed class Implementation : SHA3_384 + { + private readonly HashProvider _hashProvider; + + public Implementation() + { + _hashProvider = HashProviderDispenser.CreateHashProvider(HashAlgorithmNames.SHA3_384); + HashSizeValue = _hashProvider.HashSizeInBytes * 8; + } + + protected sealed override void HashCore(byte[] array, int ibStart, int cbSize) => + _hashProvider.AppendHashData(array, ibStart, cbSize); + + protected sealed override void HashCore(ReadOnlySpan source) => + _hashProvider.AppendHashData(source); + + protected sealed override byte[] HashFinal() => + _hashProvider.FinalizeHashAndReset(); + + protected sealed override bool TryHashFinal(Span destination, out int bytesWritten) => + _hashProvider.TryFinalizeHashAndReset(destination, out bytesWritten); + + public sealed override void Initialize() => _hashProvider.Reset(); + + protected sealed override void Dispose(bool disposing) + { + _hashProvider.Dispose(disposing); + base.Dispose(disposing); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs new file mode 100644 index 00000000000000..407319d4f58698 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs @@ -0,0 +1,325 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Security.Cryptography +{ + /// + /// Computes the SHA3-512 hash for the input data. + /// + /// + /// This algorithm is specified by FIPS 202. + /// + public abstract class SHA3_512 : HashAlgorithm + { + /// + /// The hash size produced by the SHA3-512 algorithm, in bits. + /// + public const int HashSizeInBits = 512; + + /// + /// The hash size produced by the SHA3-512 algorithm, in bytes. + /// + public const int HashSizeInBytes = HashSizeInBits / 8; + + /// + /// Initializes a new instance of . + /// + protected SHA3_512() + { + HashSizeValue = HashSizeInBits; + } + + /// + /// Gets a value that indicates whether the algorithm is supported on the current platform. + /// + /// + /// if the algorithm is supported; otherwise, . + /// + public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_512); + + /// + /// Creates an instance of the default implementation of . + /// + /// + /// A new instance of . + /// + /// + /// The platform does not support SHA3-512. + /// + public static new SHA3_512 Create() + { + CheckSha3Support(); + return new Implementation(); + } + + /// + /// Computes the hash of data using the SHA3-512 algorithm. + /// + /// The data to hash. + /// The hash of the data. + /// + /// is . + /// + /// + /// The platform does not support SHA3-512. + /// + public static byte[] HashData(byte[] source) + { + ArgumentNullException.ThrowIfNull(source); + + return HashData(new ReadOnlySpan(source)); + } + + /// + /// Computes the hash of data using the SHA3-512 algorithm. + /// + /// The data to hash. + /// The hash of the data. + /// + /// The platform does not support SHA3-512. + /// + public static byte[] HashData(ReadOnlySpan source) + { + byte[] buffer = new byte[HashSizeInBytes]; + + int written = HashData(source, buffer.AsSpan()); + Debug.Assert(written == buffer.Length); + + return buffer; + } + + /// + /// Computes the hash of data using the SHA3-512 algorithm. + /// + /// The data to hash. + /// The buffer to receive the hash value. + /// The total number of bytes written to . + /// + /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-512 algorithm always produces a 512-bit hash, or 64 bytes. + /// + /// + /// The platform does not support SHA3-512. + /// + public static int HashData(ReadOnlySpan source, Span destination) + { + if (!TryHashData(source, destination, out int bytesWritten)) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + return bytesWritten; + } + + + /// + /// Attempts to compute the hash of data using the SHA3-512 algorithm. + /// + /// The data to hash. + /// The buffer to receive the hash value. + /// + /// When this method returns, the total number of bytes written into . + /// + /// + /// if is too small to hold the + /// calculated hash, otherwise. + /// + /// + /// The platform does not support SHA3-512. + /// + public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) + { + CheckSha3Support(); + + if (destination.Length < HashSizeInBytes) + { + bytesWritten = 0; + return false; + } + + bytesWritten = HashProviderDispenser.OneShotHashProvider.HashData(HashAlgorithmNames.SHA3_512, source, destination); + Debug.Assert(bytesWritten == HashSizeInBytes); + + return true; + } + + /// + /// Computes the hash of a stream using the SHA3-512 algorithm. + /// + /// The stream to hash. + /// The buffer to receive the hash value. + /// The total number of bytes written to . + /// + /// is . + /// + /// + ///

+ /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-512 algorithm always produces a 512-bit hash, or 64 bytes. + ///

+ ///

-or-

+ ///

+ /// does not support reading. + ///

+ ///
+ /// + /// The platform does not support SHA3-512. + /// + public static int HashData(Stream source, Span destination) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStream(HashAlgorithmNames.SHA3_512, source, destination); + } + + /// + /// Computes the hash of a stream using the SHA3-512 algorithm. + /// + /// The stream to hash. + /// The hash of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + /// + /// The platform does not support SHA3-512. + /// + public static byte[] HashData(Stream source) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStream(HashAlgorithmNames.SHA3_512, HashSizeInBytes, source); + } + + /// + /// Asynchronously computes the hash of a stream using the SHA3-512 algorithm. + /// + /// The stream to hash. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The hash of the data. + /// + /// is . + /// + /// + /// does not support reading. + /// + /// + /// The platform does not support SHA3-512. + /// + public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStreamAsync(HashAlgorithmNames.SHA3_512, source, cancellationToken); + } + + /// + /// Asynchronously computes the hash of a stream using the SHA3-512 algorithm. + /// + /// The stream to hash. + /// The buffer to receive the hash value. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// The total number of bytes written to . + /// + /// is . + /// + /// + ///

+ /// The buffer in is too small to hold the calculated hash + /// size. The SHA3-512 algorithm always produces a 512-bit hash, or 64 bytes. + ///

+ ///

-or-

+ ///

+ /// does not support reading. + ///

+ ///
+ /// + /// The platform does not support SHA3-512. + /// + public static ValueTask HashDataAsync( + Stream source, + Memory destination, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(source); + + if (destination.Length < HashSizeInBytes) + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + + if (!source.CanRead) + throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + + CheckSha3Support(); + return LiteHashProvider.HashStreamAsync( + HashAlgorithmNames.SHA3_512, + source, + destination, + cancellationToken); + } + + private static void CheckSha3Support() + { + if (!IsSupported) + throw new PlatformNotSupportedException(); + } + + private sealed class Implementation : SHA3_512 + { + private readonly HashProvider _hashProvider; + + public Implementation() + { + _hashProvider = HashProviderDispenser.CreateHashProvider(HashAlgorithmNames.SHA3_512); + HashSizeValue = _hashProvider.HashSizeInBytes * 8; + } + + protected sealed override void HashCore(byte[] array, int ibStart, int cbSize) => + _hashProvider.AppendHashData(array, ibStart, cbSize); + + protected sealed override void HashCore(ReadOnlySpan source) => + _hashProvider.AppendHashData(source); + + protected sealed override byte[] HashFinal() => + _hashProvider.FinalizeHashAndReset(); + + protected sealed override bool TryHashFinal(Span destination, out int bytesWritten) => + _hashProvider.TryFinalizeHashAndReset(destination, out bytesWritten); + + public sealed override void Initialize() => _hashProvider.Reset(); + + protected sealed override void Dispose(bool disposing) + { + _hashProvider.Dispose(disposing); + base.Dispose(disposing); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs index 6928cb4423785b..98e59d865f1cfc 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs @@ -34,6 +34,18 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg { oid = Oids.ECDsaWithSha512; } + else if (hashAlgorithm == HashAlgorithmName.SHA3_256) + { + oid = Oids.ECDsaWithSha3_256; + } + else if (hashAlgorithm == HashAlgorithmName.SHA3_384) + { + oid = Oids.ECDsaWithSha3_384; + } + else if (hashAlgorithm == HashAlgorithmName.SHA3_512) + { + oid = Oids.ECDsaWithSha3_512; + } else { throw new ArgumentOutOfRangeException( diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs index d9abca544ac36d..122d506cfa9b47 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs @@ -60,6 +60,18 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg { oid = Oids.RsaPkcs1Sha512; } + else if (hashAlgorithm == HashAlgorithmName.SHA3_256) + { + oid = Oids.RsaPkcs1Sha3_Sha256; + } + else if (hashAlgorithm == HashAlgorithmName.SHA3_384) + { + oid = Oids.RsaPkcs1Sha3_Sha384; + } + else if (hashAlgorithm == HashAlgorithmName.SHA3_512) + { + oid = Oids.RsaPkcs1Sha3_Sha512; + } else { throw new ArgumentOutOfRangeException( diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs b/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs index e39bc782bc04a4..c65b78ace1288e 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs @@ -47,6 +47,8 @@ public bool Supports384PrivateKey public bool SupportsSha2Oaep { get; } = true; public bool SupportsPss { get; } = true; + + public bool SupportsSha3 { get; } = SHA3_256.IsSupported; // If SHA3_256 is supported, assume 384 and 512 are, too. } public partial class RSAFactory diff --git a/src/libraries/System.Security.Cryptography/tests/HashAlgorithmNameTests.cs b/src/libraries/System.Security.Cryptography/tests/HashAlgorithmNameTests.cs index e4d78699bfdd1c..70d1056a9abf22 100644 --- a/src/libraries/System.Security.Cryptography/tests/HashAlgorithmNameTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HashAlgorithmNameTests.cs @@ -60,6 +60,9 @@ public static IEnumerable ValidInputs yield return new object[] { "2.16.840.1.101.3.4.2.1", HashAlgorithmName.SHA256 }; yield return new object[] { "2.16.840.1.101.3.4.2.2", HashAlgorithmName.SHA384 }; yield return new object[] { "2.16.840.1.101.3.4.2.3", HashAlgorithmName.SHA512 }; + yield return new object[] { "2.16.840.1.101.3.4.2.8", HashAlgorithmName.SHA3_256 }; + yield return new object[] { "2.16.840.1.101.3.4.2.9", HashAlgorithmName.SHA3_384 }; + yield return new object[] { "2.16.840.1.101.3.4.2.10", HashAlgorithmName.SHA3_512 }; } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs new file mode 100644 index 00000000000000..9a78fef4f7179f --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs @@ -0,0 +1,213 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Test.Cryptography; +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + public class HmacSha3_256Tests : HmacTests + { + protected override int BlockSize => 136; + protected override int MacSize => HMACSHA3_256.HashSizeInBytes; + + protected override HMAC Create() => new HMACSHA3_256(); + protected override HashAlgorithm CreateHashAlgorithm() => SHA3_256.Create(); + protected override byte[] HashDataOneShot(byte[] key, byte[] source) => + HMACSHA3_256.HashData(key, source); + + protected override byte[] HashDataOneShot(ReadOnlySpan key, ReadOnlySpan source) => + HMACSHA3_256.HashData(key, source); + + protected override int HashDataOneShot(ReadOnlySpan key, ReadOnlySpan source, Span destination) => + HMACSHA3_256.HashData(key, source, destination); + + protected override bool TryHashDataOneShot(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int written) => + HMACSHA3_256.TryHashData(key, source, destination, out written); + + protected override byte[] HashDataOneShot(ReadOnlySpan key, Stream source) => + HMACSHA3_256.HashData(key, source); + + protected override byte[] HashDataOneShot(byte[] key, Stream source) => + HMACSHA3_256.HashData(key, source); + + protected override int HashDataOneShot(ReadOnlySpan key, Stream source, Span destination) => + HMACSHA3_256.HashData(key, source, destination); + + protected override ValueTask HashDataOneShotAsync( + ReadOnlyMemory key, + Stream source, + Memory destination, + CancellationToken cancellationToken) => HMACSHA3_256.HashDataAsync(key, source, destination, cancellationToken); + + protected override ValueTask HashDataOneShotAsync( + ReadOnlyMemory key, + Stream source, + CancellationToken cancellationToken) => HMACSHA3_256.HashDataAsync(key, source, cancellationToken); + + protected override ValueTask HashDataOneShotAsync( + byte[] key, + Stream source, + CancellationToken cancellationToken) => HMACSHA3_256.HashDataAsync(key, source, cancellationToken); + + private static readonly byte[][] s_testKeys = new byte[][] + { + // From: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA3-256.pdf + null, + ByteUtils.HexToByteArray("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + + "8081828384858687"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + + "a0a1a2a3a4a5a6a7"), + ByteUtils.HexToByteArray("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), + }; + + private static readonly byte[][] s_testData = new byte[][] + { + null, + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3d626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e2c2077697468207472756e636174656420746167"), + }; + + private static readonly byte[][] s_testMacs = new byte[][] + { + null, + ByteUtils.HexToByteArray("4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205"), + ByteUtils.HexToByteArray("68b94e2e538a9be4103bebb5aa016d47961d4d1aa906061313b557f8af2c3faa"), + ByteUtils.HexToByteArray("9bcf2c238e235c3ce88404e813bd2f3a97185ac6f238c63d6229a00b07974258"), + ByteUtils.HexToByteArray("c8dc7148d8c1423aa549105dafdf9cad"), // Truncated test case. + }; + + + public HmacSha3_256Tests() : base(s_testKeys, s_testData, s_testMacs) + { + } + + [Theory] + [MemberData(nameof(TestCaseIds))] + public void HmacSha3_256_VerifyTestCases(int caseId) + { + VerifyHmac(caseId, s_testMacs[caseId]); + } + + public static IEnumerable TestCaseIds + { + get + { + for (int i = 1; i < s_testKeys.Length; i++) + { + yield return new object[] { i }; + } + } + } + + [Fact] + public void HmacSha3_256_Rfc2104_2() + { + VerifyHmacRfc2104_2(); + } + + [Fact] + public void HmacSha3_256_ThrowsArgumentNullForNullConstructorKey() + { + AssertExtensions.Throws("key", () => new HMACSHA3_256(null)); + } + + [Fact] + public void HmacSha3_256_EmptyKey() + { + VerifyRepeating( + input: "Crypto is fun!", + 1, + hexKey: "", + output: "c49c24ae6dce7e90d5e2853ad9e647d89ac3dd04eb71aa0912ab4b4b1068ba6a"); + } + + [Fact] + public void HmacSha3_256_Stream_MultipleOf4096() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl sha3-256 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "0102030405060708", + 1024, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "F09DD1B814BF4A576FF8AEAFF69509E3093895426F441A428953221F3CB9E421"); + } + + [Fact] + public void HmacSha3_256_Stream_NotMultipleOf4096() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl sha3-256 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "0102030405060708", + 1025, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "F1DB96FF2B53CBA0338FF519BFA10153731DB48A63C26EB66294895B220F72B5"); + } + + [Fact] + public void HmacSha3_256_Stream_Empty() + { + // Verfied with: + // echo -n "" | openssl sha3-256 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "", + 0, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "72756291FF30F3E916BEF99EC9CF5938B25D90BBCAC1BDB1E1E6564E8EC6FDA5"); + } + + [Fact] + public async Task HmacSha3_256_Stream_MultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl sha3-256 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "0102030405060708", + 1024, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "F09DD1B814BF4A576FF8AEAFF69509E3093895426F441A428953221F3CB9E421"); + } + + [Fact] + public async Task HmacSha3_256_Stream_NotMultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl sha3-256 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "0102030405060708", + 1025, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "F1DB96FF2B53CBA0338FF519BFA10153731DB48A63C26EB66294895B220F72B5"); + } + + [Fact] + public async Task HmacSha3_256_Stream_Empty_Async() + { + // Verfied with: + // echo -n "" | openssl sha3-256 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "", + 0, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "72756291FF30F3E916BEF99EC9CF5938B25D90BBCAC1BDB1E1E6564E8EC6FDA5"); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs new file mode 100644 index 00000000000000..9bfbe70c64941f --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs @@ -0,0 +1,221 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Test.Cryptography; +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + public class HmacSha3_384Tests : HmacTests + { + protected override int BlockSize => 104; + protected override int MacSize => HMACSHA3_384.HashSizeInBytes; + + protected override HMAC Create() => new HMACSHA3_384(); + protected override HashAlgorithm CreateHashAlgorithm() => SHA3_384.Create(); + protected override byte[] HashDataOneShot(byte[] key, byte[] source) => + HMACSHA3_384.HashData(key, source); + + protected override byte[] HashDataOneShot(ReadOnlySpan key, ReadOnlySpan source) => + HMACSHA3_384.HashData(key, source); + + protected override int HashDataOneShot(ReadOnlySpan key, ReadOnlySpan source, Span destination) => + HMACSHA3_384.HashData(key, source, destination); + + protected override bool TryHashDataOneShot(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int written) => + HMACSHA3_384.TryHashData(key, source, destination, out written); + + protected override byte[] HashDataOneShot(ReadOnlySpan key, Stream source) => + HMACSHA3_384.HashData(key, source); + + protected override byte[] HashDataOneShot(byte[] key, Stream source) => + HMACSHA3_384.HashData(key, source); + + protected override int HashDataOneShot(ReadOnlySpan key, Stream source, Span destination) => + HMACSHA3_384.HashData(key, source, destination); + + protected override ValueTask HashDataOneShotAsync( + ReadOnlyMemory key, + Stream source, + Memory destination, + CancellationToken cancellationToken) => HMACSHA3_384.HashDataAsync(key, source, destination, cancellationToken); + + protected override ValueTask HashDataOneShotAsync( + ReadOnlyMemory key, + Stream source, + CancellationToken cancellationToken) => HMACSHA3_384.HashDataAsync(key, source, cancellationToken); + + protected override ValueTask HashDataOneShotAsync( + byte[] key, + Stream source, + CancellationToken cancellationToken) => HMACSHA3_384.HashDataAsync(key, source, cancellationToken); + + private static readonly byte[][] s_testKeys = new byte[][] + { + // From: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA3-256.pdf + null, + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f1011121314151617" + + "18191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + + "6061626364656667"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + + "808182838485868788898a8b8c8d8e8f9091929394959697"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f"), + }; + + private static readonly byte[][] s_testData = new byte[][] + { + null, + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3d626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e2c2077697468207472756e636174656420746167"), + }; + + private static readonly byte[][] s_testMacs = new byte[][] + { + null, + ByteUtils.HexToByteArray( + "d588a3c51f3f2d906e8298c1199aa8ff6296218127f6b38a" + + "90b6afe2c5617725bc99987f79b22a557b6520db710b7f42"), + ByteUtils.HexToByteArray( + "a27d24b592e8c8cbf6d4ce6fc5bf62d8fc98bf2d486640d9" + + "eb8099e24047837f5f3bffbe92dcce90b4ed5b1e7e44fa90"), + ByteUtils.HexToByteArray( + "e5ae4c739f455279368ebf36d4f5354c95aa184c899d3870" + + "e460ebc288ef1f9470053f73f7c6da2a71bcaec38ce7d6ac"), + ByteUtils.HexToByteArray("25f4bf53606e91af79d24a4bb1fd6aecd44414a30c8ebb0a"), // Truncated + }; + + + public HmacSha3_384Tests() : base(s_testKeys, s_testData, s_testMacs) + { + } + + [Theory] + [MemberData(nameof(TestCaseIds))] + public void HmacSha3_384_VerifyTestCases(int caseId) + { + VerifyHmac(caseId, s_testMacs[caseId]); + } + + public static IEnumerable TestCaseIds + { + get + { + for (int i = 1; i < s_testKeys.Length; i++) + { + yield return new object[] { i }; + } + } + } + + [Fact] + public void HmacSha3_384_Rfc2104_2() + { + VerifyHmacRfc2104_2(); + } + + [Fact] + public void HmacSha3_384_ThrowsArgumentNullForNullConstructorKey() + { + AssertExtensions.Throws("key", () => new HMACSHA3_384(null)); + } + + [Fact] + public void HmacSha3_384_EmptyKey() + { + VerifyRepeating( + input: "Crypto is fun!", + 1, + hexKey: "", + output: "16C079F7D15505E9E541421E63C432A063F39C1E3E953E6DC7B8A81FE5620AFFA430C3E6BE6A0F605755C7C5EE4E347E"); + } + + [Fact] + public void HmacSha3_384_Stream_MultipleOf4096() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl sha3-384 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "0102030405060708", + 1024, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "17D03C8153AF1719F5829C8CBF328D4200900ED1AB038A399B4F256A490BD4D2AB311C71D2ED0C20ABA96E57768CCA6E"); + } + + [Fact] + public void HmacSha3_384_Stream_NotMultipleOf4096() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl sha3-384 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "0102030405060708", + 1025, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "5360719A6A9DFEB1143C2866A7F72EA29404C3DBF37F244A0497F400DA126B2728118863454288F26E3796BE72238958"); + } + + [Fact] + public void HmacSha3_384_Stream_Empty() + { + // Verfied with: + // echo -n "" | openssl sha3-384 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "", + 0, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "5B0196779BDAF859E99869A63C9FDF3821E9100A370B5E9B88F76B9DA87410F99846E7DBB4F8A69368C5C5A834B3128D"); + } + + [Fact] + public async Task HmacSha3_384_Stream_MultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl sha3-384 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "0102030405060708", + 1024, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "17D03C8153AF1719F5829C8CBF328D4200900ED1AB038A399B4F256A490BD4D2AB311C71D2ED0C20ABA96E57768CCA6E"); + } + + [Fact] + public async Task HmacSha3_384_Stream_NotMultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl sha3-384 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "0102030405060708", + 1025, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "5360719A6A9DFEB1143C2866A7F72EA29404C3DBF37F244A0497F400DA126B2728118863454288F26E3796BE72238958"); + } + + [Fact] + public async Task HmacSha3_384_Stream_Empty_Async() + { + // Verfied with: + // echo -n "" | openssl sha3-384 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "", + 0, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "5B0196779BDAF859E99869A63C9FDF3821E9100A370B5E9B88F76B9DA87410F99846E7DBB4F8A69368C5C5A834B3128D"); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs new file mode 100644 index 00000000000000..e2a25faae8725d --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs @@ -0,0 +1,227 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Test.Cryptography; +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + public class HmacSha3_512Tests : HmacTests + { + protected override int BlockSize => 72; + protected override int MacSize => HMACSHA3_512.HashSizeInBytes; + + protected override HMAC Create() => new HMACSHA3_512(); + protected override HashAlgorithm CreateHashAlgorithm() => SHA3_512.Create(); + protected override byte[] HashDataOneShot(byte[] key, byte[] source) => + HMACSHA3_512.HashData(key, source); + + protected override byte[] HashDataOneShot(ReadOnlySpan key, ReadOnlySpan source) => + HMACSHA3_512.HashData(key, source); + + protected override int HashDataOneShot(ReadOnlySpan key, ReadOnlySpan source, Span destination) => + HMACSHA3_512.HashData(key, source, destination); + + protected override bool TryHashDataOneShot(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int written) => + HMACSHA3_512.TryHashData(key, source, destination, out written); + + protected override byte[] HashDataOneShot(ReadOnlySpan key, Stream source) => + HMACSHA3_512.HashData(key, source); + + protected override byte[] HashDataOneShot(byte[] key, Stream source) => + HMACSHA3_512.HashData(key, source); + + protected override int HashDataOneShot(ReadOnlySpan key, Stream source, Span destination) => + HMACSHA3_512.HashData(key, source, destination); + + protected override ValueTask HashDataOneShotAsync( + ReadOnlyMemory key, + Stream source, + Memory destination, + CancellationToken cancellationToken) => HMACSHA3_512.HashDataAsync(key, source, destination, cancellationToken); + + protected override ValueTask HashDataOneShotAsync( + ReadOnlyMemory key, + Stream source, + CancellationToken cancellationToken) => HMACSHA3_512.HashDataAsync(key, source, cancellationToken); + + protected override ValueTask HashDataOneShotAsync( + byte[] key, + Stream source, + CancellationToken cancellationToken) => HMACSHA3_512.HashDataAsync(key, source, cancellationToken); + + private static readonly byte[][] s_testKeys = new byte[][] + { + // From: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA3-512.pdf + null, + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + + "4041424344454647"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + + "8081828384858687"), + ByteUtils.HexToByteArray( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"), + }; + + private static readonly byte[][] s_testData = new byte[][] + { + null, + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3d626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"), + ByteUtils.HexToByteArray("53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e2c2077697468207472756e636174656420746167"), + }; + + private static readonly byte[][] s_testMacs = new byte[][] + { + null, + ByteUtils.HexToByteArray( + "4efd629d6c71bf86162658f29943b1c308ce27cdfa6db0d9c3ce81763f9cbce5" + + "f7ebe9868031db1a8f8eb7b6b95e5c5e3f657a8996c86a2f6527e307f0213196"), + ByteUtils.HexToByteArray( + "544e257ea2a3e5ea19a590e6a24b724ce6327757723fe2751b75bf007d80f6b3" + + "60744bf1b7a88ea585f9765b47911976d3191cf83c039f5ffab0d29cc9d9b6da"), + ByteUtils.HexToByteArray( + "5f464f5e5b7848e3885e49b2c385f0694985d0e38966242dc4a5fe3fea4b37d4" + + "6b65ceced5dcf59438dd840bab22269f0ba7febdb9fcf74602a35666b2a32915"), + ByteUtils.HexToByteArray("7bb06d859257b25ce73ca700df34c5cbef5c898bac91029e0b27975d4e526a08"), // Truncated + }; + + + public HmacSha3_512Tests() : base(s_testKeys, s_testData, s_testMacs) + { + } + + [Theory] + [MemberData(nameof(TestCaseIds))] + public void HmacSha3_512_VerifyTestCases(int caseId) + { + VerifyHmac(caseId, s_testMacs[caseId]); + } + + public static IEnumerable TestCaseIds + { + get + { + for (int i = 1; i < s_testKeys.Length; i++) + { + yield return new object[] { i }; + } + } + } + + [Fact] + public void HmacSha3_512_Rfc2104_2() + { + VerifyHmacRfc2104_2(); + } + + [Fact] + public void HmacSha3_512_ThrowsArgumentNullForNullConstructorKey() + { + AssertExtensions.Throws("key", () => new HMACSHA3_512(null)); + } + + [Fact] + public void HmacSha3_512_EmptyKey() + { + VerifyRepeating( + input: "Crypto is fun!", + 1, + hexKey: "", + output: "8F1658BB962C7048A50BEA174FA7697596F3F5F127228EEA64589DFFB0C1A07C" + + "98792648C97886B3DD9E63AB962581C67DA5EE04F2B15263555B1796782CB556"); + } + + [Fact] + public void HmacSha3_512_Stream_MultipleOf4096() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl sha3-512 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "0102030405060708", + 1024, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "43A635D00606EFB4797B0B50B3C2CCAACDC8C2DA38D1369EA49CDD93EDE27824" + + "317D9014C429DB18E5A6BFD811F7B484922471085F17ED31F6A7EB4E07BFFA97"); + } + + [Fact] + public void HmacSha3_512_Stream_NotMultipleOf4096() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl sha3-512 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "0102030405060708", + 1025, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "90D378A7546A66804E6C0ADF3203D3836244FD8CF628294E7F3AD95539EDF6D9" + + "E86DECE850D50DE76386CB293FA832778C7D6607A4F00AD666DA3EFFD6143E70"); + } + + [Fact] + public void HmacSha3_512_Stream_Empty() + { + // Verfied with: + // echo -n "" | openssl sha3-512 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + VerifyRepeating( + input: "", + 0, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "908D1BE1A2CC5CC4B8C62E98D09AB6E967529FCB24F4177CB94CB072F5968D01" + + "CA58633748DC80D4615E3D21228BB3A5F535FA1CB963DF463CC28ABAF1A9B2D1"); + } + + [Fact] + public async Task HmacSha3_512_Stream_MultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl sha3-512 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "0102030405060708", + 1024, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "43A635D00606EFB4797B0B50B3C2CCAACDC8C2DA38D1369EA49CDD93EDE27824" + + "317D9014C429DB18E5A6BFD811F7B484922471085F17ED31F6A7EB4E07BFFA97"); + } + + [Fact] + public async Task HmacSha3_512_Stream_NotMultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl sha3-512 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "0102030405060708", + 1025, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "90D378A7546A66804E6C0ADF3203D3836244FD8CF628294E7F3AD95539EDF6D9" + + "E86DECE850D50DE76386CB293FA832778C7D6607A4F00AD666DA3EFFD6143E70"); + } + + [Fact] + public async Task HmacSha3_512_Stream_Empty_Async() + { + // Verfied with: + // echo -n "" | openssl sha3-512 -hex -mac HMAC -macopt hexkey:000102030405060708090A0B0C0D0E0F + await VerifyRepeatingAsync( + input: "", + 0, + hexKey: "000102030405060708090A0B0C0D0E0F", + output: "908D1BE1A2CC5CC4B8C62E98D09AB6E967529FCB24F4177CB94CB072F5968D01" + + "CA58633748DC80D4615E3D21228BB3A5F535FA1CB963DF463CC28ABAF1A9B2D1"); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/HmacTests.cs index 436f407c8b81b2..61f79e79eff0d0 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacTests.cs @@ -400,7 +400,7 @@ public void OneShot_TryExistingBuffer_TooSmall() [Fact] public void OneShot_TryExistingBuffer_Exact() { - for (int caseId = 1; caseId <= 7; caseId++) + for (int caseId = 1; caseId < _testKeys.Length; caseId++) { byte[] buffer = new byte[MacSize]; byte[] key = _testKeys[caseId]; @@ -418,7 +418,7 @@ public void OneShot_TryExistingBuffer_Exact() [Fact] public void OneShot_TryExistingBuffer_Larger() { - for (int caseId = 1; caseId <= 7; caseId++) + for (int caseId = 1; caseId < _testKeys.Length; caseId++) { Span buffer = new byte[MacSize + 20]; byte[] key = _testKeys[caseId]; @@ -445,7 +445,7 @@ public void OneShot_TryExistingBuffer_Larger() [InlineData(10, 20)] public void OneShot_TryExistingBuffer_OverlapsKey(int keyOffset, int bufferOffset) { - for (int caseId = 1; caseId <= 7; caseId++) + for (int caseId = 1; caseId < _testKeys.Length; caseId++) { byte[] key = _testKeys[caseId]; byte[] data = _testData[caseId]; @@ -471,7 +471,7 @@ public void OneShot_TryExistingBuffer_OverlapsKey(int keyOffset, int bufferOffse [InlineData(10, 20)] public void OneShot_TryExistingBuffer_OverlapsSource(int sourceOffset, int bufferOffset) { - for (int caseId = 1; caseId <= 7; caseId++) + for (int caseId = 1; caseId < _testKeys.Length; caseId++) { byte[] key = _testKeys[caseId]; byte[] data = _testData[caseId]; diff --git a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs index 400b8aa57834c0..b744b8f09bc6fc 100644 --- a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs @@ -25,6 +25,13 @@ public static IEnumerable GetHashAlgorithms() yield return new object[] { SHA256.Create(), HashAlgorithmName.SHA256 }; yield return new object[] { SHA384.Create(), HashAlgorithmName.SHA384 }; yield return new object[] { SHA512.Create(), HashAlgorithmName.SHA512 }; + + if (PlatformDetection.SupportsSha3) + { + yield return new object[] { SHA3_256.Create(), HashAlgorithmName.SHA3_256 }; + yield return new object[] { SHA3_384.Create(), HashAlgorithmName.SHA3_384 }; + yield return new object[] { SHA3_512.Create(), HashAlgorithmName.SHA3_512 }; + } } public static IEnumerable GetHMACs() @@ -33,10 +40,18 @@ public static IEnumerable GetHMACs() { yield return new object[] { new HMACMD5(), HashAlgorithmName.MD5 }; } + yield return new object[] { new HMACSHA1(), HashAlgorithmName.SHA1 }; yield return new object[] { new HMACSHA256(), HashAlgorithmName.SHA256 }; yield return new object[] { new HMACSHA384(), HashAlgorithmName.SHA384 }; yield return new object[] { new HMACSHA512(), HashAlgorithmName.SHA512 }; + + if (PlatformDetection.SupportsSha3) + { + yield return new object[] { new HMACSHA3_256(), HashAlgorithmName.SHA3_256 }; + yield return new object[] { new HMACSHA3_384(), HashAlgorithmName.SHA3_384 }; + yield return new object[] { new HMACSHA3_512(), HashAlgorithmName.SHA3_512 }; + } } [Fact] diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs index df32356190fd49..fc202e43e0e93d 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs @@ -281,6 +281,17 @@ public static void Pbkdf2_Rfc6070(string password, string salt, int iterations, Assert.Equal(expected, actual); } + [Theory] + [MemberData(nameof(Pbkdf2_OpenSsl_Vectors))] + public static void Pbkdf2_OpenSsl(string hashAlgorithm, string password, string salt, int iterations, string expectedHex) + { + HashAlgorithmName hashAlgorithmName = new HashAlgorithmName(hashAlgorithm); + byte[] expected = expectedHex.HexToByteArray(); + byte[] saltBytes = Encoding.UTF8.GetBytes(salt); + byte[] actual = Rfc2898DeriveBytes.Pbkdf2(password, saltBytes, iterations, hashAlgorithmName, expected.Length); + Assert.Equal(expected, actual); + } + [Fact] [OuterLoop("Uses a high number of iterations that can take over 20 seconds on some machines")] public static void Pbkdf2_Rfc6070_HighIterations() @@ -293,6 +304,17 @@ public static void Pbkdf2_Rfc6070_HighIterations() Assert.Equal(expected, actual); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.DoesNotSupportSha3))] + [InlineData(nameof(HashAlgorithmName.SHA3_256))] + [InlineData(nameof(HashAlgorithmName.SHA3_384))] + [InlineData(nameof(HashAlgorithmName.SHA3_512))] + public static void UnsupportedPkbdf2Algorithms(string hashAlgorithm) + { + HashAlgorithmName hashAlgorithmName = new HashAlgorithmName(hashAlgorithm); + Assert.Throws(() => + Rfc2898DeriveBytes.Pbkdf2(s_passwordBytes, s_salt, iterations: 1, hashAlgorithmName, s_extractLength)); + } + public static IEnumerable Pbkdf2_PasswordBytes_Compare_Data() { string largeInputHex = new string('A', 8192); // 8192 hex characters = 4096 bytes. @@ -323,6 +345,30 @@ public static IEnumerable Pbkdf2_PasswordBytes_Compare_Data() yield return new object[] { HashAlgorithmName.SHA384.Name, 257, 257, password.ByteArrayToHex(), "0000000000000000" }; yield return new object[] { HashAlgorithmName.SHA512.Name, 257, 257, password.ByteArrayToHex(), "0000000000000000" }; } + + if (PlatformDetection.SupportsSha3) + { + // Test around HMAC SHA3_256 block boundary (136) + for (int blockBoundary = 135; blockBoundary <= 137; blockBoundary++) + { + byte[] password = new byte[blockBoundary]; + yield return new object[] { HashAlgorithmName.SHA3_256.Name, 257, 257, password.ByteArrayToHex(), "0000000000000000" }; + } + + // Test around HMAC SHA3_384 block boundary (104) + for (int blockBoundary = 103; blockBoundary <= 105; blockBoundary++) + { + byte[] password = new byte[blockBoundary]; + yield return new object[] { HashAlgorithmName.SHA3_384.Name, 257, 257, password.ByteArrayToHex(), "0000000000000000" }; + } + + // Test around HMAC SHA3_512 block boundary (72) + for (int blockBoundary = 71; blockBoundary <= 73; blockBoundary++) + { + byte[] password = new byte[blockBoundary]; + yield return new object[] { HashAlgorithmName.SHA3_512.Name, 257, 257, password.ByteArrayToHex(), "0000000000000000" }; + } + } } public static IEnumerable Pbkdf2_PasswordString_Compare_Data() @@ -352,12 +398,59 @@ public static IEnumerable Pbkdf2_Rfc6070_Vectors() yield return new object[] { "pass\0word", "sa\0lt", 4096, "56fa6aa75548099dcc37d7f03425e0c3" }; } - private static HashAlgorithmName[] SupportedHashAlgorithms => new [] + public static IEnumerable Pbkdf2_OpenSsl_Vectors() + { + if (!PlatformDetection.SupportsSha3) { - HashAlgorithmName.SHA1, - HashAlgorithmName.SHA256, - HashAlgorithmName.SHA384, - HashAlgorithmName.SHA512 + yield break; + } + + // Values come from https://github.com/openssl/openssl/blob/6821acbffda908ec69769ed7f110cfde57d8ca58/test/recipes/30-test_evp_data/evppbe_pbkdf2.txt + // hashAlgorithm, password, salt, iterations, expected + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_256), + "password", + "salt", + 4096, + "778b6e237a0f49621549ff70d218d208", + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_384), + "password", + "salt", + 4096, + "9a5f1e45e8b83f1b259ba72d11c59087", }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_512), + "password", + "salt", + 4096, + "2bfaf2d5ceb6d10f5e262cd902488cfd", + }; + } + + private static IEnumerable SupportedHashAlgorithms + { + get + { + yield return HashAlgorithmName.SHA1; + yield return HashAlgorithmName.SHA256; + yield return HashAlgorithmName.SHA384; + yield return HashAlgorithmName.SHA512; + + if (PlatformDetection.SupportsSha3) + { + yield return HashAlgorithmName.SHA3_256; + yield return HashAlgorithmName.SHA3_384; + yield return HashAlgorithmName.SHA3_512; + } + } + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs index 4ac54e571a52d0..9fb0c149988fb1 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs @@ -607,6 +607,42 @@ private static IEnumerable GetKnownValuesTestCases() IterationCount = 1, AnswerHex = "1E437A1C79D75BE61E91141DAE20", }; + + if (PlatformDetection.SupportsSha3) + { + // https://github.com/openssl/openssl/blob/6821acbffda908ec69769ed7f110cfde57d8ca58/test/recipes/30-test_evp_data/evppbe_pbkdf2.txt#L128-L133 + yield return new KnownValuesTestCase + { + CaseName = "OpenSSL SHA3-256", + HashAlgorithmName = nameof(HashAlgorithmName.SHA3_256), + Password = "password", + Salt = "salt"u8.ToArray(), + IterationCount = 4096, + AnswerHex = "778B6E237A0F49621549FF70D218D208", + }; + + // https://github.com/openssl/openssl/blob/6821acbffda908ec69769ed7f110cfde57d8ca58/test/recipes/30-test_evp_data/evppbe_pbkdf2.txt#L135-L140 + yield return new KnownValuesTestCase + { + CaseName = "OpenSSL SHA3-384", + HashAlgorithmName = nameof(HashAlgorithmName.SHA3_384), + Password = "password", + Salt = "salt"u8.ToArray(), + IterationCount = 4096, + AnswerHex = "9A5F1E45E8B83F1B259BA72D11C59087", + }; + + // https://github.com/openssl/openssl/blob/6821acbffda908ec69769ed7f110cfde57d8ca58/test/recipes/30-test_evp_data/evppbe_pbkdf2.txt#L142-L147 + yield return new KnownValuesTestCase + { + CaseName = "OpenSSL SHA3-512", + HashAlgorithmName = nameof(HashAlgorithmName.SHA3_512), + Password = "password", + Salt = "salt"u8.ToArray(), + IterationCount = 4096, + AnswerHex = "2BFAF2D5CEB6D10F5E262CD902488CFD", + }; + } } public class KnownValuesTestCase diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs new file mode 100644 index 00000000000000..8bd0c54bf72d61 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs @@ -0,0 +1,196 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + public class Sha3_256Tests : HashAlgorithmTestDriver + { + protected override HashAlgorithm Create() + { + return SHA3_256.Create(); + } + + protected override bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) + { + return SHA3_256.TryHashData(source, destination, out bytesWritten); + } + + protected override byte[] HashData(byte[] source) => SHA3_256.HashData(source); + + protected override byte[] HashData(ReadOnlySpan source) => SHA3_256.HashData(source); + + protected override int HashData(ReadOnlySpan source, Span destination) => + SHA3_256.HashData(source, destination); + + protected override int HashData(Stream source, Span destination) => + SHA3_256.HashData(source, destination); + + protected override byte[] HashData(Stream source) => SHA3_256.HashData(source); + + protected override ValueTask HashDataAsync(Stream source, Memory destination, CancellationToken cancellationToken) => + SHA3_256.HashDataAsync(source, destination, cancellationToken); + + protected override ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken) => + SHA3_256.HashDataAsync(source, cancellationToken); + + [Fact] + public void Sha3_256_Kats() + { + foreach ((string Msg, string MD) kat in Fips202Kats) + { + Verify(Convert.FromHexString(kat.Msg), kat.MD); + } + } + + private static IEnumerable<(string Msg, string MD)> Fips202Kats + { + get + { + // Generated from SHA3_256ShortMsg.rsp + yield return (Msg: "", MD: "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"); + yield return (Msg: "e9", MD: "f0d04dd1e6cfc29a4460d521796852f25d9ef8d28b44ee91ff5b759d72c1e6d6"); + yield return (Msg: "d477", MD: "94279e8f5ccdf6e17f292b59698ab4e614dfe696a46c46da78305fc6a3146ab7"); + yield return (Msg: "b053fa", MD: "9d0ff086cd0ec06a682c51c094dc73abdc492004292344bd41b82a60498ccfdb"); + yield return (Msg: "e7372105", MD: "3a42b68ab079f28c4ca3c752296f279006c4fe78b1eb79d989777f051e4046ae"); + yield return (Msg: "0296f2c40a", MD: "53a018937221081d09ed0497377e32a1fa724025dfdc1871fa503d545df4b40d"); + yield return (Msg: "e6fd42037f80", MD: "2294f8d3834f24aa9037c431f8c233a66a57b23fa3de10530bbb6911f6e1850f"); + yield return (Msg: "37b442385e0538", MD: "cfa55031e716bbd7a83f2157513099e229a88891bb899d9ccd317191819998f8"); + yield return (Msg: "8bca931c8a132d2f", MD: "dbb8be5dec1d715bd117b24566dc3f24f2cc0c799795d0638d9537481ef1e03e"); + yield return (Msg: "fb8dfa3a132f9813ac", MD: "fd09b3501888445ffc8c3bb95d106440ceee469415fce1474743273094306e2e"); + yield return (Msg: "71fbacdbf8541779c24a", MD: "cc4e5a216b01f987f24ab9cad5eb196e89d32ed4aac85acb727e18e40ceef00e"); + yield return (Msg: "7e8f1fd1882e4a7c49e674", MD: "79bef78c78aa71e11a3375394c2562037cd0f82a033b48a6cc932cc43358fd9e"); + yield return (Msg: "5c56a6b18c39e66e1b7a993a", MD: "b697556cb30d6df448ee38b973cb6942559de4c2567b1556240188c55ec0841c"); + yield return (Msg: "9c76ca5b6f8d1212d8e6896ad8", MD: "69dfc3a25865f3535f18b4a7bd9c0c69d78455f1fc1f4bf4e29fc82bf32818ec"); + yield return (Msg: "687ff7485b7eb51fe208f6ff9a1b", MD: "fe7e68ae3e1a91944e4d1d2146d9360e5333c099a256f3711edc372bc6eeb226"); + yield return (Msg: "4149f41be1d265e668c536b85dde41", MD: "229a7702448c640f55dafed08a52aa0b1139657ba9fc4c5eb8587e174ecd9b92"); + yield return (Msg: "d83c721ee51b060c5a41438a8221e040", MD: "b87d9e4722edd3918729ded9a6d03af8256998ee088a1ae662ef4bcaff142a96"); + yield return (Msg: "266e8cbd3e73d80df2a49cfdaf0dc39cd1", MD: "6c2de3c95900a1bcec6bd4ca780056af4acf3aa36ee640474b6e870187f59361"); + yield return (Msg: "a1d7ce5104eb25d6131bb8f66e1fb13f3523", MD: "ee9062f39720b821b88be5e64621d7e0ca026a9fe7248d78150b14bdbaa40bed"); + yield return (Msg: "d751ccd2cd65f27db539176920a70057a08a6b", MD: "7aaca80dbeb8dc3677d18b84795985463650d72f2543e0ec709c9e70b8cd7b79"); + yield return (Msg: "b32dec58865ab74614ea982efb93c08d9acb1bb0", MD: "6a12e535dbfddab6d374058d92338e760b1a211451a6c09be9b61ee22f3bb467"); + yield return (Msg: "4e0cc4f5c6dcf0e2efca1f9f129372e2dcbca57ea6", MD: "d2b7717864e9438dd02a4f8bb0203b77e2d3cd8f8ffcf9dc684e63de5ef39f0d"); + yield return (Msg: "d16d978dfbaecf2c8a04090f6eebdb421a5a711137a6", MD: "7f497913318defdc60c924b3704b65ada7ca3ba203f23fb918c6fb03d4b0c0da"); + yield return (Msg: "47249c7cb85d8f0242ab240efd164b9c8b0bd3104bba3b", MD: "435e276f06ae73aa5d5d6018f58e0f009be351eada47b677c2f7c06455f384e7"); + yield return (Msg: "cf549a383c0ac31eae870c40867eeb94fa1b6f3cac4473f2", MD: "cdfd1afa793e48fd0ee5b34dfc53fbcee43e9d2ac21515e4746475453ab3831f"); + yield return (Msg: "9b3fdf8d448680840d6284f2997d3af55ffd85f6f4b33d7f8d", MD: "25005d10e84ff97c74a589013be42fb37f68db64bdfc7626efc0dd628077493a"); + yield return (Msg: "6b22fe94be2d0b2528d9847e127eb6c7d6967e7ec8b9660e77cc", MD: "157a52b0477639b3bc179667b35c1cdfbb3eef845e4486f0f84a526e940b518c"); + yield return (Msg: "d8decafdad377904a2789551135e782e302aed8450a42cfb89600c", MD: "3ddecf5bba51643cd77ebde2141c8545f862067b209990d4cb65bfa65f4fa0c0"); + yield return (Msg: "938fe6afdbf14d1229e03576e532f078898769e20620ae2164f5abfa", MD: "9511abd13c756772b852114578ef9b96f9dc7d0f2b8dcde6ea7d1bd14c518890"); + yield return (Msg: "66eb5e7396f5b451a02f39699da4dbc50538fb10678ec39a5e28baa3c0", MD: "540acf81810a199996a612e885781308802fe460e9c638cc022e17076be8597a"); + yield return (Msg: "de98968c8bd9408bd562ac6efbca2b10f5769aacaa01365763e1b2ce8048", MD: "6b2f2547781449d4fa158180a178ef68d7056121bf8a2f2f49891afc24978521"); + yield return (Msg: "94464e8fafd82f630e6aab9aa339d981db0a372dc5c1efb177305995ae2dc0", MD: "ea7952ad759653cd47a18004ac2dbb9cf4a1e7bba8a530cf070570c711a634ea"); + yield return (Msg: "c178ce0f720a6d73c6cf1caa905ee724d5ba941c2e2628136e3aad7d853733ba", MD: "64537b87892835ff0963ef9ad5145ab4cfce5d303a0cb0415b3b03f9d16e7d6b"); + yield return (Msg: "6ef70a3a21f9f7dc41c553c9b7ef70db82ca6994ac89b3627da4f521f07e1ae263", MD: "0afe03b175a1c9489663d8a6f66d1b24aba5139b996400b8bd3d0e1a79580e4d"); + yield return (Msg: "0c4a931ff7eace5ea7cd8d2a6761940838f30e43c5d1253299abd1bd903fed1e8b36", MD: "dc5bebe05c499496a7ebfe04309cae515e3ea57c5d2a5fe2e6801243dd52c93b"); + yield return (Msg: "210f7b00bf8b4337b42450c721c3f781256359d208733846b97c0a4b7b044c38dbb219", MD: "3305c9d28e05288a2d13994d64c88d3506399cd62b2b544213cf3539a8e92e2e"); + yield return (Msg: "3cb8992759e2dc60ebb022bd8ee27f0f98039e6a9fe360373b48c7850ce113a0ff7b2ae5", MD: "3c00bf3e12ade9d2de2756506f809f147c8d6adc22e7bb666e0b1d26469e65a5"); + yield return (Msg: "22634f6ba7b4fccaa3ba4040b664dbe5a72bf394fb534e49c76ec4cdc223f4969e2d37e899", MD: "a87e5c78837d7be0060d8f5eda975489ec961b28d7088f42a70f92414ae17793"); + yield return (Msg: "6e1dcd796b2015ee6760f98fdb40e668b2cf38b05c91f6a91e83bcc8ac59f816f90a59d64e8e", MD: "746bf845c08aa186b5fe1ca35528232c4a491a3a2a32cd23e990bc603f3268ae"); + yield return (Msg: "ee0be20320f9d44073281265a6e9fa6b9d252495624b8d016b8ef57e1b4e859d8ad3b50b89416d", MD: "a3257baf14ca16e1137dc5158703f3b02ebc74fc7677165fe86d4be1f38e2f7c"); + yield return (Msg: "8ae2da242635b6568289bf6bec8a438dbac1f5b4d50a90bb7449bdb92a59378e23452dbcabbbe879", MD: "e25c44802c5cf2e9f633e683d37aa8c8db8a0e21c367808121d14d96c8a400b5"); + yield return (Msg: "bdd0252dec5b798ef20e51791a18e8ca234d9bfde632a9e5395337a112dd97cdf068c9f57615424f59", MD: "e02c1b197979c44a5a50d05ea4882c16d8205c2e3344265f8fe0e80aed06c065"); + yield return (Msg: "c4c7b6315cb60b0e6cd01ef0b65f6486fdae4b94c6be21465c3a31c416ad2f06dcf3d6eae8eecf84ca7a", MD: "2da21867cd6b5402d3caff92a05fddfca90199fd51a94a066af164ce3d36c949"); + yield return (Msg: "b17977aced3a1184b14b0e41a04dd8b513c925ca19211e1abdc6c1b987ac845545fb3b820a083b4f7883c0", MD: "f91b016d013ede8d6a2e1efd4c0dd99417da8b0222d787867ca02b0ea2e80e45"); + yield return (Msg: "f65c3aa1d9981a84e49fc86d938f3f756f60e3858d5e1f6957dd4d268e28d68e90ba9a11d7b192d6c37fb30b", MD: "3acbebf8eda9d3c99a6b6b666366c391e8200d55fd33ad8680734def1dc7ae85"); + yield return (Msg: "49abba1fa98f3c4470d5dd4ed36924af4a7ad62f4c2dd13e599238883ed7d0cb95bbaae58b460332e6b7681446", MD: "02bcd9ea4f1aa5276f38e30351a14a072bc5d53a52d04d559a65ca46f1bcb56e"); + yield return (Msg: "275645b5a2514fe65a82efac57e406f224e0259677674f1d133f00a5ee9a6d1a8fed0eadbbff5a825041d2a9715d", MD: "c70a874d786cd0f3f09fa4dc1bb8f551d45f26d77ad63de1a9fdfb3b7c09c041"); + yield return (Msg: "cd02b32107b9a640fc1bf439ac81a5c27d037c6076e1cfe6ad229638037ac1550e71cf9557c29c2fc6017afd5a8184", MD: "36c73d11d450784eb99af068cd4e1cbc5768c8a2118010aceec6d852dda80d95"); + yield return (Msg: "5a72e0e1aec82a6541f04883bb463b0c39c22b59431cfb8bfd332117a1afb5832ce5c76a58fcf6c6cb4e3e6f8e1112de", MD: "90fc3193552ec71d3315ebbb807913afd4cd2f0833a65e40d011d64de5e66513"); + yield return (Msg: "43402165911890719f9179f883bbbc2a3be77682e60dd24b356a22621c6d2e3dcdd4cb2ce613b0dfe9f58629ee853e0394", MD: "5c4b6ceac9441defa99b10b805a725d4018b74b3e1f24ad8934fc89b41b8fd9e"); + yield return (Msg: "fc56ca9a93982a4669ccaba6e3d184a19de4ce800bb643a360c14572aedb22974f0c966b859d91ad5d713b7ad99935794d22", MD: "e21806ce766bbce8b8d1b99bcf162fd154f54692351aec8e6914e1a694bda9ee"); + yield return (Msg: "ace6297e50d50a11388118efc88ef97209b11e9dfcb7ad482fc9bf7d8deecc237ad163d920c51f250306d6cedc411386a457c7", MD: "f5581403a082bbf5ad7e09bdfccc43bf9683ebc88291d71d9ce885a37e952bd6"); + yield return (Msg: "3bad18046e9424de24e12944cd992cfba4556f0b2ae88b7bd342be5cff9586092bb66fac69c529040d10dd66aa35c1023d87eb68", MD: "faed76ff5a1cd99183b311e502c54e516d70a87050cf8961c8cd46f65c1358cd"); + yield return (Msg: "e564c9a1f1aaf8545a259f52c3fd1821ed03c22fd7424a0b2ad629d5d3026ef4f27cbe06f30b991dfa54de2885f192af4dc4ddc46d", MD: "811529c600c9d780f796a29a6b3e89f8a12b3f29c36f72b06cca7edc36f48dc0"); + yield return (Msg: "6043fa6465d69cab45520af5f0fd46c81dbf677531799802629863681cea30ffa3b00836fbf49f87051d92aaeac0ed09bcb9f0755b7b", MD: "b0fceecdaef6c76d5fc3835b523ce2416f4a9b9bd1f90234445df0f2b689f2f5"); + yield return (Msg: "2040c538c79237e6f2b8188c6375ec2f610ac2301607b9c23660c3a1e1c3a902cb2950c59aac3af28f984f6369c4debe8623dfa74c967b", MD: "e33dbdc0acc23fcfad3c759c4333410bd3a40efb1366ade157d2c81d65a0a6c7"); + yield return (Msg: "00ff6c96b7aa3cf27d036cf20af7031434113252574bda9cf9244d85aef2593d3a7a83bff6be904b75164a1766828042bc3f4f090d98a03d", MD: "d000eafca34815783bed9b050c6901c97f2e77d4771a0ed724dd8f6ff1448791"); + yield return (Msg: "e8df14936cce118139e690f1662f88cfbc9c333b6dea658c02cb1d959644592842542fd9d8d61a04d4a892128f0ddff7b6502efffbabe5cb0a", MD: "3479a9617a3adca35854c08fe987c2fe7ff2b01b04f2d952c107b3f066420551"); + yield return (Msg: "4ed981a31f70dd6b70c161be1f01fc1bba54d06d9494e7eb194e213d5e0e71e0fddd49cb1f075353da22624cbe4ba871aab32906e45b6fbb691b", MD: "9c824a00e068d2fda73f9c2e7798e8d9394f57f94df0edeb132e78e8a379a0cf"); + yield return (Msg: "7802b70c6158bc26d5f157671c3f3d81ab399db552b9f851b72333770348eb1fdb8a085f924095eb9d5ccfd8474b7ba5a61c7d7bcde5a7b44362cf", MD: "fa9726ccb068c0adb5d20079c35a318b3d951eb43b196c509ab790b7e9202207"); + yield return (Msg: "ff83dcd7c1a488e5a128d5b746284552f1f2c091615d9519f459bc9010ca5e0ac19796c4a3fd7a15032a55a1410737d07855b07f61fbd8f5759e9218", MD: "8bd8d494a41acda4b7cd2994badaecff0f46ba2743458f6c3fdc0226f9492ede"); + yield return (Msg: "afd4764cc7d5de16a3cf80c51d0c0d919f18700c7dc9bc4e887d634fe0a3aa94097d590e4123b73f11ccb59e23496a3d53d2bfa908056c11c52c23abfb", MD: "e9e3b3da648cf230f1973f3814eb81316d2a496826ea39adf4674576f97e1167"); + yield return (Msg: "6fa6de509719ffbf17759f051453c0ac3cbe13346546bbc17050541074b034af197af06e41142211ee906a476039b3e07d6cb83a76aac6fca8eac307c034", MD: "766630993fbb651fd8d3603e3eebc81931fb1302a46791df259a6e13ca2cba9f"); + yield return (Msg: "93cbb7e47c8859bef939155bea488090283ecf5023d99767c960d86baa333af05aa696fc170fb8bbac1e6473956d96b964580ee6640f0cc57be9598e55fc86", MD: "d3212abca1100eb7658c0f916daf2692c57a47b772ee031c4ec6ad28a4a46de9"); + yield return (Msg: "67e384d209f1bc449fa67da6ce5fbbe84f4610129f2f0b40f7c0caea7ed5cb69be22ffb7541b2077ec1045356d9db4ee7141f7d3f84d324a5d00b33689f0cb78", MD: "9c9160268608ef09fe0bd3927d3dffa0c73499c528943e837be467b50e5c1f1e"); + yield return (Msg: "4bef1a43faacc3e38412c875360606a8115d9197d59f61a85e0b48b433db27695dc962ed75d191c4013979f401cf3a67c472c99000d3a152227db61de313ab5a1c", MD: "8703a1f7424c3535f1d4f88c9b03d194893499478969fbb0a5dc2808a069ab8f"); + yield return (Msg: "f0be5e961bb55b3a9452a536504f612a3e66aec8160a882e5156eb7278433b7ea21de31e39383d57fcdfb2fb4a8d227a9d6085fb55cad3abb78a225535da0e34efea", MD: "2fa180209bf6b4ad13c357d917fabb3e52c101a0cdb3f2299fa0f7f81dfb848e"); + yield return (Msg: "206f1c36ba25aea73398fffc9b65c4637cc1f05a6bbee014dccbd61e3b7aa9423887bbac62152a4bf73a4b7afabe54e08720589464da7985d8e6591ac081d115df2fe6", MD: "558ea7c800b687380cce7e06006e1ebe0b89973f788c4caac5780f22dbf382e8"); + yield return (Msg: "8cd71434c00663f3bda0205508a4a266548dc69e00ca91fde06d165b40279af92674f75bd8133e5a9eb9a075c9068f68f4b820008a1fb42d89d1d759859e68f8efc6fb60", MD: "085b343b08516f320a9b90fe50440a8bc51ae0850fa38d88724a4d6bd3df1ad4"); + yield return (Msg: "4cf5bbd91cac61c21102052634e99faedd6cdddcd4426b42b6a372f29a5a5f35f51ce580bb1845a3c7cfcd447d269e8caeb9b320bb731f53fe5c969a65b12f40603a685afe", MD: "f9dbb88c5bb4415e17dee9222174538eeab371b12d8d572cfdf55b806e3158e4"); + yield return (Msg: "e00e46c96dec5cb36cf4732048376657bcd1eff08ccc05df734168ae5cc07a0ad5f25081c07d098a4b285ec623407b85e53a0d8cd6999d16d3131c188befbfc9ebb10d62daf9", MD: "3571326a1577c400b967ac1c26df2a0dcf5db7070eac262a8071da16afa7c419"); + yield return (Msg: "981f41a83d8f17f71fc03f915a30cd8ac91d99aa1b49ef5c29fb88c68646b93a588debcd67474b457400c339cca028731df0b599875ab80df6f18b11b0b1c62f2a07b3d8209402", MD: "62aea8760759a996f4d855e99bcd79e9a57ea362522d9b42fd82c12c9294a217"); + yield return (Msg: "5c589fc54fefc4d6e2249a36583e1992fc6b8a9c070e8e00c45a639af22063e66ae5cdb80238c82db043a5e1f39f65626e6d7be5d6a2d3380fa212f89211200412e5e4315fc04e40", MD: "18deba74e9d93ae7df93c6c316ef201bf5e3a661e68868e14d4f56264f5d858c"); + yield return (Msg: "7c8691e7b2560fe87fcc5e2877f7e3c84d9101eca4818f6322a58986c6cf05627c0d6919ef2edc859f81fa1f33e0cc1f10edf7e52a9c33981af2ff0d720c94ea4d62170b2a4d1224fa", MD: "5a5a438b57c1b3ce8756094252362afeaa9fc91cd45b385d16994ec8af49aa6b"); + yield return (Msg: "97359b564b2bc20800ed1e5151b4d2581a0427ce9539d324c3637cfb0e5378dc2cf6d72946e2a3535a2f664ede88ed42a6814c84072b22c43de71e880a77c2d9a05b673bc15a82e3255f", MD: "be54f2e435f760d5b77c0ae61ef0aa7f5f3366f47819f350dc8a39aff8c73a8f"); + yield return (Msg: "a0dfaecd3e307c5ddf9a93603f7e19725a779218734904525b14586ff0ce0425e4efe7e1c06e745c28ed136f6031c4280fd4061d433ef700b6d1bc745064231fecf387015f94f504b6ad8c", MD: "60d80f1c703dad5da93db222fb45fb7fa768c8aa2787f4b81f1e00365b8f49e2"); + yield return (Msg: "568d66d061306c3419a1928ce7edc8e3400c30998f09bdac6f63ff351eb23d362e8dc5927eac805d694ac9563dcd7fb2efa9591c0d827af9f39146f0424873aa8e3963d65734b1713baf0a44", MD: "7a4fe37f296991121792dd7c2c30390725a1eebbf20b766a5a1c3c6c3646d996"); + yield return (Msg: "d65b9f881d1fc7f17d6dd429faca8404e6ce60fba7d89b7fba003c8ef84d8083182979327611fc341291ba80dc70ad3b2f28b6d29b988445e7fdb7c6561f45822ac81dbf677a0b27d961dc6358", MD: "51cc71b6934afcf28fa49942b76323f36cd6a0aecc5a0e49c10994ddcabdbb80"); + yield return (Msg: "711c88adf13e7a0e694652f2b9a397543f4937fafb4ccca7f1ad1d93cf74e818d0fedfaee099f019014ec9e1edfe9c03fdb11fe6492ad89011bf971a5c674461de15daff1f44b47adad308baa314", MD: "1780e52e306858478290c46b04d8068f078a7f6ad8e3790a68fc40dccfbdadc9"); + yield return (Msg: "f714a27cd2d1bc754f5e4972ab940d366a754e029b6536655d977956a2c53880332424ddf597e6866a22bfca7aa26b7d74bc4c925014c4ed37bfe37245fa42628d1c2ee75dc909edc469ee3452d894", MD: "f4afa72f3e489ad473dc247aae353da99fb005b490e2c4e1f5bd16a99732b100"); + yield return (Msg: "fe0c3280422c4ef6c82116e947da89f344d6ff997bf1aec6807e7379a695d0ba20ae31d2666f73bbdbc3a6d6ac2c12dcfb5a79173dfc9cd2e0d6000e3114f2767edec995772c6b47dadc136d500251e5", MD: "89198e2363efd4e0ba7a8a45f690f02712e6f856668517bae118d11e9a9dc7cc"); + yield return (Msg: "02e238461d0a99d49c4cd16f442edf682c39b93114fc3d79f8546a99e5ead02f0cfc45081561da44b5c70eb48340418707fd6b2614580d5c581868ba32f1ee3ac34bf6224845b32ba7f867e34700d45025", MD: "abef81b33591eedcac0cf32fb5a91c931f2d719c37801409133552170ce50dbf"); + yield return (Msg: "fb7c8cd4031007f8159d5c4c6120dee6777a3ace0a245b56f31e8aae7828dab3cf35c308de1d0d684592ef3a9e55796603a92f68d109f7a3ac1635f7c4d334955614c812753431bb0a0743291a0fc41547f3", MD: "5a67284d39e4f37caa64ca1a54593c35f6d8f3a3ec20d460393a39f6f57c4486"); + yield return (Msg: "6b2e868c7d0ee1c240d3a67e2fdf36e8e23817c02644a54453d10454da5859d41e833a5285ec63e8ce28aa64a50435a7740eea4b7d5827892678b35993d3f5da7a1c64f533173f3d0fa37e1aebf70827052c26", MD: "aecf5dab6fea9ffd1bce2cdfeec0bee9d214a669e8306d5b6688afa8957fc91f"); + yield return (Msg: "e5f3ba000c43bb6aca4e0a711a75912a48241cffa5b4b0b17f901f9e5097d94036c205f7a307d008567d05e58ac0dfaf6d971bf9d3d450cf2c7c83f6b328f676e9ab425642f5a5a71e389dc4fa49b6d7e848a09f", MD: "182d6e4316f4bc18d7163b1b21462d99f99c6f34d2c00ee771ce54fd6c5018b9"); + yield return (Msg: "939c61e68af5e2fdb75a2eebb159a85b0c87a126ce22701622f5c5ef517c3ab0ed492b1650a6c862457c685c04732198645b95f84ccb0e726a07ce132827a044dc76b34d3f19a81721f1ea365bc23e2604949bd5e8", MD: "121057b0b9a627be07dc54e7d1b719f0a3df9d20d29a03a38b5df0a51503df93"); + yield return (Msg: "9eadaf4811a604c65eaa7b1c6e89f2c0ab96bebec25a950ba78aac16d9371ca1e7458acf331e077ef6a735d68474ab22d2389bdf357fb2136c9f40e1e1eb99592c2bbb95d94931016b4d37faa08b1e9bf71bf2d3708a", MD: "c237194b902e48dca5bd096cb51562079d0cdccb2af8088197676c17b0896be2"); + yield return (Msg: "71dcca239dced2ac5cc49a9bf9ea69a99be22ba62216716b524db80f337dee5eb7e032869e4adc1497babd1fa82fa8c3cfbd30d2eadfb4c5d40f99f9d194d7182c9cb7d41e8adbdcf2917e086782fdd756e2961c944070", MD: "377d1cffb626735810b613fd31ef9bbb4577cd752521abe3a41afa921e623da0"); + yield return (Msg: "ea130d3236bca7dffb4b9e50e805309a503e7347227aeb9f1bd15c263a98dd65753d2eedaa734b9ad88f41158f32419ca529f3062b910c019f3f239f635fc1116e5ab7b242feb4471ed9168474e501d39d6bae52cc21061a", MD: "85c7a52d53f7b41162ea9f1ef0d07c3fb8f0ec621617f88cb3828ebe5388ab3d"); + yield return (Msg: "28f1be1156792af95c6f72e971bf1b64e0127b7653ff1e8c527f698907a27d1544815e38c7745529bc859260832416f2b41cd01e60c506239a7bf7553650bf70d1fe7a2c1220ac122ea1e18db27490447d8545a70bf0ffc8fa", MD: "b2eb3762a743d252567796692863b55636cb088e75527efd7306a2f6e3a48a85"); + yield return (Msg: "c8400ef09c13e8acc8a72258f5d1d20302c6e43b53250c2f6c38ff15be77e3cac04d04b8421fc8fdff8be5ca71edd108e9287b42dea338bf859100eea376da08a0e695f0dc90b95e467cbd3c2a917a504a5ae01c310ae802c4bd", MD: "69966e89b7bc7f39cd85791b92180ff3fed658d8240e393e1e6d7c24b8d0ac95"); + yield return (Msg: "a48950c961438e09f4d054ac66a498e5f1a4f6eabfde9b4bf5776182f0e43bcbce5dd436318f73fa3f92220cee1a0ff07ef132d047a530cbb47e808f90b2cc2a80dc9a1dd1ab2bb274d7a390475a6b8d97dcd4c3e26ffde6e17cf6", MD: "44c00cf622beca0fad08539ea466dcbe4476aef6b277c450ce8282fbc9a49111"); + yield return (Msg: "e543edcff8c094c0b329c8190b31c03fa86f06ace957918728692d783fa824ba4a4e1772afbe2d3f5cba701250d673405d2c38d52c52522c818947bcc0373835b198c4cc80b029d20884ac8c50893c3f565d528a0cb51bf8a197d9d6", MD: "6d5260384f3cefd3758fb900dcba3730d2b23cee03d197abeff01369dc73c180"); + yield return (Msg: "4e10ab631718aa5f6e69ee2c7e17908ec82cb81667e508f6981f3814790cfd5d112a305c91762c0bd9dd78e93ef3a64c8be77af945b74ff234a0b78f1ed962d0d68041f276d5ea40e8a63f2cab0a4a9ed3526c8c523db7cb776b9825b4", MD: "d88e5f3b2d0a698fd943233760a3000a3360d9040e7374b22e39ea58d868102d"); + yield return (Msg: "604d8842855354811cd736d95c7f46d043a194048b64bf6cda22c3e0391113dcc723e881ae2ad8dc5740aa6bda6669ddb96bb71acd10648380693f7b3d862c262553777004bd6852831618519fbb824759f4dd65af1b2a79cc01096d7c8d", MD: "8a8ab6cf5c02b9ae8f4c170740eff1592f3eda11d3420ac8b421d93cfbb35db8"); + yield return (Msg: "628180e14f41ebdfde3b4439de55ee9cd743d41040f3457ef2280370dd659619fa0ce69580c709725b275a6eda8bcb82a8447c20fdf68cba15412f83e2a10079fe9399a3e3fa61975ec0a64041c0ecde59e4844e9f8a608cb22d2576854182", MD: "8d154bf6f9cb72efc0d8b3927a8f690060d1d48bbe5cc72094d2c8b149a75132"); + yield return (Msg: "fc150b1619d5c344d615e86fca1a723f4eeb24fbe21b12facde3615a04744ef54d8a7191a4454357de35df878cb305692278648759681919d1af73c1fb0ff9783678aec838da933db0376e1629fcca3f32913f84bc2ff3ffc3f261d2312f591c", MD: "3f626c8bb20a132495bd3022b3fcd0ce0604b91a9d70132dab4099f73dde23d5"); + yield return (Msg: "6dadbecdd15e5646e3f37a6fe5b328e06113cce3c8cf07285939afba44d117321017902b3a9d2ff51f60d18e1b585dcdf34e49e170ee60fa4d1dc246548d2c1fc38e7983f42769c43d65a28016f3f4d479ebe1cd8fec5d1f886dd21aca5067d94f", MD: "9098ea34c40b541b153e80a8bd92da19432b18b7d329760b302f8a54c395dd06"); + yield return (Msg: "9cc5fd3035b72dc63b8c3c326fd013081e6b8716f526d3fe176b45256d4c37cc3dc8417dff49ada96c702b8fd715c65fc08a17a0a720b9cf1eedfd4922ccde6baba437f782ee33b95371056b0350dad743470c3b663299f16fcfd34f6fc459cd0ee4", MD: "b0c04f24bb6d3d4fcbfdf9222d0e886f1eb60a0566a478085f7623a025a5b981"); + yield return (Msg: "f3f063fbcf2d74aa5a02d240c962ed7bb119b3a212bdb41594e28428108e613152ed16e01e451fcf702b0e5a08f82eb12677652b93e05fdee00ae86cf2dc9a1fbf05b93952ec5b8515eacc324fb830e1ec236afd7d073d4b7f7ab1c2e048b99cbfa012", MD: "f930d79360b581b1bbfdeac57133a339444f5c44538c921631eabaf058277d32"); + yield return (Msg: "840739a3d6992c13ec63e6dbf46f9d6875b2bd87d8878a7b265c074e13ab17643c2de356ad4a7bfda6d3c0cc9ff381638963e46257de087bbdd5e8cc3763836b4e833a421781791dfcae9901be5805c0bbf99cca6daf574634ec2c61556f32e642730510", MD: "19795657e08cfbb247a17cf209a4905f46e4ddf58eea47feee0be9bb9f5c460f"); + yield return (Msg: "4a51b49393ab4d1b44fb6dc6628855a34e7c94d13b8b2142e5d5a7bf810e202cefdca50e3780844a33b9942f89e5c5b7dd6afb0a44541d44fb40687859780af5025fecc85e10cf8249429a3b0c6ff2d68c350c87c2fcbf936bd9de5701b2c48ce9a330c9ee", MD: "128fb4114e43eefd19277c708be9e6873e66d7fd59c58a1485b7b015facfa795"); + yield return (Msg: "afc309e6b7b74dfb0d368e3894266fc4a706c3325e21f5550d07a6560e3d9703c134ca6ad078e4a7b82ad6fa85b0bc1ddcab05d43f29d5c58d1da78ac80c37051b089ff31ce2c0c44e9ce3abea1da0f1df28008e178fdefafca493413bf1d256c729d0a9225e", MD: "03e782b01a4ba10f640470bb3cae487eb9cbbaab8c9941978b194f6a312cf79e"); + yield return (Msg: "c5ae750f2230642092397b84ad5526c46ae9480ada16892816e0f2db7690b751035653ea2f33da3cc4168b591b46a5548eff7d012f60ccfdbb854deec9f0880c472de8e127b5144c56147cccee4732fbac68fc59a48da74b33ed9e643644bbe279795c7c737eba", MD: "f64b7ab243ce6e6c04b483888ba8a655465c21d95eb60c7b8d6e566a3811bae2"); + yield return (Msg: "603e13f61499e12ec6b33b68847a281d314f54dc705c0f3fc428981ff5689c04b519fadf83cbc9fcd0409c326035045df480570e265bb080940037ce4076a36437aafdb371c1a62af9ad9b614dfef89708fbbb5ebef2cb9528cc399781e4c5b22f1aa4dba623809f", MD: "5f76962fd3d373e5db2953c0823a51fe81f874450bedf7e46876394b04d3ef66"); + yield return (Msg: "e03115cfa19efcd796da389063c4be6acce684d983f8edfb3da6887b0b94fbb5e89e3a1a8e64fdd68f0670b1a02c2c33384a660c5a2266b3ae8a3b4cd76faecf011a7467b9b2a818020278a5a57d1eb1c87f1224c2d67dd02e81f1553eb75841532c2b7cca8fe5e418", MD: "d107ee6ee4a58871a33c49657faa2573e475f11918c4a4e3801d0e17fb93c6e3"); + yield return (Msg: "0e6c1d58b1b9d3a2d399aafd60529e07d483a2755bb7e44c373b5355632d5fca76d6ff56c93af93ddcec5ed6f62753420c1b1758e48542df7b824b00a3a54dfaf0470b18d51e31e10b12dd8e324b5dc1bb8f3b7305cb762ec6ef137dadffd4a2466748861d9004f626b0", MD: "02ab2dbb02944354799051247b1a25c19f3696e1afcb502b859e83798b33fd77"); + yield return (Msg: "6db2a43a229b10c3629249fc5136468b4d84df7b89ec90ebf7aa7a036c53aa2dffae9e81b2c60580543dc706a5e3457abc87e248a60ec29150c2d221a6ec08a1fda4ec0daee8576904ec7ab059b1230e7bd93c4e55ba9496cbb1e352e5b8086e303b94c861288ce53c466b", MD: "8cc4d39b2f5ba0bc9d2ee2a8777cf08533e60cc69b65a7b31c5c2121193aa31e"); + yield return (Msg: "31d995f7ff8b6de70829a8336c610f10df2c866107a4922b25151849f8566861df5a79163d02767f21357ad82733997899261f03dafb1ce1056f20efd16d4374b89768565823c38e19e899d910b847b023f1867b6e4fed02e604b8243c0bc7cb05b9ea1f17955bfa36698c9c", MD: "c99c7191b34c9ad3f941d4ad442cc865205cbb4c2a6927c592e831cbc4d36fcf"); + yield return (Msg: "cb0b8cb7de621c8e0a0fc6be2fc18d0e8818a2c2dd0b3219fa87831a61583f903c4d105495976ccac973b3ae3a09771145931a9e74c19f22f45cba4c492b29b1401347122581dfe2370d3e0359578cd10a355c619711810a8f8c232578671312c0a45c7cf7e81bdd3b249044f3", MD: "6d2f57a7e42b35369cf2cd60caf9e65aca7d9aa019e6824bb806348f1acf3c7c"); + yield return (Msg: "48dff78aed5f6e823054924a78dc1b8e51a117f1610181529f6d164ebf0f6406f0b02422cad8c916823759a361437ca17423d3fd84cc8afe486a31ccda01c732685418a32c064a7b9effb288e811ecc99adb2a759feecc3f702f31d9877dcdb717937c15fa2f163bea744400f58c", MD: "14b631f0f00a3024ad1810dabf02711e28449668abe27f69380942268968d4f6"); + yield return (Msg: "06cc9fa542ceb35c88fb6ab82c29d5dcd530f807d3f1c3bcb3974421101d1aa6ac112de6bf979cd28eb0f70c40bcaf91ed3eca9bf9e0dbc6a0b73271d1c7506740ca9ebfb72d5e00ac5ce189193ffa308804b42a6d20402bb99031cdac65ec36eb7f59f5d299df2e0b8690f760b9a0", MD: "574fd82a9fceb8f7bbbf244d16e0412cbda8153b720846c32b8f10fe5779a881"); + yield return (Msg: "8d93627c0b7cbf61a7fe70e78c2c8ed23b1344b4cfed31bd85980dd37b4690e5b8758f7d6d2269957a39a1ac3451cc196696ae9e9606a04089e13456095a1ce1e593481b3ac84f53f1cb10f789b099f316c948398ad52fa13474bdf486de9b431bd5d57ef9d83a42139a05f112b2bd08", MD: "344ec86642eabb206b2fd930e4c5dde78aa878577d6c271cb0069d4999495652"); + yield return (Msg: "d0af484b8be6b41c1971ae9d90650a1e894356c9191d6be303fa424f2b7c09544ec076a0f1865c8c97927ca137529d5bedc0df2ef08a4cc7c470b094b1eeaa86731c041633d24086b60f7369d59c57652dec9b3817477df9db289ba020e306c9a78a99b539128992deb23cfc508c5fc3af", MD: "b7ba998726477c32792e9c3eddc1cb6feb7c3933e49f2e7590d8ce7a2113e6f8"); + yield return (Msg: "b212f7ef04ffcdcf72c39a6309486c0eeb390ff8f218d6bd978b976612f7f898c350e90bd130723e1126af69295019b4f52c06a629ab74e03887020b75d73f0f78e12785c42feb70a7e5f12761511c9688c44da6aaa02afa35b31edc94c3a0779b6ab9462525c0ccfba76986f873fe1e6ba9", MD: "2f26b96c1fa3f3dee728f17584e733b4189821c659b8885a5fb1d12d60d2aaa9"); + yield return (Msg: "86591ada83fba8175a0fe91d264e7f9b2df97ee4c32570e76b579d6140508951932abdadd6a4ca53b8bb8c42927aac0a02126881d52d97b82b80e72dd59f6a42021651ee1bb5f7b3eb2b21d003d784b75dda87c13f714b216282e8175474fa661b445d071bd5341f3a88302f410d0f8a857962", MD: "e3edbc8c42ce5d2384dfb24fb1de5d4798b1bc3cc78c97033894040dfa6feb6c"); + yield return (Msg: "92b5a8e84b6a2ac4d5b1e61d63804abd641dd630058ec6d5f752f135724ef1947a0a84c6611d32448de6307f7b7d857404e96b81df94f87768fcfdf09faa2fe37468847542afe012995ff1bd40b257a47a7309f8896bf4fb711de55bfeb3a8be0837729ef6067c578182f17ebb080a754f22773c", MD: "80ed0a702812297c2aa1b6b4b530c2b5ed17ecfba6d51791cf152d4303ced2e6"); + yield return (Msg: "d284a0a9a4de5d4c68cc23884c95ad7619aa39b20a2cf401deaeb3362c3ce356f79cc3fa82d3d1f565ec8137e1f435f171496afaa1152f722315dca5209f0031cce39b6c3d718e007dfb4fd8de5ce1408dda04476aa8a96817afa86a4f8fb5857ae091c67ebd7db5d783f434ead699aa96e56f610d", MD: "654eccefd0a4fdb2ac0ab56288c64399b37bc4d57ff4a9f1cce94362fc491bda"); + yield return (Msg: "f57f0f8795385b805246a0a2573afc274346a9eccf50c626b0455a50bfb09668578b5a5afe54fbbd486444bdf97dba586aa224ce2e2b4b52f418ff06afa65a26f5204983a5f84734cd166c88cb70a73fb2db48f9ef20c1ee2c53ade07460114e98e7e2ebd24ac84ea90422eb143c4a42e2991a565959", MD: "135ec8b144a667dceae8fadd287df81c10ef3ebef87ff2fb56e60ae708a88f3b"); + yield return (Msg: "2a41a52e6578873588a57f11f1be7c7eb398d01f3bfdec2c33fe6b65a68a534a6540978daa82e0c8fccb8c6c5242f7f97b8ffa75bdedb217bd8083439eea5cbb6d193c13bd62f5658ed4304774c6b1faf5b3dce432487840cabab415fb5d67640a739ca6e5414e760869708a9d7331e7e7ad7d55e035c7", MD: "a6a1b8a26f6f440f19f16dce1d3001477d73ee7f6c374bce2922167b81970d6a"); + yield return (Msg: "4d11aa5d3c6b6900f49ff90dd815744572be5648b64bde638b9db7a9877dd745fa8ea80e2f7f655cee85c71a4509e21d899e49b4973579815f947587a404ad83fd4a248020d9d2a65f46485373fc926d793161f63a196ae0af590923c5be2a0e5d2f69da97e0788550c9c1dee9574ddc4a61e533275d7729", MD: "fc5159f0ddd6d765c85fcc3fc3ac1dc0d317d8ea0b110e96ac9f7a398dc386c5"); + yield return (Msg: "05cd99bfe031d123ca7061d3de0956f4bbf164bad792db881713d6599ddab55ee24fcee804e360896152c8766424f8309f7a24641a07be0feb5da5e5076a9af45842f385101f93433ca5199f9c6b5872b2b808e4198aba8e18dd12db772930b4912d6f5cabeb529884f4bb142de55e021b3276047b22b64cc5", MD: "8aa07742e6f1f47ad020ed6684edc8dba4af36b782955f0f972be3ae980aea0e"); + yield return (Msg: "529684398d68bdc19e7a00ce32cc1a8c1315b97f07137474f61f0cb84a04f2879b1109c78c6dacf7f0abf362329e3298f36fc31ef4ec06653723a5f961301dfb63537ad15946611cb2cd54ea928e322e7423fd6d146ee0b98c2c71e3bdcd33edf0845fbebd9ae4192d07acd01b432135e05af0d22f3f0c5a3d62", MD: "a07049b6ebd7b355479a3d802fda436b83ae6747d741cf9626f7c62f47cbd563"); + yield return (Msg: "982fb5f4af498a4a75e33a033235ea3ddb70d9d236519f883ff5b388cbef30126b98d96e93a65a26fb00d17246d18cf4e2db14a52f0f6b10e35a93beadc14ff118b02e95b38fc4736f973ba848e40b5527cb0599076d96bc578c4aada09e8faf6820bc4f562d5199974f808b7f95edca74e6b3940894a7f66534e0", MD: "09c60fec5a089a23f5da3ed2492aa21fcf7aa36183850fafc15ae8c63f596db0"); + yield return (Msg: "ca88614828f8acdb5fcffab6bb2fb62d932b7808e4d9cc3139a835b0cef471d9f4d8ffc4b744dffebf4f997e74ce80db662538bceb5d768f0a77077e9700149ea0e6a46a088a62717216a14b60119dd19c31038ed870b4709161c6c339c5cc60945a582263f3be9a40cd1a04c921947900f6e266f2390f3c970f7b69", MD: "fe2d4183ccdaa816b4446a9b6c07d0ba4b42ac743599db5dc482b1941f443c71"); + yield return (Msg: "ab6b92daf83275cb9c1b76cfb59fbcc8ac53188e0b6980918e7ac0c07c836ca9372d19e11251cca664bbb3c3db2e13b412a9820b65e95612042f5db24643cf9340b9808597735a1f92670ba573a2fb2f088d81087d70565574344af7576d35b2ed98318e2ca0067d4fa8e63f28045b83b6887d4ffa0668a10712ed5759", MD: "744538e1ae1cd7357710b56c3bc6f1bd7a8564118a1e0f9acc30fcf0b5396eef"); + yield return (Msg: "bfd4c7c8e90858ccf9c8834abefd9c1846ca4a11966fdd139d6de24a6bebf4b19f58d5d51e52bddd0bc6f1c7f35998f44707cae7100aeb4adefe373101429da3fca1d15737329dbbf47c783a84de59bfbb2fcd75a1a148d26aebb8d3a9a76089c0f8e4d49b71a06f9e323e2cdb54888189887a44b1fa9cb32b7c8fb7c9e0", MD: "58b17843bc851a721c5a258eef57b3854d02190e732d9b8e7a9f926ac409c173"); + yield return (Msg: "c5019433c285da2bb93f119e58b4f36cd1e4d99dda35dbf4f8ae39c7fe65fa0ed03bd2b96dc649472d8f1a94477ed9f29592d97c9cd54da7c790ad1af3bb5cc030b7871bc64050db779d2caf0419895bf3b7b50b8e22fbe62fe30fe7bbd6ace86ddf7b00d5d9370f20cf0f97996f4bce70bb33f1ba022cdaba0f25d55fa031", MD: "f7c92a3fb7f180370d628be78de874d693f74ccc7a54c741634258d8c512fd7f"); + yield return (Msg: "84b60cb3720bf29748483cf7abd0d1f1d9380459dfa968460c86e5d1a54f0b19dac6a78bf9509460e29dd466bb8bdf04e5483b782eb74d6448166f897add43d295e946942ad9a814fab95b4aaede6ae4c8108c8edaeff971f58f7cf96566c9dc9b6812586b70d5bc78e2f829ec8e179a6cd81d224b161175fd3a33aacfb1483f", MD: "8814630a39dcb99792cc4e08cae5dd078973d15cd19f17bacf04deda9e62c45f"); + yield return (Msg: "14365d3301150d7c5ba6bb8c1fc26e9dab218fc5d01c9ed528b72482aadee9c27bef667907797d55514468f68791f053daa2df598d7db7d54beea493bdcbb0c75c7b36ad84b9996dca96354190bd96d9d7fbe8ff54ffaf77c55eb92985da50825ee3b4179f5ec88b6fa60bb361d0caf9493494fe4d28ef843f0f498a2a9331b82a", MD: "9b690531dee948a9c559a2e0efab2ec824151a9175f2730a030b748d07cbaa7f"); + yield return (Msg: "4a757db93f6d4c6529211d70d5f8491799c0f73ae7f24bbd2138db2eaf2c63a85063b9f7adaa03fc348f275323248334e3ffdf9798859f9cf6693d29566ff7d50976c505ecb58e543c459b39acdf4ce4b5e80a682eaa7c1f1ce5fe4acb864ff91eb6892b23165735ea49626898b40ceeb78161f5d0ea4a103cb404d937f9d1dc362b", MD: "1ac7cc7e2e8ea14fb1b90096f41265100712c5dd41519d78b2786cfb6355af72"); + yield return (Msg: "da11c39c77250f6264dda4b096341ff9c4cc2c900633b20ea1664bf32193f790a923112488f882450cf334819bbaca46ffb88eff0265aa803bc79ca42739e4347c6bff0bb9aa99780261ffe42be0d3b5135d03723338fb2776841a0b4bc26360f9ef769b34c2bec5ed2feb216e2fa30fa5c37430c0360ecbfba3af6fb6b8dedacbb95c", MD: "c163cd43de224ac5c262ae39db746cfcad66074ebaec4a6da23d86b310520f21"); + yield return (Msg: "3341ca020d4835838b0d6c8f93aaaebb7af60730d208c85283f6369f1ee27fd96d38f2674f316ef9c29c1b6b42dd59ec5236f65f5845a401adceaa4cf5bbd91cac61c21102052634e99faedd6cdddcd4426b42b6a372f29a5a5f35f51ce580bb1845a3c7cfcd447d269e8caeb9b320bb731f53fe5c969a65b12f40603a685afed86bfe53", MD: "6c3e93f2b49f493344cc3eb1e9454f79363032beee2f7ea65b3d994b5cae438f"); + yield return (Msg: "989fc49594afc73405bacee4dbbe7135804f800368de39e2ea3bbec04e59c6c52752927ee3aa233ba0d8aab5410240f4c109d770c8c570777c928fce9a0bec9bc5156c821e204f0f14a9ab547e0319d3e758ae9e28eb2dbc3d9f7acf51bd52f41bf23aeb6d97b5780a35ba08b94965989744edd3b1d6d67ad26c68099af85f98d0f0e4fff9", MD: "b10adeb6a9395a48788931d45a7b4e4f69300a76d8b716c40c614c3113a0f051"); + yield return (Msg: "e5022f4c7dfe2dbd207105e2f27aaedd5a765c27c0bc60de958b49609440501848ccf398cf66dfe8dd7d131e04f1432f32827a057b8904d218e68ba3b0398038d755bd13d5f168cfa8a11ab34c0540873940c2a62eace3552dcd6953c683fdb29983d4e417078f1988c560c9521e6f8c78997c32618fc510db282a985f868f2d973f82351d11", MD: "3293a4b9aeb8a65e1014d3847500ffc8241594e9c4564cbd7ce978bfa50767fe"); + yield return (Msg: "b1f6076509938432145bb15dbe1a7b2e007934be5f753908b50fd24333455970a7429f2ffbd28bd6fe1804c4688311f318fe3fcd9f6744410243e115bcb00d7e039a4fee4c326c2d119c42abd2e8f4155a44472643704cc0bc72403b8a8ab0fd4d68e04a059d6e5ed45033b906326abb4eb4147052779bad6a03b55ca5bd8b140e131bed2dfada", MD: "f82d9602b231d332d902cb6436b15aef89acc591cb8626233ced20c0a6e80d7a"); + yield return (Msg: "56ea14d7fcb0db748ff649aaa5d0afdc2357528a9aad6076d73b2805b53d89e73681abfad26bee6c0f3d20215295f354f538ae80990d2281be6de0f6919aa9eb048c26b524f4d91ca87b54c0c54aa9b54ad02171e8bf31e8d158a9f586e92ffce994ecce9a5185cc80364d50a6f7b94849a914242fcb73f33a86ecc83c3403630d20650ddb8cd9c4", MD: "4beae3515ba35ec8cbd1d94567e22b0d7809c466abfbafe9610349597ba15b45"); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs new file mode 100644 index 00000000000000..c44ef67bc50ef6 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs @@ -0,0 +1,164 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + public class SHA3_384Tests : HashAlgorithmTestDriver + { + protected override HashAlgorithm Create() + { + return SHA3_384.Create(); + } + + protected override bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) + { + return SHA3_384.TryHashData(source, destination, out bytesWritten); + } + + protected override byte[] HashData(byte[] source) => SHA3_384.HashData(source); + + protected override byte[] HashData(ReadOnlySpan source) => SHA3_384.HashData(source); + + protected override int HashData(ReadOnlySpan source, Span destination) => + SHA3_384.HashData(source, destination); + + protected override int HashData(Stream source, Span destination) => + SHA3_384.HashData(source, destination); + + protected override byte[] HashData(Stream source) => SHA3_384.HashData(source); + + protected override ValueTask HashDataAsync(Stream source, Memory destination, CancellationToken cancellationToken) => + SHA3_384.HashDataAsync(source, destination, cancellationToken); + + protected override ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken) => + SHA3_384.HashDataAsync(source, cancellationToken); + + [Fact] + public void SHA3_384_Kats() + { + foreach ((string Msg, string MD) kat in Fips202Kats) + { + Verify(Convert.FromHexString(kat.Msg), kat.MD); + } + } + + private static IEnumerable<(string Msg, string MD)> Fips202Kats + { + get + { + // Generated from SHA3_384ShortMsg.rsp + yield return (Msg: "", MD: "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"); + yield return (Msg: "80", MD: "7541384852e10ff10d5fb6a7213a4a6c15ccc86d8bc1068ac04f69277142944f4ee50d91fdc56553db06b2f5039c8ab7"); + yield return (Msg: "fb52", MD: "d73a9d0e7f1802352ea54f3e062d3910577bf87edda48101de92a3de957e698b836085f5f10cab1de19fd0c906e48385"); + yield return (Msg: "6ab7d6", MD: "ea12d6d32d69ad2154a57e0e1be481a45add739ee7dd6e2a27e544b6c8b5ad122654bbf95134d567987156295d5e57db"); + yield return (Msg: "11587dcb", MD: "cb6e6ce4a266d438ddd52867f2e183021be50223c7d57f8fdcaa18093a9d0126607df026c025bff40bc314af43fd8a08"); + yield return (Msg: "4d7fc6cae6", MD: "e570d463a010c71b78acd7f9790c78ce946e00cc54dae82bfc3833a10f0d8d35b03cbb4aa2f9ba4b27498807a397cd47"); + yield return (Msg: "5a6659e9f0e7", MD: "21b1f3f63b907f968821185a7fe30b16d47e1d6ee5b9c80be68947854de7a8ef4a03a6b2e4ec96abdd4fa29ab9796f28"); + yield return (Msg: "17510eca2fe11b", MD: "35fba6958b6c68eae8f2b5f5bdf5ebcc565252bc70f983548c2dfd5406f111a0a95b1bb9a639988c8d65da912d2c3ea2"); + yield return (Msg: "c44a2c58c84c393a", MD: "60ad40f964d0edcf19281e415f7389968275ff613199a069c916a0ff7ef65503b740683162a622b913d43a46559e913c"); + yield return (Msg: "a36e5a59043b6333d7", MD: "bd045661663436d07720ff3c8b6f922066dfe244456a56ca46dfb3f7e271116d932107c7b04cc7c60173e08d0c2e107c"); + yield return (Msg: "c0920f2bd1e2d302259b", MD: "3d1584220409f88d38409a29ecaebb490ef884b5acba2c7eaf23914bab7f5f0fc97ee1e6336f88dfd4d0a06e902ccd25"); + yield return (Msg: "70ae731af5e0d92d264ec9", MD: "563359fd93fe09f3fe49fcf5f17e7f92aab589cdec3e55e4c3715e7775814bbbfb8c4c732e28d3b6e6404860812dc6e9"); + yield return (Msg: "69c74a9b0db538eeff64d93d", MD: "88c66389ca2c320a39022aa441fa884fbc6ed2d3cc9ac475372d947d4960579a64e061a297d1831d3524f98d8094404b"); + yield return (Msg: "a4a9327be21b9277e08c40abc7", MD: "751f5da5ff9e2460c99348070d5068d8a3d7ffcec7fd0e6f68f6cd4a2ef4226df8d9b4613c3b0d10a168eaf54eabe01a"); + yield return (Msg: "cc4764d3e295097298f2af8882f6", MD: "10f287f256643ad0dfb5955dd34587882e445cd5ae8da337e7c170fc0c1e48a03fb7a54ec71335113dbdccccc944da41"); + yield return (Msg: "5a23ad0ce89e0fb1df4a95bb2488f0", MD: "23840671e7570a248cf3579c7c8810b5fcc35b975a3a43b506cc67faefa6dbe1c945abc09a903e199f759dcbc7f2c4d0"); + yield return (Msg: "65b27f6c5578a4d5d9f6519c554c3097", MD: "dd734f4987fe1a71455cf9fb1ee8986882c82448827a7880fc90d2043c33b5cbc0ed58b8529e4c6bc3a7288829e0a40d"); + yield return (Msg: "a74847930a03abeea473e1f3dc30b88815", MD: "dba6f929fe55f9d66c5f67c0af3b82f17bcf58b36752f3165c16083fea8fd478ee6903f27f820ad2dd9950afb48c6700"); + yield return (Msg: "6efaf78ed4d293927eef2c3a71930e6e887a", MD: "8218498ab01b63041c2ba0709e3309496124ddf0904543a9e0d9d096a750dda97f7a02208af3d8c618d4be7c2bb2a288"); + yield return (Msg: "fd039eb6e4657388b947ec01e737efbbad47da", MD: "c5b3130ef8dbc580e1103fecae69c9a882d9ebf5a3def5938b07f843452a09c9f72f0dbca91d33b021cf6aa6fe60d2ed"); + yield return (Msg: "9c694943389bdc4e05ad7c2f63ceac2820e1d2d7", MD: "f692c025c5c5f3d1275213c1df9bf9eb6d2188eda90ab5bffe631f1dbf70ebd628caee88b7d149e1ac4e262873979afe"); + yield return (Msg: "0fb18357b018b9bbb2cbb4cac50bc85609c92b8e7f", MD: "d164306c99e3798790f0923fe92dbf2f96c3907127dacaa467c766ac75788062589272cb7690b8af2030dd8bd61a3df2"); + yield return (Msg: "26cb40a460e2e727aeb867e0140d0f34790110deb5d7", MD: "af2a42a4c67c3226c55b89605b0dee27e796c2792115f6097203db5aed89e35f563a8246d399fde00c2a5b97ed5a5e17"); + yield return (Msg: "6690a3a0373c829facc56f824382f4feed6eb184642b4f", MD: "84e1b68bc9e2daefc19b567dec911ef46f5f37a74fdbbb6155e7e646f2735df2ac44e239689eb5b536465dc571e55cb2"); + yield return (Msg: "7d80b160c4b536a3beb79980599344047c5f82a1dfc3eed4", MD: "041cc5861ba334563c61d4ef9710d4896c311c92edbe0d7cd53e803bf2f4eb6057235570770ce87c5520d7ec14198722"); + yield return (Msg: "02128283ffc0cfe254ac8f542be3f05fbe4e855dd22ae98a81", MD: "3840981a766d725f83d334e8982965033a5fbb5107d94ffef33b1f700cd46348091a49f6620c37ae3ef5b20513494826"); + yield return (Msg: "27911dd0a6843ccae965d876aa1916f1dcd71e518f7f2197152e", MD: "f59f8428555984d1526cded8129c649fb1b683d35cec7c5e1209441a6a9e7c17f0784151b5ab8a8c492b402a3acb98c4"); + yield return (Msg: "d9378bb66e8c8dee556d691cbc9fdddd6333ca5d50668862c3c57d", MD: "994532d1a557e990b1cc9e0395a2ad8b05619ca322db9da3c4ed2ee194c051d04582fde72dd2b8f674cf6ec958db75da"); + yield return (Msg: "ae1828047c5f82a7b9712f3399832124b892f2f7aea51c8fe3536cd6", MD: "d51111f8bffb44d81ad19683198f29d2033144d3cd856c749cac5b9cae0e712f500f8d0ef813f38e305ce175a7d6162c"); + yield return (Msg: "7dd2d76fa054cf461e132e9ef914acdc53080a508cdc5368ab8c6224ff", MD: "6c0b3395e4c86518ab0a06267320ee9ec95e50385b7a2527ddaa1bd0ead262c56122d4f4eb08b0ae22b3ee7e6f44dd18"); + yield return (Msg: "6fd72888a021f36e550967cb5605b55b78657c9272d93c3ded340d67da6f", MD: "0551583a5b4007401c77ef4382fd8e245c9cf12e976c9766af6b7ae3c7e07a82b3079f903b083d5ec85cb94e46a85ac0"); + yield return (Msg: "d500eb9546553619cdc31e0848c502db92d547efef3ae5eeaa22258afcf0a9", MD: "5edde2f94f8695f277ec05efcc00761fafd272200aed0e63d221c2b6c65b4972a6526f9a1f2e6ace0e81938f043fe877"); + yield return (Msg: "6189597e0198a18c65fa0bdd0797f13037c75c4058b7d3454c0f71bd2dd13b6c", MD: "110630ca7631b7620e6bee6ed6e929098965571936c34829484983eba9532b8175528c228c57439453f027a4f7c83ca3"); + yield return (Msg: "243b941d748541af303f8e9d2c371cd03e437d62a9df485ddc176dc65da8c7da00", MD: "5884201f7a555ea3c5deeb019fd9e8c161e1b89756045e475b141ec5135ce5a41c93e5e1f79534d36fd8345ba434da43"); + yield return (Msg: "2dc3d789582c1a806c3b491d5972ef8f1733f1f5e02866dc9de2a8029ec0ab608d13", MD: "05a3903b519cdf679120c7ccb4ef178b58e4502fcd461360988fa06669294851e629d9dd3e77ffb73d24599d5d3edd36"); + yield return (Msg: "e5b3f6962fe57230780b3d55b29effe0dfebde2c81ba97d4512ecdbd33eca1576a7f82", MD: "7ac2776afb74f55bbc4f6eccf825ee13ac7445fb54974e6c24ebc0f03fdcd8530199a61106a31b4279e02201ee0f54fd"); + yield return (Msg: "da03486aa3cebbd6502e9f5a6f0f835e973a581befcc1aadefe7b3696ba71c70cd58c584", MD: "02c44ceec0bb7dc0f664ebe44230192b5b0bb646bb944d23fa1ff3586dc0523fa9d7f0dd6df5449ab9edd9a1096b07dc"); + yield return (Msg: "3c686d321ba66185cdca83ba9f41984fa61b826ef56b136e13f1239dadf6e03d877866ccb8", MD: "ad624edd9f2c3a32b56c53d9e813c01d66bcfe424c4a96907d52ac1ddd68370ec86dac67504a90e8a8e75502e01081d2"); + yield return (Msg: "4dcff99fac33840f6532547fb69b456902d6718fd5d4538e23462db6d00da61975f2b8e26298", MD: "cf37dd27997c1bb7e6dc405170066e74c6ce517c029ed8dce126d025da74e0b8e86da567e8d7d8d5b5d3e2a546df7489"); + yield return (Msg: "2799f672328834d7eaef9439795d35ce93c9094f58ded9f17c968a97a50a9e461489fed988e7f6", MD: "85cfc23c97cb13910b808e7033809a45aa0b7f7138de618c2ca622c8b813c988e264af3b96c7925dcbd1d2761757d800"); + yield return (Msg: "c7e947507822f28a562745a8fe6fed6cb47d73145804c894954e21245cde04fa9155a35904926aca", MD: "8bddf3baebbc5b04fe0b0a9c3c2b730abe918ce4892d2843c613ee96da0228512f0d1307c7d1a8922e79a92e957dd18e"); + yield return (Msg: "6c497bf6ff69cb39e3faa349212b8b6691ca237905ac0099c450b6d33abf362bedb65bdeb307bfea23", MD: "3639fab6191b35246278522cfacee0cd5b15580a26c505ae3c46b4b1c2572016b48f1b012bbbedec47916950fbb33a1d"); + yield return (Msg: "d15936f3b0c9018271812b4c81453c4457c7edd110bcea7f5735d6f5882d8f27155eb4cc285a65138ad6", MD: "0293eeef0aa3392c93d9c6ca89c08b317622572d4de2286a4b9ae6c2f9c9e0e64ee6c483d4f10859077e3c6868430214"); + yield return (Msg: "df18139f34b8904ef0681c1b7a3c86653e44b2535d6cecd1a2a17cd5b9357be79b85e5e04dd9eff2ca8b9a", MD: "db9e171d6e3336631c9ceec6b4d732ce62b015939269fb69fae7d22725500e8a2fc9f1459cf0a31fb9d16d7c44583f52"); + yield return (Msg: "0459dcbc149333ea2f937b779a5f3728148449a9aea3662cdd2cc653ce6a2050f9c0d54bf9326c039b263eb9", MD: "464ba409fbb45e985f84ee24662eb7c042c3c2ad9649f1ac4a8b2be9c07d37ed2e4284362057493f6a7e52c356b05bc5"); + yield return (Msg: "eb3f7002c8352270340b8da8643622e5f7e32cdb208a0dec06c6cb9e6b64cc4d8cb9de1d49397b3386464a25d1", MD: "a26bd76ce42d818dbec462d8fe7cdd957e6b84ae8750fb5e1c9c76bc6000e23737e073a59b4600e5056524edc667909d"); + yield return (Msg: "47e3e3d8c68ac9d9f4b3759d8c7d9dd901e35b096ee4c8b6cbe0cdf467463630926c08289abe153bfa1bcde3cd7c", MD: "b504ef475a568f9caba8352a0b2d243acdf3d2b41d8890a6fb3abb8aa28a29e0c7527d20e2d79b25b400ec27c314db72"); + yield return (Msg: "838d9c181c5ab59592723bd69360e0d7fd15232beada7591ea899ac78ffd53a32fc73a5fe522ed35d92a6e2bc148ca", MD: "53e99e1158d59032ffe4b5ea304c7d2f7a61b6b2a96ac97832ca26013549fe3f7dcdf926bd74ceabe4f1ff172daed6e6"); + yield return (Msg: "a90d2aa5b241e1ca9dab5b6dc05c3e2c93fc5a2210a6315d60f9b791b36b560d70e135ef8e7dba9441b74e53dab0606b", MD: "4a16881ce156f45fdfdb45088e3f23be1b4c5a7a6a35315d36c51c75f275733319aca185d4ab33130ffe45f751f1bbc5"); + yield return (Msg: "8c29345d3a091a5d5d71ab8f5a068a5711f7ba00b1830d5ed0bcdfb1bb8b03cd0af5fe78789c7314f289df7eee288735fe", MD: "e27b39a96255ff69c45285fca6edaaa3954ce32c1e3d9b1f60c1b6676594bb45caf0889fc11daf93a1b60746229689dd"); + yield return (Msg: "32876feefe9915a32399083472e3c3805ef261800b25582aa7c36395fd3ec05d47b49c4944bbcc2b8b5ebd081f63ae7943d0", MD: "f96433cdb69a607433ea2eb77d87d3328867dc4076b67ccf17f50f9e08e89a86624b60f2ecdb8affcd431fc13173fe75"); + yield return (Msg: "e2e77eb54f321f86f52ea3d3c8cdc3bc74d8b4f2f334591e5e63b781034da9d7b941d5827037dee40c58dc0d74c00996e582bc", MD: "a352ab33ca730482c376bdc573c9d1dc6d3597f9be9f798b74a57beaa8e9c57b78ee6761056eb67363e882fefcad4fb9"); + yield return (Msg: "da14b6d0b2ec4cf1e7c790e7f8f4212b8f4d05f50e75e2a56a5d70623c0d2e0115a15428129109b3b136d756e38a5c8463304290", MD: "aae7ad977e17ac0e560c0e0186433420f9fddcd191b9e91567cee05df88f1e1aee50424a313998a873f7a9c289a02217"); + yield return (Msg: "2db06f09abaa6a9e942d62741eacd0aa3b60d868bddf8717bef059d23f9efe170f8b5dc3ef87da3df361d4f12bfd720083a7a035e8", MD: "85d4e3e5abcb1b59ca6f551eb43b43ff64890511f73a9083a2ce6e9c2861c6e9664c765629024f4b01b0cd1594a5981b"); + yield return (Msg: "26bad23e51c4560c172076538b28716782ee6304962f68e27182048948d5c367a51a1c206a3e9b25135b40883b2e220f61cb5787ed8f", MD: "a44c7f84ab962f68283404f8c5c4029dbc35d2138e075c9327580baf89f292937bf99422e45756b3f942bf0a5ae4acb6"); + yield return (Msg: "77a9f652a003a83d22fb849b73fed7d37830c0dc53f89cea7dbec24e14f37197765206fe0e6672016e4dec4d9ebbe3e1b4423771a5d0a8", MD: "29c8bb39bb2aad419a00a80216ec71ec5ec9ab54c41927e3e3f2f48f079a5886d7fe89db98c807ab686d2339001d6252"); + yield return (Msg: "268c7b3a84849fec5c769bc4ad377dea10c9d20c91dd17fdbd9670a2fc909d0e212129ec40dee41dbf6194a3b04ae8be5e84ad5426ca4496", MD: "0dfc6ffcf4a387ec09ff862c6139a6f7ac77abb2b5e1f6dc814eb71525f8657ac74a7697c2975c70a543af0e227d03ca"); + yield return (Msg: "b8324341a6891a6b5e001a7d2ebba6e02e8335c124185309a4c9e9907c43bd8d4fa73c527fdf783650316dd24b148870e1436ac05111e9cdcc", MD: "6278d1cc17fb6d54129d04987d4774fa846dcac4ba8b6b72f41e63dc387ce0081ba29fb2c17c6744edae24e669cc9e75"); + yield return (Msg: "5ef8b3d79d299bee2c414560c7de626cc0d9fb429884aa69cc30095ef1f36b7e03a8ca25fb3601189f163b209e0facf8dc447f690b710fb47b72", MD: "7ec9505f33f4a5493574422de078e0490b61be8e8d6f158192bb7d2bdc2dc335598dc88d9b443cd1c14b883a77119df1"); + yield return (Msg: "ad7321c9a8b8f0bfe100811114270daad57f6e88772326b62d88a37a6f55c2cf9f759115ed6a590878e4dcefb592db151538db7de20229d26a181c", MD: "3782d2caa537294e809e9df837b1b07e2f1df07d0f4c12e12459f56eeaa478d5b3a41e519d9414eafa5ddd5661c831ba"); + yield return (Msg: "0719d9664541f0a824f71c83b809bb6afc973c9f7428e1ed11f7c29a558e1698b796aefb49eec2b098faf06bd43e82e1312bf0388c38a5bb523506d3", MD: "362c05f678df92883d56e19221391fb00d0f0afcec51d3e0feb15ba2fb60693b09d69118af649648933259d7b1e240ab"); + yield return (Msg: "5415c2596aa7d21e855be98491bd702357c19f21f46294f98a8aa37b3532ee1541ca35509adbef9d83eb99528ba14ef0bd2998a718da861c3f16fe6971", MD: "8f9fd7d879d6b51ee843e1fbcd40bb67449ae744db9f673e3452f028cb0189d9cb0fef7bdb5c760d63fea0e3ba3dd8d1"); + yield return (Msg: "b979a25a424b1e4c7ea71b6645545248498a2b8c4b568e4c8f3ff6e58d2ac8fbe97be4bea57d796b96041d1514511da5f6351120be7ab428107ef3c66921", MD: "e248a64b6ef112bf3d29948b1c995808e506c049f3906d74c3ee1e4d9f351658681901fe42c8e28024fe31014e2d342b"); + yield return (Msg: "e64c7bb9cd99ce547d43de3cc3b6f7d87a2df9d8a4760c18baf590c740ec53c89bfa075827e1f3f2858ce86f325077725e726103fbe94f7a1466c39f60924f", MD: "d1e5a72d2595f38714c6198ac14f8a5cdd894dcf9b4b8e975174b100df7bbf4f7ce291b4864f27c0b64e6330f6c1c82c"); + yield return (Msg: "91b7a1fd0e20072d9c5be7196e5eaf8df36fdf145895b30d4e4c02010d7c663499ac9d7a44732f4c7430511ba6fb0ae4b3dc9405523a054fdf962f5c5b79c423", MD: "07c2e0aeae30da83b5a6b320aa1cf727b10c2034583d7acda55648fa3daa017aa15588b6e2149101c56e3d7df7c76df1"); + yield return (Msg: "5bbc2d4efe63cbfc9fc221dd8d8384075a79c80a27d6a8c5219e677f4c5bb8338013dc2ab1770acf735d13c0bc704621ec2691350cf3ea2f53bded45ef8fc70702", MD: "dd0bbfe4b799642191abe316df9d59a3743566778b4459c51c3be3f658bdce45516ad188fbe1a8cad8a1fa78f8ebb645"); + yield return (Msg: "129549278e8976c38b5505815725400c3d2081edf141ad002e62ff299d9a0743f9c9f25971710b194dc88285d50b6cec6e140c19072f51cab32a9f6497abd3e407c6", MD: "ca26aec527fadcd5ebeb4eafa7c102f79a3c2edb452afd04f6162dd7a17bdd1aad7d616508a89a3ec6a40791d915acc8"); + yield return (Msg: "b9a9f378adeff4337bc7ec10d526c6dda07028375549f7fda7a81d05662c8a0da3b478f4152af42abb9f9a65c39da095abb8161ba6676b35411234bd466c2914e00370", MD: "99914f684e0b317f9338af0c71e9655a3af7153eb9fabaae61454bf8de9e0bfd274c1eff6c4b550e47afcb3b20fa7d9e"); + yield return (Msg: "101da5b09700dcadf80e5b7900f4e94c54d5f175569a854e488aa36fb41ab7220b0662178ca07a596768528123de3b2a3d944aa412875cedfeaf58dcc6d5b4a033a53b69", MD: "d3e32c9b271e11e4968397d85d76938b974ac1ba55bcbe8d7b7da02dbd7e3b9c9af0d98bbd7e50c436fcf9e3551e3432"); + yield return (Msg: "14761bbc5685b5de692973e2df7c9c4750889c19a952f912c817890546d5e37d940d13a14ac7925abbd875b8cd60e4920896ce6decc8db9f889da2b5489e1d110ff459d885", MD: "272222ed50631aff465c0e6fe49ecdfdca983bcb7231e50903e200b335b845108202c28315912c9c4fd50e2c6f13a9ea"); + yield return (Msg: "ed538009aeaed3284c29a6253702904967e0ea979f0a34a5f3d7b5ab886662da9b8e01efc4188e077c2cdeb5de0a8252aafbee948f86db62aae6e9e74abc89e6f6021a4db140", MD: "8361b680243b1661d6f1df53db363cae41c2ebb7438c00606d76b9c2a253faa1f09d6f520d69d692ec1dca0c7885119c"); + yield return (Msg: "c434d88468f1eda23848d0804b476933f24baeadec69743dd90d8455f1e1f290f6f1aaf3670c4c74f76d3ab83e9bef21ad8d9208c712ca478e70d5fb3c4bd48834c969dd38f484", MD: "9c26e96fcc09a76cc13d24ad25c9cef4300e96e97e4fb59b441baffed07f6a70b1464f2548c7fd7839810dbb9e9c1e18"); + yield return (Msg: "3064e5ba1e7751bf7198e0811ff4d4ca17d1311c25d9c3a316b562691cde75c974b0b52645c134ddcc709d77b6c1bd24cd684265d723c308bb4d0159e6b16d97ed9ceaa57436d302", MD: "1ea779739b204abe911b4923e6f60fece271eedfc7f074fe1919f0cbc6ce2a99234b003389520884b660165f5a1e80f8"); + yield return (Msg: "89d9521ad84b1c9afc2fbd0edc227193acd3330764b0d2cb71bf47c7aac946af85be13858b55976009f3b36b09ced4308052c817c9c4d0295225f61a9659a0874b88667cdcc5213919", MD: "4209bb8f869f6f17c8d5c368c489ac51a75e24a85a12de1b16fefc292ce636ff8fa360e82f05684f6b0b074ba370a933"); + yield return (Msg: "3216662da0227993d88288187177a0287de4eccf245d7c718b8045bbfb8869d93f1fb9e94d7478b0298e628c07e0edaab01dcf79264dc05f8b2181aa3f831dc949726fbcf80de4c9c9ed", MD: "64c45e018cfbc88f8f4ffe3cef0df3a94aab3049fafae28e28efbb2a4b94809eb302caf901010abfa194f72965663d35"); + yield return (Msg: "e776e6749c5b6c7def59cb98340984539280a9874f80412d4df0ee73d58acd1094d49ed4e35125834cf8cfe349e599144e4f2e200aba4fd3eb6d78cde027c1d5620e0270b5e83ab26b8d32", MD: "94bd67b7f2587b0bda5487cc45d00e4365f1ee40073cdf0d23a5ea3fba01eef42a46bfbac5306d67be02d8d918ae5c9a"); + yield return (Msg: "5d8f84b2f208b58a68e88ce8efb543a8404f0ec0c9805c760ad359d13faab84d3f8bb1d2a4bb45e72c0ec9245ffda2e572f94e466cffa44b876d5c5ed914d1ff338e06b74ad1e74d1405d23d", MD: "947350307748c29467f00103d0a07c3c228c5f494fc88fe2352ca5d10449d0dda7076780c05439a09694eb528d1f477a"); + yield return (Msg: "357d5765595065efe281afb8d021d4764fba091adde05e02af0a437051a04a3b8e552ec48fb7152c470412c40e40eec58b842842d8993a5ae1c61eb20de5112321bc97af618bbfbaf8e2a87699", MD: "32286970204c3451958f5155f090448f061dd81b136a14592a3204c6b08e922ee5bb6d6534dbf8efb4bb7387092c8400"); + yield return (Msg: "a8cb78e1485cbb7a9474c1c1f8e0f307cda5139a7e947df5ea20ac330a6dffcad4a9bd755f9f58724789eeee532615be550dd84f5241fde0e3058aeedbf287f02a460445027f5e6b3829bf71ecf4", MD: "51168bfeef8a981c0def0c4cb067baf15ce5feb8d5f7e9d6076b2836267391aee1fd3a0b5d3434ceb5cf2d6fa06fa063"); + yield return (Msg: "81acca82545e767ab59dcc750a09849cebad08ff31c9297f4fd510ebe6c27769938319180ccc66f36b1a7cf9c9f3538b0f6f371509f77cf0bc4d6d87facc85b933f2e27f8e1bf6cf388f80c0fcbfba", MD: "4ae44d6509986893a8414753b57d11f9c554d89c15ad6d70687c56c6c2ac73537acbb0d51f48e6bea6cf762d58890d7a"); + yield return (Msg: "94987498b1ca87a6f3fa4b999db726115c455d0ec24029b2f5810e49a94668864b8c470f7fc07c3dcd97f41c973b45ba4fa7879ee7546596881573b6863fc39d940eb3fa3444084f721341f5d23d2561", MD: "a733b118be72a187ddcbe5ba67e04b589f9cd9f8482c4bd9d64c580aba7d19d2d1f9c1ddf95fe6efdeffd44f67fcabb5"); + yield return (Msg: "de6b32c2d40d0659166db235259b530ea43f44e75d8b3e9e856ec4c1410bbea3696964af8b6c5dfd3304282369a4bc4e7cf66b91fecd0c7c105b59f1e0a496336f327440980a34614ee00fff2587d6b813", MD: "17ba30c0b5fc185b3245313b83dd0481145953101128914765784af751745b8a2b6a90a434548f3adaf1f07f18649890"); + yield return (Msg: "854211bedacc19f77b46cfa447a4ad672ea9b643f09f5cf5274ba28888207e2466b38127776fb976db8ad7165a378df6ee1e3a0f8109c9aff7e0d6126fd71333c6e6ebe15d7a65151d6a4a83b82c8a6f3149", MD: "ca85632a9f7c32ac4705c6458770025dda4fd07a8d5d6921b897b0da490d64400587649f2d20bf608b9a18d071b63b48"); + yield return (Msg: "822373d9d3d5b06a8da48a43095740fb98c9caf717350fd2c3b058024ff705b9346b7f0a495a6d4d93802bc45ece777f8c6a6e7c2ef6b8135115ff911a2ba5241665b6f7cbfa1b9d93b011b3aaa1dac1853fb2", MD: "6e84587c8c6e54353a6032e7505902ef7f0f0538dd1bb32922e13a7d4d98c47a541015381eab27e9186398120da7fb32"); + yield return (Msg: "c04b701f688092bbd1cf4217bc4b5877f2e60c087bdac46611482a61d51f820140403bc85be0c336332da0938734bde8c502014f3509266c73c6c93c22a1bd0ddf15a5ce7410c2894e9d092e32c079922ba1abb7", MD: "75c585503f15a526113608bc183180b1cb80f4d1b466c576bf021b1ce7a1528391f70e10446681849fa8a643cb2b6828"); + yield return (Msg: "009dd821cbed1235880fe647e191fe6f6555fdc98b8aad0ff3da5a6df0e5799044ef8e012ad54cb19a46fdd5c82f24f3ee77613d4bed961f6b7f4814aaac48bdf43c9234ce2e759e9af2f4ff16d86d5327c978dad5", MD: "02a09d37d31e4365c26bec0eaacecf29eea4e8d21ab915dd605248764d964f10ebb8fafdb591982d33869a1d08a7e313"); + yield return (Msg: "0b7dd6709d55e0d526d64c0c5af40acf595be353d705be7b7a0b1c4c83bbe6a1b1ec681f628e9d6cfc85ad9c8bb8b4ecac64c5b3a9b72f95e59afefa7bcec5be223a9b2b54836424afde52a29b22ab652d22cce34b39", MD: "5c84ae39d959b79555231746ad5b33689a31720ed0070f6772147977edd0aead07fb8b7b71b0bd587ebc5c1a80d564c7"); + yield return (Msg: "3e9b65d7bf4239420afa8639c8195b63902b24495b95c4143978e49843d88a92d1feed2eed1a88cd072d6d04ea26dce8ee4b14896fdb69bc7ff2971ed8ac5655148d2e9921218d74efdf17c56b533d0bb17d11e07d7458", MD: "ab7890d1b51af10285752bf9da5eee5c3e87a285dc33262d0261aa9a575f303e94845d7ab21b48f4e6884568cd78b550"); + yield return (Msg: "9436da433d1ebd10b946b129cb34bccec9b8f705aaba3f8561352ed36a8449aba2dd7ba15b1bc308b0c02913163af63a346524dff5521432db477f529606afb5d552efc95cb040db566b4d39eddaa19319e518a7b5c6931e", MD: "968ae9104f9c907c5a72936250dfedd62cd04f6e5ddd2c113490808a11884449aaef5d013ea3993a6cb6fc5c08754408"); + yield return (Msg: "37254bf9bc7cd4ed72e72b6bb623a0cc8eeb963d827aef65ad4bc54913235b6d3551533ce33421aa52ffbf186eb9a2787188eeb1b52ee645c6d4a631bc071415c80014940c28fbfeb0db472c326c8dacfd6ab21f3e225edef3", MD: "975e10fac9aa77b780e5f6c2151ec4a3c72ff26e41233cc774c074df1b78cce5af1191ba955a0bce15926ae691b0ffe7"); + yield return (Msg: "79e77cd08a6ef770bbe4bedf61557ea632b42d78637149670d4d6157d56ed7b2ccaee45d9439dcebc557b4118e86c15aa0ccc21c474b21abda1676cc56434d6d46422993e66dc99387dfa985358accf69884b9dd18a2c4d04448", MD: "94729f5f99a54f5a3ea69233ff9d522392d4596eb6ac2bbb07492ece3c67317412bb47ae317ddd20536c3adc003862f1"); + yield return (Msg: "64b76cb554f6becc238a3fcfc3eb97993667ec82fdc3fb28d42567709c3250c7997328aeddfdc2750451ac462281bf66fa94f4b8712c7a8342660574f20268e707c466627519c56259fea55be91e10faab3ad2ade6ce8b6557f202", MD: "26d48ef5067d704ee9e2a64e399de23068908b3c911ffc4056c168362c37385c92d37d51354b6505a82c4d22fec37eaa"); + yield return (Msg: "3df27829bfb1ab7d381f146b30370ef56b392b73b35b1be5d8bbcf88f499dda7f3c327b45350b8972991ee466545de96560cf451711fda884e3d9b2af3e909d655d25cee1c931beda79c40fa507097bdf1126771a7b9543ad5cb84b9", MD: "5fa4ebfa24150236c03409f0857b31cb95b0150f381c8858b01559957b1268f73c698709233e6b15468675a102d0c5e5"); + yield return (Msg: "b00f4e67ca08ccfa32b2698f70411d8f570f69c896e18ec8896cfe89551810543303f7df0c49f5b94783cce7df8d76d0b88d155633302d46003711f233339b1c9a8c20164ec8a328890a4932b7d90d92d023b548e4820558f8bd327010", MD: "eaa756b5892fdfc793d74e3f9f4d6c7a5a6a2241dd11e0c38ced59c8ec7be377a41d1d06774a5970ce9722d8e119d0ad"); + yield return (Msg: "a4f95f6a46a9cbf384a7e98e102d1fdc96839d1bf26b35a5a0bd6cb9734fd17e8a178d4581943c0fe469fb4fe94cc2f15e1ef59ae05b35324eb57ca07dfc69d42d41d80b3c3bb64e1aea143c7d79790a56697dc803ec93e6c68f27f6761c", MD: "1aff8d9c64f0c162ed0195d1f3a342a010d14be0636903c48020ba42de1cfa8b98ae2142d89af3e69e9eb4c735857dd1"); + yield return (Msg: "02713084bf93fdc35135515243c3bc0f4b2b447f2d3461c0dc104cbfe23479ab036762a91d1987c953f7b3386abc80b8734a1d4eabf94f3a9f2fb62c943152b5253846fc2ec8dbb2e93dc74857a7b05fe2d7ec8040ba8b0d9ae69777ee739a", MD: "84da02114e341a3636f00822b32bd21a8a1f7b39f2956bd97f39346fedf9aae63b304c65c93a541e8bcda549576d5f27"); + yield return (Msg: "00ce225eaea24843406fa42cc8450e66f76ac9f549b8591f7d40942f4833fc734a034c8741c551d57ddafb5d94ceb4b25680f045038306e6bcc53e88386e2b45b80b3ba23dec8c13f8ca01c202ae968c4d0df04cdb38395d2df42a5aff646928", MD: "81d6e0d96575a9b8ca083ee9ec2ead57ddf72b97d7709086a2f4a749d3f61d16423463487562c7f09aba1b26e8cae47b"); + yield return (Msg: "7af3feed9b0f6e9408e8c0397c9bb671d0f3f80926d2f48f68d2e814f12b3d3189d8174897f52a0c926ccf44b9d057cc04899fdc5a32e48c043fd99862e3f761dc3115351c8138d07a15ac23b8fc5454f0373e05ca1b7ad9f2f62d34caf5e1435c", MD: "00e95f4e8a32a03e0a3afba0fd62c7c3c7120b41e297a7ff14958c0bdf015a478f7bab9a22082bfb0d206e88f4685117"); + yield return (Msg: "2eae76f4e7f48d36cd83607813ce6bd9ab0ecf846ad999df67f64706a4708977f0e9440f0b31dc350c17b355007fed90d4b577b175014763357ce5a271212a70702747c98f8f0ad89bf95d6b7fbb10a51f34d8f2835e974038a3dd6df3f2affb7811", MD: "eb396cfaf26ee2775af3c9a3a3047664ca34cbc228ccbb966df187d518717df6a328ecc316ed0ed09b170080eccc486f"); + yield return (Msg: "093e56d33bd9337ad2ad268d14bac69a64a8a7361350cf9f787e69a043f5beb50eb460703578a81be882639f7e9ac9a50c54affa3792fd38464a61a37c8a4551a4b9ff8eed1f487ef8a8f00430e4d0e35a53ff236ce049b7a3abdc5cd00b45c4f3d49b", MD: "4a339128486e5b274fc4ed538c0ec9e57f780e9c500c5f92b04ae81a22fbeebf3785259a0bb3b6d9b47f31873cd8dffa"); + yield return (Msg: "0593babe7a6202077c026e253cb4c60ee7bad7b1c31a20da7aa0ce56b622eb57ed07d21a7f0ae6c6fe3c8398cc48353decfb287f1204e024fcf82a13059953b9f85797ab2217dc8dab34a13226c33104661c1ca79396e7d97e91039d32bafc98cc8af3bb", MD: "5981815c1618cc49cd5cf71a4b7b32b8cd7b7ef553bfaef2149ac723ff2582a2d345c5bd05943e155ced1e5f091c5601"); + yield return (Msg: "ae1828047c5f82a7b9712f3399832124b892f2f7aea51c8fe3536cd6a584b4a7777cc1ecac158c03354bb467b8fe2c8ce2f4310afd1e80fec51cc5ad7702566b2c5d21bc6571e4b8e7c59cb4c9e23f1ecb57ada9e900e4aa308874c2d12d34be74c332bbce", MD: "7257f5bfa7d33d1cf5f4550d0cb78750e84c5b7d25027da6acec64bdf30879a0e5c97fe7c468e743aa5ec2bddb29d193"); + yield return (Msg: "3bceedf5df8fe699871decb7dd48203e2518fb0fce0f865f46adce5c133a921320bf40915456204869a3ceb5fca3ed40e0a41a64b8951f0fc580694cfc55bd1f5ce926b07e3e32ac6e055de9b961ce49c7ee41e06b024559b933a79518192e969855889c85d1", MD: "60d7f8bd85fb7a13701db5aded2b7771ab5e476ec34f1fd4298978defbd2b31bb2979391559a164b3ed28f6a39031a11"); + yield return (Msg: "6c36147652e71b560becbca1e7656c81b4f70bece26321d5e55e67a3db9d89e26f2f2a38fd0f289bf7fa22c2877e38d9755412794cef24d7b855303c332e0cb5e01aa50bb74844f5e345108d6811d5010978038b699ffaa370de8473f0cda38b89a28ed6cabaf6", MD: "b1319192df11faa00d3c4b068becc8f1ba3b00e0d1ff1f93c11a3663522fdb92ab3cca389634687c632e0a4b5a26ce92"); + yield return (Msg: "92c41d34bd249c182ad4e18e3b856770766f1757209675020d4c1cf7b6f7686c8c1472678c7c412514e63eb9f5aee9f5c9d5cb8d8748ab7a5465059d9cbbb8a56211ff32d4aaa23a23c86ead916fe254cc6b2bff7a9553df1551b531f95bb41cbbc4acddbd372921", MD: "71307eec1355f73e5b726ed9efa1129086af81364e30a291f684dfade693cc4bc3d6ffcb7f3b4012a21976ff9edcab61"); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs new file mode 100644 index 00000000000000..0d9c3ed5a77db5 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + public class SHA3_512Tests : HashAlgorithmTestDriver + { + protected override HashAlgorithm Create() + { + return SHA3_512.Create(); + } + + protected override bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) + { + return SHA3_512.TryHashData(source, destination, out bytesWritten); + } + + protected override byte[] HashData(byte[] source) => SHA3_512.HashData(source); + + protected override byte[] HashData(ReadOnlySpan source) => SHA3_512.HashData(source); + + protected override int HashData(ReadOnlySpan source, Span destination) => + SHA3_512.HashData(source, destination); + + protected override int HashData(Stream source, Span destination) => + SHA3_512.HashData(source, destination); + + protected override byte[] HashData(Stream source) => SHA3_512.HashData(source); + + protected override ValueTask HashDataAsync(Stream source, Memory destination, CancellationToken cancellationToken) => + SHA3_512.HashDataAsync(source, destination, cancellationToken); + + protected override ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken) => + SHA3_512.HashDataAsync(source, cancellationToken); + + [Fact] + public void SHA3_512_Kats() + { + foreach ((string Msg, string MD) kat in Fips202Kats) + { + Verify(Convert.FromHexString(kat.Msg), kat.MD); + } + } + + private static IEnumerable<(string Msg, string MD)> Fips202Kats + { + get + { + // Generated from SHA3_512ShortMsg.rsp + yield return (Msg: "", MD: "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"); + yield return (Msg: "e5", MD: "150240baf95fb36f8ccb87a19a41767e7aed95125075a2b2dbba6e565e1ce8575f2b042b62e29a04e9440314a821c6224182964d8b557b16a492b3806f4c39c1"); + yield return (Msg: "ef26", MD: "809b4124d2b174731db14585c253194c8619a68294c8c48947879316fef249b1575da81ab72aad8fae08d24ece75ca1be46d0634143705d79d2f5177856a0437"); + yield return (Msg: "37d518", MD: "4aa96b1547e6402c0eee781acaa660797efe26ec00b4f2e0aec4a6d10688dd64cbd7f12b3b6c7f802e2096c041208b9289aec380d1a748fdfcd4128553d781e3"); + yield return (Msg: "fc7b8cda", MD: "58a5422d6b15eb1f223ebe4f4a5281bc6824d1599d979f4c6fe45695ca89014260b859a2d46ebf75f51ff204927932c79270dd7aef975657bb48fe09d8ea008e"); + yield return (Msg: "4775c86b1c", MD: "ce96da8bcd6bc9d81419f0dd3308e3ef541bc7b030eee1339cf8b3c4e8420cd303180f8da77037c8c1ae375cab81ee475710923b9519adbddedb36db0c199f70"); + yield return (Msg: "71a986d2f662", MD: "def6aac2b08c98d56a0501a8cb93f5b47d6322daf99e03255457c303326395f765576930f8571d89c01e727cc79c2d4497f85c45691b554e20da810c2bc865ef"); + yield return (Msg: "ec83d707a1414a", MD: "84fd3775bac5b87e550d03ec6fe4905cc60e851a4c33a61858d4e7d8a34d471f05008b9a1d63044445df5a9fce958cb012a6ac778ecf45104b0fcb979aa4692d"); + yield return (Msg: "af53fa3ff8a3cfb2", MD: "03c2ac02de1765497a0a6af466fb64758e3283ed83d02c0edb3904fd3cf296442e790018d4bf4ce55bc869cebb4aa1a799afc9d987e776fef5dfe6628e24de97"); + yield return (Msg: "3d6093966950abd846", MD: "53e30da8b74ae76abf1f65761653ebfbe87882e9ea0ea564addd7cfd5a6524578ad6be014d7799799ef5e15c679582b791159add823b95c91e26de62dcb74cfa"); + yield return (Msg: "1ca984dcc913344370cf", MD: "6915ea0eeffb99b9b246a0e34daf3947852684c3d618260119a22835659e4f23d4eb66a15d0affb8e93771578f5e8f25b7a5f2a55f511fb8b96325ba2cd14816"); + yield return (Msg: "fc7b8cdadebe48588f6851", MD: "c8439bb1285120b3c43631a00a3b5ac0badb4113586a3dd4f7c66c5d81012f7412617b169fa6d70f8e0a19e5e258e99a0ed2dcfa774c864c62a010e9b90ca00d"); + yield return (Msg: "ecb907adfb85f9154a3c23e8", MD: "94ae34fed2ef51a383fb853296e4b797e48e00cad27f094d2f411c400c4960ca4c610bf3dc40e94ecfd0c7a18e418877e182ca3ae5ca5136e2856a5531710f48"); + yield return (Msg: "d91a9c324ece84b072d0753618", MD: "fb1f06c4d1c0d066bdd850ab1a78b83296eba0ca423bb174d74283f46628e6095539214adfd82b462e8e9204a397a83c6842b721a32e8bb030927a568f3c29e6"); + yield return (Msg: "c61a9188812ae73994bc0d6d4021", MD: "069e6ab1675fed8d44105f3b62bbf5b8ff7ae804098986879b11e0d7d9b1b4cb7bc47aeb74201f509ddc92e5633abd2cbe0ddca2480e9908afa632c8c8d5af2a"); + yield return (Msg: "a6e7b218449840d134b566290dc896", MD: "3605a21ce00b289022193b70b535e6626f324739542978f5b307194fcf0a5988f542c0838a0443bb9bb8ff922a6a177fdbd12cf805f3ed809c48e9769c8bbd91"); + yield return (Msg: "054095ba531eec22113cc345e83795c7", MD: "f3adf5ccf2830cd621958021ef998252f2b6bc4c135096839586d5064a2978154ea076c600a97364bce0e9aab43b7f1f2da93537089de950557674ae6251ca4d"); + yield return (Msg: "5b1ec1c4e920f5b995b6a788b6e989ac29", MD: "135eea17ca4785482c19cd668b8dd2913216903311fa21f6b670b9b573264f8875b5d3c071d92d63556549e523b2af1f1a508bd1f105d29a436f455cd2ca1604"); + yield return (Msg: "133b497b00932773a53ba9bf8e61d59f05f4", MD: "783964a1cf41d6d210a8d7c81ce6970aa62c9053cb89e15f88053957ecf607f42af08804e76f2fbdbb31809c9eefc60e233d6624367a3b9c30f8ee5f65be56ac"); + yield return (Msg: "88c050ea6b66b01256bda299f399398e1e3162", MD: "6bf7fc8e9014f35c4bde6a2c7ce1965d9c1793f25c141021cc1c697d111363b3854953c2b4009df41878b5558e78a9a9092c22b8baa0ed6baca005455c6cca70"); + yield return (Msg: "d7d5363350709e96939e6b68b3bbdef6999ac8d9", MD: "7a46beca553fffa8021b0989f40a6563a8afb641e8133090bc034ab6763e96d7b7a0da4de3abd5a67d8085f7c28b21a24aefb359c37fac61d3a5374b4b1fb6bb"); + yield return (Msg: "54746a7ba28b5f263d2496bd0080d83520cd2dc503", MD: "d77048df60e20d03d336bfa634bc9931c2d3c1e1065d3a07f14ae01a085fe7e7fe6a89dc4c7880f1038938aa8fcd99d2a782d1bbe5eec790858173c7830c87a2"); + yield return (Msg: "73df7885830633fc66c9eb16940b017e9c6f9f871978", MD: "0edee1ea019a5c004fd8ae9dc8c2dd38d4331abe2968e1e9e0c128d2506db981a307c0f19bc2e62487a92992af77588d3ab7854fe1b68302f796b9dcd9f336df"); + yield return (Msg: "14cb35fa933e49b0d0a400183cbbea099c44995fae1163", MD: "af2ef4b0c01e381b4c382208b66ad95d759ec91e386e953984aa5f07774632d53b581eba32ed1d369c46b0a57fee64a02a0e5107c22f14f2227b1d11424becb5"); + yield return (Msg: "75a06869ca2a6ea857e26e78bb78a139a671ccb098d8205a", MD: "88be1934385522ae1d739666f395f1d7f99978d62883a261adf5d618d012dfab5224575634446876b86b3e5f7609d397d338a784b4311027b1024ddfd4995a0a"); + yield return (Msg: "b413ab364dd410573b53f4c2f28982ca07061726e5d999f3c2", MD: "289e889b25f9f38facfccf3bdbceea06ef3baad6e9612b7232cd553f4884a7a642f6583a1a589d4dcb2dc771f1ff6d711b85f731145a89b100680f9a55dcbb3f"); + yield return (Msg: "d7f9053984213ebabc842fd8ce483609a9af5dc140ecdbe63336", MD: "f167cb30e4bacbdc5ed53bc615f8c9ea19ad4f6bd85ca0ff5fb1f1cbe5b576bda49276aa5814291a7e320f1d687b16ba8d7daab2b3d7e9af3cd9f84a1e9979a1"); + yield return (Msg: "9b7f9d11be48e786a11a472ab2344c57adf62f7c1d4e6d282074b6", MD: "82fa525d5efaa3cce39bffef8eee01afb52067097f8965cde71703345322645eae59dbaebed0805693104dfb0c5811c5828da9a75d812e5562615248c03ff880"); + yield return (Msg: "115784b1fccfabca457c4e27a24a7832280b7e7d6a123ffce5fdab72", MD: "ec12c4ed5ae84808883c5351003f7e26e1eaf509c866b357f97472e5e19c84f99f16dbbb8bfff060d6c0fe0ca9c34a210c909b05f6a81f441627ce8e666f6dc7"); + yield return (Msg: "c3b1ad16b2877def8d080477d8b59152fe5e84f3f3380d55182f36eb5f", MD: "4b9144edeeec28fd52ba4176a78e080e57782d2329b67d8ac8780bb6e8c2057583172af1d068922feaaff759be5a6ea548f5db51f4c34dfe7236ca09a67921c7"); + yield return (Msg: "4c66ca7a01129eaca1d99a08dd7226a5824b840d06d0059c60e97d291dc4", MD: "567c46f2f636223bd5ed3dc98c3f7a739b42898e70886f132eac43c2a6fadabe0dd9f1b6bc4a9365e5232295ac1ac34701b0fb181d2f7f07a79d033dd426d5a2"); + yield return (Msg: "481041c2f56662316ee85a10b98e103c8d48804f6f9502cf1b51cfa525cec1", MD: "46f0058abe678195b576df5c7eb8d739468cad1908f7953ea39c93fa1d96845c38a2934d23804864a8368dae38191d983053ccd045a9ab87ef2619e9dd50c8c1"); + yield return (Msg: "7c1688217b313278b9eae8edcf8aa4271614296d0c1e8916f9e0e940d28b88c5", MD: "627ba4de74d05bb6df8991112e4d373bfced37acde1304e0f664f29fa126cb497c8a1b717b9929120883ec8898968e4649013b760a2180a9dc0fc9b27f5b7f3b"); + yield return (Msg: "785f6513fcd92b674c450e85da22257b8e85bfa65e5d9b1b1ffc5c469ad337d1e3", MD: "5c11d6e4c5c5f76d26876c5976b6f555c255c785b2f28b6700ca2d8b3b3fa585636239277773330f4cf8c5d5203bcc091b8d47e7743bbc0b5a2c54444ee2acce"); + yield return (Msg: "34f4468e2d567b1e326c0942970efa32c5ca2e95d42c98eb5d3cab2889490ea16ee5", MD: "49adfa335e183c94b3160154d6698e318c8b5dd100b0227e3e34cabea1fe0f745326220f64263961349996bbe1aae9054de6406e8b350408ab0b9f656bb8daf7"); + yield return (Msg: "53a0121c8993b6f6eec921d2445035dd90654add1298c6727a2aed9b59bafb7dd62070", MD: "918b4d92e1fcb65a4c1fa0bd75c562ac9d83186bb2fbfae5c4784de31a14654546e107df0e79076b8687bb3841c83ba9181f9956cd43428ba72f603881b33a71"); + yield return (Msg: "d30fa4b40c9f84ac9bcbb535e86989ec6d1bec9b1b22e9b0f97370ed0f0d566082899d96", MD: "39f104c1da4af314d6bceb34eca1dfe4e67484519eb76ba38e4701e113e6cbc0200df86e4439d674b0f42c72233360478ba5244384d28e388c87aaa817007c69"); + yield return (Msg: "f34d100269aee3ead156895e8644d4749464d5921d6157dffcbbadf7a719aee35ae0fd4872", MD: "565a1dd9d49f8ddefb79a3c7a209f53f0bc9f5396269b1ce2a2b283a3cb45ee3ae652e4ca10b26ced7e5236227006c94a37553db1b6fe5c0c2eded756c896bb1"); + yield return (Msg: "12529769fe5191d3fce860f434ab1130ce389d340fca232cc50b7536e62ad617742e022ea38a", MD: "daee10e815fff0f0985d208886e22f9bf20a3643eb9a29fda469b6a7dcd54b5213c851d6f19338d63688fe1f02936c5dae1b7c6d5906a13a9eeb934400b6fe8c"); + yield return (Msg: "b2e3a0eb36bf16afb618bfd42a56789179147effecc684d8e39f037ec7b2d23f3f57f6d7a7d0bb", MD: "04029d6d9e8e394afa387f1d03ab6b8a0a6cbab4b6b3c86ef62f7142ab3c108388d42cb87258b9e6d36e5814d8a662657cf717b35a5708365e8ec0396ec5546b"); + yield return (Msg: "25c4a5f4a07f2b81e0533313664bf615c73257e6b2930e752fe5050e25ff02731fd2872f4f56f727", MD: "ec2d38e5bb5d7b18438d5f2029c86d05a03510db0e66aa299c28635abd0988c58be203f04b7e0cc25451d18f2341cd46f8705d46c2066dafab30d90d63bf3d2c"); + yield return (Msg: "134bb8e7ea5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0a09921237acd7d66f4da23480b9c1222", MD: "8f966aef96831a1499d63560b2578021ad970bf7557b8bf8078b3e12cefab122fe71b1212dc704f7094a40b36b71d3ad7ce2d30f72c1baa4d4bbccb3251198ac"); + yield return (Msg: "f793256f039fad11af24cee4d223cd2a771598289995ab802b5930ba5c666a24188453dcd2f0842b8152", MD: "22c3d9712535153a3e206b1033929c0fd9d937c39ba13cf1a6544dfbd68ebc94867b15fda3f1d30b00bf47f2c4bf41dabdeaa5c397dae901c57db9cd77ddbcc0"); + yield return (Msg: "23cc7f9052d5e22e6712fab88e8dfaa928b6e015ca589c3b89cb745b756ca7c7634a503bf0228e71c28ee2", MD: "6ecf3ad6064218ee101a555d20fab6cbeb6b145b4eeb9c8c971fc7ce05581a34b3c52179590e8a134be2e88c7e549875f4ff89b96374c6995960de3a5098cced"); + yield return (Msg: "a60b7b3df15b3f1b19db15d480388b0f3b00837369aa2cc7c3d7315775d7309a2d6f6d1371d9c875350dec0a", MD: "8d651605c6b32bf022ea06ce6306b2ca6b5ba2781af87ca2375860315c83ad88743030d148ed8d73194c461ec1e84c045fc914705747614c04c8865b51da94f7"); + yield return (Msg: "2745dd2f1b215ea509a912e5761cccc4f19fa93ba38445c528cb2f099de99ab9fac955baa211fd8539a671cdb6", MD: "4af918eb676ce278c730212ef79d818773a76a43c74d643f238e9b61acaf4030c617c4d6b3b7514c59b3e5e95d82e1e1e35443e851718b13b63e70b123d1b72c"); + yield return (Msg: "88adee4b46d2a109c36fcfb660f17f48062f7a74679fb07e86cad84f79fd57c86d426356ec8e68c65b3caa5bc7ba", MD: "6257acb9f589c919c93c0adc4e907fe011bef6018fbb18e618ba6fcc8cbc5e40641be589e86dbb0cf7d7d6bf33b98d8458cce0af7857f5a7c7647cf350e25af0"); + yield return (Msg: "7d40f2dc4af3cfa12b00d64940dc32a22d66d81cb628be2b8dda47ed6728020d55b695e75260f4ec18c6d74839086a", MD: "5c46c84a0a02d898ed5885ce99c47c77afd29ae015d027f2485d630f9b41d00b7c1f1faf6ce57a08b604b35021f7f79600381994b731bd8e6a5b010aeb90e1eb"); + yield return (Msg: "3689d8836af0dc132f85b212eb670b41ecf9d4aba141092a0a8eca2e6d5eb0ba4b7e61af9273624d14192df7388a8436", MD: "17355e61d66e40f750d0a9a8e8a88cd6f9bf6070b7efa76442698740b4487ea6c644d1654ef16a265204e03084a14cafdccf8ff298cd54c0b4009967b6dd47cc"); + yield return (Msg: "58ff23dee2298c2ca7146227789c1d4093551047192d862fc34c1112d13f1f744456cecc4d4a02410523b4b15e598df75a", MD: "aca89aa547c46173b4b2a380ba980da6f9ac084f46ac9ddea5e4164aeef31a9955b814a45aec1d8ce340bd37680952c5d68226dda1cac2677f73c9fd9174fd13"); + yield return (Msg: "67f3f23df3bd8ebeb0096452fe4775fd9cc71fbb6e72fdcc7eb8094f42c903121d0817a927bcbabd3109d5a70420253deab2", MD: "f4207cc565f266a245f29bf20b95b5d9a83e1bb68ad988edc91faa25f25286c8398bac7dd6628259bff98f28360f263dfc54c4228bc437c5691de1219b758d9f"); + yield return (Msg: "a225070c2cb122c3354c74a254fc7b84061cba33005cab88c409fbd3738ff67ce23c41ebef46c7a61610f5b93fa92a5bda9569", MD: "e815a9a4e4887be014635e97958341e0519314b3a3289e1835121b153b462272b0aca418be96d60e5ab355d3eb463697c0191eb522b60b8463d89f4c3f1bf142"); + yield return (Msg: "6aa0886777e99c9acd5f1db6e12bda59a807f92411ae99c9d490b5656acb4b115c57beb3c1807a1b029ad64be1f03e15bafd91ec", MD: "241f2ebaf7ad09e173b184244e69acd7ebc94774d0fa3902cbf267d4806063b044131bcf4af4cf180eb7bd4e7960ce5fe3dc6aebfc6b90eec461f414f79a67d9"); + yield return (Msg: "6a06092a3cd221ae86b286b31f326248270472c5ea510cb9064d6024d10efee7f59e98785d4f09da554e97cdec7b75429d788c112f", MD: "d14a1a47f2bef9e0d4b3e90a6be9ab5893e1110b12db38d33ffb9a61e1661aecc4ea100839cfee58a1c5aff72915c14170dd99e13f71b0a5fc1985bf43415cb0"); + yield return (Msg: "dfc3fa61f7fffc7c88ed90e51dfc39a4f288b50d58ac83385b58a3b2a3a39d729862c40fcaf9bc308f713a43eecb0b72bb9458d204ba", MD: "947bc873dc41df195f8045deb6ea1b840f633917e79c70a88d38b8862197dc2ab0cc6314e974fb5ba7e1703b22b1309e37bd430879056bdc166573075a9c5e04"); + yield return (Msg: "52958b1ff0049efa5d050ab381ec99732e554dcd03725da991a37a80bd4756cf65d367c54721e93f1e0a22f70d36e9f841336956d3c523", MD: "9cc5aad0f529f4bac491d733537b69c8ec700fe38ab423d815e0927c8657f9cb8f4207762d816ab697580122066bc2b68f4177335d0a6e9081540779e572c41f"); + yield return (Msg: "302fa84fdaa82081b1192b847b81ddea10a9f05a0f04138fd1da84a39ba5e18e18bc3cea062e6df92ff1ace89b3c5f55043130108abf631e", MD: "8c8eaae9a445643a37df34cfa6a7f09deccab2a222c421d2fc574bbc5641e504354391e81eb5130280b1226812556d474e951bb78dbdd9b77d19f647e2e7d7be"); + yield return (Msg: "b82f500d6bc2dddcdc162d46cbfaa5ae64025d5c1cd72472dcd2c42161c9871ce329f94df445f0c8aceecafd0344f6317ecbb62f0ec2223a35", MD: "55c69d7accd179d5d9fcc522f794e7af5f0eec7198ffa39f80fb55b866c0857ff3e7aeef33e130d9c74ef90606ca821d20b7608b12e6e561f9e6c7122ace3db0"); + yield return (Msg: "86da9107ca3e16a2b58950e656a15c085b88033e79313e2c0f92f99f06fa187efba5b8fea08eb7145f8476304180dd280f36a072b7eac197f085", MD: "0d3b1a0459b4eca801e0737ff9ea4a12b9a483a73a8a92742a93c297b7149326bd92c1643c8177c8924482ab3bbd916c417580cc75d3d3ae096de531bc5dc355"); + yield return (Msg: "141a6eafe157053e780ac7a57b97990616ce1759ed132cb453bcdfcabdbb70b3767da4eb94125d9c2a8d6d20bfaeacc1ffbe49c4b1bb5da7e9b5c6", MD: "bdbdd5b94cdc89466e7670c63ba6a55b58294e93b351261a5457bf5a40f1b5b2e0acc7fceb1bfb4c8872777eeeaff7927fd3635ca18c996d870bf86b12b89ba5"); + yield return (Msg: "6e0c65ee0943e34d9bbd27a8547690f2291f5a86d713c2be258e6ac16919fe9c4d491895d3a961bb97f5fac255891a0eaa18f80e1fa1ebcb639fcfc1", MD: "39ebb992b8d39daae973e3813a50e9e79a67d8458a6f17f97a6dd30dd7d11d95701a11129ffeaf7d45781b21cac0c4c034e389d7590df5beeb9805072d0183b9"); + yield return (Msg: "57780b1c79e67fc3beaabead4a67a8cc98b83fa7647eae50c8798b96a516597b448851e93d1a62a098c4767333fcf7b463ce91edde2f3ad0d98f70716d", MD: "3ef36c3effad6eb5ad2d0a67780f80d1b90efcb74db20410c2261a3ab0f784429df874814748dc1b6efaab3d06dd0a41ba54fce59b67d45838eaa4aa1fadfa0f"); + yield return (Msg: "bcc9849da4091d0edfe908e7c3386b0cadadb2859829c9dfee3d8ecf9dec86196eb2ceb093c5551f7e9a4927faabcfaa7478f7c899cbef4727417738fc06", MD: "1fcd8a2c7b4fd98fcdc5fa665bab49bde3f9f556aa66b3646638f5a2d3806192f8a33145d8d0c535c85adff3cc0ea3c2715b33cec9f8886e9f4377b3632e9055"); + yield return (Msg: "05a32829642ed4808d6554d16b9b8023353ce65a935d126602970dba791623004dede90b52ac7f0d4335130a63cba68c656c139989614de20913e83db320db", MD: "49d8747bb53ddde6d1485965208670d1130bf35619d7506a2f2040d1129fcf0320207e5b36fea083e84ffc98755e691ad8bd5dc66f8972cb9857389344e11aad"); + yield return (Msg: "56ac4f6845a451dac3e8886f97f7024b64b1b1e9c5181c059b5755b9a6042be653a2a0d5d56a9e1e774be5c9312f48b4798019345beae2ffcc63554a3c69862e", MD: "5fde5c57a31febb98061f27e4506fa5c245506336ee90d595c91d791a5975c712b3ab9b3b5868f941db0aeb4c6d2837c4447442f8402e0e150a9dc0ef178dca8"); + yield return (Msg: "8a229f8d0294fe90d4cc8c875460d5d623f93287f905a999a2ab0f9a47046f78ef88b09445c671189c59388b3017cca2af8bdf59f8a6f04322b1701ec08624ab63", MD: "16b0fd239cc632842c443e1b92d286dd519cfc616a41f2456dd5cddebd10703c3e9cb669004b7f169bb4f99f350ec96904b0e8dd4de8e6be9953dc892c65099f"); + yield return (Msg: "87d6aa9979025b2437ea8159ea1d3e5d6f17f0a5b913b56970212f56de7884840c0da9a72865e1892aa780b8b8f5f57b46fc070b81ca5f00eee0470ace89b1e1466a", MD: "d816acf1797decfe34f4cc49e52aa505cc59bd17fe69dc9543fad82e9cf96298183021f704054d3d06adde2bf54e82a090a57b239e88daa04cb76c4fc9127843"); + yield return (Msg: "0823616ab87e4904308628c2226e721bb4169b7d34e8744a0700b721e38fe05e3f813fe4075d4c1a936d3a33da20cfb3e3ac722e7df7865330b8f62a73d9119a1f2199", MD: "e1da6be4403a4fd784c59be4e71c658a78bb8c5d7d571c5e816fbb3e218a4162f62de1c285f3779781cb5506e29c94e1b7c7d65af2aa71ea5c96d9585b5e45d5"); + yield return (Msg: "7d2d913c2460c09898b20366ae34775b1564f10edea49c073cebe41989bb93f38a533af1f425d3382f8aa40159b567358ee5a73b67df6d0dc09c1c92bf3f9a28124ab07f", MD: "3aa1e19a52b86cf414d977768bb535b7e5817117d436b4425ec8d775e8cb0e0b538072213884c7ff1bb9ca9984c82d65cb0115cc07332b0ea903e3b38650e88e"); + yield return (Msg: "fca5f68fd2d3a52187b349a8d2726b608fccea7db42e906b8718e85a0ec654fac70f5a839a8d3ff90cfed7aeb5ea9b08f487fc84e1d9f7fb831dea254468a65ba18cc5a126", MD: "2c74f846ecc722ea4a1eb1162e231b6903291fffa95dd5e1d17dbc2c2be7dfe549a80dd34487d714130ddc9924aed904ad55f49c91c80ceb05c0c034dae0a0a4"); + yield return (Msg: "881ff70ca34a3e1a0e864fd2615ca2a0e63def254e688c37a20ef6297cb3ae4c76d746b5e3d6bb41bd0d05d7df3eeded74351f4eb0ac801abe6dc10ef9b635055ee1dfbf4144", MD: "9a10a7ce23c0497fe8783927f833232ae664f1e1b91302266b6ace25a9c253d1ecab1aaaa62f865469480b2145ed0e489ae3f3f9f7e6da27492c81b07e606fb6"); + yield return (Msg: "b0de0430c200d74bf41ea0c92f8f28e11b68006a884e0d4b0d884533ee58b38a438cc1a75750b6434f467e2d0cd9aa4052ceb793291b93ef83fd5d8620456ce1aff2941b3605a4", MD: "9e9e469ca9226cd012f5c9cc39c96adc22f420030fcee305a0ed27974e3c802701603dac873ae4476e9c3d57e55524483fc01adaef87daa9e304078c59802757"); + yield return (Msg: "0ce9f8c3a990c268f34efd9befdb0f7c4ef8466cfdb01171f8de70dc5fefa92acbe93d29e2ac1a5c2979129f1ab08c0e77de7924ddf68a209cdfa0adc62f85c18637d9c6b33f4ff8", MD: "b018a20fcf831dde290e4fb18c56342efe138472cbe142da6b77eea4fce52588c04c808eb32912faa345245a850346faec46c3a16d39bd2e1ddb1816bc57d2da"); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj index eda1865b105c6e..d32b7c3f519491 100644 --- a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj +++ b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj @@ -262,6 +262,9 @@ + + + @@ -296,6 +299,9 @@ + + + diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs index c2b0b22b000b35..ab6c74b90a1eba 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs @@ -57,21 +57,26 @@ public static void PublicKeyEncoding(EccTestData testData) } [Theory] - [InlineData("SHA256")] - [InlineData("SHA384")] - [InlineData("SHA512")] - public static void SignatureAlgorithm_StableNotSame(string hashAlgorithmName) + [MemberData(nameof(SignatureDigestAlgorithms))] + public static void SignatureAlgorithm_StableNotSame(HashAlgorithmName hashAlgorithm, bool isSupported) { using (ECDsa ecdsa = ECDsa.Create(EccTestData.Secp256r1Data.KeyParameters)) { - HashAlgorithmName hashAlgorithm = new HashAlgorithmName(hashAlgorithmName); var generator = X509SignatureGenerator.CreateForECDsa(ecdsa); - byte[] sigAlg = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - byte[] sigAlg2 = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - - Assert.NotSame(sigAlg, sigAlg2); - Assert.Equal(sigAlg, sigAlg2); + if (isSupported) + { + byte[] sigAlg = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + byte[] sigAlg2 = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + + Assert.NotSame(sigAlg, sigAlg2); + Assert.Equal(sigAlg, sigAlg2); + } + else + { + Assert.Throws(() => + generator.GetSignatureAlgorithmIdentifier(hashAlgorithm)); + } } } @@ -93,18 +98,14 @@ public static void SignatureAlgorithm_NotSupported(string hashAlgorithmName) } [Theory] - [InlineData("SHA256")] - [InlineData("SHA384")] - [InlineData("SHA512")] - public static void SignatureAlgorithm_Encoding(string hashAlgorithmName) + [MemberData(nameof(SignatureDigestAlgorithms))] + public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm, bool isSupported) { + _ = isSupported; string expectedAlgOid; - switch (hashAlgorithmName) + switch (hashAlgorithm.Name) { - case "SHA1": - expectedAlgOid = "06072A8648CE3D0401"; - break; case "SHA256": expectedAlgOid = "06082A8648CE3D040302"; break; @@ -114,8 +115,17 @@ public static void SignatureAlgorithm_Encoding(string hashAlgorithmName) case "SHA512": expectedAlgOid = "06082A8648CE3D040304"; break; + case "SHA3_256": + expectedAlgOid = "060960864801650304030A"; + break; + case "SHA3_384": + expectedAlgOid = "060960864801650304030B"; + break; + case "SHA3_512": + expectedAlgOid = "060960864801650304030C"; + break; default: - throw new ArgumentOutOfRangeException(nameof(hashAlgorithmName)); + throw new ArgumentOutOfRangeException(nameof(hashAlgorithm)); } EccTestData testData = EccTestData.Secp521r1Data; @@ -125,7 +135,7 @@ public static void SignatureAlgorithm_Encoding(string hashAlgorithmName) using (ECDsa ecdsa = ECDsa.Create(testData.KeyParameters)) { var generator = X509SignatureGenerator.CreateForECDsa(ecdsa); - byte[] sigAlg = generator.GetSignatureAlgorithmIdentifier(new HashAlgorithmName(hashAlgorithmName)); + byte[] sigAlg = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); Assert.Equal(expectedHex, sigAlg.ByteArrayToHex()); } @@ -135,5 +145,20 @@ public static IEnumerable GetApplicableTestData() { return EccTestData.EnumerateApplicableTests().Select(x => new object[] { x }); } + + public static IEnumerable SignatureDigestAlgorithms + { + get + { + // hashAlgorithm, isSupported + yield return new object[] { HashAlgorithmName.SHA256, true }; + yield return new object[] { HashAlgorithmName.SHA384, true }; + yield return new object[] { HashAlgorithmName.SHA512, true }; + + yield return new object[] { HashAlgorithmName.SHA3_256, PlatformDetection.SupportsSha3 }; + yield return new object[] { HashAlgorithmName.SHA3_384, PlatformDetection.SupportsSha3 }; + yield return new object[] { HashAlgorithmName.SHA3_512, PlatformDetection.SupportsSha3 }; + } + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs index 0ded7c8c85950c..68ffe29919c6b7 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; using Test.Cryptography; using Xunit; @@ -57,25 +58,29 @@ public static void PublicKeyEncoding() } [Theory] - [InlineData("SHA256")] - [InlineData("SHA384")] - [InlineData("SHA512")] - public static void SignatureAlgorithm_StableNotSame(string hashAlgorithmName) + [MemberData(nameof(SignatureDigestAlgorithms))] + public static void SignatureAlgorithm_StableNotSame(HashAlgorithmName hashAlgorithm, bool isSupported) { using (RSA rsa = RSA.Create()) { RSAParameters parameters = TestData.RsaBigExponentParams; rsa.ImportParameters(parameters); - var signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); - - HashAlgorithmName hashAlgorithm = new HashAlgorithmName(hashAlgorithmName); - - byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - byte[] sigAlg2 = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - - Assert.NotSame(sigAlg, sigAlg2); - Assert.Equal(sigAlg, sigAlg2); + if (isSupported) + { + var signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); + + byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + byte[] sigAlg2 = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + + Assert.NotSame(sigAlg, sigAlg2); + Assert.Equal(sigAlg, sigAlg2); + } + else + { + Assert.Throws( + () => X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1)); + } } } @@ -101,14 +106,12 @@ public static void SignatureAlgorithm_NotSupported(string hashAlgorithmName) } [Theory] - [InlineData("SHA256")] - [InlineData("SHA384")] - [InlineData("SHA512")] - public static void SignatureAlgorithm_Encoding(string hashAlgorithmName) + [MemberData(nameof(SignatureDigestAlgorithms))] + public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm, bool isSupported) { string expectedOid; - switch (hashAlgorithmName) + switch (hashAlgorithm.Name) { case "MD5": expectedOid = "06092A864886F70D010104"; @@ -125,8 +128,17 @@ public static void SignatureAlgorithm_Encoding(string hashAlgorithmName) case "SHA512": expectedOid = "06092A864886F70D01010D"; break; + case "SHA3_256": + expectedOid = "060960864801650304030E"; + break; + case "SHA3_384": + expectedOid = "060960864801650304030F"; + break; + case "SHA3_512": + expectedOid = "0609608648016503040310"; + break; default: - throw new ArgumentOutOfRangeException(nameof(hashAlgorithmName)); + throw new ArgumentOutOfRangeException(nameof(hashAlgorithm)); } string expectedHex = $"30{(expectedOid.Length / 2 + 2):X2}{expectedOid}0500"; @@ -136,11 +148,33 @@ public static void SignatureAlgorithm_Encoding(string hashAlgorithmName) RSAParameters parameters = TestData.RsaBigExponentParams; rsa.ImportParameters(parameters); - HashAlgorithmName hashAlgorithm = new HashAlgorithmName(hashAlgorithmName); - X509SignatureGenerator signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); - byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + if (isSupported) + { + X509SignatureGenerator signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); + byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + + Assert.Equal(expectedHex, sigAlg.ByteArrayToHex()); + } + else + { + Assert.Throws( + () => X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1)); + } + } + } - Assert.Equal(expectedHex, sigAlg.ByteArrayToHex()); + public static IEnumerable SignatureDigestAlgorithms + { + get + { + // hashAlgorithm, isSupported + yield return new object[] { HashAlgorithmName.SHA256, true }; + yield return new object[] { HashAlgorithmName.SHA384, true }; + yield return new object[] { HashAlgorithmName.SHA512, true }; + + yield return new object[] { HashAlgorithmName.SHA3_256, PlatformDetection.SupportsSha3 }; + yield return new object[] { HashAlgorithmName.SHA3_384, PlatformDetection.SupportsSha3 }; + yield return new object[] { HashAlgorithmName.SHA3_512, PlatformDetection.SupportsSha3 }; } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs index ef89a1da872d41..70c586b25000b9 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs @@ -83,6 +83,9 @@ public static void SignatureAlgorithm_StableNotSame(string hashAlgorithmName) [InlineData("MD5")] [InlineData("SHA1")] [InlineData("Potato")] + [InlineData("SHA3_256")] // There are no OIDs assigned for RSA-PSS-withSHA3 family. + [InlineData("SHA3_384")] + [InlineData("SHA3_512")] public static void SignatureAlgorithm_NotSupported(string hashAlgorithmName) { using (RSA rsa = RSA.Create()) diff --git a/src/native/libs/System.Security.Cryptography.Native/configure.cmake b/src/native/libs/System.Security.Cryptography.Native/configure.cmake index e4be90d163454d..74ed49f5d19168 100644 --- a/src/native/libs/System.Security.Cryptography.Native/configure.cmake +++ b/src/native/libs/System.Security.Cryptography.Native/configure.cmake @@ -17,6 +17,11 @@ check_function_exists( HAVE_OPENSSL_CHACHA20POLY1305 ) +check_function_exists( + EVP_sha3_256 + HAVE_OPENSSL_SHA3 +) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/pal_crypto_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pal_crypto_config.h) diff --git a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c index 590830c2c76e38..d0ae03ef44d828 100644 --- a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c @@ -162,6 +162,9 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_EvpSha256) DllImportEntry(CryptoNative_EvpSha384) DllImportEntry(CryptoNative_EvpSha512) + DllImportEntry(CryptoNative_EvpSha3_256) + DllImportEntry(CryptoNative_EvpSha3_384) + DllImportEntry(CryptoNative_EvpSha3_512) DllImportEntry(CryptoNative_ExtendedKeyUsageDestroy) DllImportEntry(CryptoNative_GetAsn1IntegerDerSize) DllImportEntry(CryptoNative_GetAsn1StringBytes) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index e09907c1f8b305..3c8f16f32747f8 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -153,6 +153,14 @@ 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); +#endif + #define API_EXISTS(fn) (fn != NULL) // List of all functions from the libssl that are used in the System.Security.Cryptography.Native. @@ -374,6 +382,9 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void); 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) \ REQUIRED_FUNCTION(EXTENDED_KEY_USAGE_free) \ REQUIRED_FUNCTION(GENERAL_NAMES_free) \ REQUIRED_FUNCTION(HMAC) \ @@ -856,6 +867,9 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_sha256 EVP_sha256_ptr #define EVP_sha384 EVP_sha384_ptr #define EVP_sha512 EVP_sha512_ptr +#define EVP_sha3_256 EVP_sha3_256_ptr +#define EVP_sha3_384 EVP_sha3_384_ptr +#define EVP_sha3_512 EVP_sha3_512_ptr #define EXTENDED_KEY_USAGE_free EXTENDED_KEY_USAGE_free_ptr #define GENERAL_NAMES_free GENERAL_NAMES_free_ptr #define HMAC HMAC_ptr 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 6592ac1551a7b8..d7aef5a7d1b674 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,3 +3,4 @@ #cmakedefine01 HAVE_OPENSSL_EC2M #cmakedefine01 HAVE_OPENSSL_ALPN #cmakedefine01 HAVE_OPENSSL_CHACHA20POLY1305 +#cmakedefine01 HAVE_OPENSSL_SHA3 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 f4b6b3e0fc13b2..98da52b81c0cac 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c @@ -175,6 +175,45 @@ const EVP_MD* CryptoNative_EvpSha512(void) return EVP_sha512(); } +const EVP_MD* CryptoNative_EvpSha3_256(void) +{ + // No error queue impact. +#if HAVE_OPENSSL_SHA3 + if (API_EXISTS(EVP_sha3_256)) + { + return EVP_sha3_256(); + } +#endif + + return NULL; +} + +const EVP_MD* CryptoNative_EvpSha3_384(void) +{ + // No error queue impact. +#if HAVE_OPENSSL_SHA3 + if (API_EXISTS(EVP_sha3_384)) + { + return EVP_sha3_384(); + } +#endif + + return NULL; +} + +const EVP_MD* CryptoNative_EvpSha3_512(void) +{ + // No error queue impact. +#if HAVE_OPENSSL_SHA3 + if (API_EXISTS(EVP_sha3_512)) + { + return EVP_sha3_512(); + } +#endif + + return NULL; +} + int32_t CryptoNative_GetMaxMdSize(void) { // No error queue impact. diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp.h b/src/native/libs/System.Security.Cryptography.Native/pal_evp.h index 11c8a167191815..1fc90610fe4347 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.h @@ -113,6 +113,30 @@ Direct shim to EVP_sha512. */ PALEXPORT const EVP_MD* CryptoNative_EvpSha512(void); +/* +Function: +EvpSha3_256 + +Direct shim to EVP_sha3_256. +*/ +PALEXPORT const EVP_MD* CryptoNative_EvpSha3_256(void); + +/* +Function: +EvpSha3_384 + +Direct shim to EVP_sha3_384. +*/ +PALEXPORT const EVP_MD* CryptoNative_EvpSha3_384(void); + +/* +Function: +EvpSha3_512 + +Direct shim to EVP_sha3_512. +*/ +PALEXPORT const EVP_MD* CryptoNative_EvpSha3_512(void); + /* Function: GetMaxMdSize From 64f1c2e5cd4c05a8ed3d7800ed2729a3af883a4e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sun, 19 Mar 2023 20:49:15 -0400 Subject: [PATCH 02/47] Fix failures on unsupported platforms --- .../Cryptography/HashOneShotHelpers.cs | 30 ++++--- .../ECDsa/ECDsaTests.NistValidation.cs | 6 +- .../Security/Cryptography/HMACSHA3_256.cs | 13 +++ .../Security/Cryptography/HMACSHA3_384.cs | 13 +++ .../Security/Cryptography/HMACSHA3_512.cs | 13 +++ .../Pbkdf2Implementation.Apple.cs | 4 + .../tests/HashAlgorithmTestDriver.cs | 83 +++++++++++------ .../tests/HmacMD5Tests.cs | 9 +- .../tests/HmacSha1Tests.cs | 9 +- .../tests/HmacSha256Tests.cs | 9 +- .../tests/HmacSha384Tests.cs | 9 +- .../tests/HmacSha3_256Tests.cs | 29 +++--- .../tests/HmacSha3_384Tests.cs | 29 +++--- .../tests/HmacSha3_512Tests.cs | 29 +++--- .../tests/HmacSha512Tests.cs | 9 +- .../tests/HmacTests.cs | 89 +++++++++++++------ .../tests/MD5Tests.cs | 8 +- .../tests/Rfc2202HmacTests.cs | 2 +- .../tests/Rfc4231HmacTests.cs | 2 +- .../tests/Sha1Tests.cs | 8 +- .../tests/Sha256Tests.cs | 8 +- .../tests/Sha384Tests.cs | 8 +- .../tests/Sha3_256Tests.cs | 10 ++- .../tests/Sha3_384Tests.cs | 10 ++- .../tests/Sha3_512Tests.cs | 10 ++- .../tests/Sha512Tests.cs | 8 +- .../ECDsaX509SignatureGeneratorTests.cs | 36 +++----- .../RSAPkcs1X509SignatureGeneratorTests.cs | 56 ++++-------- 28 files changed, 370 insertions(+), 179 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs index 89d60020ff3a9f..596f1a8be00c87 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs @@ -28,17 +28,17 @@ internal static byte[] HashData(HashAlgorithmName hashAlgorithm, ReadOnlySpan key, ReadOnlySpan source, Sp /// public static bool TryHashData(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int bytesWritten) { + CheckSha3Support(); + if (destination.Length < HashSizeInBytes) { bytesWritten = 0; @@ -221,6 +224,7 @@ public static int HashData(ReadOnlySpan key, Stream source, Span des if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_256, key, source, destination); } @@ -243,6 +247,7 @@ public static byte[] HashData(ReadOnlySpan key, Stream source) if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_256, HashSizeInBytes, key, source); } @@ -288,6 +293,7 @@ public static ValueTask HashDataAsync(ReadOnlyMemory key, Stream s if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStreamAsync(HashAlgorithmNames.SHA3_256, key.Span, source, cancellationToken); } @@ -352,6 +358,7 @@ public static ValueTask HashDataAsync( if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStreamAsync( HashAlgorithmNames.SHA3_256, key.Span, @@ -374,5 +381,11 @@ protected override void Dispose(bool disposing) } base.Dispose(disposing); } + + private static void CheckSha3Support() + { + if (!IsSupported) + throw new PlatformNotSupportedException(); + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs index 19979b8c7bf235..3d8d6f26469596 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs @@ -59,6 +59,7 @@ public HMACSHA3_384() public HMACSHA3_384(byte[] key) { ArgumentNullException.ThrowIfNull(key); + CheckSha3Support(); this.HashName = HashAlgorithmNames.SHA3_384; _hMacCommon = new HMACCommon(HashAlgorithmNames.SHA3_384, key, BlockSize); @@ -179,6 +180,8 @@ public static int HashData(ReadOnlySpan key, ReadOnlySpan source, Sp /// public static bool TryHashData(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int bytesWritten) { + CheckSha3Support(); + if (destination.Length < HashSizeInBytes) { bytesWritten = 0; @@ -221,6 +224,7 @@ public static int HashData(ReadOnlySpan key, Stream source, Span des if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_384, key, source, destination); } @@ -243,6 +247,7 @@ public static byte[] HashData(ReadOnlySpan key, Stream source) if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_384, HashSizeInBytes, key, source); } @@ -288,6 +293,7 @@ public static ValueTask HashDataAsync(ReadOnlyMemory key, Stream s if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStreamAsync(HashAlgorithmNames.SHA3_384, key.Span, source, cancellationToken); } @@ -352,6 +358,7 @@ public static ValueTask HashDataAsync( if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStreamAsync( HashAlgorithmNames.SHA3_384, key.Span, @@ -374,5 +381,11 @@ protected override void Dispose(bool disposing) } base.Dispose(disposing); } + + private static void CheckSha3Support() + { + if (!IsSupported) + throw new PlatformNotSupportedException(); + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs index 48e7c3635323de..b7e7d9f9948b56 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs @@ -59,6 +59,7 @@ public HMACSHA3_512() public HMACSHA3_512(byte[] key) { ArgumentNullException.ThrowIfNull(key); + CheckSha3Support(); this.HashName = HashAlgorithmNames.SHA3_512; _hMacCommon = new HMACCommon(HashAlgorithmNames.SHA3_512, key, BlockSize); @@ -179,6 +180,8 @@ public static int HashData(ReadOnlySpan key, ReadOnlySpan source, Sp /// public static bool TryHashData(ReadOnlySpan key, ReadOnlySpan source, Span destination, out int bytesWritten) { + CheckSha3Support(); + if (destination.Length < HashSizeInBytes) { bytesWritten = 0; @@ -221,6 +224,7 @@ public static int HashData(ReadOnlySpan key, Stream source, Span des if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_512, key, source, destination); } @@ -243,6 +247,7 @@ public static byte[] HashData(ReadOnlySpan key, Stream source) if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStream(HashAlgorithmNames.SHA3_512, HashSizeInBytes, key, source); } @@ -288,6 +293,7 @@ public static ValueTask HashDataAsync(ReadOnlyMemory key, Stream s if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStreamAsync(HashAlgorithmNames.SHA3_512, key.Span, source, cancellationToken); } @@ -352,6 +358,7 @@ public static ValueTask HashDataAsync( if (!source.CanRead) throw new ArgumentException(SR.Argument_StreamNotReadable, nameof(source)); + CheckSha3Support(); return LiteHashProvider.HmacStreamAsync( HashAlgorithmNames.SHA3_512, key.Span, @@ -374,5 +381,11 @@ protected override void Dispose(bool disposing) } base.Dispose(disposing); } + + private static void CheckSha3Support() + { + if (!IsSupported) + throw new PlatformNotSupportedException(); + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs index be842135d75f73..4cc80b53fc5b53 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs @@ -33,6 +33,10 @@ public static unsafe void Fill( case HashAlgorithmNames.SHA512: prfAlgorithm = PAL_HashAlgorithm.Sha512; break; + case HashAlgorithmNames.SHA3_256: + case HashAlgorithmNames.SHA3_384: + case HashAlgorithmNames.SHA3_512: + throw new PlatformNotSupportedException(); default: Debug.Fail($"Unexpected hash algorithm '{hashAlgorithmName.Name}'"); throw new CryptographicException(); diff --git a/src/libraries/System.Security.Cryptography/tests/HashAlgorithmTestDriver.cs b/src/libraries/System.Security.Cryptography/tests/HashAlgorithmTestDriver.cs index 8890808c6a0cca..8443c222edaa6b 100644 --- a/src/libraries/System.Security.Cryptography/tests/HashAlgorithmTestDriver.cs +++ b/src/libraries/System.Security.Cryptography/tests/HashAlgorithmTestDriver.cs @@ -10,8 +10,10 @@ namespace System.Security.Cryptography.Tests { - public abstract class HashAlgorithmTestDriver + public abstract class HashAlgorithmTestDriver where THashTrait : IHashTrait { + public static bool IsSupported => THashTrait.IsSupported; + public static bool IsNotSupported => !IsSupported; protected abstract HashAlgorithm Create(); protected abstract bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten); protected abstract byte[] HashData(byte[] source); @@ -191,19 +193,19 @@ private void VerifyTransformBlockComputeHashInteraction(byte[] block1, byte[] bl } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_ByteArray_Null() { AssertExtensions.Throws("source", () => HashData((byte[])null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_BufferTooSmall() { AssertExtensions.Throws("destination", () => HashData(Span.Empty, default)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void VerifyObjectDisposedException() { HashAlgorithm hash = Create(); @@ -216,7 +218,7 @@ public void VerifyObjectDisposedException() Assert.Throws(() => hash.TransformFinalBlock(Array.Empty(), 0, 0)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void VerifyHashNotYetFinalized() { using (HashAlgorithm hash = Create()) @@ -226,7 +228,7 @@ public void VerifyHashNotYetFinalized() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_ComputeHash() { using (HashAlgorithm hash = Create()) @@ -236,7 +238,7 @@ public void InvalidInput_ComputeHash() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_TransformBlock() { using (HashAlgorithm hash = Create()) @@ -248,7 +250,7 @@ public void InvalidInput_TransformBlock() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_TransformFinalBlock() { using (HashAlgorithm hash = Create()) @@ -404,20 +406,43 @@ protected async Task VerifyRepeatingAsync(string input, int repeatCount, string } } - [Fact] + [ConditionalFact(nameof(IsNotSupported))] + public async Task HashData_NotSupported() + { + byte[] buffer = new byte[THashTrait.HashSizeInBytes]; + Assert.Throws(() => HashData(Array.Empty())); + Assert.Throws(() => HashData(ReadOnlySpan.Empty)); + Assert.Throws(() => HashData(ReadOnlySpan.Empty, buffer)); + Assert.Throws(() => TryHashData(ReadOnlySpan.Empty, buffer, out _)); + + Assert.Throws(() => HashData(Stream.Null)); + Assert.Throws(() => HashData(Stream.Null, buffer)); + await Assert.ThrowsAsync(async () => + await HashDataAsync(Stream.Null, default(CancellationToken))); + await Assert.ThrowsAsync(async () => + await HashDataAsync(Stream.Null, buffer, default(CancellationToken))); + } + + [ConditionalFact(nameof(IsNotSupported))] + public void Create_NotSupported() + { + Assert.Throws(() => Create()); + } + + [ConditionalFact(nameof(IsSupported))] public void HashData_Null_Stream_Throws() { AssertExtensions.Throws("source", () => HashData((Stream)null)); AssertExtensions.Throws("source", () => HashData((Stream)null, Span.Empty)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_ShortDestination_Throws() { AssertExtensions.Throws("destination", () => HashData(Stream.Null, Span.Empty)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashDataAsync_Null_Stream_Throws() { AssertExtensions.Throws( @@ -429,7 +454,7 @@ public void HashDataAsync_Null_Stream_Throws() () => HashDataAsync((Stream)null, Memory.Empty, cancellationToken: default)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashDataAsync_ShortDestination_Throws() { AssertExtensions.Throws( @@ -437,7 +462,7 @@ public void HashDataAsync_ShortDestination_Throws() () => HashDataAsync(Stream.Null, Memory.Empty, cancellationToken: default)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashDataAsync_Buffer_CancelledToken() { Memory buffer = new byte[512 / 8]; @@ -447,7 +472,7 @@ public void HashDataAsync_Buffer_CancelledToken() AssertExtensions.FilledWith(0, buffer.Span); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashDataAsync_Allocating_CancelledToken() { CancellationToken cancelledToken = new CancellationToken(canceled: true); @@ -455,7 +480,7 @@ public void HashDataAsync_Allocating_CancelledToken() Assert.True(waitable.IsCanceled, nameof(waitable.IsCanceled)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_Null() { using (HashAlgorithm hash = Create()) @@ -466,7 +491,7 @@ public void InvalidInput_Null() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_NegativeOffset() { using (HashAlgorithm hash = Create()) @@ -475,7 +500,7 @@ public void InvalidInput_NegativeOffset() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_NegativeCount() { using (HashAlgorithm hash = Create()) @@ -484,7 +509,7 @@ public void InvalidInput_NegativeCount() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_TooBigOffset() { using (HashAlgorithm hash = Create()) @@ -493,7 +518,7 @@ public void InvalidInput_TooBigOffset() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_TooBigCount() { byte[] nonEmpty = new byte[53]; @@ -507,7 +532,7 @@ public void InvalidInput_TooBigCount() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void BoundaryCondition_Count0() { byte[] nonEmpty = new byte[53]; @@ -533,7 +558,7 @@ public void BoundaryCondition_Count0() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OffsetAndCountRespected() { byte[] dataA = { 1, 1, 2, 3, 5, 8 }; @@ -550,7 +575,7 @@ public void OffsetAndCountRespected() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void ComputeHash_TryComputeHash_HashSetExplicitlyByBoth() { using (HashAlgorithm hash = Create()) @@ -569,7 +594,7 @@ public void ComputeHash_TryComputeHash_HashSetExplicitlyByBoth() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void Dispose_TryComputeHash_ThrowsException() { HashAlgorithm hash = Create(); @@ -578,7 +603,7 @@ public void Dispose_TryComputeHash_ThrowsException() Assert.Throws(() => hash.TryComputeHash(new byte[1], new byte[1], out int bytesWritten)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void Initialize_TransformBlock() { byte[] hashInput = new byte[] { 1, 2, 3, 4, 5 }; @@ -600,7 +625,7 @@ public void Initialize_TransformBlock() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void Initialize_TransformBlock_Unused() { byte[] hashInput = new byte[] { 1, 2, 3, 4, 5 }; @@ -621,7 +646,7 @@ public void Initialize_TransformBlock_Unused() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void Initialize_DoubleInitialize_Works() { byte[] hashInput = new byte[] { 1, 2, 3, 4, 5 }; @@ -645,4 +670,10 @@ public void Initialize_DoubleInitialize_Works() } } } + + public interface IHashTrait + { + static abstract bool IsSupported { get; } + static abstract int HashSizeInBytes { get; } + } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs index d657f9627b2942..b61f5d6d65689b 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs @@ -10,8 +10,14 @@ namespace System.Security.Cryptography.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public class HmacMD5Tests : Rfc2202HmacTests + public class HmacMD5Tests : Rfc2202HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => HMACSHA1.HashSizeInBytes; + } + private static readonly byte[][] s_testKeys2202 = { null, @@ -45,6 +51,7 @@ public HmacMD5Tests() protected override int MacSize => HMACMD5.HashSizeInBytes; protected override HMAC Create() => new HMACMD5(); + protected override HMAC Create(byte[] key) => new HMACMD5(key); protected override HashAlgorithm CreateHashAlgorithm() => MD5.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACMD5.HashData(key, source); diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs index 9b5aa3effca47b..5e952d88f74d78 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs @@ -9,8 +9,14 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha1Tests : Rfc2202HmacTests + public class HmacSha1Tests : Rfc2202HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => HMACSHA1.HashSizeInBytes; + } + private static readonly byte[][] s_testKeys2202 = { null, @@ -44,6 +50,7 @@ public HmacSha1Tests() protected override int MacSize => HMACSHA1.HashSizeInBytes; protected override HMAC Create() => new HMACSHA1(); + protected override HMAC Create(byte[] key) => new HMACSHA1(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA1.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA1.HashData(key, source); diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs index dea079824ff1fc..ceace692f737b7 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs @@ -9,12 +9,19 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha256Tests : Rfc4231HmacTests + public class HmacSha256Tests : Rfc4231HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => HMACSHA256.HashSizeInBytes; + } + protected override int BlockSize => 64; protected override int MacSize => HMACSHA256.HashSizeInBytes; protected override HMAC Create() => new HMACSHA256(); + protected override HMAC Create(byte[] key) => new HMACSHA256(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA256.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA256.HashData(key, source); diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs index d026442de4bb4a..4d36c1dd526168 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs @@ -9,12 +9,19 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha384Tests : Rfc4231HmacTests + public class HmacSha384Tests : Rfc4231HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => HMACSHA384.HashSizeInBytes; + } + protected override int BlockSize => 128; protected override int MacSize => HMACSHA384.HashSizeInBytes; protected override HMAC Create() => new HMACSHA384(); + protected override HMAC Create(byte[] key) => new HMACSHA384(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA384.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA384.HashData(key, source); diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs index 9a78fef4f7179f..3e3b73f2a04237 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs @@ -10,12 +10,19 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha3_256Tests : HmacTests + public class HmacSha3_256Tests : HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => HMACSHA3_256.IsSupported; + public static int HashSizeInBytes => HMACSHA3_256.HashSizeInBytes; + } + protected override int BlockSize => 136; protected override int MacSize => HMACSHA3_256.HashSizeInBytes; protected override HMAC Create() => new HMACSHA3_256(); + protected override HMAC Create(byte[] key) => new HMACSHA3_256(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA3_256.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA3_256.HashData(key, source); @@ -98,7 +105,7 @@ public HmacSha3_256Tests() : base(s_testKeys, s_testData, s_testMacs) { } - [Theory] + [ConditionalTheory(nameof(IsSupported))] [MemberData(nameof(TestCaseIds))] public void HmacSha3_256_VerifyTestCases(int caseId) { @@ -116,19 +123,19 @@ public static IEnumerable TestCaseIds } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_256_Rfc2104_2() { VerifyHmacRfc2104_2(); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_256_ThrowsArgumentNullForNullConstructorKey() { AssertExtensions.Throws("key", () => new HMACSHA3_256(null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_256_EmptyKey() { VerifyRepeating( @@ -138,7 +145,7 @@ public void HmacSha3_256_EmptyKey() output: "c49c24ae6dce7e90d5e2853ad9e647d89ac3dd04eb71aa0912ab4b4b1068ba6a"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_256_Stream_MultipleOf4096() { // Verfied with: @@ -150,7 +157,7 @@ public void HmacSha3_256_Stream_MultipleOf4096() output: "F09DD1B814BF4A576FF8AEAFF69509E3093895426F441A428953221F3CB9E421"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_256_Stream_NotMultipleOf4096() { // Verfied with: @@ -162,7 +169,7 @@ public void HmacSha3_256_Stream_NotMultipleOf4096() output: "F1DB96FF2B53CBA0338FF519BFA10153731DB48A63C26EB66294895B220F72B5"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_256_Stream_Empty() { // Verfied with: @@ -174,7 +181,7 @@ public void HmacSha3_256_Stream_Empty() output: "72756291FF30F3E916BEF99EC9CF5938B25D90BBCAC1BDB1E1E6564E8EC6FDA5"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_256_Stream_MultipleOf4096_Async() { // Verfied with: @@ -186,7 +193,7 @@ await VerifyRepeatingAsync( output: "F09DD1B814BF4A576FF8AEAFF69509E3093895426F441A428953221F3CB9E421"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_256_Stream_NotMultipleOf4096_Async() { // Verfied with: @@ -198,7 +205,7 @@ await VerifyRepeatingAsync( output: "F1DB96FF2B53CBA0338FF519BFA10153731DB48A63C26EB66294895B220F72B5"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_256_Stream_Empty_Async() { // Verfied with: diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs index 9bfbe70c64941f..019cd011d8a944 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs @@ -10,12 +10,19 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha3_384Tests : HmacTests + public class HmacSha3_384Tests : HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => HMACSHA3_384.IsSupported; + public static int HashSizeInBytes => HMACSHA3_384.HashSizeInBytes; + } + protected override int BlockSize => 104; protected override int MacSize => HMACSHA3_384.HashSizeInBytes; protected override HMAC Create() => new HMACSHA3_384(); + protected override HMAC Create(byte[] key) => new HMACSHA3_384(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA3_384.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA3_384.HashData(key, source); @@ -106,7 +113,7 @@ public HmacSha3_384Tests() : base(s_testKeys, s_testData, s_testMacs) { } - [Theory] + [ConditionalTheory(nameof(IsSupported))] [MemberData(nameof(TestCaseIds))] public void HmacSha3_384_VerifyTestCases(int caseId) { @@ -124,19 +131,19 @@ public static IEnumerable TestCaseIds } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_384_Rfc2104_2() { VerifyHmacRfc2104_2(); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_384_ThrowsArgumentNullForNullConstructorKey() { AssertExtensions.Throws("key", () => new HMACSHA3_384(null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_384_EmptyKey() { VerifyRepeating( @@ -146,7 +153,7 @@ public void HmacSha3_384_EmptyKey() output: "16C079F7D15505E9E541421E63C432A063F39C1E3E953E6DC7B8A81FE5620AFFA430C3E6BE6A0F605755C7C5EE4E347E"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_384_Stream_MultipleOf4096() { // Verfied with: @@ -158,7 +165,7 @@ public void HmacSha3_384_Stream_MultipleOf4096() output: "17D03C8153AF1719F5829C8CBF328D4200900ED1AB038A399B4F256A490BD4D2AB311C71D2ED0C20ABA96E57768CCA6E"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_384_Stream_NotMultipleOf4096() { // Verfied with: @@ -170,7 +177,7 @@ public void HmacSha3_384_Stream_NotMultipleOf4096() output: "5360719A6A9DFEB1143C2866A7F72EA29404C3DBF37F244A0497F400DA126B2728118863454288F26E3796BE72238958"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_384_Stream_Empty() { // Verfied with: @@ -182,7 +189,7 @@ public void HmacSha3_384_Stream_Empty() output: "5B0196779BDAF859E99869A63C9FDF3821E9100A370B5E9B88F76B9DA87410F99846E7DBB4F8A69368C5C5A834B3128D"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_384_Stream_MultipleOf4096_Async() { // Verfied with: @@ -194,7 +201,7 @@ await VerifyRepeatingAsync( output: "17D03C8153AF1719F5829C8CBF328D4200900ED1AB038A399B4F256A490BD4D2AB311C71D2ED0C20ABA96E57768CCA6E"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_384_Stream_NotMultipleOf4096_Async() { // Verfied with: @@ -206,7 +213,7 @@ await VerifyRepeatingAsync( output: "5360719A6A9DFEB1143C2866A7F72EA29404C3DBF37F244A0497F400DA126B2728118863454288F26E3796BE72238958"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_384_Stream_Empty_Async() { // Verfied with: diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs index e2a25faae8725d..1a307a2e830910 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs @@ -10,12 +10,19 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha3_512Tests : HmacTests + public class HmacSha3_512Tests : HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => HMACSHA3_512.IsSupported; + public static int HashSizeInBytes => HMACSHA3_512.HashSizeInBytes; + } + protected override int BlockSize => 72; protected override int MacSize => HMACSHA3_512.HashSizeInBytes; protected override HMAC Create() => new HMACSHA3_512(); + protected override HMAC Create(byte[] key) => new HMACSHA3_512(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA3_512.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA3_512.HashData(key, source); @@ -105,7 +112,7 @@ public HmacSha3_512Tests() : base(s_testKeys, s_testData, s_testMacs) { } - [Theory] + [ConditionalTheory(nameof(IsSupported))] [MemberData(nameof(TestCaseIds))] public void HmacSha3_512_VerifyTestCases(int caseId) { @@ -123,19 +130,19 @@ public static IEnumerable TestCaseIds } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_512_Rfc2104_2() { VerifyHmacRfc2104_2(); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_512_ThrowsArgumentNullForNullConstructorKey() { AssertExtensions.Throws("key", () => new HMACSHA3_512(null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_512_EmptyKey() { VerifyRepeating( @@ -146,7 +153,7 @@ public void HmacSha3_512_EmptyKey() "98792648C97886B3DD9E63AB962581C67DA5EE04F2B15263555B1796782CB556"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_512_Stream_MultipleOf4096() { // Verfied with: @@ -159,7 +166,7 @@ public void HmacSha3_512_Stream_MultipleOf4096() "317D9014C429DB18E5A6BFD811F7B484922471085F17ED31F6A7EB4E07BFFA97"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_512_Stream_NotMultipleOf4096() { // Verfied with: @@ -172,7 +179,7 @@ public void HmacSha3_512_Stream_NotMultipleOf4096() "E86DECE850D50DE76386CB293FA832778C7D6607A4F00AD666DA3EFFD6143E70"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HmacSha3_512_Stream_Empty() { // Verfied with: @@ -185,7 +192,7 @@ public void HmacSha3_512_Stream_Empty() "CA58633748DC80D4615E3D21228BB3A5F535FA1CB963DF463CC28ABAF1A9B2D1"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_512_Stream_MultipleOf4096_Async() { // Verfied with: @@ -198,7 +205,7 @@ await VerifyRepeatingAsync( "317D9014C429DB18E5A6BFD811F7B484922471085F17ED31F6A7EB4E07BFFA97"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_512_Stream_NotMultipleOf4096_Async() { // Verfied with: @@ -211,7 +218,7 @@ await VerifyRepeatingAsync( "E86DECE850D50DE76386CB293FA832778C7D6607A4F00AD666DA3EFFD6143E70"); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public async Task HmacSha3_512_Stream_Empty_Async() { // Verfied with: diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs index 44aec88b8e1e2d..45bf467a97d570 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs @@ -9,12 +9,19 @@ namespace System.Security.Cryptography.Tests { - public class HmacSha512Tests : Rfc4231HmacTests + public class HmacSha512Tests : Rfc4231HmacTests { + public sealed class Traits : IHmacTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => HMACSHA512.HashSizeInBytes; + } + protected override int BlockSize => 128; protected override int MacSize => HMACSHA512.HashSizeInBytes; protected override HMAC Create() => new HMACSHA512(); + protected override HMAC Create(byte[] key) => new HMACSHA512(key); protected override HashAlgorithm CreateHashAlgorithm() => SHA512.Create(); protected override byte[] HashDataOneShot(byte[] key, byte[] source) => HMACSHA512.HashData(key, source); diff --git a/src/libraries/System.Security.Cryptography/tests/HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/HmacTests.cs index 61f79e79eff0d0..c6bd7ee994f3f5 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacTests.cs @@ -9,8 +9,11 @@ namespace System.Security.Cryptography.Tests { - public abstract class HmacTests + public abstract class HmacTests where THmacTrait : IHmacTrait { + public static bool IsSupported => THmacTrait.IsSupported; + public static bool IsNotSupported => !IsSupported; + // RFC2202 defines the test vectors for HMACMD5 and HMACSHA1 // RFC4231 defines the test vectors for HMACSHA{224,256,384,512} // They share the same datasets for cases 1-5, but cases 6 and 7 differ. @@ -26,6 +29,7 @@ protected HmacTests(byte[][] testKeys, byte[][] testData, byte[][] testMacs) } protected abstract HMAC Create(); + protected abstract HMAC Create(byte[] key); protected abstract HashAlgorithm CreateHashAlgorithm(); protected abstract byte[] HashDataOneShot(byte[] key, byte[] source); @@ -254,7 +258,7 @@ protected void VerifyHmacRfc2104_2() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_Null() { using (HMAC hash = Create()) @@ -265,7 +269,7 @@ public void InvalidInput_Null() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_NegativeOffset() { using (HMAC hash = Create()) @@ -274,7 +278,7 @@ public void InvalidInput_NegativeOffset() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_NegativeCount() { using (HMAC hash = Create()) @@ -283,7 +287,7 @@ public void InvalidInput_NegativeCount() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_TooBigOffset() { using (HMAC hash = Create()) @@ -292,7 +296,7 @@ public void InvalidInput_TooBigOffset() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidInput_TooBigCount() { byte[] nonEmpty = new byte[53]; @@ -306,7 +310,7 @@ public void InvalidInput_TooBigCount() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void BoundaryCondition_Count0() { byte[] nonEmpty = new byte[53]; @@ -332,7 +336,7 @@ public void BoundaryCondition_Count0() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OffsetAndCountRespected() { byte[] dataA = { 1, 1, 2, 3, 5, 8 }; @@ -349,7 +353,7 @@ public void OffsetAndCountRespected() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void InvalidKey_ThrowArgumentNullException() { using (HMAC hash = Create()) @@ -358,21 +362,21 @@ public void InvalidKey_ThrowArgumentNullException() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OneShot_NullKey_ArgumentNullException() { AssertExtensions.Throws("key", () => HashDataOneShot(key: (byte[])null, source: Array.Empty())); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OneShot_NullSource_ArgumentNullException() { AssertExtensions.Throws("source", () => HashDataOneShot(key: Array.Empty(), source: (byte[])null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OneShot_ExistingBuffer_TooSmall() { byte[] buffer = new byte[MacSize - 1]; @@ -385,7 +389,7 @@ public void OneShot_ExistingBuffer_TooSmall() AssertExtensions.FilledWith(0, buffer); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OneShot_TryExistingBuffer_TooSmall() { byte[] buffer = new byte[MacSize - 1]; @@ -397,7 +401,7 @@ public void OneShot_TryExistingBuffer_TooSmall() AssertExtensions.FilledWith(0, buffer); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OneShot_TryExistingBuffer_Exact() { for (int caseId = 1; caseId < _testKeys.Length; caseId++) @@ -415,7 +419,7 @@ public void OneShot_TryExistingBuffer_Exact() } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void OneShot_TryExistingBuffer_Larger() { for (int caseId = 1; caseId < _testKeys.Length; caseId++) @@ -438,7 +442,7 @@ public void OneShot_TryExistingBuffer_Larger() } } - [Theory] + [ConditionalTheory(nameof(IsSupported))] [InlineData(0, 10)] [InlineData(10, 10)] [InlineData(10, 0)] @@ -464,7 +468,7 @@ public void OneShot_TryExistingBuffer_OverlapsKey(int keyOffset, int bufferOffse } } - [Theory] + [ConditionalTheory(nameof(IsSupported))] [InlineData(0, 10)] [InlineData(10, 10)] [InlineData(10, 0)] @@ -490,7 +494,7 @@ public void OneShot_TryExistingBuffer_OverlapsSource(int sourceOffset, int buffe } } - [Theory] + [ConditionalTheory(nameof(IsSupported))] [InlineData(new byte[0], new byte[] { 1 })] [InlineData(new byte[] { 1 }, new byte[0])] public void OneShot_Empty_Matches_Instances(byte[] key, byte[] source) @@ -505,7 +509,7 @@ public void OneShot_Empty_Matches_Instances(byte[] key, byte[] source) } } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_Source_Null() { AssertExtensions.Throws( @@ -517,7 +521,7 @@ public void HashData_Stream_Source_Null() () => HashDataOneShot(Array.Empty(), (Stream)null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_Source_Null_Async() { AssertExtensions.Throws( @@ -529,7 +533,7 @@ public void HashData_Stream_Source_Null_Async() () => HashDataOneShotAsync(Array.Empty(), (Stream)null, default)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_ByteKey_Null() { AssertExtensions.Throws( @@ -537,7 +541,7 @@ public void HashData_Stream_ByteKey_Null() () => HashDataOneShot((byte[])null, Stream.Null)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_ByteKey_Null_Async() { AssertExtensions.Throws( @@ -545,7 +549,7 @@ public void HashData_Stream_ByteKey_Null_Async() () => HashDataOneShotAsync((byte[])null, Stream.Null, default)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_DestinationTooSmall() { byte[] destination = new byte[MacSize - 1]; @@ -561,7 +565,7 @@ public void HashData_Stream_DestinationTooSmall() AssertExtensions.FilledWith(0, destination); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_DestinationTooSmall_Async() { byte[] destination = new byte[MacSize - 1]; @@ -577,7 +581,7 @@ public void HashData_Stream_DestinationTooSmall_Async() AssertExtensions.FilledWith(0, destination); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_NotReadable() { AssertExtensions.Throws( @@ -589,7 +593,7 @@ public void HashData_Stream_NotReadable() () => HashDataOneShot(ReadOnlySpan.Empty, UntouchableStream.Instance)); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_Cancelled() { Memory buffer = new byte[512 / 8]; @@ -603,12 +607,43 @@ public void HashData_Stream_Cancelled() AssertExtensions.FilledWith(0, buffer.Span); } - [Fact] + [ConditionalFact(nameof(IsSupported))] public void HashData_Stream_Allocating_Cancelled() { CancellationToken cancelledToken = new CancellationToken(canceled: true); ValueTask waitable = HashDataOneShotAsync(ReadOnlyMemory.Empty, Stream.Null, cancelledToken); Assert.True(waitable.IsCanceled, nameof(waitable.IsCanceled)); } + + [ConditionalFact(nameof(IsNotSupported))] + public void Ctor_NotSupported() + { + Assert.Throws(() => Create()); + Assert.Throws(() => Create(new byte[42])); + } + + [ConditionalFact(nameof(IsNotSupported))] + public async Task HashData_NotSupported() + { + byte[] key = new byte[1]; + byte[] buffer = new byte[THmacTrait.HashSizeInBytes]; + Assert.Throws(() => HashDataOneShot(key, Array.Empty())); + Assert.Throws(() => HashDataOneShot(key, ReadOnlySpan.Empty)); + Assert.Throws(() => HashDataOneShot(key, ReadOnlySpan.Empty, buffer)); + Assert.Throws(() => TryHashDataOneShot(key, ReadOnlySpan.Empty, buffer, out _)); + + Assert.Throws(() => HashDataOneShot(key, Stream.Null)); + Assert.Throws(() => HashDataOneShot(key, Stream.Null, buffer)); + await Assert.ThrowsAsync(async () => + await HashDataOneShotAsync(key, Stream.Null, default(CancellationToken))); + await Assert.ThrowsAsync(async () => + await HashDataOneShotAsync(key, Stream.Null, buffer, default(CancellationToken))); + } + } + + public interface IHmacTrait + { + static abstract bool IsSupported { get; } + static abstract int HashSizeInBytes { get; } } } diff --git a/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs b/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs index 26ab965bf4799f..317d108cf7400b 100644 --- a/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs @@ -9,8 +9,14 @@ namespace System.Security.Cryptography.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public class MD5Tests : HashAlgorithmTestDriver + public class MD5Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => MD5.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return MD5.Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs index e4bcc0a66667a2..f40e8638086159 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs @@ -6,7 +6,7 @@ namespace System.Security.Cryptography.Tests { - public abstract class Rfc2202HmacTests : HmacTests + public abstract class Rfc2202HmacTests : HmacTests where THmacTrait : IHmacTrait { private static readonly byte[][] s_testData2202 = { diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs index 2dd668a288ffd8..dedc5f526311db 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs @@ -6,7 +6,7 @@ namespace System.Security.Cryptography.Tests { - public abstract class Rfc4231HmacTests : HmacTests + public abstract class Rfc4231HmacTests : HmacTests where THmacTrait : IHmacTrait { private static readonly byte[][] s_testKeys4231 = { diff --git a/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs index 46f0f24534348f..0374735b796b57 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs @@ -8,8 +8,14 @@ namespace System.Security.Cryptography.Tests { - public class Sha1Tests : HashAlgorithmTestDriver + public class Sha1Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => SHA1.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA1.Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs index 4abad52b940941..6fa2e0822c7733 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs @@ -8,8 +8,14 @@ namespace System.Security.Cryptography.Tests { - public class Sha256Tests : HashAlgorithmTestDriver + public class Sha256Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => SHA256.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA256.Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs index c7cfea805683c7..a78783fc2ccb1c 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs @@ -8,8 +8,14 @@ namespace System.Security.Cryptography.Tests { - public class Sha384Tests : HashAlgorithmTestDriver + public class Sha384Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => SHA384.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA384.Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs index 8bd0c54bf72d61..106ab038ada9b1 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs @@ -9,8 +9,14 @@ namespace System.Security.Cryptography.Tests { - public class Sha3_256Tests : HashAlgorithmTestDriver + public class Sha3_256Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => SHA3_256.IsSupported; + public static int HashSizeInBytes => SHA3_256.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA3_256.Create(); @@ -39,7 +45,7 @@ protected override ValueTask HashDataAsync(Stream source, Memory dest protected override ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken) => SHA3_256.HashDataAsync(source, cancellationToken); - [Fact] + [ConditionalFact(nameof(IsSupported))] public void Sha3_256_Kats() { foreach ((string Msg, string MD) kat in Fips202Kats) diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs index c44ef67bc50ef6..75b107a5389ebe 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs @@ -9,8 +9,14 @@ namespace System.Security.Cryptography.Tests { - public class SHA3_384Tests : HashAlgorithmTestDriver + public class SHA3_384Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => SHA3_384.IsSupported; + public static int HashSizeInBytes => SHA3_384.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA3_384.Create(); @@ -39,7 +45,7 @@ protected override ValueTask HashDataAsync(Stream source, Memory dest protected override ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken) => SHA3_384.HashDataAsync(source, cancellationToken); - [Fact] + [ConditionalFact(nameof(IsSupported))] public void SHA3_384_Kats() { foreach ((string Msg, string MD) kat in Fips202Kats) diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs index 0d9c3ed5a77db5..e1b12974508cdd 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs @@ -9,8 +9,14 @@ namespace System.Security.Cryptography.Tests { - public class SHA3_512Tests : HashAlgorithmTestDriver + public class SHA3_512Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => SHA3_512.IsSupported; + public static int HashSizeInBytes => SHA3_512.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA3_512.Create(); @@ -39,7 +45,7 @@ protected override ValueTask HashDataAsync(Stream source, Memory dest protected override ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken) => SHA3_512.HashDataAsync(source, cancellationToken); - [Fact] + [ConditionalFact(nameof(IsSupported))] public void SHA3_512_Kats() { foreach ((string Msg, string MD) kat in Fips202Kats) diff --git a/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs index 465f41c15fdf69..07da487ed77dc3 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs @@ -8,8 +8,14 @@ namespace System.Security.Cryptography.Tests { - public class Sha512Tests : HashAlgorithmTestDriver + public class Sha512Tests : HashAlgorithmTestDriver { + public sealed class Traits : IHashTrait + { + public static bool IsSupported => true; + public static int HashSizeInBytes => SHA512.HashSizeInBytes; + } + protected override HashAlgorithm Create() { return SHA512.Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs index ab6c74b90a1eba..fd677a42e4e00b 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs @@ -58,25 +58,17 @@ public static void PublicKeyEncoding(EccTestData testData) [Theory] [MemberData(nameof(SignatureDigestAlgorithms))] - public static void SignatureAlgorithm_StableNotSame(HashAlgorithmName hashAlgorithm, bool isSupported) + public static void SignatureAlgorithm_StableNotSame(HashAlgorithmName hashAlgorithm) { using (ECDsa ecdsa = ECDsa.Create(EccTestData.Secp256r1Data.KeyParameters)) { var generator = X509SignatureGenerator.CreateForECDsa(ecdsa); - if (isSupported) - { - byte[] sigAlg = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - byte[] sigAlg2 = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - - Assert.NotSame(sigAlg, sigAlg2); - Assert.Equal(sigAlg, sigAlg2); - } - else - { - Assert.Throws(() => - generator.GetSignatureAlgorithmIdentifier(hashAlgorithm)); - } + byte[] sigAlg = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + byte[] sigAlg2 = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + + Assert.NotSame(sigAlg, sigAlg2); + Assert.Equal(sigAlg, sigAlg2); } } @@ -99,9 +91,8 @@ public static void SignatureAlgorithm_NotSupported(string hashAlgorithmName) [Theory] [MemberData(nameof(SignatureDigestAlgorithms))] - public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm, bool isSupported) + public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm) { - _ = isSupported; string expectedAlgOid; switch (hashAlgorithm.Name) @@ -151,13 +142,12 @@ public static IEnumerable SignatureDigestAlgorithms get { // hashAlgorithm, isSupported - yield return new object[] { HashAlgorithmName.SHA256, true }; - yield return new object[] { HashAlgorithmName.SHA384, true }; - yield return new object[] { HashAlgorithmName.SHA512, true }; - - yield return new object[] { HashAlgorithmName.SHA3_256, PlatformDetection.SupportsSha3 }; - yield return new object[] { HashAlgorithmName.SHA3_384, PlatformDetection.SupportsSha3 }; - yield return new object[] { HashAlgorithmName.SHA3_512, PlatformDetection.SupportsSha3 }; + yield return new object[] { HashAlgorithmName.SHA256 }; + yield return new object[] { HashAlgorithmName.SHA384 }; + yield return new object[] { HashAlgorithmName.SHA512 }; + yield return new object[] { HashAlgorithmName.SHA3_256 }; + yield return new object[] { HashAlgorithmName.SHA3_384 }; + yield return new object[] { HashAlgorithmName.SHA3_512 }; } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs index 68ffe29919c6b7..84a4bfba5f1f51 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs @@ -59,28 +59,20 @@ public static void PublicKeyEncoding() [Theory] [MemberData(nameof(SignatureDigestAlgorithms))] - public static void SignatureAlgorithm_StableNotSame(HashAlgorithmName hashAlgorithm, bool isSupported) + public static void SignatureAlgorithm_StableNotSame(HashAlgorithmName hashAlgorithm) { using (RSA rsa = RSA.Create()) { RSAParameters parameters = TestData.RsaBigExponentParams; rsa.ImportParameters(parameters); - if (isSupported) - { - var signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); - - byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - byte[] sigAlg2 = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - - Assert.NotSame(sigAlg, sigAlg2); - Assert.Equal(sigAlg, sigAlg2); - } - else - { - Assert.Throws( - () => X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1)); - } + var signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); + + byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + byte[] sigAlg2 = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + + Assert.NotSame(sigAlg, sigAlg2); + Assert.Equal(sigAlg, sigAlg2); } } @@ -107,7 +99,7 @@ public static void SignatureAlgorithm_NotSupported(string hashAlgorithmName) [Theory] [MemberData(nameof(SignatureDigestAlgorithms))] - public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm, bool isSupported) + public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm) { string expectedOid; @@ -148,18 +140,10 @@ public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm, RSAParameters parameters = TestData.RsaBigExponentParams; rsa.ImportParameters(parameters); - if (isSupported) - { - X509SignatureGenerator signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); - byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); - - Assert.Equal(expectedHex, sigAlg.ByteArrayToHex()); - } - else - { - Assert.Throws( - () => X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1)); - } + X509SignatureGenerator signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); + byte[] sigAlg = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); + + Assert.Equal(expectedHex, sigAlg.ByteArrayToHex()); } } @@ -167,14 +151,12 @@ public static IEnumerable SignatureDigestAlgorithms { get { - // hashAlgorithm, isSupported - yield return new object[] { HashAlgorithmName.SHA256, true }; - yield return new object[] { HashAlgorithmName.SHA384, true }; - yield return new object[] { HashAlgorithmName.SHA512, true }; - - yield return new object[] { HashAlgorithmName.SHA3_256, PlatformDetection.SupportsSha3 }; - yield return new object[] { HashAlgorithmName.SHA3_384, PlatformDetection.SupportsSha3 }; - yield return new object[] { HashAlgorithmName.SHA3_512, PlatformDetection.SupportsSha3 }; + yield return new object[] { HashAlgorithmName.SHA256 }; + yield return new object[] { HashAlgorithmName.SHA384 }; + yield return new object[] { HashAlgorithmName.SHA512 }; + yield return new object[] { HashAlgorithmName.SHA3_256 }; + yield return new object[] { HashAlgorithmName.SHA3_384 }; + yield return new object[] { HashAlgorithmName.SHA3_512 }; } } } From d077e4e38dca6445ca658e522b0f8fb5d38d6cc4 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 10:44:12 -0400 Subject: [PATCH 03/47] Some HKDF tests --- .../tests/HKDFTests.cs | 106 ++++++++++++------ 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs index 059c60c42bbf90..bc8cdd148d56e1 100644 --- a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs @@ -15,25 +15,25 @@ public abstract class HKDFTests protected abstract byte[] DeriveKey(HashAlgorithmName hash, byte[] ikm, int outputLength, byte[] salt, byte[] info); [Theory] - [MemberData(nameof(GetRfc5869TestCases))] - public void Rfc5869ExtractTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCases))] + public void Rfc5869ExtractTests(HkdfTestCase test) { byte[] prk = Extract(test.Hash, test.Prk.Length, test.Ikm, test.Salt); Assert.Equal(test.Prk, prk); } [Theory] - [MemberData(nameof(GetRfc5869TestCases))] + [MemberData(nameof(GetHkdfTestCases))] [SkipOnPlatform(TestPlatforms.Browser, "MD5 is not supported on Browser")] - public void Rfc5869ExtractTamperHashTests(Rfc5869TestCase test) + public void Rfc5869ExtractTamperHashTests(HkdfTestCase test) { byte[] prk = Extract(HashAlgorithmName.MD5, 128 / 8, test.Ikm, test.Salt); Assert.NotEqual(test.Prk, prk); } [Theory] - [MemberData(nameof(GetRfc5869TestCases))] - public void Rfc5869ExtractTamperIkmTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCases))] + public void Rfc5869ExtractTamperIkmTests(HkdfTestCase test) { byte[] ikm = test.Ikm.ToArray(); ikm[0] ^= 1; @@ -42,8 +42,8 @@ public void Rfc5869ExtractTamperIkmTests(Rfc5869TestCase test) } [Theory] - [MemberData(nameof(GetRfc5869TestCasesWithNonEmptySalt))] - public void Rfc5869ExtractTamperSaltTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCasesWithNonEmptySalt))] + public void Rfc5869ExtractTamperSaltTests(HkdfTestCase test) { byte[] salt = test.Salt.ToArray(); salt[0] ^= 1; @@ -92,8 +92,8 @@ public void Rfc5869ExtractEmptySalt() } [Theory] - [MemberData(nameof(GetRfc5869TestCases))] - public void Rfc5869ExpandTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCases))] + public void Rfc5869ExpandTests(HkdfTestCase test) { byte[] okm = Expand(test.Hash, test.Prk, test.Okm.Length, test.Info); Assert.Equal(test.Okm, okm); @@ -118,8 +118,8 @@ public void Rfc5869ExpandNonsensicalHash() } [Theory] - [MemberData(nameof(GetRfc5869TestCases))] - public void Rfc5869ExpandTamperPrkTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCases))] + public void Rfc5869ExpandTamperPrkTests(HkdfTestCase test) { byte[] prk = test.Prk.ToArray(); prk[0] ^= 1; @@ -148,8 +148,8 @@ public void Rfc5869ExpandOkmMaxSize() } [Theory] - [MemberData(nameof(GetRfc5869TestCases))] - public void Rfc5869DeriveKeyTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCases))] + public void Rfc5869DeriveKeyTests(HkdfTestCase test) { byte[] okm = DeriveKey(test.Hash, test.Ikm, test.Okm.Length, test.Salt, test.Info); Assert.Equal(test.Okm, okm); @@ -174,8 +174,8 @@ public void Rfc5869DeriveKeyNonSensicalHash() } [Theory] - [MemberData(nameof(GetRfc5869TestCases))] - public void Rfc5869DeriveKeyTamperIkmTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCases))] + public void Rfc5869DeriveKeyTamperIkmTests(HkdfTestCase test) { byte[] ikm = test.Ikm.ToArray(); ikm[0] ^= 1; @@ -184,8 +184,8 @@ public void Rfc5869DeriveKeyTamperIkmTests(Rfc5869TestCase test) } [Theory] - [MemberData(nameof(GetRfc5869TestCasesWithNonEmptySalt))] - public void Rfc5869DeriveKeyTamperSaltTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCasesWithNonEmptySalt))] + public void Rfc5869DeriveKeyTamperSaltTests(HkdfTestCase test) { byte[] salt = test.Salt.ToArray(); salt[0] ^= 1; @@ -194,8 +194,8 @@ public void Rfc5869DeriveKeyTamperSaltTests(Rfc5869TestCase test) } [Theory] - [MemberData(nameof(GetRfc5869TestCasesWithNonEmptyInfo))] - public void Rfc5869DeriveKeyTamperInfoTests(Rfc5869TestCase test) + [MemberData(nameof(GetHkdfTestCasesWithNonEmptyInfo))] + public void Rfc5869DeriveKeyTamperInfoTests(HkdfTestCase test) { byte[] info = test.Info.ToArray(); info[0] ^= 1; @@ -203,17 +203,25 @@ public void Rfc5869DeriveKeyTamperInfoTests(Rfc5869TestCase test) Assert.NotEqual(test.Okm, okm); } - public static IEnumerable GetRfc5869TestCases() + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsSha3))] + [MemberData(nameof(Sha3TestCases))] + public void Sha3Tests(HkdfTestCase test) { - foreach (Rfc5869TestCase test in Rfc5869TestCases) + byte[] okm = Expand(test.Hash, test.Prk, test.Okm.Length, test.Info); + Assert.Equal(test.Okm, okm); + } + + public static IEnumerable GetHkdfTestCases() + { + foreach (HkdfTestCase test in HkdfTestCases) { yield return new object[] { test }; } } - public static IEnumerable GetRfc5869TestCasesWithNonEmptySalt() + public static IEnumerable GetHkdfTestCasesWithNonEmptySalt() { - foreach (Rfc5869TestCase test in Rfc5869TestCases) + foreach (HkdfTestCase test in HkdfTestCases) { if (test.Salt != null && test.Salt.Length != 0) { @@ -222,9 +230,9 @@ public static IEnumerable GetRfc5869TestCasesWithNonEmptySalt() } } - public static IEnumerable GetRfc5869TestCasesWithNonEmptyInfo() + public static IEnumerable GetHkdfTestCasesWithNonEmptyInfo() { - foreach (Rfc5869TestCase test in Rfc5869TestCases) + foreach (HkdfTestCase test in HkdfTestCases) { if (test.Info != null && test.Info.Length != 0) { @@ -245,11 +253,18 @@ public static IEnumerable GetPrkTooShortTestCases() { yield return new object[] { HashAlgorithmName.MD5, 128 / 8 - 1 }; } + + if (PlatformDetection.SupportsSha3) + { + yield return new object[] { HashAlgorithmName.SHA3_256, SHA3_256.HashSizeInBytes - 1 }; + yield return new object[] { HashAlgorithmName.SHA3_384, SHA3_384.HashSizeInBytes - 1 }; + yield return new object[] { HashAlgorithmName.SHA3_512, SHA3_512.HashSizeInBytes - 1 }; + } } - private static Rfc5869TestCase[] Rfc5869TestCases { get; } = new Rfc5869TestCase[7] + private static HkdfTestCase[] HkdfTestCases { get; } = new HkdfTestCase[7] { - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Basic test case with SHA-256", Hash = HashAlgorithmName.SHA256, @@ -264,7 +279,7 @@ public static IEnumerable GetPrkTooShortTestCases() "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" + "34007208d5b887185865").HexToByteArray(), }, - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Test with SHA-256 and longer inputs/outputs", Hash = HashAlgorithmName.SHA256, @@ -297,7 +312,7 @@ public static IEnumerable GetPrkTooShortTestCases() "cc30c58179ec3e87c14c01d5c1f3434f" + "1d87").HexToByteArray(), }, - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Test with SHA-256 and zero-length salt/info", Hash = HashAlgorithmName.SHA256, @@ -312,7 +327,7 @@ public static IEnumerable GetPrkTooShortTestCases() "b8a11f5c5ee1879ec3454e5f3c738d2d" + "9d201395faa4b61a96c8").HexToByteArray(), }, - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Basic test case with SHA-1", Hash = HashAlgorithmName.SHA1, @@ -325,7 +340,7 @@ public static IEnumerable GetPrkTooShortTestCases() "a4f14b822f5b091568a9cdd4f155fda2" + "c22e422478d305f3f896").HexToByteArray(), }, - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Test with SHA-1 and longer inputs/outputs", Hash = HashAlgorithmName.SHA1, @@ -356,7 +371,7 @@ public static IEnumerable GetPrkTooShortTestCases() "927336d0441f4c4300e2cff0d0900b52" + "d3b4").HexToByteArray(), }, - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Test with SHA-1 and zero-length salt/info", Hash = HashAlgorithmName.SHA1, @@ -369,7 +384,7 @@ public static IEnumerable GetPrkTooShortTestCases() "b9ae52057220a306e07b6b87e8df21d0" + "ea00033de03984d34918").HexToByteArray(), }, - new Rfc5869TestCase() + new HkdfTestCase() { Name = "Test with SHA-1, salt not provided (defaults to HashLen zero octets), zero-length info", Hash = HashAlgorithmName.SHA1, @@ -384,7 +399,28 @@ public static IEnumerable GetPrkTooShortTestCases() }, }; - public struct Rfc5869TestCase + public static IEnumerable Sha3TestCases + { + // These cases were generated from the openssl kdf command. + // openssl kdf -keylen 8 -kdfopt digest:SHA3-256 -kdfopt hexkey:000102030405060708090A0B0C0D0E0F -kdfopt salt:mysalt -kdfopt info:myinfo -binary HKDF | xxd -p + get + { + yield return new object[] + { + new HkdfTestCase + { + Name = "SHA3-256 with salt and info", + Hash = HashAlgorithmName.SHA3_256, + Ikm = "000102030405060708090A0B0C0D0E0F".HexToByteArray(), + Salt = "mysalt"u8.ToArray(), + Info = "myinfo"u8.ToArray(), + Okm = "ea306108f87774ac".HexToByteArray(), + } + }; + } + } + + public struct HkdfTestCase { public string Name { get; set; } public HashAlgorithmName Hash { get; set; } From deccd5a8baf9bea4e6bcf93136293e34f44fa501 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 15:15:26 +0000 Subject: [PATCH 04/47] Get HKDF working with tests --- .../Cryptography/HashOneShotHelpers.cs | 18 +++++++ .../tests/HKDFTests.cs | 47 ++++++++++++++++--- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs index 596f1a8be00c87..0bcecf65650eff 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs @@ -156,6 +156,24 @@ internal static int MacData( { return HMACSHA384.HashData(key, source, destination); } + else if (hashAlgorithm == HashAlgorithmName.SHA3_256) + { + return HMACSHA3_256.IsSupported ? + HMACSHA3_256.HashData(key, source, destination) : + throw new PlatformNotSupportedException(); + } + else if (hashAlgorithm == HashAlgorithmName.SHA3_384) + { + return HMACSHA3_384.IsSupported ? + HMACSHA3_384.HashData(key, source, destination) : + throw new PlatformNotSupportedException(); + } + else if (hashAlgorithm == HashAlgorithmName.SHA3_512) + { + return HMACSHA3_512.IsSupported ? + HMACSHA3_512.HashData(key, source, destination) : + throw new PlatformNotSupportedException(); + } else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) { return HMACMD5.HashData(key, source, destination); diff --git a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs index bc8cdd148d56e1..0be73e89dc9fd6 100644 --- a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs @@ -203,12 +203,20 @@ public void Rfc5869DeriveKeyTamperInfoTests(HkdfTestCase test) Assert.NotEqual(test.Okm, okm); } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsSha3))] + [Theory] [MemberData(nameof(Sha3TestCases))] public void Sha3Tests(HkdfTestCase test) { - byte[] okm = Expand(test.Hash, test.Prk, test.Okm.Length, test.Info); - Assert.Equal(test.Okm, okm); + if (PlatformDetection.SupportsSha3) + { + byte[] okm = DeriveKey(test.Hash, test.Ikm, test.Okm.Length, test.Salt, test.Info); + Assert.Equal(test.Okm, okm); + } + else + { + Assert.Throws(() => + DeriveKey(test.Hash, test.Ikm, test.Okm.Length, test.Salt, test.Info)); + } } public static IEnumerable GetHkdfTestCases() @@ -402,7 +410,8 @@ public static IEnumerable GetPrkTooShortTestCases() public static IEnumerable Sha3TestCases { // These cases were generated from the openssl kdf command. - // openssl kdf -keylen 8 -kdfopt digest:SHA3-256 -kdfopt hexkey:000102030405060708090A0B0C0D0E0F -kdfopt salt:mysalt -kdfopt info:myinfo -binary HKDF | xxd -p + // openssl kdf -keylen 8 -kdfopt digest:SHA3-256 -kdfopt hexkey:000102030405060708090A0B0C0D0E0F \ + // -kdfopt salt:mysalt -kdfopt info:myinfo -binary HKDF | xxd -p get { yield return new object[] @@ -411,10 +420,36 @@ public static IEnumerable Sha3TestCases { Name = "SHA3-256 with salt and info", Hash = HashAlgorithmName.SHA3_256, - Ikm = "000102030405060708090A0B0C0D0E0F".HexToByteArray(), + Ikm = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F".HexToByteArray(), + Salt = "mysalt"u8.ToArray(), + Info = "myinfo"u8.ToArray(), + Okm = "35bd9d1c75cf7e30".HexToByteArray(), + } + }; + + yield return new object[] + { + new HkdfTestCase + { + Name = "SHA3-384 with salt and info", + Hash = HashAlgorithmName.SHA3_384, + Ikm = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F".HexToByteArray(), + Salt = "mysalt"u8.ToArray(), + Info = "myinfo"u8.ToArray(), + Okm = "323a8ab50c7190c8".HexToByteArray(), + } + }; + + yield return new object[] + { + new HkdfTestCase + { + Name = "SHA3-512 with salt and info", + Hash = HashAlgorithmName.SHA3_512, + Ikm = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F".HexToByteArray(), Salt = "mysalt"u8.ToArray(), Info = "myinfo"u8.ToArray(), - Okm = "ea306108f87774ac".HexToByteArray(), + Okm = "27693b36a489e9f1".HexToByteArray(), } }; } From 2fa0c130177a66ca967257a844d64928eecd3e7c Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 11:29:28 -0400 Subject: [PATCH 05/47] Add derived hash tests --- .../tests/HashDerivedTests.cs | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/tests/HashDerivedTests.cs b/src/libraries/System.Security.Cryptography/tests/HashDerivedTests.cs index 6734bca6bb5a53..1c58b8758eef7f 100644 --- a/src/libraries/System.Security.Cryptography/tests/HashDerivedTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HashDerivedTests.cs @@ -11,28 +11,28 @@ public static class HashDerivedTests public static void HashSize_SetForDerived_SHA1() { using DerivedSHA1 sha = new DerivedSHA1(); - Assert.Equal(160, sha.HashSize); + Assert.Equal(SHA1.HashSizeInBits, sha.HashSize); } [Fact] public static void HashSize_SetForDerived_SHA256() { using DerivedSHA256 sha = new DerivedSHA256(); - Assert.Equal(256, sha.HashSize); + Assert.Equal(SHA256.HashSizeInBits, sha.HashSize); } [Fact] public static void HashSize_SetForDerived_SHA384() { using DerivedSHA384 sha = new DerivedSHA384(); - Assert.Equal(384, sha.HashSize); + Assert.Equal(SHA384.HashSizeInBits, sha.HashSize); } [Fact] public static void HashSize_SetForDerived_SHA512() { using DerivedSHA512 sha = new DerivedSHA512(); - Assert.Equal(512, sha.HashSize); + Assert.Equal(SHA512.HashSizeInBits, sha.HashSize); } [Fact] @@ -40,7 +40,28 @@ public static void HashSize_SetForDerived_SHA512() public static void HashSize_SetForDerived_MD5() { using DerivedMD5 sha = new DerivedMD5(); - Assert.Equal(128, sha.HashSize); + Assert.Equal(MD5.HashSizeInBits, sha.HashSize); + } + + [Fact] + public static void HashSize_SetForDerived_SHA3_256() + { + using DerivedSHA3_256 sha = new DerivedSHA3_256(); + Assert.Equal(SHA3_256.HashSizeInBits, sha.HashSize); + } + + [Fact] + public static void HashSize_SetForDerived_SHA3_384() + { + using DerivedSHA3_384 sha = new DerivedSHA3_384(); + Assert.Equal(SHA3_384.HashSizeInBits, sha.HashSize); + } + + [Fact] + public static void HashSize_SetForDerived_SHA3_512() + { + using DerivedSHA3_512 sha = new DerivedSHA3_512(); + Assert.Equal(SHA3_512.HashSizeInBits, sha.HashSize); } private class DerivedSHA1 : SHA1 @@ -71,14 +92,28 @@ private class DerivedSHA512 : SHA512 protected override void HashCore(byte[] array, int ibStart, int cbSize) => throw null; } - private class DerivedMD5 : MD5 + private class DerivedSHA3_256 : SHA3_256 { public override void Initialize() => throw null; protected override byte[] HashFinal() => throw null; protected override void HashCore(byte[] array, int ibStart, int cbSize) => throw null; } - private class DerivedHMACMD5 : HMACMD5 + private class DerivedSHA3_384 : SHA3_384 + { + public override void Initialize() => throw null; + protected override byte[] HashFinal() => throw null; + protected override void HashCore(byte[] array, int ibStart, int cbSize) => throw null; + } + + private class DerivedSHA3_512 : SHA3_512 + { + public override void Initialize() => throw null; + protected override byte[] HashFinal() => throw null; + protected override void HashCore(byte[] array, int ibStart, int cbSize) => throw null; + } + + private class DerivedMD5 : MD5 { public override void Initialize() => throw null; protected override byte[] HashFinal() => throw null; From 9319d662bc0368f643fafa34218c6d5b71f702b0 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 11:31:22 -0400 Subject: [PATCH 06/47] Remove outdated comment --- .../CertificateCreation/ECDsaX509SignatureGeneratorTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs index fd677a42e4e00b..580e5121fc9642 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs @@ -141,7 +141,6 @@ public static IEnumerable SignatureDigestAlgorithms { get { - // hashAlgorithm, isSupported yield return new object[] { HashAlgorithmName.SHA256 }; yield return new object[] { HashAlgorithmName.SHA384 }; yield return new object[] { HashAlgorithmName.SHA512 }; From 9d1f65152e4c89bf9b1e4cd4c04a8b21652cd2ed Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 13:48:14 -0400 Subject: [PATCH 07/47] Fix hash validation for PBKDF2 --- .../Security/Cryptography/HMACSHA3_256.cs | 2 +- .../Security/Cryptography/HMACSHA3_384.cs | 2 +- .../Security/Cryptography/HMACSHA3_512.cs | 2 +- .../Pbkdf2Implementation.Apple.cs | 4 -- .../Pbkdf2Implementation.Windows.cs | 17 ++++++- .../Rfc2898DeriveBytes.OneShot.cs | 45 +++++++++++++++---- 6 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs index eeeed37a283f25..53e443cc15f824 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs @@ -16,7 +16,7 @@ namespace System.Security.Cryptography public class HMACSHA3_256 : HMAC { private HMACCommon _hMacCommon; - private const int BlockSize = 136; // FIPS 202 Table 3. + internal const int BlockSize = 136; // FIPS 202 Table 3. /// /// The hash size produced by the HMAC SHA3-256 algorithm, in bits. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs index 3d8d6f26469596..4e407249244c6a 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs @@ -16,7 +16,7 @@ namespace System.Security.Cryptography public class HMACSHA3_384 : HMAC { private HMACCommon _hMacCommon; - private const int BlockSize = 104; // FIPS 202 Table 3. + internal const int BlockSize = 104; // FIPS 202 Table 3. /// /// The hash size produced by the HMAC SHA3-384 algorithm, in bits. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs index b7e7d9f9948b56..f18326eecf184e 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs @@ -16,7 +16,7 @@ namespace System.Security.Cryptography public class HMACSHA3_512 : HMAC { private HMACCommon _hMacCommon; - private const int BlockSize = 72; // FIPS 202 Table 3. + internal const int BlockSize = 72; // FIPS 202 Table 3. /// /// The hash size produced by the HMAC SHA3-512 algorithm, in bits. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs index 4cc80b53fc5b53..be842135d75f73 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Apple.cs @@ -33,10 +33,6 @@ public static unsafe void Fill( case HashAlgorithmNames.SHA512: prfAlgorithm = PAL_HashAlgorithm.Sha512; break; - case HashAlgorithmNames.SHA3_256: - case HashAlgorithmNames.SHA3_384: - case HashAlgorithmNames.SHA3_512: - throw new PlatformNotSupportedException(); default: Debug.Fail($"Unexpected hash algorithm '{hashAlgorithmName.Name}'"); throw new CryptographicException(); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Windows.cs index 6829cbf7b63571..d05af7124b3af5 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Pbkdf2Implementation.Windows.cs @@ -97,6 +97,15 @@ private static unsafe void FillKeyDerivation( case HashAlgorithmNames.SHA512: hashBufferSize = SHA512.HashData(password, hashBuffer); break; + case HashAlgorithmNames.SHA3_256: + hashBufferSize = SHA3_256.HashData(password, hashBuffer); + break; + case HashAlgorithmNames.SHA3_384: + hashBufferSize = SHA3_384.HashData(password, hashBuffer); + break; + case HashAlgorithmNames.SHA3_512: + hashBufferSize = SHA3_512.HashData(password, hashBuffer); + break; default: Debug.Fail($"Unexpected hash algorithm '{hashAlgorithmName}'"); throw new CryptographicException(); @@ -259,7 +268,7 @@ private static unsafe void FillDeriveKeyPBKDF2( private static int GetHashBlockSize(string hashAlgorithmName) { - // Block sizes per NIST FIPS pub 180-4. + // Block sizes per NIST FIPS pub 180-4 and FIPS 202. switch (hashAlgorithmName) { case HashAlgorithmNames.SHA1: @@ -268,6 +277,12 @@ private static int GetHashBlockSize(string hashAlgorithmName) case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: return 1024 / 8; + case HashAlgorithmNames.SHA3_256: + return HMACSHA3_256.BlockSize; + case HashAlgorithmNames.SHA3_384: + return HMACSHA3_384.BlockSize; + case HashAlgorithmNames.SHA3_512: + return HMACSHA3_512.BlockSize; default: Debug.Fail($"Unexpected hash algorithm '{hashAlgorithmName}'"); throw new CryptographicException(); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs index 0486220680f4cd..ff35cc2099d971 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs @@ -323,16 +323,45 @@ private static void ValidateHashAlgorithm(HashAlgorithmName hashAlgorithm) ArgumentException.ThrowIfNullOrEmpty(hashAlgorithmName, nameof(hashAlgorithm)); // MD5 intentionally left out. - if (hashAlgorithmName != HashAlgorithmName.SHA1.Name && - hashAlgorithmName != HashAlgorithmName.SHA256.Name && - hashAlgorithmName != HashAlgorithmName.SHA384.Name && - hashAlgorithmName != HashAlgorithmName.SHA512.Name && - hashAlgorithmName != HashAlgorithmName.SHA3_256.Name && - hashAlgorithmName != HashAlgorithmName.SHA3_384.Name && - hashAlgorithmName != HashAlgorithmName.SHA3_512.Name) + if (hashAlgorithmName == HashAlgorithmName.SHA1.Name || + hashAlgorithmName == HashAlgorithmName.SHA256.Name || + hashAlgorithmName == HashAlgorithmName.SHA384.Name || + hashAlgorithmName == HashAlgorithmName.SHA512.Name) { - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName)); + return; + } + + if (hashAlgorithmName == HashAlgorithmName.SHA3_256.Name) + { + if (HMACSHA3_256.IsSupported) + { + return; + } + + throw new PlatformNotSupportedException(); + } + + if (hashAlgorithmName == HashAlgorithmName.SHA3_384.Name) + { + if (HMACSHA3_384.IsSupported) + { + return; + } + + throw new PlatformNotSupportedException(); } + + if (hashAlgorithmName == HashAlgorithmName.SHA3_512.Name) + { + if (HMACSHA3_512.IsSupported) + { + return; + } + + throw new PlatformNotSupportedException(); + } + + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName)); } } } From 0e79766126799c783905802e737f4aa7a621b83c Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 14:30:26 -0400 Subject: [PATCH 08/47] Wire in CNG algorithm support testing --- .../Windows/BCrypt/BCryptAlgorithmCache.cs | 37 +++++++++++++++++++ .../Security/Cryptography/HMACSHA3_256.cs | 2 +- .../Security/Cryptography/HMACSHA3_384.cs | 2 +- .../Security/Cryptography/HMACSHA3_512.cs | 2 +- .../HashProviderDispenser.Apple.cs | 2 + .../HashProviderDispenser.Browser.cs | 2 + .../HashProviderDispenser.OpenSsl.cs | 2 + .../HashProviderDispenser.Windows.cs | 23 +++++++++++- 8 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs index aec34aeb523478..839ed8aa4f9206 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs @@ -13,6 +13,7 @@ internal static partial class BCrypt internal static class BCryptAlgorithmCache { private static readonly ConcurrentDictionary<(string HashAlgorithmId, BCryptOpenAlgorithmProviderFlags Flags), (SafeBCryptAlgorithmHandle Handle, int HashSizeInBytes)> s_handles = new(); + private static readonly ConcurrentDictionary<(string HashAlgorithmId, BCryptOpenAlgorithmProviderFlags Flags), bool> s_supported = new(); /// /// Returns a SafeBCryptAlgorithmHandle of the desired algorithm and flags. This is a shared handle so do not dispose it! @@ -43,6 +44,42 @@ public static unsafe SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(st } } } + + public static unsafe bool IsBCryptAlgorithmSupported(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags) + { + var key = (hashAlgorithmId, flags); + + while (true) + { + if (s_supported.TryGetValue(key, out bool supported)) + { + return supported; + } + + NTSTATUS status = BCryptOpenAlgorithmProvider( + out SafeBCryptAlgorithmHandle handle, + key.hashAlgorithmId, + null, + key.flags); + + if (s_supported.TryAdd(key, status == NTSTATUS.STATUS_SUCCESS)) + { + // It's a valid algorithm. Let's prime the handle cache while we are here. Presumably it's + // going to get used if we're asking if it's supported. + int hashSize = BCryptGetDWordProperty(handle, BCryptPropertyStrings.BCRYPT_HASH_LENGTH); + Debug.Assert(hashSize > 0); + + if (s_handles.TryAdd(key, (handle, hashSize))) + { + // If we added it to the cache, don't dispose of it. + continue; + } + } + + // Either the algorithm isn't supported or we don't need it for priming the cache, so Dispose. + handle.Dispose(); + } + } } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs index 53e443cc15f824..f46a8755a5f6d5 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs @@ -75,7 +75,7 @@ public HMACSHA3_256(byte[] key) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => SHA3_256.IsSupported; + public static bool IsSupported => HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_256); /// public override byte[] Key diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs index 4e407249244c6a..83cd46d83416c6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs @@ -75,7 +75,7 @@ public HMACSHA3_384(byte[] key) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => SHA3_384.IsSupported; + public static bool IsSupported => HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_384); /// public override byte[] Key diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs index f18326eecf184e..d25cf91d575050 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs @@ -75,7 +75,7 @@ public HMACSHA3_512(byte[] key) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => SHA3_512.IsSupported; + public static bool IsSupported => HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_512); /// public override byte[] Key diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs index c4082d78713f39..58ed1b42610e61 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Apple.cs @@ -36,6 +36,8 @@ internal static bool HashSupported(string hashAlgorithmId) } } + internal static bool MacSupported(string hashAlgorithmId) => HashSupported(hashAlgorithmId); + internal static class OneShotHashProvider { public static unsafe int MacData( diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs index 7e97eb1b30bd59..eea8e204cdc589 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs @@ -19,6 +19,8 @@ internal static bool HashSupported(string hashAlgorithmId) } } + internal static bool MacSupported(string hashAlgorithmId) => HashSupported(hashAlgorithmId); + public static HashProvider CreateHashProvider(string hashAlgorithmId) { switch (hashAlgorithmId) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs index 52778f04b5094d..e6836fbbfc4d41 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs @@ -27,6 +27,8 @@ internal static bool HashSupported(string hashAlgorithmId) return Interop.Crypto.HashAlgorithmToEvp(hashAlgorithmId) != IntPtr.Zero; } + internal static bool MacSupported(string hashAlgorithmId) => HashSupported(hashAlgorithmId); + internal static class OneShotHashProvider { public static int MacData( diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs index dcbeb7763f7ca3..418cc925a8d48b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs @@ -29,10 +29,27 @@ public static HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlySpa internal static bool HashSupported(string hashAlgorithmId) { + switch (hashAlgorithmId) + { + // We know that MD5, SHA1, and SHA2 are supported on all platforms. Don't bother asking. + case HashAlgorithmNames.MD5: + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + case HashAlgorithmNames.SHA384: + case HashAlgorithmNames.SHA512: + return true; + default: + return BCryptAlgorithmCache.IsBCryptAlgorithmSupported( + hashAlgorithmId, + BCryptOpenAlgorithmProviderFlags.None); + } + } - //TODO: This needs to ask CNG. + internal static bool MacSupported(string hashAlgorithmId) + { switch (hashAlgorithmId) { + // We know that MD5, SHA1, and SHA2 are supported on all platforms. Don't bother asking. case HashAlgorithmNames.MD5: case HashAlgorithmNames.SHA1: case HashAlgorithmNames.SHA256: @@ -40,7 +57,9 @@ internal static bool HashSupported(string hashAlgorithmId) case HashAlgorithmNames.SHA512: return true; default: - return false; + return BCryptAlgorithmCache.IsBCryptAlgorithmSupported( + hashAlgorithmId, + BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG); } } From 5741ea2ac12a49e64961408cc7e89e4ec569d33c Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 20 Mar 2023 14:35:59 -0400 Subject: [PATCH 09/47] Fix querying invalid handles --- .../Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs index 839ed8aa4f9206..068a6a371e583a 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs @@ -62,7 +62,9 @@ public static unsafe bool IsBCryptAlgorithmSupported(string hashAlgorithmId, BCr null, key.flags); - if (s_supported.TryAdd(key, status == NTSTATUS.STATUS_SUCCESS)) + bool isSupported = status == NTSTATUS.STATUS_SUCCESS; + + if (s_supported.TryAdd(key, isSupported) && isSupported) { // It's a valid algorithm. Let's prime the handle cache while we are here. Presumably it's // going to get used if we're asking if it's supported. From faa42cf450712a966a2c6c6578f3edbf8a708bbb Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 21 Mar 2023 14:02:48 -0400 Subject: [PATCH 10/47] Wire SHA3 in to SP800108 --- .../Cryptography/SP800108HmacCounterKdf.cs | 5 + .../SP800108HmacCounterKdfTests.Functional.cs | 166 +++++++++++++++++- .../Cryptography/HashAlgorithmNames.cs | 5 + 3 files changed, 175 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs index 6598136dfe7a77..fe131d4de9be4d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs @@ -558,6 +558,11 @@ private static void CheckHashAlgorithm(HashAlgorithmName hashAlgorithm) case HashAlgorithmNames.SHA256: case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: +#if NET8_0_OR_GREATER + case HashAlgorithmNames.SHA3_256: + case HashAlgorithmNames.SHA3_384: + case HashAlgorithmNames.SHA3_512: +#endif break; default: throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName)); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs index 338ffc7a2a6527..f4149d3cebbda4 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.DotNet.XUnitExtensions; using System.Collections.Generic; using System.Globalization; using Xunit; @@ -81,7 +82,7 @@ public static void EmptyTests(byte[] key, string label, string context, byte[] e VerifyKbkdf(expected, key, HashAlgorithmName.SHA256, label.ToCharArray(), context.ToCharArray()); } - [Theory] + [ConditionalTheory] [InlineData(nameof(HashAlgorithmName.SHA1), 512 / 8 - 1, new byte[] { 0xc9, 0x0f, 0x9d, 0x91, 0x85, 0xe5, 0xeb, 0x9b })] [InlineData(nameof(HashAlgorithmName.SHA1), 512 / 8, new byte[] { 0x7b, 0xdb, 0x38, 0x28, 0xc0, 0x9f, 0x49, 0x05 })] [InlineData(nameof(HashAlgorithmName.SHA1), 512 / 8 + 1, new byte[] { 0x6c, 0x3a, 0xba, 0x28, 0x38, 0xad, 0x51, 0x2c })] @@ -94,8 +95,28 @@ public static void EmptyTests(byte[] key, string label, string context, byte[] e [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8 - 1, new byte[] { 0xa4, 0xe5, 0x24, 0xe8, 0x56, 0x2b, 0x48, 0xa4 })] [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8, new byte[] { 0xba, 0xf6, 0xed, 0xa7, 0x3a, 0xf7, 0x12, 0x27 })] [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8 + 1, new byte[] { 0x34, 0xdf, 0x2d, 0x21, 0xfd, 0xf1, 0x0e, 0x13 })] +#if NET8_0_OR_GREATER + [InlineData(nameof(HashAlgorithmName.SHA3_256), 1088 / 8 - 1, new byte[] { 0xa1, 0x96, 0xae, 0x83, 0x56, 0xf4, 0x2a, 0x4b })] + [InlineData(nameof(HashAlgorithmName.SHA3_256), 1088 / 8, new byte[] { 0xe7, 0xe9, 0xe0, 0x98, 0x09, 0x54, 0x54, 0x2d })] + [InlineData(nameof(HashAlgorithmName.SHA3_256), 1088 / 8 + 1, new byte[] { 0x7d, 0x7a, 0x71, 0xdf, 0x1f, 0x5d, 0x5b, 0x44 })] + [InlineData(nameof(HashAlgorithmName.SHA3_384), 832 / 8 - 1, new byte[] { 0xd6, 0x08, 0x69, 0xd0, 0x99, 0x98, 0x6d, 0xcc })] + [InlineData(nameof(HashAlgorithmName.SHA3_384), 832 / 8, new byte[] { 0x49, 0x83, 0x06, 0x4e, 0x08, 0xf8, 0x93, 0x62 })] + [InlineData(nameof(HashAlgorithmName.SHA3_384), 832 / 8 + 1, new byte[] { 0xcc, 0x03, 0x1f, 0x57, 0x5e, 0x0c, 0xe1, 0xe8 })] + [InlineData(nameof(HashAlgorithmName.SHA3_512), 576 / 8 - 1, new byte[] { 0x47, 0xd2, 0x7e, 0x61, 0x01, 0x61, 0x9a, 0xd0 })] + [InlineData(nameof(HashAlgorithmName.SHA3_512), 576 / 8, new byte[] { 0xda, 0x56, 0x5b, 0x08, 0x73, 0xbc, 0x4d, 0x33 })] + [InlineData(nameof(HashAlgorithmName.SHA3_512), 576 / 8 + 1, new byte[] { 0xd3, 0xa1, 0xfd, 0x76, 0xc4, 0xf9, 0x62, 0xc3 })] +#endif public static void Kdk_HmacBlockBoundarySizes(string hashAlgorithmName, int kdkSize, byte[] expected) { +#if NET8_0_OR_GREATER + if ((hashAlgorithmName == nameof(HashAlgorithmName.SHA3_256) && !SHA3_256.IsSupported) || + (hashAlgorithmName == nameof(HashAlgorithmName.SHA3_384) && !SHA3_384.IsSupported) || + (hashAlgorithmName == nameof(HashAlgorithmName.SHA3_512) && !SHA3_512.IsSupported)) + { + throw new SkipTestException($"Algorithm '{hashAlgorithmName}' is not supported on the current platform."); + } +#endif + // We do HMAC key adjust for the CNG implementation when the kdk exceeds the block size of the HMAC algorithm. // This tests one byte below, at, and above the block size for each HMAC algorithm. // Verified against OpenSSL 3. Example command used below. Adjust the digest and the seq upper boundary as needed. @@ -306,6 +327,149 @@ public static IEnumerable GetOutputLengthBoundaries() 0x61, } }; + +#if NET8_0_OR_GREATER + if (HMACSHA3_256.IsSupported) + { + // HMACSHA3_256 output size is 32 bytes + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_256), + new byte[63] + { + 0x25, 0xb6, 0xc5, 0xba, 0x60, 0x47, 0x95, 0xb6, 0x5c, 0x92, 0xcb, 0x8f, 0xd2, 0x4d, 0x40, 0xfa, + 0x68, 0xa9, 0xa6, 0xd3, 0x2c, 0x7f, 0x3c, 0xcd, 0x88, 0x89, 0xdc, 0x45, 0x10, 0xeb, 0x16, 0x38, + 0xf3, 0xe2, 0xe0, 0x26, 0xb5, 0xbc, 0x61, 0x9f, 0x56, 0x66, 0x7d, 0xbd, 0x55, 0x4e, 0x6b, 0x70, + 0x84, 0xc1, 0x9c, 0x95, 0x1e, 0x8f, 0x1b, 0xdc, 0xc2, 0x68, 0xc3, 0x10, 0x9c, 0x13, 0xf8, + } + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_256), + new byte[64] + { + 0xc8, 0x8a, 0xfe, 0xd4, 0x62, 0xa6, 0x9e, 0xa6, 0x90, 0xa7, 0xb1, 0xe2, 0x01, 0xff, 0x67, 0x52, + 0x5d, 0xca, 0xa9, 0x13, 0xa2, 0x92, 0x3c, 0xc0, 0x42, 0xd1, 0x1b, 0xe2, 0xff, 0xe0, 0xa2, 0xb9, + 0x48, 0x3d, 0xb1, 0x17, 0x73, 0x76, 0x3d, 0x37, 0x0f, 0xc6, 0x6f, 0x65, 0xa5, 0xb9, 0x23, 0xcf, + 0xc0, 0xd4, 0x5f, 0xdf, 0x46, 0x0e, 0xab, 0xce, 0x8e, 0x7d, 0x2c, 0x9d, 0x71, 0x40, 0xf0, 0x89, + } + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_256), + new byte[65] + { + 0xcc, 0x3a, 0x45, 0x55, 0x26, 0x1e, 0x56, 0xf4, 0x3c, 0x18, 0x66, 0x1d, 0xa8, 0xe3, 0x91, 0xe7, + 0xbc, 0xc3, 0x93, 0x1f, 0x85, 0xbe, 0x0c, 0xfb, 0xab, 0x10, 0xa1, 0x52, 0x93, 0xc7, 0x3c, 0xac, + 0x20, 0x09, 0xfb, 0x40, 0x95, 0xb9, 0x0f, 0x0a, 0x35, 0x50, 0xe2, 0x05, 0x33, 0x20, 0xdd, 0xb0, + 0xb7, 0xca, 0xda, 0x15, 0xa8, 0xc8, 0x73, 0x5d, 0xb7, 0x22, 0x5f, 0x23, 0xef, 0xcd, 0x33, 0x41, + 0xa2, + } + }; + } + + if (HMACSHA3_384.IsSupported) + { + // HMACSHA3_384 output size is 48 bytes + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_384), + new byte[95] + { + 0x80, 0x3b, 0x0a, 0x83, 0xe5, 0xae, 0xab, 0xff, 0x16, 0x7a, 0x04, 0x60, 0x97, 0x74, 0x39, 0xcf, + 0x8b, 0xeb, 0xbb, 0x57, 0x89, 0x62, 0x24, 0xab, 0x01, 0x61, 0xce, 0x23, 0xbc, 0xc1, 0xe0, 0xc4, + 0x9e, 0x73, 0xd1, 0x21, 0xdc, 0x21, 0xee, 0x30, 0xdb, 0xec, 0xb0, 0xbf, 0xec, 0xaa, 0x24, 0x18, + 0xf9, 0x93, 0xda, 0xd1, 0xaf, 0xfe, 0xbb, 0x1c, 0x7f, 0xcd, 0xea, 0x8f, 0x57, 0x41, 0x3c, 0x01, + 0xa8, 0x94, 0x06, 0x27, 0x8d, 0x95, 0x5d, 0x62, 0x61, 0xe7, 0x67, 0x60, 0xc4, 0xa2, 0xc4, 0xf5, + 0x7e, 0x38, 0x6e, 0x30, 0x38, 0x83, 0x7d, 0x5e, 0xf4, 0x0f, 0xdf, 0xd3, 0xac, 0x65, 0x48, + } + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_384), + new byte[96] + { + 0xb8, 0xea, 0xbd, 0xcb, 0x67, 0xcb, 0xd7, 0xf5, 0x12, 0xdf, 0xc2, 0x35, 0x89, 0x66, 0x80, 0x6f, + 0xc4, 0x7c, 0x28, 0xf2, 0x4b, 0xf5, 0xd1, 0x4d, 0x54, 0x4c, 0x78, 0xae, 0xde, 0xc2, 0xae, 0xb0, + 0x7d, 0xfc, 0x02, 0x6e, 0x0e, 0x08, 0x2b, 0xfc, 0xd2, 0x2b, 0xae, 0xfc, 0xa1, 0x55, 0xf7, 0xc7, + 0xd5, 0x77, 0xe4, 0x84, 0xbb, 0x53, 0x1d, 0x3d, 0xd2, 0x7a, 0x61, 0x97, 0x8a, 0xd3, 0xae, 0x1b, + 0x47, 0xbe, 0xa9, 0x40, 0x02, 0xac, 0x55, 0x1b, 0x74, 0x72, 0x02, 0x5b, 0xa8, 0xa8, 0xd4, 0xfe, + 0xcf, 0xd1, 0xb2, 0x44, 0x01, 0xec, 0xb7, 0xef, 0x63, 0x0f, 0x16, 0xae, 0xa9, 0x63, 0xb1, 0x56, + } + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_384), + new byte[97] + { + 0x62, 0x93, 0xa5, 0x45, 0x03, 0x7a, 0x2f, 0x50, 0xfe, 0x6b, 0xe6, 0x85, 0x56, 0x88, 0x8c, 0x78, + 0xbd, 0x4f, 0x08, 0x68, 0xdd, 0x33, 0xab, 0x18, 0x05, 0x81, 0x79, 0x70, 0x24, 0xe0, 0x3f, 0x94, + 0x40, 0x9b, 0xc3, 0x41, 0xa2, 0xe0, 0xfd, 0x02, 0xe8, 0xb8, 0x41, 0x53, 0x2e, 0x95, 0x59, 0xc5, + 0xf7, 0xab, 0x5b, 0xe9, 0x2d, 0x15, 0x0a, 0xcc, 0xb8, 0xc0, 0x87, 0xbd, 0x78, 0x39, 0xb9, 0xb8, + 0x83, 0x2c, 0x49, 0x7b, 0x45, 0x9b, 0x81, 0xed, 0x33, 0xdc, 0x75, 0xf1, 0x7d, 0xbd, 0x44, 0xce, + 0xa5, 0xf3, 0xbe, 0x43, 0xa5, 0x15, 0x7c, 0x7e, 0xcd, 0x06, 0x09, 0xb0, 0x4a, 0x17, 0x48, 0xf3, + 0x51, + } + }; + } + + if (HMACSHA3_512.IsSupported) + { + // HMACSHA3_512 output size is 64 bytes + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_512), + new byte[127] + { + 0x41, 0xe4, 0xb5, 0xe6, 0x5b, 0x8c, 0xce, 0x14, 0xa8, 0x39, 0xd3, 0xdf, 0xb4, 0x27, 0x0f, 0xff, + 0x1f, 0x9a, 0xca, 0x24, 0x03, 0x59, 0x4b, 0x86, 0x40, 0x66, 0xf0, 0xae, 0xdc, 0x59, 0x44, 0x0e, + 0x6a, 0x87, 0xa5, 0x38, 0x5a, 0x79, 0x27, 0xa5, 0x61, 0x91, 0x1a, 0x9d, 0x39, 0xca, 0x80, 0xe0, + 0x11, 0x3b, 0xd0, 0xfa, 0x2e, 0x48, 0x70, 0x83, 0x31, 0xa7, 0xa6, 0x6c, 0x5f, 0xf2, 0x2f, 0x09, + 0x5b, 0x1e, 0xad, 0x8b, 0x4f, 0xbd, 0x63, 0x26, 0x6f, 0xcd, 0xc6, 0xce, 0xff, 0xa6, 0x86, 0xbe, + 0xf6, 0x4b, 0x81, 0x63, 0x65, 0x24, 0x48, 0xbc, 0x59, 0x6a, 0x4f, 0x00, 0xb5, 0x9e, 0x9b, 0xbd, + 0x85, 0xbc, 0xf6, 0xf1, 0xf1, 0xaa, 0xd3, 0x91, 0x9b, 0x7b, 0x26, 0xfe, 0xd0, 0xd7, 0x4c, 0x34, + 0xdd, 0x2c, 0x57, 0x2e, 0x10, 0x09, 0x76, 0x32, 0xed, 0x3a, 0x95, 0x7d, 0x88, 0x2b, 0xdc, + } + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_512), + new byte[128] + { + 0xbe, 0x9f, 0x29, 0xd7, 0x9d, 0x11, 0x7e, 0xd7, 0x33, 0xd4, 0xcf, 0x66, 0xed, 0x1a, 0x61, 0xfd, + 0xb0, 0x68, 0x3b, 0x03, 0xd1, 0x7c, 0x1a, 0x69, 0xd0, 0x33, 0x1c, 0xf4, 0x7a, 0xf0, 0x4a, 0x46, + 0xed, 0x4a, 0x33, 0xbf, 0x2b, 0x18, 0x16, 0x4b, 0xda, 0x30, 0x96, 0x11, 0xee, 0x52, 0x4b, 0x0e, + 0x22, 0xa0, 0x8f, 0xb0, 0xdc, 0xe6, 0x8c, 0x57, 0xd0, 0x6e, 0x25, 0xd8, 0x29, 0xf7, 0xf9, 0x94, + 0xe3, 0x73, 0x20, 0x4e, 0x11, 0xc0, 0xa9, 0x3b, 0x00, 0xf0, 0x8e, 0xff, 0xb3, 0x07, 0x87, 0x4c, + 0x3b, 0x96, 0x09, 0xff, 0x14, 0x3b, 0x65, 0x17, 0x5f, 0x54, 0x16, 0xaf, 0x15, 0xe5, 0x59, 0x5b, + 0x75, 0xf5, 0x03, 0x61, 0x5b, 0xd9, 0xf3, 0x7c, 0x71, 0x96, 0xaa, 0x67, 0xef, 0xdd, 0x40, 0x4c, + 0xd2, 0x9e, 0xf6, 0x05, 0x02, 0x93, 0x23, 0x83, 0x33, 0xcc, 0x0f, 0xf2, 0xdd, 0x9c, 0xd6, 0x46, + } + }; + + yield return new object[] + { + nameof(HashAlgorithmName.SHA3_512), + new byte[129] + { + 0x5f, 0xf7, 0xd9, 0x1e, 0x98, 0xb3, 0xa4, 0xab, 0x4d, 0xc8, 0x50, 0x9a, 0xd7, 0x50, 0x37, 0xba, + 0x10, 0xeb, 0x1b, 0x10, 0x5f, 0x6c, 0xfe, 0x81, 0x75, 0x5d, 0x6c, 0x63, 0x8a, 0xfe, 0x60, 0x4f, + 0xb3, 0x9e, 0xf4, 0x84, 0x5d, 0xa3, 0x88, 0xf7, 0x29, 0x5c, 0x30, 0xbb, 0xf7, 0x30, 0x69, 0x84, + 0xab, 0x9e, 0xc6, 0xb0, 0xc3, 0xce, 0x45, 0x7a, 0xf2, 0xac, 0x18, 0x0b, 0x09, 0x8c, 0xbb, 0xae, + 0x22, 0x12, 0xef, 0xd8, 0xec, 0x6f, 0x9f, 0xbf, 0x09, 0x7f, 0xe2, 0xb6, 0xc8, 0x6a, 0xf7, 0x5e, + 0x86, 0x27, 0x22, 0xeb, 0xa8, 0x7b, 0x1f, 0x54, 0x97, 0x16, 0x0f, 0x21, 0xad, 0xcd, 0xd9, 0x9d, + 0xd6, 0x01, 0x0b, 0x79, 0xe9, 0x16, 0xd8, 0xcd, 0xa6, 0x93, 0x25, 0xd1, 0xeb, 0xac, 0x9b, 0x5f, + 0x26, 0xf4, 0xad, 0x0a, 0xf2, 0xc6, 0x4d, 0xad, 0x69, 0x96, 0xb7, 0xc8, 0xcd, 0xe0, 0x13, 0xfb, + 0xf6, + } + }; + } +#endif } public static IEnumerable GetRfc8009TestVectors() diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index 8f10590302e4bb..83c7e44fd6864d 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -9,5 +9,10 @@ internal static class HashAlgorithmNames internal const string SHA256 = nameof(SHA256); internal const string SHA384 = nameof(SHA384); internal const string SHA512 = nameof(SHA512); +#if NET8_0_OR_GREATER + internal const string SHA3_256 = nameof(SHA3_256); + internal const string SHA3_384 = nameof(SHA3_384); + internal const string SHA3_512 = nameof(SHA3_512); +#endif } } From e8ff0b78f489d0d88f411396479557cbfef865c5 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 21 Mar 2023 14:22:34 -0400 Subject: [PATCH 11/47] SP800108: Throw PNSE for SHA3 on .NET 8 when not supported --- .../Cryptography/SP800108HmacCounterKdf.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs index fe131d4de9be4d..a9f37b0fb11a4e 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs @@ -558,12 +558,27 @@ private static void CheckHashAlgorithm(HashAlgorithmName hashAlgorithm) case HashAlgorithmNames.SHA256: case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: + break; #if NET8_0_OR_GREATER case HashAlgorithmNames.SHA3_256: + if (!HMACSHA3_256.IsSupported) + { + throw new PlatformNotSupportedException(); + } + break; case HashAlgorithmNames.SHA3_384: + if (!HMACSHA3_384.IsSupported) + { + throw new PlatformNotSupportedException(); + } + break; case HashAlgorithmNames.SHA3_512: -#endif + if (!HMACSHA3_512.IsSupported) + { + throw new PlatformNotSupportedException(); + } break; +#endif default: throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName)); } From 7b90ccaec0880af426bd8b8770622e1b6f90c6a8 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 22 Mar 2023 22:30:27 -0400 Subject: [PATCH 12/47] Fix CNG identifiers --- .../src/System/Security/Cryptography/HashAlgorithmName.cs | 6 +++--- .../src/System/Security/Cryptography/HashAlgorithmNames.cs | 6 +++--- .../CertificateCreation/ECDsaX509SignatureGeneratorTests.cs | 6 +++--- .../RSAPkcs1X509SignatureGeneratorTests.cs | 6 +++--- .../RSAPssX509SignatureGeneratorTests.cs | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs index 22fa837a17e59b..c2e444b63a352a 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmName.cs @@ -55,17 +55,17 @@ namespace System.Security.Cryptography /// /// Gets a representing "SHA3-256" /// - public static HashAlgorithmName SHA3_256 => new HashAlgorithmName("SHA3_256"); + public static HashAlgorithmName SHA3_256 => new HashAlgorithmName("SHA3-256"); /// /// Gets a representing "SHA3-384" /// - public static HashAlgorithmName SHA3_384 => new HashAlgorithmName("SHA3_384"); + public static HashAlgorithmName SHA3_384 => new HashAlgorithmName("SHA3-384"); /// /// Gets a representing "SHA3-512" /// - public static HashAlgorithmName SHA3_512 => new HashAlgorithmName("SHA3_512"); + public static HashAlgorithmName SHA3_512 => new HashAlgorithmName("SHA3-512"); private readonly string? _name; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index 6f7cd248807171..00cfa2636a0170 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -14,9 +14,9 @@ internal static partial class HashAlgorithmNames public const string SHA384 = "SHA384"; public const string SHA512 = "SHA512"; - public const string SHA3_256 = "SHA3_256"; - public const string SHA3_384 = "SHA3_384"; - public const string SHA3_512 = "SHA3_512"; + public const string SHA3_256 = "SHA3-256"; + public const string SHA3_384 = "SHA3-384"; + public const string SHA3_512 = "SHA3-512"; /// /// Map HashAlgorithm type to string; .NET Framework uses CryptoConfig functionality. diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs index 580e5121fc9642..5c932f2dc45b1c 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/ECDsaX509SignatureGeneratorTests.cs @@ -106,13 +106,13 @@ public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm) case "SHA512": expectedAlgOid = "06082A8648CE3D040304"; break; - case "SHA3_256": + case "SHA3-256": expectedAlgOid = "060960864801650304030A"; break; - case "SHA3_384": + case "SHA3-384": expectedAlgOid = "060960864801650304030B"; break; - case "SHA3_512": + case "SHA3-512": expectedAlgOid = "060960864801650304030C"; break; default: diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs index 84a4bfba5f1f51..453892e6349ecf 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPkcs1X509SignatureGeneratorTests.cs @@ -120,13 +120,13 @@ public static void SignatureAlgorithm_Encoding(HashAlgorithmName hashAlgorithm) case "SHA512": expectedOid = "06092A864886F70D01010D"; break; - case "SHA3_256": + case "SHA3-256": expectedOid = "060960864801650304030E"; break; - case "SHA3_384": + case "SHA3-384": expectedOid = "060960864801650304030F"; break; - case "SHA3_512": + case "SHA3-512": expectedOid = "0609608648016503040310"; break; default: diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs index 70c586b25000b9..216bb1ca84cbec 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/RSAPssX509SignatureGeneratorTests.cs @@ -83,9 +83,9 @@ public static void SignatureAlgorithm_StableNotSame(string hashAlgorithmName) [InlineData("MD5")] [InlineData("SHA1")] [InlineData("Potato")] - [InlineData("SHA3_256")] // There are no OIDs assigned for RSA-PSS-withSHA3 family. - [InlineData("SHA3_384")] - [InlineData("SHA3_512")] + [InlineData("SHA3-256")] // There are no OIDs assigned for RSA-PSS-withSHA3 family. + [InlineData("SHA3-384")] + [InlineData("SHA3-512")] public static void SignatureAlgorithm_NotSupported(string hashAlgorithmName) { using (RSA rsa = RSA.Create()) From 9948ff62857c498f499befb5edeafc568aa55a29 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 22 Mar 2023 22:31:06 -0400 Subject: [PATCH 13/47] Fix PlatformDetection --- .../Common/tests/TestUtilities/System/PlatformDetection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 8ca81264a2dc66..6e74665013924a 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -661,7 +661,7 @@ private static bool GetSupportsSha3() return OpenSslVersion.Major == 1 && OpenSslVersion.Minor >= 1 && OpenSslVersion.Build >= 1; } - if (IsWindowsVersionOrLater(11, 0, 0)) // TODO: what is the right version here? + if (IsWindowsVersionOrLater(10, 0, 25314)) { return true; } From 8081638cd4025ac22f89f0baacb4aa50826872d5 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 23 Mar 2023 14:11:55 -0400 Subject: [PATCH 14/47] Use correct version --- .../Common/tests/TestUtilities/System/PlatformDetection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 6e74665013924a..593adc4b6c47e2 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -661,7 +661,7 @@ private static bool GetSupportsSha3() return OpenSslVersion.Major == 1 && OpenSslVersion.Minor >= 1 && OpenSslVersion.Build >= 1; } - if (IsWindowsVersionOrLater(10, 0, 25314)) + if (IsWindowsVersionOrLater(10, 0, 25324)) { return true; } From 693e19bb24a6fba1da8d11ed1498fed3a4032063 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 23 Mar 2023 15:12:10 -0400 Subject: [PATCH 15/47] Psuedo handles for Windows --- .../BCrypt/Interop.BCryptAlgPseudoHandle.cs | 6 ++++++ .../HashProviderDispenser.Windows.cs | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptAlgPseudoHandle.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptAlgPseudoHandle.cs index 57c508bf709479..d0a4e878f2764a 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptAlgPseudoHandle.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptAlgPseudoHandle.cs @@ -23,6 +23,12 @@ public enum BCryptAlgPseudoHandle : uint BCRYPT_HMAC_SHA384_ALG_HANDLE = 0x000000c1, BCRYPT_HMAC_SHA512_ALG_HANDLE = 0x000000d1, BCRYPT_PBKDF2_ALG_HANDLE = 0x00000331, + BCRYPT_SHA3_256_ALG_HANDLE = 0x000003B1, + BCRYPT_SHA3_384_ALG_HANDLE = 0x000003C1, + BCRYPT_SHA3_512_ALG_HANDLE = 0x000003D1, + BCRYPT_HMAC_SHA3_256_ALG_HANDLE = 0x000003E1, + BCRYPT_HMAC_SHA3_384_ALG_HANDLE = 0x000003F1, + BCRYPT_HMAC_SHA3_512_ALG_HANDLE = 0x00000401, } internal static bool PseudoHandlesSupported { get; } = diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs index 418cc925a8d48b..2b13f4ae33ac4b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs @@ -179,6 +179,27 @@ private static unsafe void HashDataUsingPseudoHandle( Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA512_ALG_HANDLE; digestSizeInBytes = SHA512.HashSizeInBytes; } + else if (hashAlgorithmId == HashAlgorithmNames.SHA3_256) + { + algHandle = isHmac ? + Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA3_256_ALG_HANDLE : + Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA3_256_ALG_HANDLE; + digestSizeInBytes = SHA3_256.HashSizeInBytes; + } + else if (hashAlgorithmId == HashAlgorithmNames.SHA3_384) + { + algHandle = isHmac ? + Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA3_384_ALG_HANDLE : + Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA3_384_ALG_HANDLE; + digestSizeInBytes = SHA3_384.HashSizeInBytes; + } + else if (hashAlgorithmId == HashAlgorithmNames.SHA3_512) + { + algHandle = isHmac ? + Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA3_512_ALG_HANDLE : + Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA3_512_ALG_HANDLE; + digestSizeInBytes = SHA3_512.HashSizeInBytes; + } else { Debug.Fail("Unknown hash algorithm."); From 1f399e7b81568181fa1e76d2be68bf9a9455c8d6 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 23 Mar 2023 15:23:15 -0400 Subject: [PATCH 16/47] Fix algorithm identifiers throughout --- .../Interop.Evp.DigestAlgs.cs | 5 +-- .../Interop.EVP.DigestAlgs.cs | 6 +-- .../SP800108HmacCounterKdfTests.Functional.cs | 42 +++++++++---------- .../Cryptography/HashAlgorithmNames.cs | 7 ++-- .../tests/Rfc2898OneShotTests.cs | 12 +++--- .../tests/Rfc2898Tests.cs | 6 +-- 6 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs index 32bba680d8298d..5fed35e9a7960e 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs @@ -52,10 +52,7 @@ internal static IntPtr EvpSha512() => nameof(HashAlgorithmName.SHA384) => EvpSha384(), nameof(HashAlgorithmName.SHA512) => EvpSha512(), nameof(HashAlgorithmName.MD5) => EvpMd5(), - - nameof(HashAlgorithmName.SHA3_256) or - nameof(HashAlgorithmName.SHA3_384) or - nameof(HashAlgorithmName.SHA3_512) => throw new PlatformNotSupportedException(), + "SHA3-256" or "SHA3-384" or "SHA3-512" => throw new PlatformNotSupportedException(), _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)) }; } 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 7ebc6fb545438a..ea3dd3b7736784 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 @@ -74,13 +74,13 @@ internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) case nameof(HashAlgorithmName.SHA256): return EvpSha256(); case nameof(HashAlgorithmName.SHA384): return EvpSha384(); case nameof(HashAlgorithmName.SHA512): return EvpSha512(); - case nameof(HashAlgorithmName.SHA3_256): + case "SHA3-256": IntPtr sha3_256 = EvpSha3_256(); return sha3_256 != 0 ? sha3_256 : throw new PlatformNotSupportedException(); - case nameof(HashAlgorithmName.SHA3_384): + case "SHA3-384": IntPtr sha3_384 = EvpSha3_384(); return sha3_384 != 0 ? sha3_384 : throw new PlatformNotSupportedException(); - case nameof(HashAlgorithmName.SHA3_512): + case "SHA3-512": IntPtr sha3_512 = EvpSha3_512(); return sha3_512 != 0 ? sha3_512 : throw new PlatformNotSupportedException(); case nameof(HashAlgorithmName.MD5): return EvpMd5(); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs index f4149d3cebbda4..474cc75ae8df27 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs @@ -96,22 +96,22 @@ public static void EmptyTests(byte[] key, string label, string context, byte[] e [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8, new byte[] { 0xba, 0xf6, 0xed, 0xa7, 0x3a, 0xf7, 0x12, 0x27 })] [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8 + 1, new byte[] { 0x34, 0xdf, 0x2d, 0x21, 0xfd, 0xf1, 0x0e, 0x13 })] #if NET8_0_OR_GREATER - [InlineData(nameof(HashAlgorithmName.SHA3_256), 1088 / 8 - 1, new byte[] { 0xa1, 0x96, 0xae, 0x83, 0x56, 0xf4, 0x2a, 0x4b })] - [InlineData(nameof(HashAlgorithmName.SHA3_256), 1088 / 8, new byte[] { 0xe7, 0xe9, 0xe0, 0x98, 0x09, 0x54, 0x54, 0x2d })] - [InlineData(nameof(HashAlgorithmName.SHA3_256), 1088 / 8 + 1, new byte[] { 0x7d, 0x7a, 0x71, 0xdf, 0x1f, 0x5d, 0x5b, 0x44 })] - [InlineData(nameof(HashAlgorithmName.SHA3_384), 832 / 8 - 1, new byte[] { 0xd6, 0x08, 0x69, 0xd0, 0x99, 0x98, 0x6d, 0xcc })] - [InlineData(nameof(HashAlgorithmName.SHA3_384), 832 / 8, new byte[] { 0x49, 0x83, 0x06, 0x4e, 0x08, 0xf8, 0x93, 0x62 })] - [InlineData(nameof(HashAlgorithmName.SHA3_384), 832 / 8 + 1, new byte[] { 0xcc, 0x03, 0x1f, 0x57, 0x5e, 0x0c, 0xe1, 0xe8 })] - [InlineData(nameof(HashAlgorithmName.SHA3_512), 576 / 8 - 1, new byte[] { 0x47, 0xd2, 0x7e, 0x61, 0x01, 0x61, 0x9a, 0xd0 })] - [InlineData(nameof(HashAlgorithmName.SHA3_512), 576 / 8, new byte[] { 0xda, 0x56, 0x5b, 0x08, 0x73, 0xbc, 0x4d, 0x33 })] - [InlineData(nameof(HashAlgorithmName.SHA3_512), 576 / 8 + 1, new byte[] { 0xd3, 0xa1, 0xfd, 0x76, 0xc4, 0xf9, 0x62, 0xc3 })] + [InlineData("SHA3-256", 1088 / 8 - 1, new byte[] { 0xa1, 0x96, 0xae, 0x83, 0x56, 0xf4, 0x2a, 0x4b })] + [InlineData("SHA3-256", 1088 / 8, new byte[] { 0xe7, 0xe9, 0xe0, 0x98, 0x09, 0x54, 0x54, 0x2d })] + [InlineData("SHA3-256", 1088 / 8 + 1, new byte[] { 0x7d, 0x7a, 0x71, 0xdf, 0x1f, 0x5d, 0x5b, 0x44 })] + [InlineData("SHA3-384", 832 / 8 - 1, new byte[] { 0xd6, 0x08, 0x69, 0xd0, 0x99, 0x98, 0x6d, 0xcc })] + [InlineData("SHA3-384", 832 / 8, new byte[] { 0x49, 0x83, 0x06, 0x4e, 0x08, 0xf8, 0x93, 0x62 })] + [InlineData("SHA3-384", 832 / 8 + 1, new byte[] { 0xcc, 0x03, 0x1f, 0x57, 0x5e, 0x0c, 0xe1, 0xe8 })] + [InlineData("SHA3-512", 576 / 8 - 1, new byte[] { 0x47, 0xd2, 0x7e, 0x61, 0x01, 0x61, 0x9a, 0xd0 })] + [InlineData("SHA3-512", 576 / 8, new byte[] { 0xda, 0x56, 0x5b, 0x08, 0x73, 0xbc, 0x4d, 0x33 })] + [InlineData("SHA3-512", 576 / 8 + 1, new byte[] { 0xd3, 0xa1, 0xfd, 0x76, 0xc4, 0xf9, 0x62, 0xc3 })] #endif public static void Kdk_HmacBlockBoundarySizes(string hashAlgorithmName, int kdkSize, byte[] expected) { #if NET8_0_OR_GREATER - if ((hashAlgorithmName == nameof(HashAlgorithmName.SHA3_256) && !SHA3_256.IsSupported) || - (hashAlgorithmName == nameof(HashAlgorithmName.SHA3_384) && !SHA3_384.IsSupported) || - (hashAlgorithmName == nameof(HashAlgorithmName.SHA3_512) && !SHA3_512.IsSupported)) + if ((hashAlgorithmName == "SHA3-256" && !SHA3_256.IsSupported) || + (hashAlgorithmName == "SHA3-384" && !SHA3_384.IsSupported) || + (hashAlgorithmName == "SHA3-512" && !SHA3_512.IsSupported)) { throw new SkipTestException($"Algorithm '{hashAlgorithmName}' is not supported on the current platform."); } @@ -334,7 +334,7 @@ public static IEnumerable GetOutputLengthBoundaries() // HMACSHA3_256 output size is 32 bytes yield return new object[] { - nameof(HashAlgorithmName.SHA3_256), + "SHA3-256", new byte[63] { 0x25, 0xb6, 0xc5, 0xba, 0x60, 0x47, 0x95, 0xb6, 0x5c, 0x92, 0xcb, 0x8f, 0xd2, 0x4d, 0x40, 0xfa, @@ -346,7 +346,7 @@ public static IEnumerable GetOutputLengthBoundaries() yield return new object[] { - nameof(HashAlgorithmName.SHA3_256), + "SHA3-256", new byte[64] { 0xc8, 0x8a, 0xfe, 0xd4, 0x62, 0xa6, 0x9e, 0xa6, 0x90, 0xa7, 0xb1, 0xe2, 0x01, 0xff, 0x67, 0x52, @@ -358,7 +358,7 @@ public static IEnumerable GetOutputLengthBoundaries() yield return new object[] { - nameof(HashAlgorithmName.SHA3_256), + "SHA3-256", new byte[65] { 0xcc, 0x3a, 0x45, 0x55, 0x26, 0x1e, 0x56, 0xf4, 0x3c, 0x18, 0x66, 0x1d, 0xa8, 0xe3, 0x91, 0xe7, @@ -375,7 +375,7 @@ public static IEnumerable GetOutputLengthBoundaries() // HMACSHA3_384 output size is 48 bytes yield return new object[] { - nameof(HashAlgorithmName.SHA3_384), + "SHA3-384", new byte[95] { 0x80, 0x3b, 0x0a, 0x83, 0xe5, 0xae, 0xab, 0xff, 0x16, 0x7a, 0x04, 0x60, 0x97, 0x74, 0x39, 0xcf, @@ -389,7 +389,7 @@ public static IEnumerable GetOutputLengthBoundaries() yield return new object[] { - nameof(HashAlgorithmName.SHA3_384), + "SHA3-384", new byte[96] { 0xb8, 0xea, 0xbd, 0xcb, 0x67, 0xcb, 0xd7, 0xf5, 0x12, 0xdf, 0xc2, 0x35, 0x89, 0x66, 0x80, 0x6f, @@ -403,7 +403,7 @@ public static IEnumerable GetOutputLengthBoundaries() yield return new object[] { - nameof(HashAlgorithmName.SHA3_384), + "SHA3-384", new byte[97] { 0x62, 0x93, 0xa5, 0x45, 0x03, 0x7a, 0x2f, 0x50, 0xfe, 0x6b, 0xe6, 0x85, 0x56, 0x88, 0x8c, 0x78, @@ -422,7 +422,7 @@ public static IEnumerable GetOutputLengthBoundaries() // HMACSHA3_512 output size is 64 bytes yield return new object[] { - nameof(HashAlgorithmName.SHA3_512), + "SHA3-512", new byte[127] { 0x41, 0xe4, 0xb5, 0xe6, 0x5b, 0x8c, 0xce, 0x14, 0xa8, 0x39, 0xd3, 0xdf, 0xb4, 0x27, 0x0f, 0xff, @@ -438,7 +438,7 @@ public static IEnumerable GetOutputLengthBoundaries() yield return new object[] { - nameof(HashAlgorithmName.SHA3_512), + "SHA3-512", new byte[128] { 0xbe, 0x9f, 0x29, 0xd7, 0x9d, 0x11, 0x7e, 0xd7, 0x33, 0xd4, 0xcf, 0x66, 0xed, 0x1a, 0x61, 0xfd, @@ -454,7 +454,7 @@ public static IEnumerable GetOutputLengthBoundaries() yield return new object[] { - nameof(HashAlgorithmName.SHA3_512), + "SHA3-512", new byte[129] { 0x5f, 0xf7, 0xd9, 0x1e, 0x98, 0xb3, 0xa4, 0xab, 0x4d, 0xc8, 0x50, 0x9a, 0xd7, 0x50, 0x37, 0xba, diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index 83c7e44fd6864d..5e951f9938837b 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -3,6 +3,7 @@ namespace System.Security.Cryptography { + // Strings need to match CNG identifiers. internal static class HashAlgorithmNames { internal const string SHA1 = nameof(SHA1); @@ -10,9 +11,9 @@ internal static class HashAlgorithmNames internal const string SHA384 = nameof(SHA384); internal const string SHA512 = nameof(SHA512); #if NET8_0_OR_GREATER - internal const string SHA3_256 = nameof(SHA3_256); - internal const string SHA3_384 = nameof(SHA3_384); - internal const string SHA3_512 = nameof(SHA3_512); + internal const string SHA3_256 = "SHA3-256"; + internal const string SHA3_384 = "SHA3-384"; + internal const string SHA3_512 = "SHA3-512"; #endif } } diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs index fc202e43e0e93d..a5dbee9dc2259b 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs @@ -305,9 +305,9 @@ public static void Pbkdf2_Rfc6070_HighIterations() } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.DoesNotSupportSha3))] - [InlineData(nameof(HashAlgorithmName.SHA3_256))] - [InlineData(nameof(HashAlgorithmName.SHA3_384))] - [InlineData(nameof(HashAlgorithmName.SHA3_512))] + [InlineData("SHA3-256")] + [InlineData("SHA3-384")] + [InlineData("SHA3-512")] public static void UnsupportedPkbdf2Algorithms(string hashAlgorithm) { HashAlgorithmName hashAlgorithmName = new HashAlgorithmName(hashAlgorithm); @@ -409,7 +409,7 @@ public static IEnumerable Pbkdf2_OpenSsl_Vectors() // hashAlgorithm, password, salt, iterations, expected yield return new object[] { - nameof(HashAlgorithmName.SHA3_256), + "SHA3-256", "password", "salt", 4096, @@ -418,7 +418,7 @@ public static IEnumerable Pbkdf2_OpenSsl_Vectors() yield return new object[] { - nameof(HashAlgorithmName.SHA3_384), + "SHA3-384", "password", "salt", 4096, @@ -427,7 +427,7 @@ public static IEnumerable Pbkdf2_OpenSsl_Vectors() yield return new object[] { - nameof(HashAlgorithmName.SHA3_512), + "SHA3-512", "password", "salt", 4096, diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs index 9fb0c149988fb1..cdb8223166a140 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs @@ -614,7 +614,7 @@ private static IEnumerable GetKnownValuesTestCases() yield return new KnownValuesTestCase { CaseName = "OpenSSL SHA3-256", - HashAlgorithmName = nameof(HashAlgorithmName.SHA3_256), + HashAlgorithmName = "SHA3-256", Password = "password", Salt = "salt"u8.ToArray(), IterationCount = 4096, @@ -625,7 +625,7 @@ private static IEnumerable GetKnownValuesTestCases() yield return new KnownValuesTestCase { CaseName = "OpenSSL SHA3-384", - HashAlgorithmName = nameof(HashAlgorithmName.SHA3_384), + HashAlgorithmName = "SHA3-384", Password = "password", Salt = "salt"u8.ToArray(), IterationCount = 4096, @@ -636,7 +636,7 @@ private static IEnumerable GetKnownValuesTestCases() yield return new KnownValuesTestCase { CaseName = "OpenSSL SHA3-512", - HashAlgorithmName = nameof(HashAlgorithmName.SHA3_512), + HashAlgorithmName = "SHA3-512", Password = "password", Salt = "salt"u8.ToArray(), IterationCount = 4096, From e80d2fd1caec486d9cb833ec8c15b1662cdd588e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 23 Mar 2023 15:26:51 -0400 Subject: [PATCH 17/47] Block sizes for SP800-108 --- .../SP800108HmacCounterKdfImplementationCng.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs index ca8f72c61428aa..46143f15c86acc 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs @@ -193,7 +193,7 @@ private static unsafe SafeBCryptKeyHandle CreateSymmetricKey(byte* symmetricKey, private static int GetHashBlockSize(string hashAlgorithmName) { - // Block sizes per NIST FIPS pub 180-4. + // Block sizes per NIST FIPS pub 180-4 and FIPS 202. switch (hashAlgorithmName) { case HashAlgorithmNames.SHA1: @@ -202,6 +202,12 @@ private static int GetHashBlockSize(string hashAlgorithmName) case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: return 1024 / 8; + case HashAlgorithmNames.SHA3_256: + return 1088 / 8; + case HashAlgorithmNames.SHA3_384: + return 832 / 8; + case HashAlgorithmNames.SHA3_512: + return 576 / 8; default: Debug.Fail($"Unexpected hash algorithm '{hashAlgorithmName}'"); throw new CryptographicException(); From 34e30772b720cb9ac83bf0fdcf4daa06a1c4e332 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 23 Mar 2023 15:30:32 -0400 Subject: [PATCH 18/47] Add one shots for SP800-108 in CNG --- .../Cryptography/SP800108HmacCounterKdfImplementationCng.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs index 75025e598ffc08..77adda425ce3d6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationCng.cs @@ -65,6 +65,12 @@ private static int HashOneShot(HashAlgorithmName hashAlgorithm, ReadOnlySpan Date: Thu, 23 Mar 2023 16:28:47 -0400 Subject: [PATCH 19/47] Use known consts for identifiers --- .../Interop.Evp.DigestAlgs.cs | 13 +++++++------ .../Interop.EVP.DigestAlgs.cs | 14 +++++++------- .../Security/Cryptography/HashAlgorithmNames.cs | 2 -- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs index 5fed35e9a7960e..6f6a6fcd1e93e3 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs @@ -47,12 +47,13 @@ internal static IntPtr EvpSha512() => internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) => hashAlgorithmId switch { - nameof(HashAlgorithmName.SHA1) => EvpSha1(), - nameof(HashAlgorithmName.SHA256) => EvpSha256(), - nameof(HashAlgorithmName.SHA384) => EvpSha384(), - nameof(HashAlgorithmName.SHA512) => EvpSha512(), - nameof(HashAlgorithmName.MD5) => EvpMd5(), - "SHA3-256" or "SHA3-384" or "SHA3-512" => throw new PlatformNotSupportedException(), + HashAlgorithmNames.SHA1 => EvpSha1(), + HashAlgorithmNames.SHA256 => EvpSha256(), + HashAlgorithmNames.SHA384 => EvpSha384(), + HashAlgorithmNames.SHA512 => EvpSha512(), + HashAlgorithmNames.MD5 => EvpMd5(), + HashAlgorithmNames.SHA3_256 or HashAlgorithmNames.SHA3_384 or HashAlgorithmNames.SHA3_512 => + throw new PlatformNotSupportedException(), _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)) }; } 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 ea3dd3b7736784..8e6cdc0695c390 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 @@ -70,17 +70,17 @@ internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) { switch (hashAlgorithmId) { - case nameof(HashAlgorithmName.SHA1): return EvpSha1(); - case nameof(HashAlgorithmName.SHA256): return EvpSha256(); - case nameof(HashAlgorithmName.SHA384): return EvpSha384(); - case nameof(HashAlgorithmName.SHA512): return EvpSha512(); - case "SHA3-256": + 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 "SHA3-384": + case HashAlgorithmNames.SHA3_384: IntPtr sha3_384 = EvpSha3_384(); return sha3_384 != 0 ? sha3_384 : throw new PlatformNotSupportedException(); - case "SHA3-512": + case HashAlgorithmNames.SHA3_512: IntPtr sha3_512 = EvpSha3_512(); return sha3_512 != 0 ? sha3_512 : throw new PlatformNotSupportedException(); case nameof(HashAlgorithmName.MD5): return EvpMd5(); diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index 5e951f9938837b..feb43d2caa487b 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -10,10 +10,8 @@ internal static class HashAlgorithmNames internal const string SHA256 = nameof(SHA256); internal const string SHA384 = nameof(SHA384); internal const string SHA512 = nameof(SHA512); -#if NET8_0_OR_GREATER internal const string SHA3_256 = "SHA3-256"; internal const string SHA3_384 = "SHA3-384"; internal const string SHA3_512 = "SHA3-512"; -#endif } } From 8b8a193cf10f0b3d34ea497c3072041f70c466c5 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 29 Mar 2023 16:06:21 -0400 Subject: [PATCH 20/47] SHA3_256 Platform guards --- .../ref/System.Security.Cryptography.cs | 70 ++++++++++++------ .../System/Security/Cryptography/SHA3_256.cs | 71 +++++++++++++------ 2 files changed, 100 insertions(+), 41 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index ff2ea254ac07d8..e56c63af295b71 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -2371,35 +2371,65 @@ public abstract partial class SHA3_256 : System.Security.Cryptography.HashAlgori public const int HashSizeInBits = 256; public const int HashSizeInBytes = 32; protected SHA3_256() { } - [System.Runtime.Versioning.SupportedOSPlatformGuardAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformGuardAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("tvos")] public static bool IsSupported { get { throw null; } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static new System.Security.Cryptography.SHA3_256 Create() { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(byte[] source) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.IO.Stream source) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.ReadOnlySpan source) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("linux")] - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } public abstract partial class SHA3_384 : System.Security.Cryptography.HashAlgorithm diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs index 0a0daff805bbe5..ed0158380fd859 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs @@ -43,8 +43,11 @@ protected SHA3_256() /// /// if the algorithm is supported; otherwise, . /// - [SupportedOSPlatformGuard("windows")] - [SupportedOSPlatformGuard("linux")] + [UnsupportedOSPlatformGuard("android")] + [UnsupportedOSPlatformGuard("osx")] + [UnsupportedOSPlatformGuard("ios")] + [UnsupportedOSPlatformGuard("tvos")] + [UnsupportedOSPlatformGuard("browser")] public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_256); /// @@ -56,8 +59,11 @@ protected SHA3_256() /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static new SHA3_256 Create() { CheckSha3Support(); @@ -75,8 +81,11 @@ protected SHA3_256() /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -92,8 +101,11 @@ public static byte[] HashData(byte[] source) /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(ReadOnlySpan source) { byte[] buffer = new byte[HashSizeInBytes]; @@ -117,8 +129,11 @@ public static byte[] HashData(ReadOnlySpan source) /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static int HashData(ReadOnlySpan source, Span destination) { if (!TryHashData(source, destination, out int bytesWritten)) @@ -127,7 +142,6 @@ public static int HashData(ReadOnlySpan source, Span destination) return bytesWritten; } - /// /// Attempts to compute the hash of data using the SHA3-256 algorithm. /// @@ -143,8 +157,11 @@ public static int HashData(ReadOnlySpan source, Span destination) /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) { CheckSha3Support(); @@ -183,8 +200,11 @@ public static bool TryHashData(ReadOnlySpan source, Span destination /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static int HashData(Stream source, Span destination) { ArgumentNullException.ThrowIfNull(source); @@ -213,8 +233,11 @@ public static int HashData(Stream source, Span destination) /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(Stream source) { ArgumentNullException.ThrowIfNull(source); @@ -244,8 +267,11 @@ public static byte[] HashData(Stream source) /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(source); @@ -283,8 +309,11 @@ public static ValueTask HashDataAsync(Stream source, CancellationToken c /// /// The platform does not support SHA3-256. /// - [SupportedOSPlatform("windows")] - [SupportedOSPlatform("linux")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync( Stream source, Memory destination, From 63d383baca9a5f28d9aabf5c896fe0735eca5f62 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 29 Mar 2023 16:26:46 -0400 Subject: [PATCH 21/47] Fix SHA3-384 and 512 UOSP --- .../ref/System.Security.Cryptography.cs | 100 ++++++++++++++++++ .../System/Security/Cryptography/SHA3_384.cs | 71 +++++++++++-- .../System/Security/Cryptography/SHA3_512.cs | 72 +++++++++++-- 3 files changed, 222 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index e56c63af295b71..c5066ae34a3ef5 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -2437,15 +2437,65 @@ public abstract partial class SHA3_384 : System.Security.Cryptography.HashAlgori public const int HashSizeInBits = 384; public const int HashSizeInBytes = 48; protected SHA3_384() { } + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("tvos")] public static bool IsSupported { get { throw null; } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static new System.Security.Cryptography.SHA3_384 Create() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(byte[] source) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.IO.Stream source) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.ReadOnlySpan source) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } public abstract partial class SHA3_512 : System.Security.Cryptography.HashAlgorithm @@ -2453,15 +2503,65 @@ public abstract partial class SHA3_512 : System.Security.Cryptography.HashAlgori public const int HashSizeInBits = 512; public const int HashSizeInBytes = 64; protected SHA3_512() { } + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("tvos")] public static bool IsSupported { get { throw null; } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static new System.Security.Cryptography.SHA3_512 Create() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(byte[] source) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.IO.Stream source) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.ReadOnlySpan source) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } public abstract partial class SHA512 : System.Security.Cryptography.HashAlgorithm diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs index 97ad591e97a62e..07a69ce0f98aa7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -42,6 +43,11 @@ protected SHA3_384() /// /// if the algorithm is supported; otherwise, . /// + [UnsupportedOSPlatformGuard("android")] + [UnsupportedOSPlatformGuard("osx")] + [UnsupportedOSPlatformGuard("ios")] + [UnsupportedOSPlatformGuard("tvos")] + [UnsupportedOSPlatformGuard("browser")] public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_384); /// @@ -53,6 +59,11 @@ protected SHA3_384() /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static new SHA3_384 Create() { CheckSha3Support(); @@ -70,6 +81,11 @@ protected SHA3_384() /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -85,6 +101,11 @@ public static byte[] HashData(byte[] source) /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(ReadOnlySpan source) { byte[] buffer = new byte[HashSizeInBytes]; @@ -108,6 +129,11 @@ public static byte[] HashData(ReadOnlySpan source) /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static int HashData(ReadOnlySpan source, Span destination) { if (!TryHashData(source, destination, out int bytesWritten)) @@ -132,6 +158,11 @@ public static int HashData(ReadOnlySpan source, Span destination) /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) { CheckSha3Support(); @@ -158,18 +189,23 @@ public static bool TryHashData(ReadOnlySpan source, Span destination /// is . /// /// - ///

+ /// /// The buffer in is too small to hold the calculated hash /// size. The SHA3-384 algorithm always produces a 384-bit hash, or 48 bytes. - ///

- ///

-or-

- ///

+ /// + /// -or- + /// /// does not support reading. - ///

+ /// ///
/// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static int HashData(Stream source, Span destination) { ArgumentNullException.ThrowIfNull(source); @@ -198,6 +234,11 @@ public static int HashData(Stream source, Span destination) /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(Stream source) { ArgumentNullException.ThrowIfNull(source); @@ -227,6 +268,11 @@ public static byte[] HashData(Stream source) /// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(source); @@ -252,18 +298,23 @@ public static ValueTask HashDataAsync(Stream source, CancellationToken c /// is . /// /// - ///

+ /// /// The buffer in is too small to hold the calculated hash /// size. The SHA3-384 algorithm always produces a 384-bit hash, or 48 bytes. - ///

- ///

-or-

- ///

+ /// + /// -or- + /// /// does not support reading. - ///

+ /// ///
/// /// The platform does not support SHA3-384. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync( Stream source, Memory destination, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs index 407319d4f58698..b2d8fe39a10023 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -42,6 +43,11 @@ protected SHA3_512() /// /// if the algorithm is supported; otherwise, . /// + [UnsupportedOSPlatformGuard("android")] + [UnsupportedOSPlatformGuard("osx")] + [UnsupportedOSPlatformGuard("ios")] + [UnsupportedOSPlatformGuard("tvos")] + [UnsupportedOSPlatformGuard("browser")] public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_512); /// @@ -53,6 +59,11 @@ protected SHA3_512() /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static new SHA3_512 Create() { CheckSha3Support(); @@ -70,6 +81,11 @@ protected SHA3_512() /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -85,6 +101,11 @@ public static byte[] HashData(byte[] source) /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(ReadOnlySpan source) { byte[] buffer = new byte[HashSizeInBytes]; @@ -108,6 +129,11 @@ public static byte[] HashData(ReadOnlySpan source) /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static int HashData(ReadOnlySpan source, Span destination) { if (!TryHashData(source, destination, out int bytesWritten)) @@ -116,7 +142,6 @@ public static int HashData(ReadOnlySpan source, Span destination) return bytesWritten; } - /// /// Attempts to compute the hash of data using the SHA3-512 algorithm. /// @@ -132,6 +157,11 @@ public static int HashData(ReadOnlySpan source, Span destination) /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) { CheckSha3Support(); @@ -158,18 +188,23 @@ public static bool TryHashData(ReadOnlySpan source, Span destination /// is . /// /// - ///

+ /// /// The buffer in is too small to hold the calculated hash /// size. The SHA3-512 algorithm always produces a 512-bit hash, or 64 bytes. - ///

- ///

-or-

- ///

+ /// + /// -or- + /// /// does not support reading. - ///

+ /// ///
/// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static int HashData(Stream source, Span destination) { ArgumentNullException.ThrowIfNull(source); @@ -198,6 +233,11 @@ public static int HashData(Stream source, Span destination) /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static byte[] HashData(Stream source) { ArgumentNullException.ThrowIfNull(source); @@ -227,6 +267,11 @@ public static byte[] HashData(Stream source) /// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(source); @@ -252,18 +297,23 @@ public static ValueTask HashDataAsync(Stream source, CancellationToken c /// is . /// /// - ///

+ /// /// The buffer in is too small to hold the calculated hash /// size. The SHA3-512 algorithm always produces a 512-bit hash, or 64 bytes. - ///

- ///

-or-

- ///

+ /// + /// -or- + /// /// does not support reading. - ///

+ /// ///
/// /// The platform does not support SHA3-512. /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("osx")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync( Stream source, Memory destination, From 95af4f502c2848a1328202e5a2633c02f80f274a Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 30 Mar 2023 10:37:05 -0400 Subject: [PATCH 22/47] Fix missing SHA3 test coverage --- .../tests/ReusabilityTests.cs | 11 ++++ .../tests/Rfc2898Tests.cs | 27 +++++--- .../tests/Sha3_256Tests.cs | 58 ++++++++++++++++- .../tests/Sha3_384Tests.cs | 62 +++++++++++++++++++ .../tests/Sha3_512Tests.cs | 62 +++++++++++++++++++ 5 files changed, 212 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs b/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs index 29571d3beb812b..4930f5c4cfcd51 100644 --- a/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs @@ -37,6 +37,17 @@ public static IEnumerable ReusabilityHashAlgorithms() yield return new object[] { new HMACSHA256(), }; yield return new object[] { new HMACSHA384(), }; yield return new object[] { new HMACSHA512(), }; + + if (PlatformDetection.SupportsSha3) + { + yield return new object[] { SHA3_256.Create() }; + yield return new object[] { SHA3_384.Create() }; + yield return new object[] { SHA3_512.Create() }; + + yield return new object[] { new HMACSHA3_256() }; + yield return new object[] { new HMACSHA3_384() }; + yield return new object[] { new HMACSHA3_512() }; + } } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs index cdb8223166a140..4342bebb14072d 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898Tests.cs @@ -361,14 +361,9 @@ public static void GetBytes_KnownValues_WithAlgorithm(KnownValuesTestCase testCa } [Theory] - [InlineData("SHA1")] - [InlineData("SHA256")] - [InlineData("SHA384")] - [InlineData("SHA512")] - public static void CheckHashAlgorithmValue(string hashAlgorithmName) + [MemberData(nameof(HashAlgorithmNames))] + public static void CheckHashAlgorithmValue(HashAlgorithmName hashAlgorithm) { - HashAlgorithmName hashAlgorithm = new HashAlgorithmName(hashAlgorithmName); - using (var pbkdf2 = new Rfc2898DeriveBytes(TestPassword, s_testSalt, DefaultIterationCount, hashAlgorithm)) { Assert.Equal(hashAlgorithm, pbkdf2.HashAlgorithm); @@ -465,6 +460,24 @@ public static IEnumerable KnownValuesTestCases() } } + public static IEnumerable HashAlgorithmNames + { + get + { + yield return new object[] { HashAlgorithmName.SHA1 }; + yield return new object[] { HashAlgorithmName.SHA256 }; + yield return new object[] { HashAlgorithmName.SHA384 }; + yield return new object[] { HashAlgorithmName.SHA512 }; + + if (PlatformDetection.SupportsSha3) + { + yield return new object[] { HashAlgorithmName.SHA3_256 }; + yield return new object[] { HashAlgorithmName.SHA3_384 }; + yield return new object[] { HashAlgorithmName.SHA3_512 }; + } + } + } + private static IEnumerable GetKnownValuesTestCases() { Encoding ascii = Encoding.ASCII; diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs index 106ab038ada9b1..a1ba50c42371c3 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs @@ -46,7 +46,7 @@ protected override ValueTask HashDataAsync(Stream source, CancellationTo SHA3_256.HashDataAsync(source, cancellationToken); [ConditionalFact(nameof(IsSupported))] - public void Sha3_256_Kats() + public void SHA3_256_Kats() { foreach ((string Msg, string MD) kat in Fips202Kats) { @@ -54,6 +54,62 @@ public void Sha3_256_Kats() } } + [ConditionalFact(nameof(IsSupported))] + public void SHA3_256_Empty_Stream() + { + VerifyRepeating("", 0, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_256_Empty_Stream_Async() + { + await VerifyRepeatingAsync("", 0, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"); + } + + [ConditionalFact(nameof(IsSupported))] + public void SHA3_256_VerifyLargeStream_MultipleOf4096() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl dgst -sha3-256 + VerifyRepeating( + "0102030405060708", + 1024, + "5e80dd4330d9124adce40a043f166d7e0f6853050fd99919c7b1436ee0a538e9"); + } + + [ConditionalFact(nameof(IsSupported))] + public void SHA3_256_VerifyLargeStream_NotMultipleOf4096() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl dgst -sha3-256 + VerifyRepeating( + "0102030405060708", + 1025, + "5dbbd15ba5745412a79835cc4bec1bede925da06eca7a5bbf50c38a6ec1c49bc"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_256_VerifyLargeStream_NotMultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl dgst -sha3-256 + await VerifyRepeatingAsync( + "0102030405060708", + 1025, + "5dbbd15ba5745412a79835cc4bec1bede925da06eca7a5bbf50c38a6ec1c49bc"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_256_VerifyLargeStream_MultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl dgst -sha3-256 + await VerifyRepeatingAsync( + "0102030405060708", + 1024, + "5e80dd4330d9124adce40a043f166d7e0f6853050fd99919c7b1436ee0a538e9"); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs index 75b107a5389ebe..6436c9d6717eb4 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs @@ -54,6 +54,68 @@ public void SHA3_384_Kats() } } + [ConditionalFact(nameof(IsSupported))] + public void SHA3_384_Empty_Stream() + { + VerifyRepeating( + "", + 0, + "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_384_Empty_Stream_Async() + { + await VerifyRepeatingAsync( + "", + 0, + "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"); + } + + [ConditionalFact(nameof(IsSupported))] + public void SHA3_384_VerifyLargeStream_MultipleOf4096() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl dgst -sha3-384 + VerifyRepeating( + "0102030405060708", + 1024, + "0aa96c328926f2faa796dc75a104e200f5b497beb0313e8822b471efebbb39cef02687e33787883a87c18f35856dcad1"); + } + + [ConditionalFact(nameof(IsSupported))] + public void SHA3_384_VerifyLargeStream_NotMultipleOf4096() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl dgst -sha3-384 + VerifyRepeating( + "0102030405060708", + 1025, + "e2d1714c8011e7b90550123006128d90fa464cb71903e4aa67342bc8780eb43ae099a2d8610e0ba3061f4f3792d344a7"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_384_VerifyLargeStream_NotMultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl dgst -sha3-384 + await VerifyRepeatingAsync( + "0102030405060708", + 1025, + "e2d1714c8011e7b90550123006128d90fa464cb71903e4aa67342bc8780eb43ae099a2d8610e0ba3061f4f3792d344a7"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_384_VerifyLargeStream_MultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl dgst -sha3-384 + await VerifyRepeatingAsync( + "0102030405060708", + 1024, + "0aa96c328926f2faa796dc75a104e200f5b497beb0313e8822b471efebbb39cef02687e33787883a87c18f35856dcad1"); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs index e1b12974508cdd..567eb6ef17e68f 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs @@ -54,6 +54,68 @@ public void SHA3_512_Kats() } } + [ConditionalFact(nameof(IsSupported))] + public void SHA3_512_Empty_Stream() + { + VerifyRepeating( + "", + 0, + "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_512_Empty_Stream_Async() + { + await VerifyRepeatingAsync( + "", + 0, + "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"); + } + + [ConditionalFact(nameof(IsSupported))] + public void SHA3_512_VerifyLargeStream_MultipleOf4096() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl dgst -sha3-512 + VerifyRepeating( + "0102030405060708", + 1024, + "b5ec7fe7061c944b65f42a3193ebafcc3b35f063dc2ac7a5af05140b2439c425e4d9e63bc97103f704a7b6849a1986cec743ac288ca2f123e82c0ce60b714615"); + } + + [ConditionalFact(nameof(IsSupported))] + public void SHA3_512_VerifyLargeStream_NotMultipleOf4096() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl dgst -sha3-512 + VerifyRepeating( + "0102030405060708", + 1025, + "ea418b3d279a9b25ddc6f8a294006c63068cbd4b872163365f7d11f6f287c8291adc0e3b77999db9606a40c989d7eca405247162104feec1d5a46e59404692a2"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_512_VerifyLargeStream_NotMultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1025}; do echo -n "0102030405060708"; done | openssl dgst -sha3-512 + await VerifyRepeatingAsync( + "0102030405060708", + 1025, + "ea418b3d279a9b25ddc6f8a294006c63068cbd4b872163365f7d11f6f287c8291adc0e3b77999db9606a40c989d7eca405247162104feec1d5a46e59404692a2"); + } + + [ConditionalFact(nameof(IsSupported))] + public async Task SHA3_512_VerifyLargeStream_MultipleOf4096_Async() + { + // Verfied with: + // for _ in {1..1024}; do echo -n "0102030405060708"; done | openssl dgst -sha3-512 + await VerifyRepeatingAsync( + "0102030405060708", + 1024, + "b5ec7fe7061c944b65f42a3193ebafcc3b35f063dc2ac7a5af05140b2439c425e4d9e63bc97103f704a7b6849a1986cec743ac288ca2f123e82c0ce60b714615"); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get From 14bc9a0b33d72c3ca27fa79aecbaeb031c953eb2 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 30 Mar 2023 11:22:55 -0400 Subject: [PATCH 23/47] Only ask CNG if supported for SHA3 --- .../Cryptography/HashProviderDispenser.Windows.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs index 2b13f4ae33ac4b..f6ae0f97eb2307 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs @@ -38,10 +38,14 @@ internal static bool HashSupported(string hashAlgorithmId) case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: return true; - default: + case HashAlgorithmNames.SHA3_256: + case HashAlgorithmNames.SHA3_384: + case HashAlgorithmNames.SHA3_512: return BCryptAlgorithmCache.IsBCryptAlgorithmSupported( hashAlgorithmId, BCryptOpenAlgorithmProviderFlags.None); + default: + return false; } } @@ -56,10 +60,14 @@ internal static bool MacSupported(string hashAlgorithmId) case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: return true; - default: + case HashAlgorithmNames.SHA3_256: + case HashAlgorithmNames.SHA3_384: + case HashAlgorithmNames.SHA3_512: return BCryptAlgorithmCache.IsBCryptAlgorithmSupported( hashAlgorithmId, BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG); + default: + return false; } } From b1a27c462e797e53f45151b4e889ba0e3e28f053 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 30 Mar 2023 17:10:35 -0400 Subject: [PATCH 24/47] Fix SHA3 availability detection for RSAOpenSsl --- .../tests/RSAOpenSslProvider.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs index 0adcda4bfad5ec..4bb36ab95b2485 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs @@ -23,7 +23,10 @@ public class RSAOpenSslProvider : IRSAProvider public bool SupportsSha1Signatures => _supportsSha1Signatures ??= SignatureSupport.CanProduceSha1Signature(Create()); - public bool SupportsSha3 => SHA3_256.IsSupported; // If SHA3_256 is supported, assume 384 and 512 are, too. + // We specifically need to ask OpenSSL about support, not the platform, since OpenSSL may be used on platforms + // which is not the native crypto implementation, such as macOS. + private const int OpenSslSha3Minimum = 0x1_01_01_00_F; //major_minor_fix_patch_status + public bool SupportsSha3 => SafeEvpPKeyHandle.OpenSslVersion >= OpenSslSha3Minimum; } public partial class RSAFactory From bb13b32810b93857d85955eaffdb285d3265637b Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 31 Mar 2023 09:41:00 -0400 Subject: [PATCH 25/47] Revert "Fix SHA3 availability detection for RSAOpenSsl" This reverts commit daf96b8b1b094dd01947835358ff5503d52dcc08. --- .../tests/RSAOpenSslProvider.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs index 4bb36ab95b2485..0adcda4bfad5ec 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RSAOpenSslProvider.cs @@ -23,10 +23,7 @@ public class RSAOpenSslProvider : IRSAProvider public bool SupportsSha1Signatures => _supportsSha1Signatures ??= SignatureSupport.CanProduceSha1Signature(Create()); - // We specifically need to ask OpenSSL about support, not the platform, since OpenSSL may be used on platforms - // which is not the native crypto implementation, such as macOS. - private const int OpenSslSha3Minimum = 0x1_01_01_00_F; //major_minor_fix_patch_status - public bool SupportsSha3 => SafeEvpPKeyHandle.OpenSslVersion >= OpenSslSha3Minimum; + public bool SupportsSha3 => SHA3_256.IsSupported; // If SHA3_256 is supported, assume 384 and 512 are, too. } public partial class RSAFactory From 733813ca8f4a170e8596ef7d2bf4569c90ed697a Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 31 Mar 2023 10:17:09 -0400 Subject: [PATCH 26/47] Prevent SHA3 usage on RSAOpenSsl for macOS --- .../Security/Cryptography/RSAOpenSsl.cs | 12 ++++ .../RSA/RSAFactory.cs | 1 + .../RSA/SignVerify.cs | 68 ++++++++++++++++--- 3 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs index dc002fdfd59732..34ad612323f2d7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs @@ -873,6 +873,18 @@ private static void ValidatePadding(RSAEncryptionPadding padding) { throw PaddingModeNotSupported(); } + + // If the hash algorithm is not supported by the platform, such as SHA3, then we don't support it for + // RSAOpenSsl, even if OpenSSL itself might support OAEP-SHA3. We use the platform's hashing in some + // places for RSA, regardless of what is implementing RSA. If RSAOpenSsl were used on macOS, then + // there would be some incongruence between what hashes OpenSSL supports and what macOS support. Signing + // for example, always uses the platform's implementation of hashing. + if (padding.Mode == RSAEncryptionPaddingMode.Oaep && + padding.OaepHashAlgorithm.Name is string name && + !HashProviderDispenser.HashSupported(name)) + { + throw new PlatformNotSupportedException(); + } } private static void ValidatePadding(RSASignaturePadding padding) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs index 3d2354ea88a3cc..b13a6ee01d8e41 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactory.cs @@ -45,5 +45,6 @@ public static RSA Create(RSAParameters rsaParameters) public static bool SupportsSha1Signatures => s_provider.SupportsSha1Signatures; public static bool SupportsSha3 => s_provider.SupportsSha3; + public static bool NoSupportsSha3 => !SupportsSha3; } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs index 0bbdd7db7372da..4d5a8ed1da6c26 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs @@ -877,19 +877,10 @@ public void VerifyHashSignature_SHA256_2048() VerifyHashSignature(hashSignature, dataHash, "SHA256", TestData.RSA2048Params); } - [ConditionalTheory] - [InlineData("SHA256")] - [InlineData("SHA384")] - [InlineData("SHA512")] - [InlineData("MD5")] - [InlineData("SHA1")] + [Theory] + [MemberData(nameof(HashAlgorithmNames))] public void PssRoundtrip(string hashAlgorithmName) { - if (!RSAFactory.SupportsSha1Signatures && hashAlgorithmName == "SHA1") - { - throw new SkipTestException("Platform does not support RSA with SHA1 signatures."); - } - RSAParameters privateParameters = TestData.RSA2048Params; RSAParameters publicParameters = new RSAParameters { @@ -1062,6 +1053,38 @@ public void VerifyExpectedSignature_PssSha512() helloSignature); } + [ConditionalTheory(typeof(RSAFactory), nameof(RSAFactory.NoSupportsSha3))] + [InlineData("SHA3-256")] + [InlineData("SHA3-384")] + [InlineData("SHA3-512")] + public void Pkcs1UnsupportedHashAlgorithm(string hashAlgorithm) + { + using (RSA rsa = RSAFactory.Create()) + { + Assert.Throws(() => + SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pkcs1)); + + Assert.Throws(() => + VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pkcs1)); + } + } + + [ConditionalTheory(typeof(RSAFactory), nameof(RSAFactory.NoSupportsSha3))] + [InlineData("SHA3-256")] + [InlineData("SHA3-384")] + [InlineData("SHA3-512")] + public void PssUnsupportedHashAlgorithm(string hashAlgorithm) + { + using (RSA rsa = RSAFactory.Create()) + { + Assert.Throws(() => + SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + + Assert.Throws(() => + VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + } + } + private void VerifyExpectedSignature_Pss( RSAParameters keyParameters, HashAlgorithmName hashAlgorithm, @@ -1314,5 +1337,28 @@ private void SignAndVerify(byte[] data, string hashAlgorithmName, RSAParameters Assert.True(signatureMatched); } } + + public static IEnumerable HashAlgorithmNames + { + get + { + yield return new object[] { HashAlgorithmName.SHA256.Name }; + yield return new object[] { HashAlgorithmName.SHA384.Name }; + yield return new object[] { HashAlgorithmName.SHA512.Name }; + yield return new object[] { HashAlgorithmName.MD5.Name }; + + if (RSAFactory.SupportsSha1Signatures) + { + yield return new object[] { HashAlgorithmName.SHA1.Name }; + } + + if (RSAFactory.SupportsSha3) + { + yield return new object[] { HashAlgorithmName.SHA3_256.Name }; + yield return new object[] { HashAlgorithmName.SHA3_384.Name }; + yield return new object[] { HashAlgorithmName.SHA3_512.Name }; + } + } + } } } From 3d608eb8a17bfbe817ce5b6af7fe985bfa854462 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 31 Mar 2023 17:34:09 -0400 Subject: [PATCH 27/47] Fixup CAPI and add some tests for signatures --- .../RSA/SignVerify.cs | 205 +++++++++++++++++- .../Security/Cryptography/CapiHelper.Unix.cs | 3 + .../RSACryptoServiceProvider.Unix.cs | 21 ++ 3 files changed, 223 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs index 4d5a8ed1da6c26..a3c8b3362c9ae6 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs @@ -504,6 +504,84 @@ public void VerifySignature_SHA256_2048() VerifySignature(signature, TestData.HelloBytes, "SHA256", TestData.RSA2048Params); } + [ConditionalFact(typeof(RSAFactory), nameof(RSAFactory.SupportsSha3))] + public void VerifySignature_SHA3_256_RSA2048() + { + byte[] signature = new byte[] + { + 0x37, 0xfc, 0x5b, 0xa7, 0xcd, 0x72, 0x93, 0x55, 0x43, 0x6f, 0x2c, 0x5c, 0xce, 0x10, 0x20, 0x67, + 0x38, 0xbc, 0x82, 0x65, 0xad, 0x64, 0x41, 0x3d, 0x7b, 0xe1, 0x13, 0x6e, 0xbf, 0x7c, 0x0a, 0xa7, + 0xc7, 0x42, 0x57, 0xf3, 0x75, 0xec, 0xda, 0xf1, 0xa0, 0xeb, 0x6d, 0x61, 0x04, 0x07, 0x4b, 0x3c, + 0xf8, 0x0d, 0x1d, 0x7a, 0xb2, 0x1f, 0xb1, 0xa4, 0xae, 0x35, 0x85, 0x18, 0xe4, 0xe1, 0xa5, 0x66, + 0x3d, 0x0c, 0xcd, 0x60, 0xf6, 0x6c, 0x89, 0xf6, 0x49, 0x87, 0x19, 0x3a, 0xa2, 0x24, 0x8a, 0xd9, + 0x17, 0x58, 0x2e, 0x50, 0x69, 0xd4, 0xae, 0x92, 0x17, 0xc1, 0xf8, 0x8e, 0xae, 0xca, 0x05, 0xc0, + 0x9c, 0x9d, 0xda, 0x0c, 0x82, 0x16, 0xae, 0xa4, 0x73, 0xe7, 0x65, 0x90, 0xb9, 0x25, 0x89, 0xe8, + 0xae, 0x60, 0x74, 0x86, 0x2e, 0xd6, 0xa8, 0x8a, 0x05, 0xda, 0x6c, 0x2e, 0x3f, 0x32, 0x24, 0x84, + 0x23, 0x87, 0x10, 0x5b, 0x42, 0x79, 0xdd, 0x64, 0x2c, 0xe4, 0x60, 0x75, 0x38, 0x2b, 0x37, 0x43, + 0x1c, 0x9b, 0x75, 0x6a, 0xf2, 0xfa, 0xbf, 0x95, 0x7f, 0xdb, 0x64, 0xe0, 0xa6, 0xc0, 0xb1, 0x24, + 0xcb, 0xf9, 0xdc, 0x30, 0xcd, 0xba, 0x54, 0x9a, 0xd4, 0xea, 0x3d, 0xcf, 0x3b, 0x08, 0x97, 0x19, + 0xdd, 0xc1, 0xf0, 0x20, 0xf6, 0x02, 0x7c, 0x0e, 0x0c, 0x84, 0x70, 0x89, 0x78, 0x5c, 0x50, 0xc5, + 0xce, 0xe5, 0xdd, 0x03, 0xf4, 0xc5, 0x86, 0x0e, 0xb7, 0x98, 0xd5, 0x96, 0x98, 0x2e, 0x02, 0xc9, + 0xb0, 0x41, 0x84, 0xa9, 0xa1, 0xda, 0x75, 0x81, 0x1d, 0x5a, 0x6a, 0x00, 0x33, 0x0f, 0x94, 0xa4, + 0x20, 0x0c, 0x91, 0xae, 0xae, 0xa4, 0xd3, 0xa8, 0x95, 0x20, 0x5c, 0x0c, 0x3b, 0x6e, 0x32, 0x7e, + 0xd3, 0x5b, 0xf4, 0x9b, 0x0c, 0xe2, 0x97, 0xd4, 0x1c, 0xf7, 0x98, 0x96, 0x77, 0xda, 0x05, 0xf5, + }; + + VerifySignature(signature, TestData.HelloBytes, HashAlgorithmName.SHA3_256.Name, TestData.RSA2048Params); + } + + [ConditionalFact(typeof(RSAFactory), nameof(RSAFactory.SupportsSha3))] + public void VerifySignature_SHA3_384_RSA2048() + { + byte[] signature = new byte[] + { + 0x96, 0x76, 0xdf, 0xa3, 0xd3, 0xac, 0x74, 0x08, 0x18, 0x41, 0x0a, 0xa1, 0x03, 0x6b, 0x28, 0x5d, + 0xf8, 0xf7, 0xe5, 0x72, 0xe1, 0x7e, 0xb0, 0x11, 0x2f, 0x91, 0xbf, 0xce, 0xba, 0xa1, 0x4e, 0xfa, + 0x6f, 0x20, 0xaa, 0xc7, 0x8d, 0xf4, 0x8a, 0xba, 0xd3, 0xa3, 0x07, 0xa0, 0x0f, 0x09, 0x44, 0x7d, + 0xcc, 0xa1, 0x7b, 0xe4, 0x17, 0xcb, 0xe9, 0xe0, 0x78, 0xff, 0xd0, 0xf2, 0xdf, 0xd1, 0xdb, 0xd3, + 0x4a, 0xfb, 0xa8, 0x11, 0xac, 0xd3, 0x27, 0xcc, 0x05, 0x59, 0xc8, 0x16, 0x5d, 0x15, 0x68, 0x4d, + 0x20, 0x17, 0xd2, 0x52, 0xa1, 0xee, 0x7f, 0xce, 0xdb, 0xd4, 0x1a, 0x18, 0x6a, 0xc1, 0x2e, 0x42, + 0x74, 0xcd, 0xc8, 0x31, 0x92, 0x24, 0x33, 0x7e, 0x41, 0x0b, 0x16, 0xf3, 0xd4, 0xa0, 0x30, 0x78, + 0x8e, 0x3a, 0x05, 0xfa, 0xcb, 0x5b, 0x9f, 0x71, 0xd4, 0xfb, 0x27, 0x17, 0x19, 0x66, 0xe1, 0x05, + 0x6d, 0x3a, 0xd8, 0x89, 0x27, 0x19, 0x4f, 0x28, 0x3f, 0x6c, 0xb9, 0xfe, 0xca, 0xfb, 0x77, 0xcc, + 0xf1, 0x46, 0x2a, 0x3a, 0x74, 0x17, 0x8a, 0xb1, 0x76, 0x3a, 0x1b, 0xc3, 0x2e, 0x29, 0x29, 0xa6, + 0xeb, 0x1e, 0xf5, 0x3d, 0x4a, 0x41, 0x39, 0x49, 0xc3, 0x87, 0xe6, 0xcb, 0x49, 0x81, 0x8c, 0xa9, + 0x8a, 0xd8, 0xf5, 0x9e, 0x1c, 0x96, 0x8f, 0xac, 0xc4, 0xac, 0xd3, 0x1b, 0x7a, 0x09, 0x33, 0x48, + 0x62, 0xcc, 0x13, 0x3b, 0xb6, 0x9c, 0x20, 0x55, 0xb3, 0x3c, 0x0b, 0x77, 0xc5, 0x0e, 0x3d, 0x26, + 0x41, 0x15, 0xbf, 0xf7, 0xea, 0xdf, 0x44, 0x9c, 0x35, 0x0b, 0xca, 0x2e, 0x6e, 0xac, 0x04, 0x34, + 0x52, 0x18, 0x68, 0xa0, 0xc8, 0x3b, 0x51, 0xfb, 0x67, 0xed, 0x89, 0x29, 0x1e, 0xe4, 0xfe, 0xb3, + 0x78, 0xb1, 0x40, 0xe3, 0xd3, 0x53, 0xf4, 0x3e, 0xa5, 0x07, 0x33, 0x83, 0xf7, 0x02, 0x39, 0x1b, + }; + + VerifySignature(signature, TestData.HelloBytes, HashAlgorithmName.SHA3_384.Name, TestData.RSA2048Params); + } + + [ConditionalFact(typeof(RSAFactory), nameof(RSAFactory.SupportsSha3))] + public void VerifySignature_SHA3_512_RSA2048() + { + byte[] signature = new byte[] + { + 0x18, 0x83, 0xab, 0x01, 0xc1, 0xaf, 0x98, 0xa9, 0xc2, 0xde, 0x2d, 0x63, 0x4f, 0x8a, 0xf6, 0x47, + 0xd9, 0xd2, 0xd1, 0xa0, 0x5b, 0xf4, 0x14, 0x6a, 0x49, 0x14, 0x56, 0x90, 0x63, 0xf9, 0x2c, 0xf6, + 0xed, 0xc2, 0x19, 0x65, 0x80, 0x0b, 0xa9, 0x7a, 0xa9, 0xcc, 0x00, 0x93, 0xdc, 0x8c, 0xcd, 0xef, + 0xa1, 0x76, 0x4c, 0x56, 0x8c, 0x36, 0x25, 0xcb, 0xbe, 0xd2, 0xbf, 0x49, 0xe6, 0xac, 0xbe, 0x50, + 0x52, 0xf8, 0xd0, 0xf9, 0xb0, 0xcb, 0xfb, 0xae, 0x41, 0x8b, 0x94, 0xbc, 0x47, 0xee, 0x71, 0x1d, + 0x9e, 0x4b, 0xcc, 0x6b, 0xe2, 0x66, 0x01, 0x92, 0x16, 0x06, 0x43, 0x64, 0x65, 0x19, 0x3a, 0xed, + 0x5f, 0x60, 0x85, 0xb1, 0xa8, 0x29, 0x76, 0x17, 0x2d, 0xb3, 0xc5, 0xee, 0x6d, 0x76, 0xef, 0x14, + 0xf8, 0x47, 0x8b, 0x35, 0x32, 0x4e, 0x8f, 0x79, 0xa8, 0x02, 0xe1, 0xe6, 0x49, 0xda, 0x50, 0x98, + 0xd7, 0xb9, 0x71, 0xf6, 0x9d, 0x9b, 0xcd, 0xb6, 0x0d, 0xd3, 0xc8, 0x9d, 0xf2, 0xac, 0xfa, 0xad, + 0xd4, 0xb6, 0xc2, 0x72, 0x9f, 0x14, 0xce, 0x24, 0x87, 0x68, 0x47, 0x6d, 0x7a, 0x73, 0xce, 0x67, + 0xb2, 0xd5, 0x07, 0x69, 0x0d, 0xc3, 0xdd, 0xb4, 0xc2, 0x56, 0xbc, 0x10, 0xc2, 0xe5, 0x9d, 0xb3, + 0xf9, 0x4d, 0xcd, 0xef, 0x9f, 0xe3, 0x3b, 0x8c, 0x49, 0xdf, 0x4b, 0x1f, 0xc0, 0x0c, 0x2d, 0xf6, + 0xad, 0x6c, 0x0f, 0x83, 0x5c, 0x74, 0xb0, 0xff, 0x95, 0x7f, 0x37, 0x34, 0x7b, 0x07, 0x50, 0x91, + 0x7f, 0xd2, 0x26, 0x39, 0x1f, 0xad, 0x72, 0x8a, 0x47, 0x2e, 0x6c, 0xb4, 0xf2, 0xcd, 0x09, 0xfd, + 0x1b, 0xca, 0xf6, 0xbe, 0x70, 0x14, 0xe8, 0x51, 0x1e, 0xf4, 0x5b, 0xd9, 0x57, 0xa6, 0x73, 0xe2, + 0xa0, 0xde, 0xc4, 0x67, 0x7a, 0x4a, 0xe2, 0x24, 0x64, 0x79, 0xd5, 0xe7, 0x39, 0xfc, 0xb2, 0xd9, + }; + + VerifySignature(signature, TestData.HelloBytes, HashAlgorithmName.SHA3_512.Name, TestData.RSA2048Params); + } + [Theory] [MemberData(nameof(RoundTripTheories))] public void SignAndVerify_Roundtrip(string hashAlgorithm, RSAParameters rsaParameters) @@ -1053,6 +1131,102 @@ public void VerifyExpectedSignature_PssSha512() helloSignature); } + [ConditionalFact(typeof(RSAFactory), nameof(RSAFactory.SupportsSha3))] + public void VerifyExpectedSignature_PssSha3_256() + { + // Signature independently created with + // echo -n Hello | openssl dgst -sha3-256 -binary | openssl pkeyutl -sign -inkey key.pem -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha3-256 | xxd -i -c 16 + byte[] helloSignature = + { + 0x0b, 0x02, 0x36, 0x0c, 0x56, 0x6b, 0x93, 0xa8, 0x4e, 0x4d, 0x0e, 0xa3, 0x67, 0x28, 0xc6, 0xea, + 0xdb, 0x05, 0xc8, 0x63, 0x64, 0xe5, 0xec, 0xf9, 0xc1, 0x25, 0x5a, 0x34, 0xe6, 0x3f, 0xe1, 0x38, + 0x49, 0x45, 0x0b, 0x34, 0x6b, 0xa7, 0x91, 0xe1, 0x22, 0xe0, 0x2c, 0x8d, 0x46, 0x23, 0x38, 0xb1, + 0x9e, 0x4c, 0xf3, 0xa0, 0xff, 0x57, 0x96, 0x01, 0xbb, 0xa4, 0x0f, 0x03, 0x27, 0xaf, 0x8e, 0x99, + 0x5e, 0x0e, 0x99, 0xfd, 0xc6, 0x55, 0x81, 0x65, 0x56, 0x83, 0x2d, 0x42, 0xa3, 0x60, 0xc3, 0x36, + 0x69, 0xb4, 0x39, 0x04, 0x70, 0xfe, 0x26, 0x9b, 0x65, 0x6a, 0x15, 0xaa, 0xfc, 0xc5, 0x70, 0x71, + 0xba, 0x01, 0x49, 0xae, 0x27, 0xd4, 0x52, 0x28, 0xe4, 0xce, 0x37, 0x8a, 0x7d, 0x16, 0x2f, 0x59, + 0x3a, 0x1d, 0x36, 0x44, 0x82, 0xba, 0x51, 0xa3, 0x2c, 0xf9, 0x7e, 0xad, 0x36, 0xd4, 0x24, 0xfb, + 0x77, 0xae, 0x55, 0x10, 0x6e, 0xbc, 0x9d, 0xc8, 0xd7, 0xf4, 0x2b, 0x07, 0x70, 0x20, 0x8e, 0xd4, + 0xc6, 0xb3, 0x7f, 0x72, 0x9e, 0xa7, 0x0e, 0xd5, 0x31, 0x5d, 0x8c, 0x0c, 0xca, 0xae, 0x5a, 0x5a, + 0x38, 0x10, 0x42, 0x9f, 0x4f, 0x64, 0xc8, 0xe3, 0xdb, 0x4c, 0x17, 0x0b, 0x7b, 0x97, 0x82, 0x1f, + 0x9c, 0x88, 0xcf, 0x5e, 0xe7, 0x19, 0x8f, 0xa9, 0x5f, 0xd0, 0x1b, 0x19, 0x21, 0x2a, 0x2d, 0x36, + 0x45, 0x4a, 0xb1, 0x4d, 0xc8, 0xe1, 0x5e, 0x53, 0x24, 0xe1, 0x0b, 0x03, 0x01, 0x5d, 0xd9, 0x8f, + 0xe3, 0x3a, 0xdb, 0x3f, 0xbf, 0xa4, 0x24, 0x16, 0x44, 0x3e, 0x52, 0x5c, 0x6c, 0xfd, 0x2d, 0x0e, + 0x22, 0x69, 0xcf, 0x2a, 0x58, 0x8f, 0xe7, 0x31, 0x88, 0x22, 0xb8, 0x21, 0x68, 0x56, 0x6b, 0xb6, + 0xab, 0x76, 0x81, 0x41, 0x59, 0xb9, 0xe5, 0xc2, 0x61, 0x06, 0xea, 0x9b, 0x5b, 0x57, 0xf7, 0xb0, + }; + + VerifyExpectedSignature_Pss( + TestData.RSA2048Params, + HashAlgorithmName.SHA3_256, + TestData.HelloBytes, + helloSignature); + } + + [ConditionalFact(typeof(RSAFactory), nameof(RSAFactory.SupportsSha3))] + public void VerifyExpectedSignature_PssSha3_384() + { + // Signature independently created with + // echo -n Hello | openssl dgst -sha3-384 -binary | openssl pkeyutl -sign -inkey key.pem -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha3-384 | xxd -i -c 16 + byte[] helloSignature = + { + 0x75, 0x00, 0x1d, 0xa9, 0x3b, 0xfa, 0x79, 0x57, 0x4a, 0x3c, 0x9f, 0xec, 0x7b, 0xa4, 0x1f, 0x17, + 0x3a, 0x32, 0x20, 0x90, 0x62, 0x16, 0x25, 0xae, 0x80, 0x54, 0x71, 0xb0, 0xf5, 0x28, 0x5c, 0x97, + 0xfc, 0x4c, 0x21, 0x18, 0xb0, 0xfb, 0x90, 0xae, 0xca, 0xa6, 0x76, 0xf5, 0x14, 0x7a, 0x23, 0x47, + 0x39, 0x1c, 0xf4, 0x62, 0x23, 0x82, 0x18, 0x72, 0x58, 0x64, 0x9a, 0xe2, 0x3b, 0x4e, 0x5a, 0xe5, + 0xf1, 0x16, 0x77, 0xe4, 0xbe, 0xb5, 0x90, 0x54, 0x34, 0x38, 0x24, 0xe4, 0xe1, 0x59, 0xd2, 0x58, + 0x82, 0xc3, 0x68, 0x95, 0xb0, 0x1a, 0x0e, 0x1a, 0x67, 0x4a, 0x28, 0x1e, 0x7e, 0x5c, 0x67, 0xd2, + 0x2e, 0x9c, 0xb6, 0x12, 0x29, 0xf4, 0x57, 0x62, 0xaa, 0xf6, 0x46, 0x00, 0x90, 0xee, 0xc1, 0xb8, + 0x06, 0x40, 0x41, 0x8d, 0xc4, 0x69, 0x68, 0x75, 0xc5, 0xfc, 0xbc, 0x73, 0x40, 0x7c, 0xd6, 0xef, + 0xd0, 0x28, 0xe7, 0x32, 0x52, 0x34, 0x2d, 0x43, 0xca, 0xb8, 0x1e, 0x80, 0x07, 0x1c, 0xe6, 0x54, + 0xd9, 0x03, 0x06, 0xc0, 0xc7, 0x1a, 0x5a, 0xaf, 0x1a, 0xf3, 0xaa, 0xce, 0xa4, 0x02, 0xff, 0xf5, + 0xed, 0x7e, 0x0b, 0x2a, 0x68, 0x7d, 0x65, 0x98, 0xf4, 0xf4, 0x82, 0x3f, 0x54, 0x2a, 0x18, 0x02, + 0xf9, 0x3e, 0x3d, 0xed, 0x18, 0x98, 0xd5, 0xb2, 0x5f, 0x7f, 0xee, 0x26, 0xa1, 0x8f, 0xf5, 0x39, + 0x97, 0xeb, 0x71, 0x18, 0xf1, 0x3c, 0x10, 0x49, 0x34, 0x2e, 0xa8, 0x92, 0x50, 0x17, 0xb7, 0x91, + 0x6b, 0x66, 0x67, 0x2b, 0xd1, 0x73, 0x0b, 0x73, 0xa3, 0xc5, 0xef, 0x03, 0x70, 0xbc, 0x38, 0x59, + 0x1d, 0x23, 0xa2, 0xf8, 0x2d, 0xae, 0x43, 0xc8, 0x6d, 0x10, 0x2c, 0x56, 0x48, 0x2a, 0xc7, 0xef, + 0xf2, 0x4e, 0x5c, 0x30, 0x75, 0xbc, 0xd3, 0xd6, 0x4c, 0xfd, 0x45, 0xc6, 0x43, 0xca, 0xe8, 0x73, + }; + + VerifyExpectedSignature_Pss( + TestData.RSA2048Params, + HashAlgorithmName.SHA3_384, + TestData.HelloBytes, + helloSignature); + } + + [ConditionalFact(typeof(RSAFactory), nameof(RSAFactory.SupportsSha3))] + public void VerifyExpectedSignature_PssSha3_512() + { + // Signature independently created with + // echo -n Hello | openssl dgst -sha3-512 -binary | openssl pkeyutl -sign -inkey key.pem -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha3-512 | xxd -i -c 16 + byte[] helloSignature = + { + 0x2b, 0x02, 0x93, 0xd1, 0x56, 0x1d, 0x03, 0xce, 0xc7, 0xe0, 0xd0, 0x76, 0xf7, 0xce, 0x76, 0xd7, + 0xd6, 0xf1, 0xeb, 0xc2, 0xc4, 0x97, 0xee, 0x16, 0xdb, 0x04, 0x9c, 0x51, 0xd3, 0xc4, 0x76, 0xcd, + 0xdb, 0x77, 0x3f, 0x82, 0xf1, 0x31, 0x56, 0x77, 0xc8, 0x44, 0xfd, 0x29, 0x42, 0xf0, 0x68, 0x5d, + 0x27, 0x11, 0x74, 0xc1, 0x44, 0x4e, 0x30, 0x6e, 0xfc, 0x3c, 0xa8, 0x61, 0x14, 0x1d, 0x84, 0xec, + 0x92, 0x2c, 0x80, 0xeb, 0x57, 0xd0, 0x81, 0xe7, 0xae, 0xf7, 0x83, 0xe1, 0xe6, 0xfb, 0xc6, 0xed, + 0x5e, 0x0a, 0xd8, 0x67, 0x01, 0xf4, 0xc8, 0x8d, 0x27, 0x7c, 0x5f, 0xff, 0xb7, 0x9d, 0xb4, 0xd4, + 0x70, 0x18, 0xd4, 0x94, 0x7d, 0x36, 0xa7, 0x63, 0xe1, 0xa2, 0x30, 0x53, 0x6a, 0xef, 0x6e, 0xfa, + 0xad, 0xf4, 0xfd, 0xea, 0xba, 0x81, 0xd9, 0x73, 0x75, 0x90, 0xff, 0x98, 0x4c, 0xdb, 0x7d, 0xc6, + 0x91, 0xd9, 0x83, 0xdf, 0x31, 0xa3, 0xb4, 0x05, 0x91, 0xf9, 0xbe, 0x96, 0xfc, 0xed, 0xfd, 0x8b, + 0x8e, 0x9a, 0xee, 0xe5, 0xaf, 0xfd, 0x7e, 0x7e, 0xe0, 0xe1, 0x65, 0xa4, 0xf1, 0xdb, 0x4f, 0x01, + 0x47, 0x00, 0xee, 0x03, 0xb7, 0x96, 0x4c, 0x73, 0xdc, 0x6f, 0xf8, 0xf9, 0xac, 0xce, 0x1e, 0x4b, + 0xb8, 0x3d, 0x5b, 0xd5, 0xea, 0xf1, 0x4b, 0xd9, 0x63, 0x45, 0x2a, 0x49, 0x22, 0x2d, 0x6c, 0xc5, + 0x48, 0xe3, 0x1d, 0xbd, 0x92, 0xed, 0x42, 0x5a, 0x0c, 0xde, 0xb3, 0x2b, 0x91, 0xbd, 0x8e, 0x74, + 0x59, 0x6c, 0x9c, 0x39, 0x24, 0x43, 0xe4, 0x5c, 0xf6, 0x26, 0xd6, 0x30, 0xa0, 0x53, 0xb5, 0x2a, + 0x0d, 0x0d, 0xfc, 0x68, 0xb5, 0xae, 0x8d, 0x7e, 0xdf, 0x45, 0xfc, 0x66, 0x43, 0x93, 0x8d, 0x40, + 0x42, 0x29, 0xe1, 0xe9, 0xe3, 0xff, 0xda, 0xd8, 0x7d, 0x64, 0x9a, 0x26, 0xea, 0xb3, 0xba, 0x7d, + }; + + VerifyExpectedSignature_Pss( + TestData.RSA2048Params, + HashAlgorithmName.SHA3_512, + TestData.HelloBytes, + helloSignature); + } + [ConditionalTheory(typeof(RSAFactory), nameof(RSAFactory.NoSupportsSha3))] [InlineData("SHA3-256")] [InlineData("SHA3-384")] @@ -1061,11 +1235,19 @@ public void Pkcs1UnsupportedHashAlgorithm(string hashAlgorithm) { using (RSA rsa = RSAFactory.Create()) { - Assert.Throws(() => + Exception ex = Assert.ThrowsAny(() => SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pkcs1)); - Assert.Throws(() => + Assert.True( + ex is PlatformNotSupportedException or CryptographicException, + "ex is PlatformNotSupportedException or CryptographicException"); + + ex = Assert.ThrowsAny(() => VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pkcs1)); + + Assert.True( + ex is PlatformNotSupportedException or CryptographicException, + "ex is PlatformNotSupportedException or CryptographicException"); } } @@ -1077,11 +1259,22 @@ public void PssUnsupportedHashAlgorithm(string hashAlgorithm) { using (RSA rsa = RSAFactory.Create()) { - Assert.Throws(() => - SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + if (RSAFactory.SupportsPss) + { + Assert.Throws(() => + SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); - Assert.Throws(() => - VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + Assert.Throws(() => + VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + } + else + { + Assert.ThrowsAny(() => + SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + + Assert.ThrowsAny(() => + VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs index 831b76f1f07a14..b11ecc91e4c62a 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs @@ -37,6 +37,7 @@ internal static HashAlgorithmName NameOrOidToHashAlgorithmName(string? nameOrOid ///
private static HashAlgorithmName AlgorithmToHashAlgorithmName(HashAlgorithm hashAlgorithm) { + // CAPI CSP doesn't support SHA-3, so don't add it here. return hashAlgorithm switch { SHA256 => HashAlgorithmName.SHA256, @@ -50,6 +51,7 @@ private static HashAlgorithmName AlgorithmToHashAlgorithmName(HashAlgorithm hash private static HashAlgorithmName OidToHashAlgorithmName(string oid) { + // CAPI CSP doesn't support SHA-3, so don't add it here. return oid switch { Oids.Sha256 => HashAlgorithmName.SHA256, @@ -63,6 +65,7 @@ private static HashAlgorithmName OidToHashAlgorithmName(string oid) private static HashAlgorithmName HashAlgorithmTypeToHashAlgorithmName(Type hashAlgType) { + // CAPI CSP doesn't support SHA-3, so don't add it here. if (typeof(SHA1).IsAssignableFrom(hashAlgType)) return HashAlgorithmName.SHA1; if (typeof(SHA256).IsAssignableFrom(hashAlgType)) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs index e6977e2e67e83f..cbbfedcdb9c2f6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs @@ -183,6 +183,8 @@ public override byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm, RS throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.SignData(data, hashAlgorithm, padding); } @@ -195,6 +197,8 @@ public override byte[] SignData(byte[] data, int offset, int count, HashAlgorith throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.SignData(data, offset, count, hashAlgorithm, padding); } @@ -207,6 +211,8 @@ public override bool TrySignData(ReadOnlySpan data, Span destination throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.TrySignData(data, destination, hashAlgorithm, padding, out bytesWritten); } @@ -228,6 +234,8 @@ public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RS throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.SignHash(hash, hashAlgorithm, padding); } @@ -240,6 +248,8 @@ public override bool TrySignHash(ReadOnlySpan hash, Span destination throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.TrySignHash(hash, destination, hashAlgorithm, padding, out bytesWritten); } @@ -345,5 +355,16 @@ private static bool IsPublic(byte[] keyBlob) return true; } + + private static void CheckSHA3HashAlgorithm(HashAlgorithmName hashAlgorithm) + { + if (hashAlgorithm == HashAlgorithmName.SHA3_256 || + hashAlgorithm == HashAlgorithmName.SHA3_384 || + hashAlgorithm == HashAlgorithmName.SHA3_512) + { + // Compat: Windows throws CryptographicException for SHA-3 HashAlgorithmName. So we will here, too. + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + } + } } } From f459f6311992051726f600aedbc672b9766c720c Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 31 Mar 2023 20:43:03 -0400 Subject: [PATCH 28/47] Fix verify for CryptoServiceProvider, too --- .../Security/Cryptography/RSACryptoServiceProvider.Unix.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs index cbbfedcdb9c2f6..7789143feb5b82 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs @@ -278,6 +278,8 @@ public override bool VerifyData(byte[] data, int offset, int count, byte[] signa throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.VerifyData(data, offset, count, signature, hashAlgorithm, padding); } @@ -290,6 +292,8 @@ public override bool VerifyData(ReadOnlySpan data, ReadOnlySpan sign throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.VerifyData(data, signature, hashAlgorithm, padding); } @@ -310,6 +314,8 @@ public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan sign throw PaddingModeNotSupported(); } + CheckSHA3HashAlgorithm(hashAlgorithm); + return _impl.VerifyHash(hash, signature, hashAlgorithm, padding); } From 4ae22beb983e65fea1c494dd42fcdbb282c64579 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sat, 1 Apr 2023 12:12:53 -0400 Subject: [PATCH 29/47] Make PSS as forgiving as PKCS1 --- .../RSA/SignVerify.cs | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs index a3c8b3362c9ae6..6b0fd33bf89e7b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs @@ -1259,22 +1259,19 @@ public void PssUnsupportedHashAlgorithm(string hashAlgorithm) { using (RSA rsa = RSAFactory.Create()) { - if (RSAFactory.SupportsPss) - { - Assert.Throws(() => - SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + Exception ex = Assert.ThrowsAny(() => + SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); - Assert.Throws(() => - VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); - } - else - { - Assert.ThrowsAny(() => - SignData(rsa, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + Assert.True( + ex is CryptographicException or PlatformNotSupportedException, + "ex is CryptographicException or PlatformNotSupportedException"); - Assert.ThrowsAny(() => - VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); - } + ex = Assert.ThrowsAny(() => + VerifyData(rsa, new byte[] { 1 }, new byte[] { 1 }, new HashAlgorithmName(hashAlgorithm), RSASignaturePadding.Pss)); + + Assert.True( + ex is CryptographicException or PlatformNotSupportedException, + "ex is CryptographicException or PlatformNotSupportedException"); } } From c178ca039185bd3f77bff5b409d688adefb60f4f Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sat, 1 Apr 2023 14:36:51 -0400 Subject: [PATCH 30/47] Add HMAC and hash tests for ECDH with SHA-3 --- .../ECDiffieHellman/ECDiffieHellmanFactory.cs | 3 + .../ECDiffieHellmanTests.Hash.cs | 105 +++++++++----- .../ECDiffieHellmanTests.Hmac.cs | 134 +++++++++++------- .../tests/ECDiffieHellmanCngProvider.cs | 1 + .../tests/EcDiffieHellmanOpenSslProvider.cs | 1 + .../DefaultECDiffieHellmanProvider.Android.cs | 2 + .../DefaultECDiffieHellmanProvider.Unix.cs | 1 + .../DefaultECDiffieHellmanProvider.Windows.cs | 1 + 8 files changed, 161 insertions(+), 87 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs index 6497640809f3ab..84bbea4587eef4 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs @@ -14,6 +14,7 @@ public interface IECDiffieHellmanProvider bool ExplicitCurvesSupported { get; } bool CanDeriveNewPublicKey { get; } bool SupportsRawDerivation { get; } + bool SupportsSha3 { get; } } public static partial class ECDiffieHellmanFactory @@ -45,5 +46,7 @@ public static bool IsCurveValid(Oid oid) public static bool CanDeriveNewPublicKey => s_provider.CanDeriveNewPublicKey; public static bool SupportsRawDerivation => s_provider.SupportsRawDerivation; + + public static bool SupportsSha3 => s_provider.SupportsSha3; } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs index dfca203f4fa14c..0065092e52aad1 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs @@ -207,56 +207,87 @@ public static void DeriveKeyMaterialEquivalentToDeriveKeyFromHash() public static IEnumerable HashDerivationTestCases() { - return new object[][] + yield return new object[] { - new object[] - { - HashAlgorithmName.SHA256, - null, - null, - "595B71C33D9D40ACD9CA847C47267DAEE7498EEF0B553482FAA45791418AC679", - }, + HashAlgorithmName.SHA256, + null, + null, + "595B71C33D9D40ACD9CA847C47267DAEE7498EEF0B553482FAA45791418AC679", + }; - new object[] - { - HashAlgorithmName.SHA1, - null, - null, - "25E464FAC33F4A5F8786627FB3685F4C31B26327", - }, + yield return new object[] + { + HashAlgorithmName.SHA1, + null, + null, + "25E464FAC33F4A5F8786627FB3685F4C31B26327", + }; - new object[] - { - HashAlgorithmName.SHA256, - "02040608", - null, - "D0F4C42D61E794E508A079822F3069C9F89D9E3385C8E090425FF38927798017", - }, + yield return new object[] + { + HashAlgorithmName.SHA256, + "02040608", + null, + "D0F4C42D61E794E508A079822F3069C9F89D9E3385C8E090425FF38927798017", + }; + + yield return new object[] + { + HashAlgorithmName.SHA256, + null, + "010305", + "20DCB58E2AC4E70B1BF47362B0D1C8B728E27D6575EA9B85106CBE05E1F7D6DB", + }; - new object[] + yield return new object[] + { + HashAlgorithmName.SHA256, + "02040608", + "010305", + "EFC758D39896E9DE96C120B0A74FB751F140BD7F3F4FC3777DC2A530145E01EC", + }; + + yield return new object[] + { + HashAlgorithmName.SHA256, + "010305", + "02040608", + "7DB5520A5D6351595FC286CD53509D964FBB152C289F072581CB5E16EBF319E8", + }; + + if (ECDiffieHellmanFactory.SupportsSha3) + { + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-256 + yield return new object[] { - HashAlgorithmName.SHA256, - null, + HashAlgorithmName.SHA3_256, "010305", - "20DCB58E2AC4E70B1BF47362B0D1C8B728E27D6575EA9B85106CBE05E1F7D6DB", - }, + "02040608", + "2AF6DA738DADF26607513ECB56451B5A476C7D42CFEC89872791B7A6C136A4F9", + }; - new object[] + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-384 + yield return new object[] { - HashAlgorithmName.SHA256, - "02040608", + HashAlgorithmName.SHA3_384, "010305", - "EFC758D39896E9DE96C120B0A74FB751F140BD7F3F4FC3777DC2A530145E01EC", - }, + "02040608", + "EE9C10A3E60EA06296699195B3E338575DA529BA167A7520CA8BF50C86C4A08AB153DD7B97ADEE58CE5A9CAAC2F52ED1", + }; - new object[] + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-512 + yield return new object[] { - HashAlgorithmName.SHA256, + HashAlgorithmName.SHA3_512, "010305", "02040608", - "7DB5520A5D6351595FC286CD53509D964FBB152C289F072581CB5E16EBF319E8", - }, - }; + "3614398AFC4A09B0490E095A7901FEA3C9C217E742064A371F2E04D6363EF864" + + "FE52EEEEA976FEC3FF98DE55D1E78E864F009FD834E1D301FA069BD44F6ECD52", + }; + } } #if NETCOREAPP diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs index b8ba791ddd7844..f95fb64aafd3a4 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs @@ -248,71 +248,105 @@ public static void SimpleHmacNullKeyForwardsNull() public static IEnumerable HmacDerivationTestCases() { - return new object[][] + yield return new object[] { - new object[] - { - HashAlgorithmName.SHA256, - null, - null, - null, - "6D7D15C9A08FD47DFDABD3541BE3BBAF93B15FC65D30E6012CCC0B23ED5C43FF", - }, - - new object[] - { - HashAlgorithmName.SHA1, - null, - null, - null, - "39D4B035BC1A1E4108B965689E27BA98ACED8449", - }, - - new object[] - { - HashAlgorithmName.SHA256, - "030609", - null, - null, - "7A4F81BF065CC521AFB162DB4A45CEFC78227178A58632EA53D3E367AB7D1979", - }, + HashAlgorithmName.SHA256, + null, + null, + null, + "6D7D15C9A08FD47DFDABD3541BE3BBAF93B15FC65D30E6012CCC0B23ED5C43FF", + }; - new object[] - { - HashAlgorithmName.SHA256, - null, - "02040608", - "010305", - "DB39A6AC9334701D2DCD508C401C65BC69348F684C85EDDE506950F049668842", - }, + yield return new object[] + { + HashAlgorithmName.SHA1, + null, + null, + null, + "39D4B035BC1A1E4108B965689E27BA98ACED8449", + }; + + yield return new object[] + { + HashAlgorithmName.SHA256, + "030609", + null, + null, + "7A4F81BF065CC521AFB162DB4A45CEFC78227178A58632EA53D3E367AB7D1979", + }; + + yield return new object[] + { + HashAlgorithmName.SHA256, + null, + "02040608", + "010305", + "DB39A6AC9334701D2DCD508C401C65BC69348F684C85EDDE506950F049668842", + }; - new object[] + yield return new object[] + { + HashAlgorithmName.SHA256, + null, + "010305", + "02040608", + "66471DE2655DF9404636F9076F845F0B71A04DDA2BA6F1469EB0F2E9EF57DC33", + }; + + yield return new object[] + { + HashAlgorithmName.SHA256, + "030609", + "02040608", + "010305", + "2F7A31FF9118A6BBF92E268568C634A9F1E244CA8C1A74C864DECC50727B7DEE", + }; + + yield return new object[] + { + HashAlgorithmName.SHA256, + "030609", + "010305", + "02040608", + "AE3CD974F262B199B0859D9F933207D2F6E3E04434D60089FE0BE801ED38D370", + }; + + if (ECDiffieHellmanFactory.SupportsSha3) + { + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-256 -mac HMAC -macopt hexkey:030609 + yield return new object[] { - HashAlgorithmName.SHA256, - null, + HashAlgorithmName.SHA3_256, + "030609", "010305", "02040608", - "66471DE2655DF9404636F9076F845F0B71A04DDA2BA6F1469EB0F2E9EF57DC33", - }, + "23E7E5648EF46D537F4159F7F40E686279D89ADFD7EF6CFA110034F42EC8CEF7", + }; - new object[] + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-384 -mac HMAC -macopt hexkey:030609 + yield return new object[] { - HashAlgorithmName.SHA256, + HashAlgorithmName.SHA3_384, "030609", - "02040608", "010305", - "2F7A31FF9118A6BBF92E268568C634A9F1E244CA8C1A74C864DECC50727B7DEE", - }, + "02040608", + "FD0F7B11489F641DE0964F81D83EF90E33C46D1628C51FA79A85AD1034A9CAD36F8A38C3925704AC0E404BC6FE50ECA4", + }; - new object[] + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-512 -mac HMAC -macopt hexkey:030609 + yield return new object[] { - HashAlgorithmName.SHA256, + HashAlgorithmName.SHA3_512, "030609", "010305", "02040608", - "AE3CD974F262B199B0859D9F933207D2F6E3E04434D60089FE0BE801ED38D370", - }, - }; + "2C32BBFBF8A41118AAD3BAA94C8995B5B027246EA3D972937C1BFD9F460C6492" + + "44EEC68EF570B4BB74B0D3BBD463F18526400A77211B5CB39311CDE21104E209", + }; + } } #if NETCOREAPP diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs b/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs index d805dbc6d2b813..1dc38e42bccce8 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs +++ b/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs @@ -36,6 +36,7 @@ public bool ExplicitCurvesSupported public bool CanDeriveNewPublicKey => true; public bool SupportsRawDerivation => PlatformDetection.IsWindows10OrLater; + public bool SupportsSha3 => PlatformDetection.SupportsSha3; private static bool NativeOidFriendlyNameExists(string oidFriendlyName) { diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs b/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs index ef4aa6f83881f5..0a7390c5b250ec 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs @@ -28,6 +28,7 @@ public ECDiffieHellman Create(ECCurve curve) public bool CanDeriveNewPublicKey => true; public bool SupportsRawDerivation => true; + public bool SupportsSha3 => PlatformDetection.SupportsSha3; } public partial class ECDiffieHellmanFactory diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Android.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Android.cs index 93c0237a8f6cb6..86c09ad26915d9 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Android.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Android.cs @@ -23,6 +23,8 @@ public bool IsCurveValid(Oid oid) public bool SupportsRawDerivation => true; + public bool SupportsSha3 => false; + private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue) { if (string.IsNullOrEmpty(friendlyNameOrValue)) diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs index d00c95b27eaffa..162831d72ac696 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs @@ -36,6 +36,7 @@ public bool ExplicitCurvesSupported public bool CanDeriveNewPublicKey { get; } = !PlatformDetection.IsiOS && !PlatformDetection.IstvOS && !PlatformDetection.IsMacCatalyst; public bool SupportsRawDerivation => true; + public bool SupportsSha3 => PlatformDetection.SupportsSha3; private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue) { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs index 49f8ff15761e17..71471a532acdb3 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs @@ -24,6 +24,7 @@ public bool ExplicitCurvesSupported public bool CanDeriveNewPublicKey => true; public bool SupportsRawDerivation => PlatformDetection.IsWindows10OrLater; + public bool SupportsSha3 => PlatformDetection.SupportsSha3; private static bool NativeOidFriendlyNameExists(string oidFriendlyName) { From 81071fd9527f3cf62e078da2f37e7abe42337fec Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 12 Apr 2023 20:51:05 -0400 Subject: [PATCH 31/47] Code review feedback --- .../src/System/Security/Cryptography/Oids.cs | 6 +-- .../Security/Cryptography/HMACCommon.cs | 40 ++++++++++++++----- .../Security/Cryptography/IncrementalHash.cs | 21 ++++++++++ .../RSAPkcs1X509SignatureGenerator.cs | 6 +-- .../tests/IncrementalHashTests.cs | 16 ++++++++ 5 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Oids.cs b/src/libraries/Common/src/System/Security/Cryptography/Oids.cs index 68e20490d329a8..63c5b1eb105f41 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Oids.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Oids.cs @@ -24,9 +24,9 @@ internal static partial class Oids internal const string RsaPkcs1Sha256 = "1.2.840.113549.1.1.11"; internal const string RsaPkcs1Sha384 = "1.2.840.113549.1.1.12"; internal const string RsaPkcs1Sha512 = "1.2.840.113549.1.1.13"; - internal const string RsaPkcs1Sha3_Sha256 = "2.16.840.1.101.3.4.3.14"; - internal const string RsaPkcs1Sha3_Sha384 = "2.16.840.1.101.3.4.3.15"; - internal const string RsaPkcs1Sha3_Sha512 = "2.16.840.1.101.3.4.3.16"; + internal const string RsaPkcs1Sha3_256 = "2.16.840.1.101.3.4.3.14"; + internal const string RsaPkcs1Sha3_384 = "2.16.840.1.101.3.4.3.15"; + internal const string RsaPkcs1Sha3_512 = "2.16.840.1.101.3.4.3.16"; internal const string Esdh = "1.2.840.113549.1.9.16.3.5"; internal const string EcDiffieHellman = "1.3.132.1.12"; internal const string DiffieHellman = "1.2.840.10046.2.1"; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs index d0d6da13ba1643..25210f555df861 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs @@ -57,17 +57,37 @@ public void ChangeKey(byte[] key) if (key.Length > _blockSize && _blockSize > 0) { // Perform RFC 2104, section 2 key adjustment. - modifiedKey = _hashAlgorithmId switch + switch (_hashAlgorithmId) { - HashAlgorithmNames.SHA256 => SHA256.HashData(key), - HashAlgorithmNames.SHA384 => SHA384.HashData(key), - HashAlgorithmNames.SHA512 => SHA512.HashData(key), - HashAlgorithmNames.SHA3_256 when SHA3_256.IsSupported => SHA3_256.HashData(key), - HashAlgorithmNames.SHA3_384 when SHA3_384.IsSupported => SHA3_384.HashData(key), - HashAlgorithmNames.SHA3_512 when SHA3_512.IsSupported => SHA3_512.HashData(key), - HashAlgorithmNames.SHA1 => SHA1.HashData(key), - HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(key), - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, _hashAlgorithmId)), + case HashAlgorithmNames.SHA256: + modifiedKey = SHA256.HashData(key); + break; + case HashAlgorithmNames.SHA384: + modifiedKey = SHA384.HashData(key); + break; + case HashAlgorithmNames.SHA512: + modifiedKey = SHA512.HashData(key); + break; + case HashAlgorithmNames.SHA3_256: + Debug.Assert(SHA3_256.IsSupported); + modifiedKey = SHA3_256.HashData(key); + break; + case HashAlgorithmNames.SHA3_384: + Debug.Assert(SHA3_384.IsSupported); + modifiedKey = SHA3_384.HashData(key); + break; + case HashAlgorithmNames.SHA3_512: + Debug.Assert(SHA3_512.IsSupported); + modifiedKey = SHA3_512.HashData(key); + break; + case HashAlgorithmNames.SHA1: + modifiedKey = SHA1.HashData(key); + break; + case HashAlgorithmNames.MD5 when Helpers.HasMD5: + modifiedKey = MD5.HashData(key); + break; + default: + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, _hashAlgorithmId)); }; } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs index 904c72c1c28050..022476b0bd3cc7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs @@ -308,6 +308,7 @@ public void Dispose() public static IncrementalHash CreateHash(HashAlgorithmName hashAlgorithm) { ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + CheckSha3Support(hashAlgorithm.Name); return new IncrementalHash(hashAlgorithm, HashProviderDispenser.CreateHashProvider(hashAlgorithm.Name)); } @@ -366,8 +367,28 @@ public static IncrementalHash CreateHMAC(HashAlgorithmName hashAlgorithm, byte[] public static IncrementalHash CreateHMAC(HashAlgorithmName hashAlgorithm, ReadOnlySpan key) { ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + CheckSha3Support(hashAlgorithm.Name); return new IncrementalHash(hashAlgorithm, new HMACCommon(hashAlgorithm.Name, key, -1)); } + + private static void CheckSha3Support(string hashAlgorithmName) + { + switch (hashAlgorithmName) + { + case HashAlgorithmNames.SHA3_256 when !SHA3_256.IsSupported: + Debug.Assert(!HMACSHA3_256.IsSupported); + throw new PlatformNotSupportedException(); + case HashAlgorithmNames.SHA3_384 when !SHA3_384.IsSupported: + Debug.Assert(!HMACSHA3_384.IsSupported); + throw new PlatformNotSupportedException(); + case HashAlgorithmNames.SHA3_512 when !SHA3_512.IsSupported: + Debug.Assert(!HMACSHA3_512.IsSupported); + throw new PlatformNotSupportedException(); + default: + // Other unknown algorithms will be handled separately as CryptographicExceptions. + break; + } + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs index 122d506cfa9b47..f652dae9a722ea 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs @@ -62,15 +62,15 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg } else if (hashAlgorithm == HashAlgorithmName.SHA3_256) { - oid = Oids.RsaPkcs1Sha3_Sha256; + oid = Oids.RsaPkcs1Sha3_256; } else if (hashAlgorithm == HashAlgorithmName.SHA3_384) { - oid = Oids.RsaPkcs1Sha3_Sha384; + oid = Oids.RsaPkcs1Sha3_384; } else if (hashAlgorithm == HashAlgorithmName.SHA3_512) { - oid = Oids.RsaPkcs1Sha3_Sha512; + oid = Oids.RsaPkcs1Sha3_512; } else { diff --git a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs index b744b8f09bc6fc..dc7c33debfa8cd 100644 --- a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs @@ -313,6 +313,22 @@ public static void UnknownHmacAlgorithm() () => IncrementalHash.CreateHMAC(new HashAlgorithmName("SHA0"), Array.Empty())); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.DoesNotSupportSha3))] + [InlineData("SHA3-256")] + [InlineData("SHA3-384")] + [InlineData("SHA3-512")] + public static void UnsupportedAlgorithms(string algorithmName) + { + Assert.Throws(() => + IncrementalHash.CreateHMAC(new HashAlgorithmName(algorithmName), ReadOnlySpan.Empty)); + + Assert.Throws(() => + IncrementalHash.CreateHMAC(new HashAlgorithmName(algorithmName), Array.Empty())); + + Assert.Throws(() => + IncrementalHash.CreateHash(new HashAlgorithmName(algorithmName))); + } + [Theory] [MemberData(nameof(GetHashAlgorithms))] public static void VerifyIncrementalHash_Span(HashAlgorithm referenceAlgorithm, HashAlgorithmName hashAlgorithm) From 630b72d0a87eb30af116c3df7ecbce3df2d43b07 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 12 Apr 2023 21:25:19 -0400 Subject: [PATCH 32/47] More code review feedback --- .../Rfc2898DeriveBytes.OneShot.cs | 26 ++++--------------- .../tests/HmacMD5Tests.cs | 7 +++++ .../tests/HmacSha1Tests.cs | 7 +++++ .../tests/HmacSha256Tests.cs | 7 +++++ .../tests/HmacSha384Tests.cs | 7 +++++ .../tests/HmacSha3_256Tests.cs | 7 +++++ .../tests/HmacSha3_384Tests.cs | 7 +++++ .../tests/HmacSha3_512Tests.cs | 7 +++++ .../tests/HmacSha512Tests.cs | 7 +++++ .../tests/MD5Tests.cs | 7 +++++ .../tests/Sha1Tests.cs | 7 +++++ .../tests/Sha256Tests.cs | 7 +++++ .../tests/Sha384Tests.cs | 7 +++++ .../tests/Sha3_256Tests.cs | 7 +++++ .../tests/Sha3_384Tests.cs | 7 +++++ .../tests/Sha3_512Tests.cs | 7 +++++ .../tests/Sha512Tests.cs | 7 +++++ 17 files changed, 117 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs index ff35cc2099d971..a07718238a6d34 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Rfc2898DeriveBytes.OneShot.cs @@ -331,8 +331,12 @@ private static void ValidateHashAlgorithm(HashAlgorithmName hashAlgorithm) return; } - if (hashAlgorithmName == HashAlgorithmName.SHA3_256.Name) + if (hashAlgorithmName == HashAlgorithmName.SHA3_256.Name || + hashAlgorithmName == HashAlgorithmName.SHA3_384.Name || + hashAlgorithmName == HashAlgorithmName.SHA3_512.Name) { + // All current platforms support HMAC-SHA3-256, 384, and 512 together, so we can simplify the check + // to just checking HMAC-SHA3-256 for the availability of 384 and 512, too. if (HMACSHA3_256.IsSupported) { return; @@ -341,26 +345,6 @@ private static void ValidateHashAlgorithm(HashAlgorithmName hashAlgorithm) throw new PlatformNotSupportedException(); } - if (hashAlgorithmName == HashAlgorithmName.SHA3_384.Name) - { - if (HMACSHA3_384.IsSupported) - { - return; - } - - throw new PlatformNotSupportedException(); - } - - if (hashAlgorithmName == HashAlgorithmName.SHA3_512.Name) - { - if (HMACSHA3_512.IsSupported) - { - return; - } - - throw new PlatformNotSupportedException(); - } - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName)); } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs index b61f5d6d65689b..2adf417aec8458 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs @@ -225,5 +225,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "C91E40247251F39BDFE6A7B72A5857F9"); } + + [Fact] + public void HmacMD5_HashSizes() + { + Assert.Equal(128, HMACMD5.HashSizeInBits); + Assert.Equal(16, HMACMD5.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs index 5e952d88f74d78..6b3b1eed43d8cf 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs @@ -248,5 +248,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "5433122F77BCF8A4D9B874B4149823EF5B7C207E"); } + + [Fact] + public void HmacSha1_HashSizes() + { + Assert.Equal(160, HMACSHA1.HashSizeInBits); + Assert.Equal(20, HMACSHA1.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs index ceace692f737b7..6abef3de5a2a2f 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs @@ -212,5 +212,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "07EFF8B326B7798C9CCFCBDBE579489AC785A7995A04618B1A2813C26744777D"); } + + [Fact] + public void HmacSha256_HashSizes() + { + Assert.Equal(256, HMACSHA256.HashSizeInBits); + Assert.Equal(32, HMACSHA256.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs index 4d36c1dd526168..d17b08a69925ee 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs @@ -225,5 +225,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "6A0FDC1C54C664AD91C7C157D2670C5D44E4D44EBAD2359A0206974C7088B1A867F76971E6C240C33B33A66BA295BB56"); } + + [Fact] + public void HmacSha384_HashSizes() + { + Assert.Equal(384, HMACSHA384.HashSizeInBits); + Assert.Equal(48, HMACSHA384.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs index 3e3b73f2a04237..cb70f5d148ce90 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs @@ -216,5 +216,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "72756291FF30F3E916BEF99EC9CF5938B25D90BBCAC1BDB1E1E6564E8EC6FDA5"); } + + [Fact] + public void HmacSha3_256_HashSizes() + { + Assert.Equal(256, HMACSHA3_256.HashSizeInBits); + Assert.Equal(32, HMACSHA3_256.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs index 019cd011d8a944..ff0e8249727f22 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs @@ -224,5 +224,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "5B0196779BDAF859E99869A63C9FDF3821E9100A370B5E9B88F76B9DA87410F99846E7DBB4F8A69368C5C5A834B3128D"); } + + [Fact] + public void HmacSha3_384_HashSizes() + { + Assert.Equal(384, HMACSHA3_384.HashSizeInBits); + Assert.Equal(48, HMACSHA3_384.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs index 1a307a2e830910..7af28e72de4dad 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs @@ -230,5 +230,12 @@ await VerifyRepeatingAsync( output: "908D1BE1A2CC5CC4B8C62E98D09AB6E967529FCB24F4177CB94CB072F5968D01" + "CA58633748DC80D4615E3D21228BB3A5F535FA1CB963DF463CC28ABAF1A9B2D1"); } + + [Fact] + public void HmacSha3_256_HashSizes() + { + Assert.Equal(512, HMACSHA3_512.HashSizeInBits); + Assert.Equal(64, HMACSHA3_512.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs index 45bf467a97d570..3568b40353af57 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs @@ -225,5 +225,12 @@ await VerifyRepeatingAsync( hexKey: "000102030405060708090A0B0C0D0E0F", output: "2FEC800CA276C44985A35AEC92067E5E53A1BB80A6FDAB1D9C97D54068118F30AD4C33717466D372EA00BBF126E5B79C6F7143DD36C31F72028330E92AE3A359"); } + + [Fact] + public void HmacSha512_HashSizes() + { + Assert.Equal(512, HMACSHA512.HashSizeInBits); + Assert.Equal(64, HMACSHA512.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs b/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs index 317d108cf7400b..52547044808c62 100644 --- a/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs @@ -154,5 +154,12 @@ public async Task MD5_Rfc1321_7_AsStream_Async() { await VerifyRepeatingAsync("1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a"); } + + [Fact] + public void Sha512_HashSizes() + { + Assert.Equal(128, MD5.HashSizeInBits); + Assert.Equal(16, MD5.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs index 0374735b796b57..61cd278e4a02a8 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha1Tests.cs @@ -137,5 +137,12 @@ public async Task Sha1_Rfc3174_4_Async() { await VerifyRepeatingAsync("0123456701234567012345670123456701234567012345670123456701234567", 10, "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452"); } + + [Fact] + public void Sha1_HashSizes() + { + Assert.Equal(160, SHA1.HashSizeInBits); + Assert.Equal(20, SHA1.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs index 6fa2e0822c7733..9d1745fe9442b9 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha256Tests.cs @@ -152,5 +152,12 @@ await VerifyRepeatingAsync( 1000000, "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); } + + [Fact] + public void Sha256_HashSizes() + { + Assert.Equal(256, SHA256.HashSizeInBits); + Assert.Equal(32, SHA256.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs index a78783fc2ccb1c..4f14559b4b93af 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha384Tests.cs @@ -140,5 +140,12 @@ public void Sha384_NistShaAll_2() "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039"); } + + [Fact] + public void Sha384_HashSizes() + { + Assert.Equal(384, SHA384.HashSizeInBits); + Assert.Equal(48, SHA384.HashSizeInBytes); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs index a1ba50c42371c3..ea028a7eb2964a 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs @@ -110,6 +110,13 @@ await VerifyRepeatingAsync( "5e80dd4330d9124adce40a043f166d7e0f6853050fd99919c7b1436ee0a538e9"); } + [Fact] + public void SHA3_256_HashSizes() + { + Assert.Equal(256, SHA3_256.HashSizeInBits); + Assert.Equal(32, SHA3_256.HashSizeInBytes); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs index 6436c9d6717eb4..fa3eaa52edcc11 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs @@ -116,6 +116,13 @@ await VerifyRepeatingAsync( "0aa96c328926f2faa796dc75a104e200f5b497beb0313e8822b471efebbb39cef02687e33787883a87c18f35856dcad1"); } + [Fact] + public void SHA3_384_HashSizes() + { + Assert.Equal(384, SHA3_384.HashSizeInBits); + Assert.Equal(48, SHA3_384.HashSizeInBytes); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs index 567eb6ef17e68f..0a06d75a39acef 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs @@ -116,6 +116,13 @@ await VerifyRepeatingAsync( "b5ec7fe7061c944b65f42a3193ebafcc3b35f063dc2ac7a5af05140b2439c425e4d9e63bc97103f704a7b6849a1986cec743ac288ca2f123e82c0ce60b714615"); } + [Fact] + public void SHA3_512_HashSizes() + { + Assert.Equal(512, SHA3_512.HashSizeInBits); + Assert.Equal(64, SHA3_512.HashSizeInBytes); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs index 07da487ed77dc3..4360bf464dde28 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha512Tests.cs @@ -158,5 +158,12 @@ await VerifyRepeatingAsync( 1000000, "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"); } + + [Fact] + public void Sha512_HashSizes() + { + Assert.Equal(512, SHA512.HashSizeInBits); + Assert.Equal(64, SHA512.HashSizeInBytes); + } } } From 7dfcd6f173dddfb9e99053d9a11bf114232d5e57 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 9 May 2023 15:22:47 -0400 Subject: [PATCH 33/47] Remove UOSP attribute from SHA3 --- .../ref/System.Security.Cryptography.cs | 150 ------------------ .../System/Security/Cryptography/SHA3_256.cs | 51 ------ .../System/Security/Cryptography/SHA3_384.cs | 51 ------ .../System/Security/Cryptography/SHA3_512.cs | 51 ------ 4 files changed, 303 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index f53f4329477062..64b28464b6f77b 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -2373,65 +2373,15 @@ public abstract partial class SHA3_256 : System.Security.Cryptography.HashAlgori public const int HashSizeInBits = 256; public const int HashSizeInBytes = 32; protected SHA3_256() { } - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("tvos")] public static bool IsSupported { get { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static new System.Security.Cryptography.SHA3_256 Create() { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(byte[] source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.IO.Stream source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.ReadOnlySpan source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } public abstract partial class SHA3_384 : System.Security.Cryptography.HashAlgorithm @@ -2439,65 +2389,15 @@ public abstract partial class SHA3_384 : System.Security.Cryptography.HashAlgori public const int HashSizeInBits = 384; public const int HashSizeInBytes = 48; protected SHA3_384() { } - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("tvos")] public static bool IsSupported { get { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static new System.Security.Cryptography.SHA3_384 Create() { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(byte[] source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.IO.Stream source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.ReadOnlySpan source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } public abstract partial class SHA3_512 : System.Security.Cryptography.HashAlgorithm @@ -2505,65 +2405,15 @@ public abstract partial class SHA3_512 : System.Security.Cryptography.HashAlgori public const int HashSizeInBits = 512; public const int HashSizeInBytes = 64; protected SHA3_512() { } - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformGuardAttribute("tvos")] public static bool IsSupported { get { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static new System.Security.Cryptography.SHA3_512 Create() { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(byte[] source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.IO.Stream source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.IO.Stream source, System.Span destination) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static byte[] HashData(System.ReadOnlySpan source) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static int HashData(System.ReadOnlySpan source, System.Span destination) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("osx")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } public abstract partial class SHA512 : System.Security.Cryptography.HashAlgorithm diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs index ed0158380fd859..9d165e154eea55 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -43,11 +42,6 @@ protected SHA3_256() /// /// if the algorithm is supported; otherwise, . /// - [UnsupportedOSPlatformGuard("android")] - [UnsupportedOSPlatformGuard("osx")] - [UnsupportedOSPlatformGuard("ios")] - [UnsupportedOSPlatformGuard("tvos")] - [UnsupportedOSPlatformGuard("browser")] public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_256); /// @@ -59,11 +53,6 @@ protected SHA3_256() /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static new SHA3_256 Create() { CheckSha3Support(); @@ -81,11 +70,6 @@ protected SHA3_256() /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -101,11 +85,6 @@ public static byte[] HashData(byte[] source) /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(ReadOnlySpan source) { byte[] buffer = new byte[HashSizeInBytes]; @@ -129,11 +108,6 @@ public static byte[] HashData(ReadOnlySpan source) /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static int HashData(ReadOnlySpan source, Span destination) { if (!TryHashData(source, destination, out int bytesWritten)) @@ -157,11 +131,6 @@ public static int HashData(ReadOnlySpan source, Span destination) /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) { CheckSha3Support(); @@ -200,11 +169,6 @@ public static bool TryHashData(ReadOnlySpan source, Span destination /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static int HashData(Stream source, Span destination) { ArgumentNullException.ThrowIfNull(source); @@ -233,11 +197,6 @@ public static int HashData(Stream source, Span destination) /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(Stream source) { ArgumentNullException.ThrowIfNull(source); @@ -267,11 +226,6 @@ public static byte[] HashData(Stream source) /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(source); @@ -309,11 +263,6 @@ public static ValueTask HashDataAsync(Stream source, CancellationToken c /// /// The platform does not support SHA3-256. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync( Stream source, Memory destination, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs index 07a69ce0f98aa7..2a02dfb813f03b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -43,11 +42,6 @@ protected SHA3_384() /// /// if the algorithm is supported; otherwise, . /// - [UnsupportedOSPlatformGuard("android")] - [UnsupportedOSPlatformGuard("osx")] - [UnsupportedOSPlatformGuard("ios")] - [UnsupportedOSPlatformGuard("tvos")] - [UnsupportedOSPlatformGuard("browser")] public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_384); /// @@ -59,11 +53,6 @@ protected SHA3_384() /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static new SHA3_384 Create() { CheckSha3Support(); @@ -81,11 +70,6 @@ protected SHA3_384() /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -101,11 +85,6 @@ public static byte[] HashData(byte[] source) /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(ReadOnlySpan source) { byte[] buffer = new byte[HashSizeInBytes]; @@ -129,11 +108,6 @@ public static byte[] HashData(ReadOnlySpan source) /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static int HashData(ReadOnlySpan source, Span destination) { if (!TryHashData(source, destination, out int bytesWritten)) @@ -158,11 +132,6 @@ public static int HashData(ReadOnlySpan source, Span destination) /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) { CheckSha3Support(); @@ -201,11 +170,6 @@ public static bool TryHashData(ReadOnlySpan source, Span destination /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static int HashData(Stream source, Span destination) { ArgumentNullException.ThrowIfNull(source); @@ -234,11 +198,6 @@ public static int HashData(Stream source, Span destination) /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(Stream source) { ArgumentNullException.ThrowIfNull(source); @@ -268,11 +227,6 @@ public static byte[] HashData(Stream source) /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(source); @@ -310,11 +264,6 @@ public static ValueTask HashDataAsync(Stream source, CancellationToken c /// /// The platform does not support SHA3-384. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync( Stream source, Memory destination, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs index b2d8fe39a10023..840deca5328d7e 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -43,11 +42,6 @@ protected SHA3_512() /// /// if the algorithm is supported; otherwise, . /// - [UnsupportedOSPlatformGuard("android")] - [UnsupportedOSPlatformGuard("osx")] - [UnsupportedOSPlatformGuard("ios")] - [UnsupportedOSPlatformGuard("tvos")] - [UnsupportedOSPlatformGuard("browser")] public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_512); /// @@ -59,11 +53,6 @@ protected SHA3_512() /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static new SHA3_512 Create() { CheckSha3Support(); @@ -81,11 +70,6 @@ protected SHA3_512() /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -101,11 +85,6 @@ public static byte[] HashData(byte[] source) /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(ReadOnlySpan source) { byte[] buffer = new byte[HashSizeInBytes]; @@ -129,11 +108,6 @@ public static byte[] HashData(ReadOnlySpan source) /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static int HashData(ReadOnlySpan source, Span destination) { if (!TryHashData(source, destination, out int bytesWritten)) @@ -157,11 +131,6 @@ public static int HashData(ReadOnlySpan source, Span destination) /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static bool TryHashData(ReadOnlySpan source, Span destination, out int bytesWritten) { CheckSha3Support(); @@ -200,11 +169,6 @@ public static bool TryHashData(ReadOnlySpan source, Span destination /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static int HashData(Stream source, Span destination) { ArgumentNullException.ThrowIfNull(source); @@ -233,11 +197,6 @@ public static int HashData(Stream source, Span destination) /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static byte[] HashData(Stream source) { ArgumentNullException.ThrowIfNull(source); @@ -267,11 +226,6 @@ public static byte[] HashData(Stream source) /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync(Stream source, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(source); @@ -309,11 +263,6 @@ public static ValueTask HashDataAsync(Stream source, CancellationToken c /// /// The platform does not support SHA3-512. /// - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("osx")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] - [UnsupportedOSPlatform("browser")] public static ValueTask HashDataAsync( Stream source, Memory destination, From d7d9abed56b6e1c3e0566be62b8fb86e496b7a9e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 9 May 2023 15:28:40 -0400 Subject: [PATCH 34/47] Remove unused using for HMAC --- .../src/System/Security/Cryptography/HMACSHA3_256.cs | 1 - .../src/System/Security/Cryptography/HMACSHA3_384.cs | 1 - .../src/System/Security/Cryptography/HMACSHA3_512.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs index f46a8755a5f6d5..6821b27ba2c0af 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs @@ -4,7 +4,6 @@ using Internal.Cryptography; using System.Diagnostics; using System.IO; -using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs index 83cd46d83416c6..2daf0af9a953d8 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs @@ -4,7 +4,6 @@ using Internal.Cryptography; using System.Diagnostics; using System.IO; -using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs index d25cf91d575050..f98dfd44ef957b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs @@ -4,7 +4,6 @@ using Internal.Cryptography; using System.Diagnostics; using System.IO; -using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; From 43385c21f17ead2c1fb5432dd40c4bcae1ac88c0 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 11:08:43 -0400 Subject: [PATCH 35/47] Code review feedback on HKDF tests --- .../tests/HKDFTests.cs | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs index 0be73e89dc9fd6..6f58c00e80994c 100644 --- a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs @@ -16,7 +16,7 @@ public abstract class HKDFTests [Theory] [MemberData(nameof(GetHkdfTestCases))] - public void Rfc5869ExtractTests(HkdfTestCase test) + public void ExtractTests(HkdfTestCase test) { byte[] prk = Extract(test.Hash, test.Prk.Length, test.Ikm, test.Salt); Assert.Equal(test.Prk, prk); @@ -25,7 +25,7 @@ public void Rfc5869ExtractTests(HkdfTestCase test) [Theory] [MemberData(nameof(GetHkdfTestCases))] [SkipOnPlatform(TestPlatforms.Browser, "MD5 is not supported on Browser")] - public void Rfc5869ExtractTamperHashTests(HkdfTestCase test) + public void ExtractTamperHashTests(HkdfTestCase test) { byte[] prk = Extract(HashAlgorithmName.MD5, 128 / 8, test.Ikm, test.Salt); Assert.NotEqual(test.Prk, prk); @@ -33,7 +33,7 @@ public void Rfc5869ExtractTamperHashTests(HkdfTestCase test) [Theory] [MemberData(nameof(GetHkdfTestCases))] - public void Rfc5869ExtractTamperIkmTests(HkdfTestCase test) + public void ExtractTamperIkmTests(HkdfTestCase test) { byte[] ikm = test.Ikm.ToArray(); ikm[0] ^= 1; @@ -43,7 +43,7 @@ public void Rfc5869ExtractTamperIkmTests(HkdfTestCase test) [Theory] [MemberData(nameof(GetHkdfTestCasesWithNonEmptySalt))] - public void Rfc5869ExtractTamperSaltTests(HkdfTestCase test) + public void ExtractTamperSaltTests(HkdfTestCase test) { byte[] salt = test.Salt.ToArray(); salt[0] ^= 1; @@ -52,7 +52,7 @@ public void Rfc5869ExtractTamperSaltTests(HkdfTestCase test) } [Fact] - public void Rfc5869ExtractDefaultHash() + public void ExtractDefaultHash() { byte[] ikm = new byte[20]; byte[] salt = new byte[20]; @@ -62,7 +62,7 @@ public void Rfc5869ExtractDefaultHash() } [Fact] - public void Rfc5869ExtractNonsensicalHash() + public void ExtractNonsensicalHash() { byte[] ikm = new byte[20]; byte[] salt = new byte[20]; @@ -72,7 +72,7 @@ public void Rfc5869ExtractNonsensicalHash() } [Fact] - public void Rfc5869ExtractEmptyIkm() + public void ExtractEmptyIkm() { byte[] salt = new byte[20]; byte[] ikm = Array.Empty(); @@ -83,7 +83,7 @@ public void Rfc5869ExtractEmptyIkm() } [Fact] - public void Rfc5869ExtractEmptySalt() + public void ExtractEmptySalt() { byte[] ikm = new byte[20]; byte[] salt = Array.Empty(); @@ -93,14 +93,14 @@ public void Rfc5869ExtractEmptySalt() [Theory] [MemberData(nameof(GetHkdfTestCases))] - public void Rfc5869ExpandTests(HkdfTestCase test) + public void ExpandTests(HkdfTestCase test) { byte[] okm = Expand(test.Hash, test.Prk, test.Okm.Length, test.Info); Assert.Equal(test.Okm, okm); } [Fact] - public void Rfc5869ExpandDefaultHash() + public void ExpandDefaultHash() { byte[] prk = new byte[20]; AssertExtensions.Throws( @@ -109,7 +109,7 @@ public void Rfc5869ExpandDefaultHash() } [Fact] - public void Rfc5869ExpandNonsensicalHash() + public void ExpandNonsensicalHash() { byte[] prk = new byte[20]; AssertExtensions.Throws( @@ -119,7 +119,7 @@ public void Rfc5869ExpandNonsensicalHash() [Theory] [MemberData(nameof(GetHkdfTestCases))] - public void Rfc5869ExpandTamperPrkTests(HkdfTestCase test) + public void ExpandTamperPrkTests(HkdfTestCase test) { byte[] prk = test.Prk.ToArray(); prk[0] ^= 1; @@ -129,7 +129,7 @@ public void Rfc5869ExpandTamperPrkTests(HkdfTestCase test) [Theory] [MemberData(nameof(GetPrkTooShortTestCases))] - public void Rfc5869ExpandPrkTooShort(HashAlgorithmName hash, int prkSize) + public void ExpandPrkTooShort(HashAlgorithmName hash, int prkSize) { byte[] prk = new byte[prkSize]; AssertExtensions.Throws( @@ -138,7 +138,7 @@ public void Rfc5869ExpandPrkTooShort(HashAlgorithmName hash, int prkSize) } [Fact] - public void Rfc5869ExpandOkmMaxSize() + public void ExpandOkmMaxSize() { byte[] prk = new byte[20]; @@ -149,14 +149,14 @@ public void Rfc5869ExpandOkmMaxSize() [Theory] [MemberData(nameof(GetHkdfTestCases))] - public void Rfc5869DeriveKeyTests(HkdfTestCase test) + public void DeriveKeyTests(HkdfTestCase test) { byte[] okm = DeriveKey(test.Hash, test.Ikm, test.Okm.Length, test.Salt, test.Info); Assert.Equal(test.Okm, okm); } [Fact] - public void Rfc5869DeriveKeyDefaultHash() + public void DeriveKeyDefaultHash() { byte[] ikm = new byte[20]; AssertExtensions.Throws( @@ -165,7 +165,7 @@ public void Rfc5869DeriveKeyDefaultHash() } [Fact] - public void Rfc5869DeriveKeyNonSensicalHash() + public void DeriveKeyNonSensicalHash() { byte[] ikm = new byte[20]; AssertExtensions.Throws( @@ -175,7 +175,7 @@ public void Rfc5869DeriveKeyNonSensicalHash() [Theory] [MemberData(nameof(GetHkdfTestCases))] - public void Rfc5869DeriveKeyTamperIkmTests(HkdfTestCase test) + public void DeriveKeyTamperIkmTests(HkdfTestCase test) { byte[] ikm = test.Ikm.ToArray(); ikm[0] ^= 1; @@ -185,7 +185,7 @@ public void Rfc5869DeriveKeyTamperIkmTests(HkdfTestCase test) [Theory] [MemberData(nameof(GetHkdfTestCasesWithNonEmptySalt))] - public void Rfc5869DeriveKeyTamperSaltTests(HkdfTestCase test) + public void DeriveKeyTamperSaltTests(HkdfTestCase test) { byte[] salt = test.Salt.ToArray(); salt[0] ^= 1; @@ -195,7 +195,7 @@ public void Rfc5869DeriveKeyTamperSaltTests(HkdfTestCase test) [Theory] [MemberData(nameof(GetHkdfTestCasesWithNonEmptyInfo))] - public void Rfc5869DeriveKeyTamperInfoTests(HkdfTestCase test) + public void DeriveKeyTamperInfoTests(HkdfTestCase test) { byte[] info = test.Info.ToArray(); info[0] ^= 1; @@ -221,7 +221,7 @@ public void Sha3Tests(HkdfTestCase test) public static IEnumerable GetHkdfTestCases() { - foreach (HkdfTestCase test in HkdfTestCases) + foreach (HkdfTestCase test in Rfc5869TestCases) { yield return new object[] { test }; } @@ -229,7 +229,7 @@ public static IEnumerable GetHkdfTestCases() public static IEnumerable GetHkdfTestCasesWithNonEmptySalt() { - foreach (HkdfTestCase test in HkdfTestCases) + foreach (HkdfTestCase test in Rfc5869TestCases) { if (test.Salt != null && test.Salt.Length != 0) { @@ -240,7 +240,7 @@ public static IEnumerable GetHkdfTestCasesWithNonEmptySalt() public static IEnumerable GetHkdfTestCasesWithNonEmptyInfo() { - foreach (HkdfTestCase test in HkdfTestCases) + foreach (HkdfTestCase test in Rfc5869TestCases) { if (test.Info != null && test.Info.Length != 0) { @@ -270,7 +270,7 @@ public static IEnumerable GetPrkTooShortTestCases() } } - private static HkdfTestCase[] HkdfTestCases { get; } = new HkdfTestCase[7] + private static HkdfTestCase[] Rfc5869TestCases { get; } = new HkdfTestCase[7] { new HkdfTestCase() { @@ -486,7 +486,7 @@ protected override byte[] DeriveKey(HashAlgorithmName hash, byte[] ikm, int outp } [Fact] - public void Rfc5869ExtractNullIkm() + public void ExtractNullIkm() { byte[] salt = new byte[20]; AssertExtensions.Throws( @@ -495,7 +495,7 @@ public void Rfc5869ExtractNullIkm() } [Fact] - public void Rfc5869ExpandOkmMaxSizePlusOne() + public void ExpandOkmMaxSizePlusOne() { byte[] prk = new byte[20]; AssertExtensions.Throws( @@ -504,7 +504,7 @@ public void Rfc5869ExpandOkmMaxSizePlusOne() } [Fact] - public void Rfc5869ExpandOkmPotentiallyOverflowingValue() + public void ExpandOkmPotentiallyOverflowingValue() { byte[] prk = new byte[20]; AssertExtensions.Throws( @@ -513,7 +513,7 @@ public void Rfc5869ExpandOkmPotentiallyOverflowingValue() } [Fact] - public void Rfc5869ExpandOutputLengthZero() + public void ExpandOutputLengthZero() { byte[] prk = new byte[20]; AssertExtensions.Throws( @@ -522,7 +522,7 @@ public void Rfc5869ExpandOutputLengthZero() } [Fact] - public void Rfc5869ExpandOutputLengthLessThanZero() + public void ExpandOutputLengthLessThanZero() { byte[] prk = new byte[20]; AssertExtensions.Throws( @@ -531,7 +531,7 @@ public void Rfc5869ExpandOutputLengthLessThanZero() } [Fact] - public void Rfc5869DeriveKeyNullIkm() + public void DeriveKeyNullIkm() { AssertExtensions.Throws( "ikm", @@ -539,7 +539,7 @@ public void Rfc5869DeriveKeyNullIkm() } [Fact] - public void Rfc5869DeriveKeyOkmMaxSizePlusOne() + public void DeriveKeyOkmMaxSizePlusOne() { byte[] ikm = new byte[20]; AssertExtensions.Throws( @@ -548,7 +548,7 @@ public void Rfc5869DeriveKeyOkmMaxSizePlusOne() } [Fact] - public void Rfc5869DeriveKeyOkmPotentiallyOverflowingValue() + public void DeriveKeyOkmPotentiallyOverflowingValue() { byte[] ikm = new byte[20]; AssertExtensions.Throws( @@ -557,7 +557,7 @@ public void Rfc5869DeriveKeyOkmPotentiallyOverflowingValue() } [Fact] - public void Rfc5869DeriveOutputLengthZero() + public void DeriveOutputLengthZero() { byte[] ikm = new byte[20]; AssertExtensions.Throws( @@ -566,7 +566,7 @@ public void Rfc5869DeriveOutputLengthZero() } [Fact] - public void Rfc5869DeriveOutputLengthLessThanZero() + public void DeriveOutputLengthLessThanZero() { byte[] ikm = new byte[20]; AssertExtensions.Throws( @@ -599,7 +599,7 @@ protected override byte[] DeriveKey(HashAlgorithmName hash, byte[] ikm, int outp } [Fact] - public void Rfc5869ExtractPrkTooLong() + public void ExtractPrkTooLong() { byte[] prk = new byte[24]; @@ -621,7 +621,7 @@ public void Rfc5869ExtractPrkTooLong() } [Fact] - public void Rfc5869OkmMaxSizePlusOne() + public void OkmMaxSizePlusOne() { byte[] prk = new byte[20]; byte[] okm = new byte[20 * 255 + 1]; @@ -631,7 +631,7 @@ public void Rfc5869OkmMaxSizePlusOne() } [Fact] - public void Rfc5869OkmMaxSizePotentiallyOverflowingValue() + public void OkmMaxSizePotentiallyOverflowingValue() { byte[] prk = new byte[20]; byte[] okm = new byte[8421505]; @@ -641,7 +641,7 @@ public void Rfc5869OkmMaxSizePotentiallyOverflowingValue() } [Fact] - public void Rfc5869ExpandOutputLengthZero() + public void ExpandOutputLengthZero() { byte[] prk = new byte[20]; byte[] okm = new byte[0]; @@ -652,7 +652,7 @@ public void Rfc5869ExpandOutputLengthZero() } [Fact] - public void Rfc5869DeriveKeySpanOkmMaxSizePlusOne() + public void DeriveKeySpanOkmMaxSizePlusOne() { byte[] ikm = new byte[20]; byte[] okm = new byte[20 * 255 + 1]; @@ -662,7 +662,7 @@ public void Rfc5869DeriveKeySpanOkmMaxSizePlusOne() } [Fact] - public void Rfc5869DeriveKeySpanOkmPotentiallyOverflowingValue() + public void DeriveKeySpanOkmPotentiallyOverflowingValue() { byte[] ikm = new byte[20]; byte[] okm = new byte[8421505]; @@ -672,7 +672,7 @@ public void Rfc5869DeriveKeySpanOkmPotentiallyOverflowingValue() } [Fact] - public void Rfc5869DeriveKeyOutputLengthZero() + public void DeriveKeyOutputLengthZero() { byte[] ikm = new byte[20]; byte[] okm = new byte[0]; @@ -687,7 +687,7 @@ public void Rfc5869DeriveKeyOutputLengthZero() [InlineData(0, 10)] // Output +10 offset over ikm [InlineData(10, 0)] // ikm +10 offset over output [InlineData(10, 20)] // Both offset, output +10 over ikm - public void Rfc5869ExtractOverlapsPrkOverKeyMaterial(int ikmOffset, int outputOffset) + public void ExtractOverlapsPrkOverKeyMaterial(int ikmOffset, int outputOffset) { ReadOnlySpan ikm = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b".HexToByteArray(); ReadOnlySpan salt = "000102030405060708090a0b0c".HexToByteArray(); @@ -708,7 +708,7 @@ public void Rfc5869ExtractOverlapsPrkOverKeyMaterial(int ikmOffset, int outputOf [InlineData(0, 10)] // Output +10 offset over salt [InlineData(10, 0)] // salt +10 offset over output [InlineData(10, 20)] // Both offset, output +10 over salt - public void Rfc5869ExtractOverlapsPrkOverSalt(int saltOffset, int outputOffset) + public void ExtractOverlapsPrkOverSalt(int saltOffset, int outputOffset) { ReadOnlySpan ikm = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b".HexToByteArray(); ReadOnlySpan salt = "000102030405060708090a0b0c".HexToByteArray(); @@ -729,7 +729,7 @@ public void Rfc5869ExtractOverlapsPrkOverSalt(int saltOffset, int outputOffset) [InlineData(0, 10)] // Output +10 offset over info [InlineData(10, 0)] // Info +10 offset over output [InlineData(10, 20)] // Both offset, output +10 over info - public void Rfc5869ExpandOverlapsOutputOverInfo(int infoOffset, int outputOffset) + public void ExpandOverlapsOutputOverInfo(int infoOffset, int outputOffset) { ReadOnlySpan info = ( "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + @@ -757,7 +757,7 @@ public void Rfc5869ExpandOverlapsOutputOverInfo(int infoOffset, int outputOffset [InlineData(0, 10)] // Output +10 offset over info [InlineData(10, 0)] // Info +10 offset over output [InlineData(10, 20)] // Both offset, output +10 over info - public void Rfc5869ExpandOverlapsOutputOverInfoShortOkm(int infoOffset, int outputOffset) + public void ExpandOverlapsOutputOverInfoShortOkm(int infoOffset, int outputOffset) { ReadOnlySpan info = ( "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + @@ -783,7 +783,7 @@ public void Rfc5869ExpandOverlapsOutputOverInfoShortOkm(int infoOffset, int outp [InlineData(0, 10)] // Output +10 offset over prk [InlineData(10, 0)] // Prk +10 offset over output [InlineData(10, 20)] // Both offset, output +10 over prk - public void Rfc5869ExpandOverlapsOutputOverPrk(int prkOffset, int outputOffset) + public void ExpandOverlapsOutputOverPrk(int prkOffset, int outputOffset) { ReadOnlySpan info = ( "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + From 08af75f428def4b59aeb4a90e3d2ff67df7b499a Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 11:17:51 -0400 Subject: [PATCH 36/47] Additional code review feedback --- src/libraries/Common/src/System/Security/Cryptography/Oids.cs | 1 - .../Cryptography/SP800108HmacCounterKdfTests.Functional.cs | 2 +- .../System.Security.Cryptography/tests/HmacSha3_384Tests.cs | 2 +- src/libraries/System.Security.Cryptography/tests/MD5Tests.cs | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Oids.cs b/src/libraries/Common/src/System/Security/Cryptography/Oids.cs index 63c5b1eb105f41..b7364108222ad1 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Oids.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Oids.cs @@ -94,7 +94,6 @@ internal static partial class Oids internal const string ECDsaWithSha3_384 = "2.16.840.1.101.3.4.3.11"; internal const string ECDsaWithSha3_512 = "2.16.840.1.101.3.4.3.12"; - internal const string Mgf1 = "1.2.840.113549.1.1.8"; internal const string PSpecified = "1.2.840.113549.1.1.9"; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs index 474cc75ae8df27..5eb6d097026c65 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs @@ -1,9 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.DotNet.XUnitExtensions; using System.Collections.Generic; using System.Globalization; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Security.Cryptography.Tests diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs index ff0e8249727f22..92873f95882eb0 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs @@ -63,7 +63,7 @@ protected override ValueTask HashDataOneShotAsync( private static readonly byte[][] s_testKeys = new byte[][] { - // From: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA3-256.pdf + // From: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA3-384.pdf null, ByteUtils.HexToByteArray( "000102030405060708090a0b0c0d0e0f1011121314151617" + diff --git a/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs b/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs index 52547044808c62..15919e84d7a91d 100644 --- a/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/MD5Tests.cs @@ -156,7 +156,7 @@ public async Task MD5_Rfc1321_7_AsStream_Async() } [Fact] - public void Sha512_HashSizes() + public void MD5_HashSizes() { Assert.Equal(128, MD5.HashSizeInBits); Assert.Equal(16, MD5.HashSizeInBytes); From 8abcc7a077d5a7148316eb2d02bd98b785a00f5b Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 11:52:29 -0400 Subject: [PATCH 37/47] Add tests for IsSupported on algorithm implementations --- .../System.Security.Cryptography/tests/HmacSha3_256Tests.cs | 6 ++++++ .../System.Security.Cryptography/tests/HmacSha3_384Tests.cs | 6 ++++++ .../System.Security.Cryptography/tests/HmacSha3_512Tests.cs | 6 ++++++ .../System.Security.Cryptography/tests/Sha3_256Tests.cs | 6 ++++++ .../System.Security.Cryptography/tests/Sha3_384Tests.cs | 6 ++++++ .../System.Security.Cryptography/tests/Sha3_512Tests.cs | 6 ++++++ 6 files changed, 36 insertions(+) diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs index cb70f5d148ce90..fb5b540ac506d0 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_256Tests.cs @@ -223,5 +223,11 @@ public void HmacSha3_256_HashSizes() Assert.Equal(256, HMACSHA3_256.HashSizeInBits); Assert.Equal(32, HMACSHA3_256.HashSizeInBytes); } + + [Fact] + public void HmacSha3_256_IsSupported_AgreesWithPlatformVersion() + { + Assert.Equal(PlatformDetection.SupportsSha3, HMACSHA3_256.IsSupported); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs index 92873f95882eb0..7dab4a444f5adb 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_384Tests.cs @@ -231,5 +231,11 @@ public void HmacSha3_384_HashSizes() Assert.Equal(384, HMACSHA3_384.HashSizeInBits); Assert.Equal(48, HMACSHA3_384.HashSizeInBytes); } + + [Fact] + public void HmacSha3_384_IsSupported_AgreesWithPlatformVersion() + { + Assert.Equal(PlatformDetection.SupportsSha3, HMACSHA3_384.IsSupported); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs index 7af28e72de4dad..3359ba4e335680 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha3_512Tests.cs @@ -237,5 +237,11 @@ public void HmacSha3_256_HashSizes() Assert.Equal(512, HMACSHA3_512.HashSizeInBits); Assert.Equal(64, HMACSHA3_512.HashSizeInBytes); } + + [Fact] + public void HmacSha3_512_IsSupported_AgreesWithPlatformVersion() + { + Assert.Equal(PlatformDetection.SupportsSha3, HMACSHA3_512.IsSupported); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs index ea028a7eb2964a..b910f3b67933cf 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs @@ -117,6 +117,12 @@ public void SHA3_256_HashSizes() Assert.Equal(32, SHA3_256.HashSizeInBytes); } + [Fact] + public void SHA3_256_IsSupported_AgreesWithPlatformVersion() + { + Assert.Equal(PlatformDetection.SupportsSha3, SHA3_256.IsSupported); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs index fa3eaa52edcc11..96671ad9031399 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs @@ -123,6 +123,12 @@ public void SHA3_384_HashSizes() Assert.Equal(48, SHA3_384.HashSizeInBytes); } + [Fact] + public void SHA3_384_IsSupported_AgreesWithPlatformVersion() + { + Assert.Equal(PlatformDetection.SupportsSha3, SHA3_384.IsSupported); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs index 0a06d75a39acef..ea61e3fe0d12d7 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs @@ -123,6 +123,12 @@ public void SHA3_512_HashSizes() Assert.Equal(64, SHA3_512.HashSizeInBytes); } + [Fact] + public void SHA3_512_IsSupported_AgreesWithPlatformVersion() + { + Assert.Equal(PlatformDetection.SupportsSha3, SHA3_512.IsSupported); + } + private static IEnumerable<(string Msg, string MD)> Fips202Kats { get From dc8ae5fb3f7d569e912b534c8aa55197db019b2d Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 12:41:34 -0400 Subject: [PATCH 38/47] Simplify IsBCryptAlgorithmSupported --- .../Windows/BCrypt/BCryptAlgorithmCache.cs | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs index 068a6a371e583a..5f060292a666c7 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/BCryptAlgorithmCache.cs @@ -49,38 +49,36 @@ public static unsafe bool IsBCryptAlgorithmSupported(string hashAlgorithmId, BCr { var key = (hashAlgorithmId, flags); - while (true) + if (s_supported.TryGetValue(key, out bool supported)) { - if (s_supported.TryGetValue(key, out bool supported)) - { - return supported; - } + return supported; + } - NTSTATUS status = BCryptOpenAlgorithmProvider( - out SafeBCryptAlgorithmHandle handle, - key.hashAlgorithmId, - null, - key.flags); + NTSTATUS status = BCryptOpenAlgorithmProvider( + out SafeBCryptAlgorithmHandle handle, + key.hashAlgorithmId, + null, + key.flags); - bool isSupported = status == NTSTATUS.STATUS_SUCCESS; + bool isSupported = status == NTSTATUS.STATUS_SUCCESS; - if (s_supported.TryAdd(key, isSupported) && isSupported) - { - // It's a valid algorithm. Let's prime the handle cache while we are here. Presumably it's - // going to get used if we're asking if it's supported. - int hashSize = BCryptGetDWordProperty(handle, BCryptPropertyStrings.BCRYPT_HASH_LENGTH); - Debug.Assert(hashSize > 0); + if (s_supported.TryAdd(key, isSupported) && isSupported) + { + // It's a valid algorithm. Let's prime the handle cache while we are here. Presumably it's + // going to get used if we're asking if it's supported. + int hashSize = BCryptGetDWordProperty(handle, BCryptPropertyStrings.BCRYPT_HASH_LENGTH); + Debug.Assert(hashSize > 0); - if (s_handles.TryAdd(key, (handle, hashSize))) - { - // If we added it to the cache, don't dispose of it. - continue; - } + if (s_handles.TryAdd(key, (handle, hashSize))) + { + // If we added the handle to the cache, don't dispose of it and return our answer. + return isSupported; } - - // Either the algorithm isn't supported or we don't need it for priming the cache, so Dispose. - handle.Dispose(); } + + // Either the algorithm isn't supported or we don't need it for priming the cache, so Dispose. + handle.Dispose(); + return isSupported; } } } From b3efe82cca726ca96d082b48c9de1a22cb64b2ad Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 16:37:39 -0400 Subject: [PATCH 39/47] Implement and test SHA3 with SignedCms --- .../src/Internal/Cryptography/PkcsHelpers.cs | 19 ++ .../Cryptography/Pkcs/CmsSignature.ECDsa.cs | 10 ++ .../Cryptography/Pkcs/CmsSignature.RSA.cs | 5 + .../Security/Cryptography/Pkcs/CmsSigner.cs | 13 +- .../Security/Cryptography/Pkcs/SignerInfo.cs | 12 +- .../tests/Oids.cs | 3 + .../SignedCms/SignedCmsTests.netcoreapp.cs | 132 ++++++++++++++ .../tests/SignedCms/SignedDocuments.cs | 163 ++++++++++++++++++ 8 files changed, 355 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs index 8679d34557cf6b..10c6727f125668 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs @@ -69,6 +69,17 @@ internal static HashAlgorithmName GetDigestAlgorithm(string? oidValue, bool forV case Oids.Sha512: case Oids.RsaPkcs1Sha512 when forVerification: return HashAlgorithmName.SHA512; +#if NET8_0_OR_GREATER + case Oids.Sha3_256: + case Oids.RsaPkcs1Sha3_256 when forVerification: + return HashAlgorithmName.SHA3_256; + case Oids.Sha3_384: + case Oids.RsaPkcs1Sha3_384 when forVerification: + return HashAlgorithmName.SHA3_384; + case Oids.Sha3_512: + case Oids.RsaPkcs1Sha3_512 when forVerification: + return HashAlgorithmName.SHA3_512; +#endif default: throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, oidValue); } @@ -86,6 +97,14 @@ internal static string GetOidFromHashAlgorithm(HashAlgorithmName algName) return Oids.Sha384; if (algName == HashAlgorithmName.SHA512) return Oids.Sha512; +#if NET8_0_OR_GREATER + if (algName == HashAlgorithmName.SHA3_256) + return Oids.Sha3_256; + if (algName == HashAlgorithmName.SHA3_384) + return Oids.Sha3_384; + if (algName == HashAlgorithmName.SHA3_512) + return Oids.Sha3_512; +#endif throw new CryptographicException(SR.Cryptography_Cms_UnknownAlgorithm, algName.Name); } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs index 5fc08e0870e9b9..f9900fed9fb6a1 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs @@ -17,6 +17,11 @@ static partial void PrepareRegistrationECDsa(Dictionary lo lookup.Add(Oids.ECDsaWithSha256, new ECDsaCmsSignature(Oids.ECDsaWithSha256, HashAlgorithmName.SHA256)); lookup.Add(Oids.ECDsaWithSha384, new ECDsaCmsSignature(Oids.ECDsaWithSha384, HashAlgorithmName.SHA384)); lookup.Add(Oids.ECDsaWithSha512, new ECDsaCmsSignature(Oids.ECDsaWithSha512, HashAlgorithmName.SHA512)); +#if NET8_0_OR_GREATER + lookup.Add(Oids.ECDsaWithSha3_256, new ECDsaCmsSignature(Oids.ECDsaWithSha3_256, HashAlgorithmName.SHA3_256)); + lookup.Add(Oids.ECDsaWithSha3_384, new ECDsaCmsSignature(Oids.ECDsaWithSha3_384, HashAlgorithmName.SHA3_384)); + lookup.Add(Oids.ECDsaWithSha3_512, new ECDsaCmsSignature(Oids.ECDsaWithSha3_512, HashAlgorithmName.SHA3_512)); +#endif lookup.Add(Oids.EcPublicKey, new ECDsaCmsSignature(null, default)); } @@ -131,6 +136,11 @@ protected override bool Sign( hashAlgorithmName == HashAlgorithmName.SHA256 ? Oids.ECDsaWithSha256 : hashAlgorithmName == HashAlgorithmName.SHA384 ? Oids.ECDsaWithSha384 : hashAlgorithmName == HashAlgorithmName.SHA512 ? Oids.ECDsaWithSha512 : +#if NET8_0_OR_GREATER + hashAlgorithmName == HashAlgorithmName.SHA3_256 ? Oids.ECDsaWithSha3_256 : + hashAlgorithmName == HashAlgorithmName.SHA3_384 ? Oids.ECDsaWithSha3_384 : + hashAlgorithmName == HashAlgorithmName.SHA3_512 ? Oids.ECDsaWithSha3_512 : +#endif null; if (oidValue == null) diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs index 12adeda2360f6e..51677662dd5219 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs @@ -20,6 +20,11 @@ static partial void PrepareRegistrationRsa(Dictionary look lookup.Add(Oids.RsaPkcs1Sha256, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha256, HashAlgorithmName.SHA256)); lookup.Add(Oids.RsaPkcs1Sha384, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha384, HashAlgorithmName.SHA384)); lookup.Add(Oids.RsaPkcs1Sha512, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha512, HashAlgorithmName.SHA512)); +#if NET8_0_OR_GREATER + lookup.Add(Oids.RsaPkcs1Sha3_256, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha3_256, HashAlgorithmName.SHA3_256)); + lookup.Add(Oids.RsaPkcs1Sha3_384, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha3_384, HashAlgorithmName.SHA3_384)); + lookup.Add(Oids.RsaPkcs1Sha3_512, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha3_512, HashAlgorithmName.SHA3_512)); +#endif lookup.Add(Oids.RsaPss, new RSAPssCmsSignature()); } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs index 0d2360240469ea..32d6262e18c085 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs @@ -185,7 +185,18 @@ internal SignerInfoAsn Sign( newSignerInfo.DigestAlgorithm.Algorithm = DigestAlgorithm.Value!; byte[] dataHash; - using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithmName)) + IncrementalHash hasher; + + try + { + hasher = IncrementalHash.CreateHash(hashAlgorithmName); + } + catch (PlatformNotSupportedException ex) + { + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName), ex); + } + + using (hasher) { hasher.AppendData(data.Span); dataHash = hasher.GetHashAndReset(); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs index 2ee1049b965d6e..021e1f8e9be2d4 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs @@ -550,7 +550,17 @@ private bool CheckHash(bool compatMode) { HashAlgorithmName hashAlgorithmName = GetDigestAlgorithm(); - IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithmName); + + IncrementalHash hasher; + + try + { + hasher = IncrementalHash.CreateHash(hashAlgorithmName); + } + catch (PlatformNotSupportedException ex) + { + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName), ex); + } if (_parentSignerInfo == null) { diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Oids.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Oids.cs index eded07b0913ebd..bcaa73082ebfc7 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Oids.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Oids.cs @@ -63,6 +63,9 @@ internal static class Oids public const string Sha256 = "2.16.840.1.101.3.4.2.1"; public const string Sha384 = "2.16.840.1.101.3.4.2.2"; public const string Sha512 = "2.16.840.1.101.3.4.2.3"; + public const string Sha3_256 = "2.16.840.1.101.3.4.2.8"; + public const string Sha3_384 = "2.16.840.1.101.3.4.2.9"; + public const string Sha3_512 = "2.16.840.1.101.3.4.2.10"; // RFC3161 Timestamping public const string TstInfo = "1.2.840.113549.1.9.16.1.4"; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs index 8ede25072e17e9..355d9e5763557d 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs @@ -691,6 +691,138 @@ public static void ComputeSignature_PreservesAttributeCertificate() Assert.Equal(countBefore + 1, countAfter); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsSha3))] + [InlineData(Oids.Sha3_256)] + [InlineData(Oids.Sha3_384)] + [InlineData(Oids.Sha3_512)] + public static void ComputeSignature_Rsa_Sha3_Roundtrip(string hashAlgorithm) + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content); + byte[] cmsBytes; + + using (X509Certificate2 cert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); + signer.DigestAlgorithm = new Oid(hashAlgorithm, null); + + cms.ComputeSignature(signer); + cmsBytes = cms.Encode(); + cms = new SignedCms(); + cms.Decode(cmsBytes); + cms.CheckSignature(true); // Assert.NoThrow + Assert.Single(cms.SignerInfos); + + SignerInfo signerInfo = cms.SignerInfos[0]; + Assert.Equal(hashAlgorithm, signerInfo.DigestAlgorithm.Value); + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsSha3))] + [InlineData(Oids.Sha3_256)] + [InlineData(Oids.Sha3_384)] + [InlineData(Oids.Sha3_512)] + public static void ComputeSignature_Ecdsa_Sha3_Roundtrip(string hashAlgorithm) + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content); + byte[] cmsBytes; + + using (X509Certificate2 cert = Certificates.ECDsaP521Win.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); + signer.DigestAlgorithm = new Oid(hashAlgorithm, null); + + cms.ComputeSignature(signer); + cmsBytes = cms.Encode(); + cms = new SignedCms(); + cms.Decode(cmsBytes); + cms.CheckSignature(true); // Assert.NoThrow + Assert.Single(cms.SignerInfos); + + SignerInfo signerInfo = cms.SignerInfos[0]; + Assert.Equal(hashAlgorithm, signerInfo.DigestAlgorithm.Value); + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.DoesNotSupportSha3))] + [InlineData(Oids.Sha3_256)] + [InlineData(Oids.Sha3_384)] + [InlineData(Oids.Sha3_512)] + public static void ComputeSignature_Sha3_NotSupported(string hashAlgorithm) + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content); + + using (X509Certificate2 cert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); + signer.DigestAlgorithm = new Oid(hashAlgorithm, null); + + Assert.Throws(() => cms.ComputeSignature(signer)); + } + } + + [Fact] + public static void ExistingDocument_Rsa_Sha3_256() + { + SignedCms cms = new SignedCms(); + cms.Decode(SignedDocuments.Rsa_Sha3_256_SignedDocument); + + if (PlatformDetection.SupportsSha3) + { + cms.CheckSignature(true); // Assert.NoThrow + Assert.Single(cms.SignerInfos); + + SignerInfo signerInfo = cms.SignerInfos[0]; + Assert.Equal(Oids.Sha3_256, signerInfo.DigestAlgorithm.Value); + } + else + { + Assert.Throws(() => cms.CheckSignature(true)); + } + } + + [Fact] + public static void ExistingDocument_Rsa_Sha3_384() + { + SignedCms cms = new SignedCms(); + cms.Decode(SignedDocuments.Rsa_Sha3_384_SignedDocument); + + if (PlatformDetection.SupportsSha3) + { + cms.CheckSignature(true); // Assert.NoThrow + Assert.Single(cms.SignerInfos); + + SignerInfo signerInfo = cms.SignerInfos[0]; + Assert.Equal(Oids.Sha3_384, signerInfo.DigestAlgorithm.Value); + } + else + { + Assert.Throws(() => cms.CheckSignature(true)); + } + } + + [Fact] + public static void ExistingDocument_Rsa_Sha3_512() + { + SignedCms cms = new SignedCms(); + cms.Decode(SignedDocuments.Rsa_Sha3_512_SignedDocument); + + if (PlatformDetection.SupportsSha3) + { + cms.CheckSignature(true); // Assert.NoThrow + Assert.Single(cms.SignerInfos); + + SignerInfo signerInfo = cms.SignerInfos[0]; + Assert.Equal(Oids.Sha3_512, signerInfo.DigestAlgorithm.Value); + } + else + { + Assert.Throws(() => cms.CheckSignature(true)); + } + } + private static void VerifyWithExplicitPrivateKey(X509Certificate2 cert, AsymmetricAlgorithm key) { using (var pubCert = new X509Certificate2(cert.RawData)) diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs index cce3114824794e..7001b325cd4029 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs @@ -1626,5 +1626,168 @@ internal static class SignedDocuments "6AB46C76047604BA7DF071EE0137B73F4D9DF616095C8F1CA9EB925B6D4C6ABC" + "FFEB73A81903169C6B487B316AFC951F696831A4B29B9ABCEA7EBCD243A553D2" + "F8B44FDA1B0AC0").HexToByteArray(); + + // produced with + // echo -n hello | openssl cms -sign -signer cert.pfx -md sha3-256 -nodetach + internal static readonly byte[] Rsa_Sha3_256_SignedDocument =( + "308205C806092A864886F70D010702A08205B9308205B5020101310D300B" + + "0609608648016503040208301406092A864886F70D010701A00704056865" + + "6C6C6FA08203303082032C30820214A003020102020900E0D8AB6819D730" + + "6E300D06092A864886F70D01010B05003038313630340603550403132D54" + + "776F2074686F7573616E6420666F7274792065696768742062697473206F" + + "662052534120676F6F646E657373301E170D313731313033323335313135" + + "5A170D3138313130333233353131355A3038313630340603550403132D54" + + "776F2074686F7573616E6420666F7274792065696768742062697473206F" + + "662052534120676F6F646E65737330820122300D06092A864886F70D0101" + + "0105000382010F003082010A028201010096C114A5898D09133EF859F89C" + + "1D848BA8CB5258793E05B92D499C55EEFACE274BBBC26803FB813B9C11C6" + + "898153CC1745DED2C4D2672F807F0B2D957BC4B65EBC9DDE26E2EA7B2A6F" + + "E9A7C4D8BD1EF6032B8F0BB6AA33C8B57248B3D5E3901D8A38A283D7E25F" + + "F8E6F522381EE5484234CFF7B30C174635418FA89E14C468AD89DCFCBBB5" + + "35E5AF53510F9EA7F9DA8C1B53375B6DAB95A291439A5648726EE1012E41" + + "388E100691642CF6917F5569D8351F2782F435A579014E8448EEA0C4AECA" + + "FF2F476799D88457E2C8BCB56E5E128782B4FE26AFF0720D91D52CCAFE34" + + "4255808F5271D09F784F787E8323182080915BE0AE15A71D66476D0F264D" + + "D084F30203010001A3393037301D0603551D0E04160414745B5F12EF962E" + + "84B897E246D399A2BADEA9C5AC30090603551D1304023000300B0603551D" + + "0F040403020780300D06092A864886F70D01010B0500038201010087A15D" + + "F37FBD6E9DED7A8FFF25E60B731F635469BA01DD14BC03B2A24D99EFD8B8" + + "94E9493D63EC88C496CB04B33DF25222544F23D43F4023612C4D97B719C1" + + "F9431E4DB7A580CDF66A3E5F0DAF89A267DD187ABFFB08361B1F79232376" + + "AA5FC5AD384CC2F98FE36C1CEA0B943E1E3961190648889C8ABE8397A5A3" + + "38843CBFB1D8B212BE46685ACE7B80475CC7C97FC0377936ABD5F664E9C0" + + "9C463897726650711A1110FA9866BC1C278D95E5636AB96FAE95CCD67FD5" + + "72A8C727E2C03E7B242457318BEC1BE52CA5BD9454A0A41140AE96ED1C56" + + "D220D1FD5DD3B1B4FB2AA0E04FC94F7E3C7D476F298962245563953AD722" + + "5EDCEAC8B8509E49292E62D8BF3182025530820251020101304530383136" + + "30340603550403132D54776F2074686F7573616E6420666F727479206569" + + "6768742062697473206F662052534120676F6F646E657373020900E0D8AB" + + "6819D7306E300B0609608648016503040208A081E4301806092A864886F7" + + "0D010903310B06092A864886F70D010701301C06092A864886F70D010905" + + "310F170D3233303531373139333732315A302F06092A864886F70D010904" + + "312204203338BE694F50C5F338814986CDF0686453A888B84F424D792AF4" + + "B9202398F392307906092A864886F70D01090F316C306A300B0609608648" + + "01650304012A300B0609608648016503040116300B060960864801650304" + + "0102300A06082A864886F70D0307300E06082A864886F70D030202020080" + + "300D06082A864886F70D0302020140300706052B0E030207300D06082A86" + + "4886F70D0302020128300D06092A864886F70D0101010500048201002CDE" + + "D12EA41BA5443CE742A804E754D00AA8A21B4B9022780DF59BD597EA44DD" + + "85EEE42AA531A645CD11CAA58297190C06A8193CE7AF16B1FD8B9DF4E2FA" + + "15024E8E845D0E3537577C6F27CEB3317D57781B618388FFB61926D24B1F" + + "75E0CC460C52FFB43D8DDA1B7AFBCD76C00EECF99F7F7D2A02B19A055C9B" + + "A5437ADE06537F4194F15AD0C5071F0275128B435B8883FE8E2E07F6B908" + + "33B9FB56015FE57B3BEC08A5B9031AB8D372C662DCA6E3CDEA5D3F3FC76E" + + "02F8E52045386B8D83D46C6300F5B54B2135F6392DD0B6A9C5531E7C9405" + + "B48BF1DA5C5C7B9D6E00937673C7C97DB3B2DB6945D7C8F0F8E455AAF4DF" + + "6F7D7A7726B09B6025ED6DE21864").HexToByteArray(); + + // produced with + // echo -n hello | openssl cms -sign -signer cert.pfx -md sha3-384 -nodetach + internal static readonly byte[] Rsa_Sha3_384_SignedDocument = ( + "308205D806092A864886F70D010702A08205C9308205C5020101310D300B" + + "0609608648016503040209301406092A864886F70D010701A00704056865" + + "6C6C6FA08203303082032C30820214A003020102020900E0D8AB6819D730" + + "6E300D06092A864886F70D01010B05003038313630340603550403132D54" + + "776F2074686F7573616E6420666F7274792065696768742062697473206F" + + "662052534120676F6F646E657373301E170D313731313033323335313135" + + "5A170D3138313130333233353131355A3038313630340603550403132D54" + + "776F2074686F7573616E6420666F7274792065696768742062697473206F" + + "662052534120676F6F646E65737330820122300D06092A864886F70D0101" + + "0105000382010F003082010A028201010096C114A5898D09133EF859F89C" + + "1D848BA8CB5258793E05B92D499C55EEFACE274BBBC26803FB813B9C11C6" + + "898153CC1745DED2C4D2672F807F0B2D957BC4B65EBC9DDE26E2EA7B2A6F" + + "E9A7C4D8BD1EF6032B8F0BB6AA33C8B57248B3D5E3901D8A38A283D7E25F" + + "F8E6F522381EE5484234CFF7B30C174635418FA89E14C468AD89DCFCBBB5" + + "35E5AF53510F9EA7F9DA8C1B53375B6DAB95A291439A5648726EE1012E41" + + "388E100691642CF6917F5569D8351F2782F435A579014E8448EEA0C4AECA" + + "FF2F476799D88457E2C8BCB56E5E128782B4FE26AFF0720D91D52CCAFE34" + + "4255808F5271D09F784F787E8323182080915BE0AE15A71D66476D0F264D" + + "D084F30203010001A3393037301D0603551D0E04160414745B5F12EF962E" + + "84B897E246D399A2BADEA9C5AC30090603551D1304023000300B0603551D" + + "0F040403020780300D06092A864886F70D01010B0500038201010087A15D" + + "F37FBD6E9DED7A8FFF25E60B731F635469BA01DD14BC03B2A24D99EFD8B8" + + "94E9493D63EC88C496CB04B33DF25222544F23D43F4023612C4D97B719C1" + + "F9431E4DB7A580CDF66A3E5F0DAF89A267DD187ABFFB08361B1F79232376" + + "AA5FC5AD384CC2F98FE36C1CEA0B943E1E3961190648889C8ABE8397A5A3" + + "38843CBFB1D8B212BE46685ACE7B80475CC7C97FC0377936ABD5F664E9C0" + + "9C463897726650711A1110FA9866BC1C278D95E5636AB96FAE95CCD67FD5" + + "72A8C727E2C03E7B242457318BEC1BE52CA5BD9454A0A41140AE96ED1C56" + + "D220D1FD5DD3B1B4FB2AA0E04FC94F7E3C7D476F298962245563953AD722" + + "5EDCEAC8B8509E49292E62D8BF3182026530820261020101304530383136" + + "30340603550403132D54776F2074686F7573616E6420666F727479206569" + + "6768742062697473206F662052534120676F6F646E657373020900E0D8AB" + + "6819D7306E300B0609608648016503040209A081F4301806092A864886F7" + + "0D010903310B06092A864886F70D010701301C06092A864886F70D010905" + + "310F170D3233303531373139353133375A303F06092A864886F70D010904" + + "31320430720AEA11019EF06440FBF05D87AA24680A2153DF3907B23631E7" + + "177CE620FA1330FF07C0FDDEE54699A4C3EE0EE9D887307906092A864886" + + "F70D01090F316C306A300B060960864801650304012A300B060960864801" + + "6503040116300B0609608648016503040102300A06082A864886F70D0307" + + "300E06082A864886F70D030202020080300D06082A864886F70D03020201" + + "40300706052B0E030207300D06082A864886F70D0302020128300D06092A" + + "864886F70D010101050004820100208BB078601C3AA70070F74E70D34C73" + + "90CC21B06CB5566708C9287F191C08E71D476ABFBCE52AE21286D114746D" + + "B1CD32F5D1738347305CEEC67332F4B9B2B272183719212562FADFE4AD81" + + "1C257220EFB0E59C271D6006AA332175CAFEB295A53BC3148156D07312DB" + + "B215307DE92BC00BD45B3E819CF15F50F05AD34EC855A1387BBE11AF6200" + + "5E1AB04CE442BB9A14490D2BA96E8490E94BC10CFC0F32671443F9EB6E6C" + + "4AAE7F036D1CD4FB93AEFAFCFA98F705298157921304D1066A723671FF9A" + + "A63C6B06E2FA16763F1A8D5A9B048BBEF5C5BF6906615A9C279532FF6AAC" + + "45361541683350FF343D3496C79EE503F1D1BF60F9CBBB562F14DCC4B80A").HexToByteArray(); + + // produced with + // echo -n hello | openssl cms -sign -signer cert.pfx -md sha3-512 -nodetach + internal static readonly byte[] Rsa_Sha3_512_SignedDocument = ( + "308205E906092A864886F70D010702A08205DA308205D6020101310D300B" + + "060960864801650304020A301406092A864886F70D010701A00704056865" + + "6C6C6FA08203303082032C30820214A003020102020900E0D8AB6819D730" + + "6E300D06092A864886F70D01010B05003038313630340603550403132D54" + + "776F2074686F7573616E6420666F7274792065696768742062697473206F" + + "662052534120676F6F646E657373301E170D313731313033323335313135" + + "5A170D3138313130333233353131355A3038313630340603550403132D54" + + "776F2074686F7573616E6420666F7274792065696768742062697473206F" + + "662052534120676F6F646E65737330820122300D06092A864886F70D0101" + + "0105000382010F003082010A028201010096C114A5898D09133EF859F89C" + + "1D848BA8CB5258793E05B92D499C55EEFACE274BBBC26803FB813B9C11C6" + + "898153CC1745DED2C4D2672F807F0B2D957BC4B65EBC9DDE26E2EA7B2A6F" + + "E9A7C4D8BD1EF6032B8F0BB6AA33C8B57248B3D5E3901D8A38A283D7E25F" + + "F8E6F522381EE5484234CFF7B30C174635418FA89E14C468AD89DCFCBBB5" + + "35E5AF53510F9EA7F9DA8C1B53375B6DAB95A291439A5648726EE1012E41" + + "388E100691642CF6917F5569D8351F2782F435A579014E8448EEA0C4AECA" + + "FF2F476799D88457E2C8BCB56E5E128782B4FE26AFF0720D91D52CCAFE34" + + "4255808F5271D09F784F787E8323182080915BE0AE15A71D66476D0F264D" + + "D084F30203010001A3393037301D0603551D0E04160414745B5F12EF962E" + + "84B897E246D399A2BADEA9C5AC30090603551D1304023000300B0603551D" + + "0F040403020780300D06092A864886F70D01010B0500038201010087A15D" + + "F37FBD6E9DED7A8FFF25E60B731F635469BA01DD14BC03B2A24D99EFD8B8" + + "94E9493D63EC88C496CB04B33DF25222544F23D43F4023612C4D97B719C1" + + "F9431E4DB7A580CDF66A3E5F0DAF89A267DD187ABFFB08361B1F79232376" + + "AA5FC5AD384CC2F98FE36C1CEA0B943E1E3961190648889C8ABE8397A5A3" + + "38843CBFB1D8B212BE46685ACE7B80475CC7C97FC0377936ABD5F664E9C0" + + "9C463897726650711A1110FA9866BC1C278D95E5636AB96FAE95CCD67FD5" + + "72A8C727E2C03E7B242457318BEC1BE52CA5BD9454A0A41140AE96ED1C56" + + "D220D1FD5DD3B1B4FB2AA0E04FC94F7E3C7D476F298962245563953AD722" + + "5EDCEAC8B8509E49292E62D8BF3182027630820272020101304530383136" + + "30340603550403132D54776F2074686F7573616E6420666F727479206569" + + "6768742062697473206F662052534120676F6F646E657373020900E0D8AB" + + "6819D7306E300B060960864801650304020AA0820104301806092A864886" + + "F70D010903310B06092A864886F70D010701301C06092A864886F70D0109" + + "05310F170D3233303531373139353830395A304F06092A864886F70D0109" + + "043142044075D527C368F2EFE848ECF6B073A36767800805E9EEF2B1857D" + + "5F984F036EB6DF891D75F72D9B154518C1CD58835286D1DA9A38DEBA3DE9" + + "8B5A53E5ED78A84976307906092A864886F70D01090F316C306A300B0609" + + "60864801650304012A300B0609608648016503040116300B060960864801" + + "6503040102300A06082A864886F70D0307300E06082A864886F70D030202" + + "020080300D06082A864886F70D0302020140300706052B0E030207300D06" + + "082A864886F70D0302020128300D06092A864886F70D0101010500048201" + + "002E3AA896EB261EE1E8A552B4D5F7A466332EBAF90B74E2E563EC939E2C" + + "C4494D8A6C27BE9D23FD009EA4CD3734E3E5BFED0845156FBC2D520A223D" + + "17113658948955A0D95B1B8D7683D1A5E1AD6C41C8E4572C1D74D1B56B3E" + + "5E17E2E05AF4AA34919F34B01EB93C6614D0781CCE28B3281C9E10FEB5CE" + + "D0280E1B86761E06A315F027577DA15EDBBA19FC2095AC4D970FE718EAE8" + + "7F4AD106E6F4C674FD1958EE16EE07C54DAB405EC7A7A55A6D3B665427D4" + + "F11C632B4F605A41821A3F15B4F537FD5F0EE3426A7A03732AC946C3B435" + + "776A873A3DAE93FB8312C681144CF51F05CE37A0DB4C1544E178F88E421C" + + "0B5456D18C13B335DA808CE60C4E35F507").HexToByteArray(); } } From 5305f10553b65e3ba8abb593dcdd0e8ea80b99b0 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 18:23:30 -0400 Subject: [PATCH 40/47] Add multi-'block' tests for SHA3 --- .../tests/Sha3_256Tests.cs | 46 +++++++++++++++++++ .../tests/Sha3_384Tests.cs | 46 +++++++++++++++++++ .../tests/Sha3_512Tests.cs | 46 +++++++++++++++++++ 3 files changed, 138 insertions(+) diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs index b910f3b67933cf..04debe723873de 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_256Tests.cs @@ -265,6 +265,52 @@ public void SHA3_256_IsSupported_AgreesWithPlatformVersion() yield return (Msg: "e5022f4c7dfe2dbd207105e2f27aaedd5a765c27c0bc60de958b49609440501848ccf398cf66dfe8dd7d131e04f1432f32827a057b8904d218e68ba3b0398038d755bd13d5f168cfa8a11ab34c0540873940c2a62eace3552dcd6953c683fdb29983d4e417078f1988c560c9521e6f8c78997c32618fc510db282a985f868f2d973f82351d11", MD: "3293a4b9aeb8a65e1014d3847500ffc8241594e9c4564cbd7ce978bfa50767fe"); yield return (Msg: "b1f6076509938432145bb15dbe1a7b2e007934be5f753908b50fd24333455970a7429f2ffbd28bd6fe1804c4688311f318fe3fcd9f6744410243e115bcb00d7e039a4fee4c326c2d119c42abd2e8f4155a44472643704cc0bc72403b8a8ab0fd4d68e04a059d6e5ed45033b906326abb4eb4147052779bad6a03b55ca5bd8b140e131bed2dfada", MD: "f82d9602b231d332d902cb6436b15aef89acc591cb8626233ced20c0a6e80d7a"); yield return (Msg: "56ea14d7fcb0db748ff649aaa5d0afdc2357528a9aad6076d73b2805b53d89e73681abfad26bee6c0f3d20215295f354f538ae80990d2281be6de0f6919aa9eb048c26b524f4d91ca87b54c0c54aa9b54ad02171e8bf31e8d158a9f586e92ffce994ecce9a5185cc80364d50a6f7b94849a914242fcb73f33a86ecc83c3403630d20650ddb8cd9c4", MD: "4beae3515ba35ec8cbd1d94567e22b0d7809c466abfbafe9610349597ba15b45"); + + // First 5 from SHA3_256LongMsg.rsp + yield return ( + Msg: + "b1caa396771a09a1db9bc20543e988e359d47c2a616417bbca1b62cb02796a888fc6eeff5c0b5c3d5062fcb4256f6ae1782f492c1cf03610b4a1fb7b814c057878e1190b9835425c7a4a0e182ad1f91535ed2a35033a5d8c670e21c575ff43c194a58a82d4a1a44881dd61f9f8161fc6b998860cbe4975780be93b6f87980bad0a99aa2cb7556b47" + + "8ca35d1f3746c33e2bb7c47af426641cc7bbb3425e2144820345e1d0ea5b7da2c3236a52906acdc3b4d34e474dd714c0c40bf006a3a1d889a632983814bbc4a14fe5f159aa89249e7c738b3b73666bac2a615a83fd21ae0a1ce7352ade7b278b587158fd2fabb217aa1fe31d0bda53272045598015a8ae4d8cec226fefa58daa05500906c4d85e75" + + "67", + MD: "cb5648a1d61c6c5bdacd96f81c9591debc3950dcf658145b8d996570ba881a05"); + + yield return ( + Msg: + "712b03d9ebe78d3a032a612939c518a6166ca9a161183a7596aa35b294d19d1f962da3ff64b57494cb5656e24adcf3b50e16f4e52135d2d9de76e94aa801cf49db10e384035329c54c9455bb3a9725fd9a44f44cb9078d18d3783d46ce372c31281aecef2f8b53d5702b863d71bc5786a33dd15d9256103b5ff7572f703d5cde6695e6c84f239acd" + + "1d6512ef581330590f4ab2a114ea064a693d5f8df5d908587bc7f998cde4a8b43d8821595566597dc8b3bf9ea78b154bd8907ee6c5d4d8a851f94be510962292b7ddda04d17b79fab4c022deb400e5489639dbc448f573d5cf72073a8001b36f73ac6677351b39d9bdb900e9a1121f488a7fa0aee60682e7dc7c531c85ec0154593ded3ae70e4121" + + "cae58445d8896b549cacf22d07cdace7625d57158721b44851d796d6511c38dac28dd37cbf2d7073b407fbc813149adc485e3dacee66755443c389d2d90dc70d8ff91816c0c5d7adbad7e30772a1f3ce76c72a6a2284ec7f174aefb6e9a895c118717999421b470a9665d2728c3c60c6d3e048d58b43c0d1b5b2f00be8b64bfe453d1e8fadf56993" + + "31f9", + MD: "095dcd0bc55206d2e1e715fb7173fc16a81979f278495dfc69a6d8f3174eba5a"); + + yield return ( + Msg: + "2a459282195123ebc6cf5782ab611a11b9487706f7795e236df3a476404f4b8c1e9904e2dc5ef29c5e06b179b8649707928c3913d1e53164747f1fa9bba6eeaf8fb759d71e32adc8c611d061345882f1cdeee3ab4cab3554adb2e43f4b01c37b4546994b25f4dcd6c497bc206865643930157cb5b2f4f25be235fa223688535907efcc253bcd0830" + + "21407ea09cb1c34684aa0c1849e7efe2d9af6938c46525af9e5afb4da6e5b83da4b61dc718672a8090549cbe5aadb44f5bc93a6b3fbdc2e6d32e2eaaae637465179ea17f23ad1e4f1ebc328e2c6dc90c302b74a1edbbb0676c136b269d70c41040a313af06ab291bf489d9700950b77f207c1fc41884799931b3bca8b93331a6e96b7a3f0a8bd24c" + + "db64964c377e0512f36444bb0643a4e3ecb328194cd5428fd89ede167472a14a9bf5730aff1e3b2c708de96eff1ebaaf63beb75f9c7d8034d6e5471e8f8a1f7efce37793a958e134619c19c54d3d42645f7a7263f25471fbaae8be3ea2fbd34ec6d7aacd7d5680948c3cd9a837c9c469a88f600d95829f4d1e4e4a5ef4ed4623c07815a1c33d9fb3" + + "b91333ff04eac92806a68a46cf2e9293f8bff466ce87fe66b46fbff7c238c7f9b2c92eb2fdc7d8084167f6f4e680d03301e5c33f78f1857d6863b1b8c36c7fce3e07d2a96a8979712079ae0023a1e3970165bfcf3a5463d2a4fdf1ca0e044f9a247528cd935734cb6d85ba53ceb95325c0eaf0ff5cd81ecb32e58917eb26bfc52dba3704bf5a927f" + + "ee3220", + MD: "cb1c691c87244c0caf733aacd427f83412cd48820b358c1b15dd9fadee54e5af"); + + yield return ( + Msg: + "32659902674c94473a283be00835eb86339d394a189a87da41dad500db27da6b6a4753b2bb219c961a227d88c6df466ba2fc1e9a2d4c982db4398778c76714d5e9940da48bc3808f3c9989131a07683b8c29d6af336e9aee1dfa57d83c48a86f17146edec07869bb06550689ebf4788159ed0a921048b4a6e3e3ec272413bec15d8e1f6a40897fa0" + + "e11d9df223ef9fc270106249ae220fdc6ebdef6d6611805421ccc850f53ee9c836baf657a94005883b5a85def344d218264f07b2ea8714afcc941096c6ded0bb6bf5b8bf652fd15a21931c58c9f526e27363ddff98c0a25bc7af9f469ab35bffea948b333f042cc18a82cec0177f33c3bdbf185b580353de79e51e675b03b31e195f19ba1f063d44" + + "def0441dc52820426c2c61cf12974ec249fd3502f017ffa06220075ced7e2d6b86a52677ba3916e8e8726062aec5bc8ea1c18b1e4137680b2c9d002191b423bee8691bd7e0f93c3b9959bc1c14d5c5cbe8f7c9c336aa16e9de9faa12f3f048c66d04cb441eb2bbc5e8a91e052c0f9000856896f9b7ba30c1e2eead36fc7ac30a7d3ddfc65caaba0e" + + "3b292d26dfba46b5e2dc9bc9acadde1c9f52b2969299bd1281ddff65822b629cfba2928613200e73661b803afdcc4a817d9361389e975e67dfadd22a797bdaf991ddf42db18711c079ecec55925f9978e478612609bacd900172011c27e24bad639ffc24a23877278318872153aef6893ccb5b68b94b33154df7334375aadd3edbb35272cc7b672d" + + "ec68faa62900873ded52f6049891b77f2d0311a84b19b73660e09d1f1998095c1da1edecfa9f741b5fd6db048dd68255085d43529279021d59ed853470d6863b7c8e07fcb0d1e6acfb1eb16f7f60bb1f46ce70493010e57930a3b4b8b87e065272f6f1dd31df057627f4214e58798b664e1e40960f2789d44ccacfb3dbd8b02a68a053976711f803" + + "4c1ed3a8", + MD: "5ac9275e02543410359a3f364b2ae3b85763321fd6d374d13fe54314e5561b01"); + + yield return ( + Msg: + "a65da8277a3b3738432bca9822d43b3d810cdad3b0ed2468d02bd269f1a416cd77392190c2dde8630eeb28a297bda786017abe9cf82f14751422ac9fff6322d5d9a33173db49792d3bc37fff501af667f7ca3dd335d028551e04039ef5a9d42a9443e1b80ea872fd945ad8999514ae4a29a35f60b0f7e971b67ae04d1ba1b53470c03847a3225c3d" + + "df593a57aed3599661ae2d2bb1cddd2fa62c4a94b8704c5c35c33e08e2debe54e567ae21e27e7eb36593ae1c807a8ef8b5c1495b15412108aaf3fce4130520aa6e2d3bdf7b3ea609fdf9ea1c64258435aae2e58a7b3abda198f979c17dbe0aa74253e979bf3a5800f388ea11a7f7454c4e36270a3083a790c77cbe89693205b32880c0d8f79b1c00" + + "0ee9b5e58f175ba7696616c17c45673cff25d1221f899836e95cc9e26a887a7115c4537e65ad4eacc319ba98a9a8860c089cbc76e7ea4c984d900b80622afbbbd1c0cdc670e3a4c523f81c77fed38b6aa988876b097da8411cc48e9b25a826460a862aa3fadfe75952aa4347c2effebdac9138ebcc6c34991e9f5b19fc2b847a87be72ff49c99ecf" + + "19d837ee3e23686cd760d9dd7adc78091bca79e42fdb9bc0120faec1a6ca52913e2a0156ba9850e1f39d712859f7fdf7daedf0e206dff67e7121e5d1590a8a068947a8657d753e83c7f009b6b2e54acc24afc9fdc9601a1d6d9d1f17aab0ce96c4d83405d1e3baba1dffa86ecccee7f1c1b80b1bbf859106ce2b647ae1e4a6a9b584ae1dfc0a4dee" + + "bb755638f1d95dcc79b1be263177e2a05c72bde545d09ba726f41d9547117e876af81bfc672e33c71442eb05675d9552df1b313d1f9934f9ddd08955fa21d6edf23000a277f6f149591299a0a96032861ecdc96bb76afa05a2bffb445d61dc891bc70c13695920b911cad0df3fa842a3e2318c57556974343f69794cb8fa18c1ad624835857e4781" + + "041198aa705c4d11f3ef82e941be2aee7a770e54521312fe6facbaf1138eee08fa90fae986a5d93719aeb30ac292a49c1d91bf4574d553a92a4a6c305ab09db6bbeffd84c7aa707f1c1628a0220d6ba4ee5e960566686228a6e766d8a30dddf30ed5aa637c949950c3d0e894a7560670b6879a7d70f3c7e5ab29aed236cc3527bdea076fec8add12" + + "d784fbcf9a", + MD: "68f62c418a6b97026cc70f6abf8419b671ee373709fa13074e37bd39f0a50fcb"); } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs index 96671ad9031399..468c38823fbc11 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_384Tests.cs @@ -239,6 +239,52 @@ public void SHA3_384_IsSupported_AgreesWithPlatformVersion() yield return (Msg: "3bceedf5df8fe699871decb7dd48203e2518fb0fce0f865f46adce5c133a921320bf40915456204869a3ceb5fca3ed40e0a41a64b8951f0fc580694cfc55bd1f5ce926b07e3e32ac6e055de9b961ce49c7ee41e06b024559b933a79518192e969855889c85d1", MD: "60d7f8bd85fb7a13701db5aded2b7771ab5e476ec34f1fd4298978defbd2b31bb2979391559a164b3ed28f6a39031a11"); yield return (Msg: "6c36147652e71b560becbca1e7656c81b4f70bece26321d5e55e67a3db9d89e26f2f2a38fd0f289bf7fa22c2877e38d9755412794cef24d7b855303c332e0cb5e01aa50bb74844f5e345108d6811d5010978038b699ffaa370de8473f0cda38b89a28ed6cabaf6", MD: "b1319192df11faa00d3c4b068becc8f1ba3b00e0d1ff1f93c11a3663522fdb92ab3cca389634687c632e0a4b5a26ce92"); yield return (Msg: "92c41d34bd249c182ad4e18e3b856770766f1757209675020d4c1cf7b6f7686c8c1472678c7c412514e63eb9f5aee9f5c9d5cb8d8748ab7a5465059d9cbbb8a56211ff32d4aaa23a23c86ead916fe254cc6b2bff7a9553df1551b531f95bb41cbbc4acddbd372921", MD: "71307eec1355f73e5b726ed9efa1129086af81364e30a291f684dfade693cc4bc3d6ffcb7f3b4012a21976ff9edcab61"); + + // First 5 from SHA3_384LongMsg.rsp + yield return ( + Msg: + "5fe35923b4e0af7dd24971812a58425519850a506dfa9b0d254795be785786c319a2567cbaa5e35bcf8fe83d943e23fa5169b73adc1fcf8b607084b15e6a013df147e46256e4e803ab75c110f77848136be7d806e8b2f868c16c3a90c14463407038cb7d9285079e" + + "f162c6a45cedf9c9f066375c969b5fcbcda37f02aacff4f31cded3767570885426bebd9eca877e44674e9ae2f0c24cdd0e7e1aaf1ff2fe7f80a1c4f5078eb34cd4f06fa94a2d1eab5806ca43fd0f06c60b63d5402b95c70c21ea65a151c5cfaf8262a46be3c72226" + + "4b", + MD: "3054d249f916a6039b2a9c3ebec1418791a0608a170e6d36486035e5f92635eaba98072a85373cb54e2ae3f982ce132b"); + + yield return ( + Msg: + "035adcb639e5f28bb5c88658f45c1ce0be16e7dafe083b98d0ab45e8dcdbfa38e3234dfd973ba555b0cf8eea3c82ae1a3633fc565b7f2cc839876d3989f35731be371f60de140e3c916231ec780e5165bf5f25d3f67dc73a1c33655dfdf439dfbf1cbba8b779158a" + + "810ad7244f06ec078120cd18760af436a238941ce1e687880b5c879dc971a285a74ee85c6a746749a30159ee842e9b03f31d613dddd22975cd7fed06bd049d772cb6cc5a705faa734e87321dc8f2a4ea366a368a98bf06ee2b0b54ac3a3aeea637caebe70ad09ccd" + + "a93cc06de95df73394a87ac9bbb5083a4d8a2458e91c7d5bf113aecae0ce279fdda76ba690787d26345e94c3edbc16a35c83c4d071b132dd81187bcd9961323011509c8f644a1c0a3f14ee40d7dd186f807f9edc7c02f6761061bbb6dd91a6c96ec0b9f10edbbd29" + + "dc52", + MD: "02535d86cc7518484a2a238c921b739b1704a50370a2924abf39958c5976e658dc5e87440063112459bddb40308b1c70"); + + yield return ( + Msg: + "7f25b2c0eb1a6911cc3328fcdcd40f28f010375f7b1b51a05402896fb999b17093b59b34fb9cc653feba3dbb9d96bd47180416946d9bd3101b691d532be6ddb3712721121054c1fb3c5c42ee44e7faf7cf8d75856545187a3220047f07373e9aa2e10c022f2aa232" + + "0f81fd3cd7b110609c131edd6e016707228d069a55731a4ead4d24ab6206b01ffd91384e60db45a907fed7428db707de721aeb4c1b84baf61ad230b6b0d034eb90f4b9cbe64de2fb98b6695dcc4f4129aa2e7a3f635166bb72d7faca227076bd5013495c72ef2e7d" + + "d8a39cd532b15d0d53307c1834c265c53cc64890becfbebec454afa90ba973584e2d3752c7c6a3b4f48aba8297bf013b0006e3b08ed354157420b559b963f7b383bd047e94745a4615a3f9239230804547ff93d19a657fece8e02114840504b7fdb9c9fea0a4ccea" + + "3ee304a330fd2b0d97191f9be86e8968a9fabc847577e08b468b4f7df43f3fc9f8b2a2ab760f4ab87bbc51b883d4b8b33ed84e4f93a1d359e6995ea1962bfc0bca789ae36e4c25717850efcd708155f52fe09f1de76b2746634dbe1290524bd73d9db5f21f9d035e" + + "183dc2", + MD: "927962c873a69caa05cadc1cb485eb1cbb07748e47d942192df4af9233f42b95a638918306ae83a8237d21c2824f666d"); + + yield return ( + Msg: + "386f98670b177683d0b804c5875fe9c7afa233ee66349c9fd1b60bb0becf5e1d887e67fd3baf34b4f90d94699d18d6bb9d77d4af358f31edc254de2d6c5fe3ec07425c633b18c1b9e3606b78b40b543e1fd31fb578cf58c45744fc073fbf3c7d7d607e815379a5fc" + + "565892d81560eab8fb5f1ae6771b998c592e6d288014f13ab283d53fcbfa66e31a9d107308402191fac2cf2b799c7dae91b93a7676898b8a6e516a86eac58ed8f6d8ed2fd4d38031e4a4466dc8798b90c48e6adb6b4391d47872443cfaffa542b4b132f6c3408f00" + + "81af8692aadb4c9bbd55053ea56d8b82998f6b4b41d331891acfe6af1bb0d6679989978368ea463743b514866d2d01fb9950e8990867bc14f1db1142254adeccf3da812949cd03cd1d569e9d0bab7ca7405cc21096e3cd4d007cbb9629372e98584b4c6b97ad0bc3" + + "14e1ab6ac71184ee555c01973570ed9b115bed956f9e4e349083013098b1e483f0fe44d5e9849f38a2f7ae152b36a266ea1faf263ea8c706632ba8629602187379546fc6b82e57ededd6d074c15c771754710731e07c207899eb47e8d7c72ffd768c36257d373375" + + "ffa06f9b3f0af11417f9ff9f9b44e1f1f96ae8aaa429af88b14da1da81c7bb38a0fe9372ed6a9ac6fb5e9e56b82593d94c5192904450227bf040b7ce0904789f979845e112a1f995c849ec3f7e49bd975a474e8201630f40fc0d80e76019f110ae158cd0f8da96ea" + + "4561f242", + MD: "d30ec9a7baeabe40f6648a624dddf8721c89542e258f0fa9afcc9e68433faef781824048b0b771a94e8f0c17a403f9fb"); + + yield return ( + Msg: + "8c569727f1d4548f1c66a5c830346259612d10c5fef90518ae2fcdbffac9cd9c0bd5265ab56ddcfeb5e838bf37526a189c1a731b790b4208e37d1d1eeacd43b1630ad07debf1e03a281cf7715276a18df2f25535ea7d9fd9b6317f8bf1cb0c111b5f5c38994aa86b" + + "fd69ac8388884de1ed1d7eba583764b3afb1b8ae18ab6ee3bb3a9432c95f7cb7bd361da0e270b73b1503b653cc20d9bd5766932e6655b250cc053e148218a449efed136e661627c4f10dc5a84d22462035b8d7b4e4b11f7fd5272385cd5d67471bf556951e63e4a4" + + "09a17260e324f203d2104be798a8ff985e080b2eb1160fdacab6aebe123d3802e5298624960f268fb4d4b9708c2098c5ef10beb6362be2298298e391498e69060e0bca9b6fc92aec656ee7f6c802342c11a703c76484295dce03bcb5cb3cc0da0bb1036e753b4641" + + "6d449d22523719f54b35a306440a2b9d335f03d3a03085a36481fc44b14dc2b652c0a59c34a68f492622671ddda332123b147e92d153008ca2e57cc629e8e5759e48c60b7636e05029d614b4373884e36d8af69b648c79ba4c444a9ce7f2f8a3d846c7171ed15231" + + "dcba75725bb26a395129329564c23758ea052f6df355436b89217169365e2f15c734510050f72c3c705afc29d6df838c0492f3e153f70ef338418ca9c5c4bd2373ad6f051ef1121351831affc4caa57e23525ea111c2a1636d0ee07fd4ed4584678e982ace8664e7" + + "7d0e55be356be558cead3755359c43e4b1f034916ac00e5f2b3d941767a069df7a61750e32aa8a3f8e0b48a5c56f3e9e8a4f518a8f2562dd48242b73f1266a24d2e64299c26fde5dead45737cb22d8b8839300104b04872645a925e77500afdd0c038404eda227da" + + "6a702db64e", + MD: "91e24f999cac1b9ab9ae456ecf47b52c1144ffd1df2d95feb05fce930e37ff767a005cf07bb7af45c8a73585e8544965"); } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs index ea61e3fe0d12d7..84b057436e7fc8 100644 --- a/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Sha3_512Tests.cs @@ -207,6 +207,52 @@ public void SHA3_512_IsSupported_AgreesWithPlatformVersion() yield return (Msg: "881ff70ca34a3e1a0e864fd2615ca2a0e63def254e688c37a20ef6297cb3ae4c76d746b5e3d6bb41bd0d05d7df3eeded74351f4eb0ac801abe6dc10ef9b635055ee1dfbf4144", MD: "9a10a7ce23c0497fe8783927f833232ae664f1e1b91302266b6ace25a9c253d1ecab1aaaa62f865469480b2145ed0e489ae3f3f9f7e6da27492c81b07e606fb6"); yield return (Msg: "b0de0430c200d74bf41ea0c92f8f28e11b68006a884e0d4b0d884533ee58b38a438cc1a75750b6434f467e2d0cd9aa4052ceb793291b93ef83fd5d8620456ce1aff2941b3605a4", MD: "9e9e469ca9226cd012f5c9cc39c96adc22f420030fcee305a0ed27974e3c802701603dac873ae4476e9c3d57e55524483fc01adaef87daa9e304078c59802757"); yield return (Msg: "0ce9f8c3a990c268f34efd9befdb0f7c4ef8466cfdb01171f8de70dc5fefa92acbe93d29e2ac1a5c2979129f1ab08c0e77de7924ddf68a209cdfa0adc62f85c18637d9c6b33f4ff8", MD: "b018a20fcf831dde290e4fb18c56342efe138472cbe142da6b77eea4fce52588c04c808eb32912faa345245a850346faec46c3a16d39bd2e1ddb1816bc57d2da"); + + // First 5 from SHA3_512LongMsg.rsp + yield return ( + Msg: + "664ef2e3a7059daf1c58caf52008c5227e85cdcb83b4c59457f02c508d4f4f69f826bd82c0cffc5cb6a97af6e561c6f96970005285e58f21ef6511d26e709889a7e513c434c90a3c" + + "f7448f0caeec7114c747b2a0758a3b4503a7cf0c69873ed31d94dbef2b7b2f168830ef7da3322c3d3e10cafb7c2c33c83bbf4c46a31da90cff3bfd4ccc6ed4b310758491eeba603a" + + "76", + MD: "e5825ff1a3c070d5a52fbbe711854a440554295ffb7a7969a17908d10163bfbe8f1d52a676e8a0137b56a11cdf0ffbb456bc899fc727d14bd8882232549d914e"); + + yield return ( + Msg: + "991c4e7402c7da689dd5525af76fcc58fe9cc1451308c0c4600363586ccc83c9ec10a8c9ddaec3d7cfbd206484d09634b9780108440bf27a5fa4a428446b3214fa17084b6eb197c5" + + "c59a4e8df1cfc521826c3b1cbf6f4212f6bfb9bc106dfb5568395643de58bffa2774c31e67f5c1e7017f57caadbb1a56cc5b8a5cf9584552e17e7af9542ba13e9c54695e0dc8f24e" + + "ddb93d5a3678e10c8a80ff4f27b677d40bef5cb5f9b3a659cc4127970cd2c11ebf22d514812dfefdd73600dfc10efba38e93e5bff47736126043e50f8b9b941e4ec3083fb762dbf1" + + "5c86", + MD: "cd0f2a48e9aa8cc700d3f64efb013f3600ebdbb524930c682d21025eab990eb6d7c52e611f884031fafd9360e5225ab7e4ec24cbe97f3af6dbe4a86a4f068ba7"); + + yield return ( + Msg: + "22e1df25c30d6e7806cae35cd4317e5f94db028741a76838bfb7d5576fbccab001749a95897122c8d51bb49cfef854563e2b27d9013b28833f161d520856ca4b61c2641c4e184800" + + "300aede3518617c7be3a4e6655588f181e9641f8df7a6a42ead423003a8c4ae6be9d767af5623078bb116074638505c10540299219b0155f45b1c18a74548e4328de37a911140531" + + "deb6434c534af2449c1abe67e18030681a61240225f87ede15d519b7ce2500bccf33e1364e2fbe6a8a2fe6c15d73242610ed36b0740080812e8902ee531c88e0359020797cbdd1fb" + + "78848ae6b5105961d05cdddb8af5fef21b02db94c9810464b8d3ea5f047b94bf0d23931f12df37e102b603cd8e5f5ffa83488df257ddde110106262e0ef16d7ef213e7b49c69276d" + + "4d048f", + MD: "a6375ff04af0a18fb4c8175f671181b4cf79653a3d70847c6d99694b3f5d41601f1dbef809675c63cac4ec83153b1c78131a7b61024ce36244f320ab8740cb7e"); + + yield return ( + Msg: + "8237ce9396ccde3a616754414cdf7b5a958c1eb7f25a48c2781b4e0dba220f8c350d7b02ece252b94f5e2e766189c4ac1a8e67f00acacead402316196a9b0a673e24a33f18b7cb6b" + + "e4a066d33e1c93abd8252feb1c8d9cff134ac0c0861150a463264e316172d0b8e7d6043f2bbf71bf97fa7f9070ca3a21b93853ec55ab67a96db884c2113bea0822a70ea46f9ae550" + + "1eb55ec74eaa3179fa96d7842092d9e023844ed96f3c9fc35bbc8ee953d677c636fdd578fd5507719e0c55702fed2eaf4f32b35ec29a7a515bbc8bf61f9baf89a77aeb8bc6f24770" + + "6c41d398cae5ec80b76abc3a5380001aea500eb31b10160139d5a8e8f1a976dd2dde5ce439a29dba24d370536a14bb87cf201e088e5e3397b3b61477c6a41e22a98af53cc34bc8c5" + + "5f15d7924e7e32fed4d3c3ddc2ac8eb1dfc438218c08c6a6a8eea888b208f6092dd9f9df49e7ede8bf11051afd23b0b983a81bcc8d00f7d1f2b27cb04c03aeee59c7df23a17775ae" + + "5984eda7", + MD: "f08819ec3a9a9806a1f55be4f0e56bce084e66fa271784974bf80e1bed7b2be559ebf5b6396ce52f7db7ef45543965f83064095a70328489178718b491a4100d"); + + yield return ( + Msg: + "cfa6c0413dfc1a619417ac3f80fd38247b56941da8c2adf3ff70cc5dabed1875b0395d69d1200b73b1c7820b38868c5b38f52bf3514a96be12e27e34601d95d21c6f51c700b4edf1" + + "cac4b2079d487418a4cc5f34f815f469c4b44ef1a7dbaaa9597026c59260c9c22736c49d76ecf7430500b74866cbcfdb5e0fc4fa46cf5ee2b06363ca4ecba6d0104440348d191ec4" + + "a4bcbc9763152ffe271a69b805a0b9656970913dfd9e8c02cd16af33a878f083c926f48ab79b1db969fec493aef6c31accc1378867808440a5d5990490b07568bc66e9872904a0f4" + + "6ae25ef4077b85ea217bdd12541a9472e2a9840e0d6ab55cc4a523f782f8c19774efbd41dad506bbafc90c438c14c780cab9fab9e74eb9452a0b29438a21878bcd4c6be4edac4e77" + + "bfd14a83d6152253a62e826de503880d37bf82d10924fab6bd23f04308a9660499bb223afcc5afd1bd2fa592d0322a9a30eab90bc7ac22018e99d2c8f573554c85b019d0c4cd75e3" + + "59e5e9907082a8d660b353588b5f085486d89bd97bb32335cbd8b9adf7d57c72c078d9d08d9c09a70e43da1f1fe5b398ef08d2e06111d9a9b25a893a5d84cd643b0ffab8ef2755f7" + + "81c1d6ca49", + MD: "3a4c2c9284c90515cb34a0895d0374e87467ffbbc7c1dda3239893a12aeae3b9951169fe85605ef7aa2c483662f3a65c72ff12becde50c23ec6a2bc8864c27c1"); } } } From a63991016f1a5d52a564c99a2ca047da4c13ab08 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 17 May 2023 19:12:18 -0400 Subject: [PATCH 41/47] Use a separate bool to track cached EVP handles --- .../Interop.EVP.DigestAlgs.cs | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) 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 8e6cdc0695c390..2497614a1f2b66 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 @@ -14,9 +14,12 @@ internal static partial class Crypto private static volatile IntPtr s_evpSha256; private static volatile IntPtr s_evpSha384; private static volatile IntPtr s_evpSha512; - private static volatile IntPtr s_evpSha3_256 = -1; - private static volatile IntPtr s_evpSha3_384 = -1; - private static volatile IntPtr s_evpSha3_512 = -1; + private static volatile IntPtr s_evpSha3_256; + private static volatile IntPtr s_evpSha3_384; + private static volatile IntPtr s_evpSha3_512; + private static volatile bool s_evpSha3_256Cached; + private static volatile bool s_evpSha3_384Cached; + private static volatile bool s_evpSha3_512Cached; [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpMd5(); @@ -51,20 +54,45 @@ private static IntPtr EvpSha512() => [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpSha3_256(); - private static IntPtr EvpSha3_256() => - s_evpSha3_256 != -1 ? s_evpSha3_256 : (s_evpSha3_256 = 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; + } [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpSha3_384(); - private static IntPtr EvpSha3_384() => - s_evpSha3_384 != -1 ? s_evpSha3_384 : (s_evpSha3_384 = 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; + } [LibraryImport(Libraries.CryptoNative)] private static partial IntPtr CryptoNative_EvpSha3_512(); - private static IntPtr EvpSha3_512() => - s_evpSha3_512 != -1 ? s_evpSha3_512 : (s_evpSha3_512 = 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; + } + internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) { From af7a6b14c86584a16801c5d1f8ec001df8f5b259 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 18 May 2023 14:36:04 -0400 Subject: [PATCH 42/47] Add a SHA3 certificate test --- .../tests/X509Certificates/CertTests.cs | 14 ++++++++++ .../tests/X509Certificates/ChainTests.cs | 16 +++++++++++ .../tests/X509Certificates/TestData.cs | 28 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs index b83841fcab79d8..770379abec4204 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs @@ -587,6 +587,20 @@ public static void CertificateWithTrailingDataCanBeRead() } } + [Fact] + public static void CertificateSha3Signed() + { + using (X509Certificate2 cert = new X509Certificate2(TestData.RsaSha3_256SignedCertificate)) + { + Assert.Equal("CN=potato", cert.Subject); + + using (RSA rsa = cert.PublicKey.GetRSAPublicKey()) + { + Assert.NotNull(rsa); + } + } + } + [ConditionalFact(typeof(PlatformSupport), nameof(PlatformSupport.PlatformCryptoProviderFunctional))] [OuterLoop("Hardware backed key generation takes several seconds.")] public static void CreateCertificate_MicrosoftPlatformCryptoProvider_EcdsaKey() diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs index 93b24685c937c7..23bef2b46c250a 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs @@ -1253,6 +1253,22 @@ public static void BuildChainForCertificateWithMD5Signature() } } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.SupportsSha3))] + [SkipOnPlatform(~TestPlatforms.Linux, "Only Linux SHA3 supports chain building.")] + public static void BuildChainForSelfSignedSha3Certificate() + { + using (ChainHolder chainHolder = new ChainHolder()) + using (X509Certificate2 cert = new X509Certificate2(TestData.RsaSha3_256SignedCertificate)) + { + X509Chain chain = chainHolder.Chain; + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + chain.ChainPolicy.VerificationTime = cert.NotBefore.AddHours(2); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(cert); + Assert.True(chain.Build(cert), AllStatusFlags(chain).ToString()); + } + } + internal static X509ChainStatusFlags AllStatusFlags(this X509Chain chain) { return chain.ChainStatus.Aggregate( diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs index 92d8606e3093b4..64c8d7e3a11062 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs @@ -2511,6 +2511,34 @@ internal struct ECDsaCngKeyValues "153ac22391a1603547ffb3f9b328c59e59b5d64568b9c451df233fe9a581116f" + "05be8c67b92bc7df9984f30535ad53817cb4abcd77cb521856").HexToByteArray(); + internal static byte[] RsaSha3_256SignedCertificate =( + "30820303308201eba00302010202147bcedeaa2286e1308106525ad7efbe" + + "fb88e96995300d060960864801650304030e05003011310f300d06035504" + + "030c06706f7461746f301e170d3233303531383138303135305a170d3233" + + "303631373138303135305a3011310f300d06035504030c06706f7461746f" + + "30820122300d06092a864886f70d01010105000382010f003082010a0282" + + "010100ef7fd4e037107937b690472066d58048580cfa3822dfb91b776e76" + + "dc1de93b7f72d613d836c423909f139f909f7e5b77c610c114f2accee09f" + + "ee9f431524480f31e246c42e31807cdd3cc831f3ef6b601df4f81ecfede1" + + "96f90f9ea25749a9cb7af32bdc4857a9f272a87acd5ca73b288ed8817f71" + + "6c1297166c76b097be22f4705f0678ce3057b05580418649b381a7bcb44f" + + "9cfd429cc788487d3632de477c1ac6d430d8beeeee258e094388b8b3a9c2" + + "7a4b48f2d049beb56de950585f3c6c6308321e53cb37894c1b2a0b55a731" + + "e7861f6342f3f451ea0977dd4ef65f95b3218702722df9aa3672888ee040" + + "5eb4f4969e416150fa5460637f0071d7e444190203010001a3533051301d" + + "0603551d0e04160414ab91d8c96f342fb48b7903361835b1a4e255534d30" + + "1f0603551d23041830168014ab91d8c96f342fb48b7903361835b1a4e255" + + "534d300f0603551d130101ff040530030101ff300d060960864801650304" + + "030e05000382010100bf3f9103c076fc81d3d0d7b770280d2cbe56eb568b" + + "24a4ea526eaec44408f3d6581968c45f20dc62c24da618b8453dd6874314" + + "82de6cb7e66826edc8daf10cb5273ae1fda4b290b6b0fa46431fdb92a03a" + + "71a0174d1f780f3de4b2d2a8067e230e77e8e8b8bc88a6e43f1fdfcd2280" + + "16de21af0a2e46f3401c5a598adc1532041b2b211087358fb15e71becd53" + + "43c6fe33b374cef8030556a42a97fdf7a1387cbbeaa4ee74a5525321355c" + + "d06582c8be0bc642e98e36fc94019b83e1fa3827db6b914e3cefb1127c89" + + "4160a40665fc6663e70f42c25de76dcdd8c6ad96deb53560e870ab826a86" + + "ad82f8f331c63b3b5f256af0b702cf2413f6a1dc37a57d1d69").HexToByteArray(); + internal static byte[] ConcatenatedPemFile = ByteUtils.AsciiBytes( @"-----BEGIN CERTIFICATE----- MIIFcDCCBFigAwIBAgIQB6krbZc11OZ5l2/FnU3CpTANBgkqhkiG9w0BAQsFADBG From 95a7cedcffd585378f77b468f6a355a08f9c39c6 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 19 May 2023 15:17:35 -0400 Subject: [PATCH 43/47] Change IsSupported to have backing fields to help enlighten JIT about SHA3 support --- .../src/System/Security/Cryptography/HMACSHA3_256.cs | 2 +- .../src/System/Security/Cryptography/HMACSHA3_384.cs | 2 +- .../src/System/Security/Cryptography/HMACSHA3_512.cs | 2 +- .../src/System/Security/Cryptography/SHA3_256.cs | 2 +- .../src/System/Security/Cryptography/SHA3_384.cs | 2 +- .../src/System/Security/Cryptography/SHA3_512.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs index 6821b27ba2c0af..d71c41bdf98540 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_256.cs @@ -74,7 +74,7 @@ public HMACSHA3_256(byte[] key) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_256); + public static bool IsSupported { get; } = HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_256); /// public override byte[] Key diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs index 2daf0af9a953d8..3e7497443098df 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_384.cs @@ -74,7 +74,7 @@ public HMACSHA3_384(byte[] key) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_384); + public static bool IsSupported { get; } = HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_384); /// public override byte[] Key diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs index f98dfd44ef957b..62a6bb4f174072 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA3_512.cs @@ -74,7 +74,7 @@ public HMACSHA3_512(byte[] key) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_512); + public static bool IsSupported { get; } = HashProviderDispenser.MacSupported(HashAlgorithmNames.SHA3_512); /// public override byte[] Key diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs index 9d165e154eea55..659fa2d2926550 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_256.cs @@ -42,7 +42,7 @@ protected SHA3_256() /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_256); + public static bool IsSupported { get; } = HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_256); /// /// Creates an instance of the default implementation of . diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs index 2a02dfb813f03b..d74787d4698e93 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_384.cs @@ -42,7 +42,7 @@ protected SHA3_384() /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_384); + public static bool IsSupported { get; } = HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_384); /// /// Creates an instance of the default implementation of . diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs index 840deca5328d7e..2c716453827a3c 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA3_512.cs @@ -42,7 +42,7 @@ protected SHA3_512() /// /// if the algorithm is supported; otherwise, . /// - public static bool IsSupported => HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_512); + public static bool IsSupported { get; } = HashProviderDispenser.HashSupported(HashAlgorithmNames.SHA3_512); /// /// Creates an instance of the default implementation of . From 81049b247a609a5e4e3c91176a2432b39006e311 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 19 May 2023 15:34:27 -0400 Subject: [PATCH 44/47] Change HashOneShotHelpers to use a switch --- .../Cryptography/HashOneShotHelpers.cs | 196 +++++------------- 1 file changed, 48 insertions(+), 148 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs index 0bcecf65650eff..e3aa2e87c6da48 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs @@ -12,40 +12,18 @@ internal static class HashOneShotHelpers { internal static byte[] HashData(HashAlgorithmName hashAlgorithm, ReadOnlySpan source) { - if (hashAlgorithm == HashAlgorithmName.SHA256) - { - return SHA256.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA1) - { - return SHA1.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA512) - { - return SHA512.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA384) - { - return SHA384.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_256) - { - return SHA3_256.IsSupported ? SHA3_256.HashData(source) : throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_384) - { - return SHA3_384.IsSupported ? SHA3_384.HashData(source) : throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_512) - { - return SHA3_512.IsSupported ? SHA3_512.HashData(source) : throw new PlatformNotSupportedException(); - } - else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) - { - return MD5.HashData(source); - } - - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + return hashAlgorithm.Name switch + { + HashAlgorithmNames.SHA256 => SHA256.HashData(source), + HashAlgorithmNames.SHA1 => SHA1.HashData(source), + HashAlgorithmNames.SHA512 => SHA512.HashData(source), + HashAlgorithmNames.SHA384 => SHA384.HashData(source), + HashAlgorithmNames.SHA3_256 => SHA3_256.HashData(source), + HashAlgorithmNames.SHA3_384 => SHA3_384.HashData(source), + HashAlgorithmNames.SHA3_512 => SHA3_512.HashData(source), + HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(source), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + }; } internal static bool TryHashData( @@ -54,84 +32,34 @@ internal static bool TryHashData( Span destination, out int bytesWritten) { - if (hashAlgorithm == HashAlgorithmName.SHA256) - { - return SHA256.TryHashData(source, destination, out bytesWritten); - } - else if (hashAlgorithm == HashAlgorithmName.SHA1) - { - return SHA1.TryHashData(source, destination, out bytesWritten); - } - else if (hashAlgorithm == HashAlgorithmName.SHA512) - { - return SHA512.TryHashData(source, destination, out bytesWritten); - } - else if (hashAlgorithm == HashAlgorithmName.SHA384) - { - return SHA384.TryHashData(source, destination, out bytesWritten); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_256) - { - return SHA3_256.IsSupported ? - SHA3_256.TryHashData(source, destination, out bytesWritten) : - throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_384) - { - return SHA3_384.IsSupported ? - SHA3_384.TryHashData(source, destination, out bytesWritten) : - throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_512) - { - return SHA3_512.IsSupported ? - SHA3_512.TryHashData(source, destination, out bytesWritten) : - throw new PlatformNotSupportedException(); - } - else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) - { - return MD5.TryHashData(source, destination, out bytesWritten); - } - - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + return hashAlgorithm.Name switch + { + HashAlgorithmNames.SHA256 => SHA256.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.SHA1 => SHA1.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.SHA512 => SHA512.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.SHA384 => SHA384.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.SHA3_256 => SHA3_256.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.SHA3_384 => SHA3_384.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.SHA3_512 => SHA3_512.TryHashData(source, destination, out bytesWritten), + HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.TryHashData(source, destination, out bytesWritten), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + }; } internal static byte[] HashData(HashAlgorithmName hashAlgorithm, Stream source) { - if (hashAlgorithm == HashAlgorithmName.SHA256) - { - return SHA256.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA1) - { - return SHA1.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA512) - { - return SHA512.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA384) - { - return SHA384.HashData(source); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_256) - { - return SHA3_256.IsSupported ? SHA3_256.HashData(source) : throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_384) - { - return SHA3_384.IsSupported ? SHA3_384.HashData(source) : throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_512) - { - return SHA3_512.IsSupported ? SHA3_512.HashData(source) : throw new PlatformNotSupportedException(); - } - else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) - { - return MD5.HashData(source); - } - - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + return hashAlgorithm.Name switch + { + HashAlgorithmNames.SHA256 => SHA256.HashData(source), + HashAlgorithmNames.SHA1 => SHA1.HashData(source), + HashAlgorithmNames.SHA512 => SHA512.HashData(source), + HashAlgorithmNames.SHA384 => SHA384.HashData(source), + HashAlgorithmNames.SHA3_256 => SHA3_256.HashData(source), + HashAlgorithmNames.SHA3_384 => SHA3_384.HashData(source), + HashAlgorithmNames.SHA3_512 => SHA3_512.HashData(source), + HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(source), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + }; } internal static int MacData( @@ -140,46 +68,18 @@ internal static int MacData( ReadOnlySpan source, Span destination) { - if (hashAlgorithm == HashAlgorithmName.SHA256) - { - return HMACSHA256.HashData(key, source, destination); - } - else if (hashAlgorithm == HashAlgorithmName.SHA1) - { - return HMACSHA1.HashData(key, source, destination); - } - else if (hashAlgorithm == HashAlgorithmName.SHA512) - { - return HMACSHA512.HashData(key, source, destination); - } - else if (hashAlgorithm == HashAlgorithmName.SHA384) - { - return HMACSHA384.HashData(key, source, destination); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_256) - { - return HMACSHA3_256.IsSupported ? - HMACSHA3_256.HashData(key, source, destination) : - throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_384) - { - return HMACSHA3_384.IsSupported ? - HMACSHA3_384.HashData(key, source, destination) : - throw new PlatformNotSupportedException(); - } - else if (hashAlgorithm == HashAlgorithmName.SHA3_512) - { - return HMACSHA3_512.IsSupported ? - HMACSHA3_512.HashData(key, source, destination) : - throw new PlatformNotSupportedException(); - } - else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) - { - return HMACMD5.HashData(key, source, destination); - } - - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + return hashAlgorithm.Name switch + { + HashAlgorithmNames.SHA256 => HMACSHA256.HashData(key, source, destination), + HashAlgorithmNames.SHA1 => HMACSHA1.HashData(key, source, destination), + HashAlgorithmNames.SHA512 => HMACSHA512.HashData(key, source, destination), + HashAlgorithmNames.SHA384 => HMACSHA384.HashData(key, source, destination), + HashAlgorithmNames.SHA3_256 => HMACSHA3_256.HashData(key, source, destination), + HashAlgorithmNames.SHA3_384 => HMACSHA3_384.HashData(key, source, destination), + HashAlgorithmNames.SHA3_512 => HMACSHA3_512.HashData(key, source, destination), + HashAlgorithmNames.MD5 when Helpers.HasMD5 => HMACMD5.HashData(key, source, destination), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + }; } } } From 64329a93c3e916ca41e36d6a51a6ff2a96bc4525 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 19 May 2023 15:36:27 -0400 Subject: [PATCH 45/47] Add trailing commas --- .../System/Security/Cryptography/HashOneShotHelpers.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs index e3aa2e87c6da48..f80e69c8bf53a8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs @@ -22,7 +22,7 @@ internal static byte[] HashData(HashAlgorithmName hashAlgorithm, ReadOnlySpan SHA3_384.HashData(source), HashAlgorithmNames.SHA3_512 => SHA3_512.HashData(source), HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(source), - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)), }; } @@ -42,7 +42,7 @@ internal static bool TryHashData( HashAlgorithmNames.SHA3_384 => SHA3_384.TryHashData(source, destination, out bytesWritten), HashAlgorithmNames.SHA3_512 => SHA3_512.TryHashData(source, destination, out bytesWritten), HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.TryHashData(source, destination, out bytesWritten), - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)), }; } @@ -58,7 +58,7 @@ internal static byte[] HashData(HashAlgorithmName hashAlgorithm, Stream source) HashAlgorithmNames.SHA3_384 => SHA3_384.HashData(source), HashAlgorithmNames.SHA3_512 => SHA3_512.HashData(source), HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(source), - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)), }; } @@ -78,7 +78,7 @@ internal static int MacData( HashAlgorithmNames.SHA3_384 => HMACSHA3_384.HashData(key, source, destination), HashAlgorithmNames.SHA3_512 => HMACSHA3_512.HashData(key, source, destination), HashAlgorithmNames.MD5 when Helpers.HasMD5 => HMACMD5.HashData(key, source, destination), - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)) + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)), }; } } From c55fea4215b199535d6b1e6c9d2e6351b38aae7a Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 19 May 2023 17:18:34 -0400 Subject: [PATCH 46/47] Fix CNG test failures --- .../Cryptography/RsaPaddingProcessor.cs | 77 ++++++++++++------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs b/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs index 4db95b2ff4d242..66256440b7e708 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs @@ -44,41 +44,62 @@ internal static class RsaPaddingProcessor 0x40, }; + private static ReadOnlySpan DigestInfoSha3_256 => new byte[] + { + 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, + 0x20, + }; + + private static ReadOnlySpan DigestInfoSha3_384 => new byte[] + { + 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, + 0x30, + }; + + private static ReadOnlySpan DigestInfoSha3_512 => new byte[] + { + 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A, 0x05, 0x00, 0x04, + 0x40, + }; + private static ReadOnlySpan EightZeros => new byte[8]; private static ReadOnlySpan GetDigestInfoForAlgorithm( HashAlgorithmName hashAlgorithmName, out int digestLengthInBytes) { - if (hashAlgorithmName == HashAlgorithmName.MD5) - { - digestLengthInBytes = MD5.HashSizeInBytes; - return DigestInfoMD5; - } - else if (hashAlgorithmName == HashAlgorithmName.SHA1) - { - digestLengthInBytes = SHA1.HashSizeInBytes; - return DigestInfoSha1; - } - else if (hashAlgorithmName == HashAlgorithmName.SHA256) - { - digestLengthInBytes = SHA256.HashSizeInBytes; - return DigestInfoSha256; - } - else if (hashAlgorithmName == HashAlgorithmName.SHA384) + switch (hashAlgorithmName.Name) { - digestLengthInBytes = SHA384.HashSizeInBytes; - return DigestInfoSha384; - } - else if (hashAlgorithmName == HashAlgorithmName.SHA512) - { - digestLengthInBytes = SHA512.HashSizeInBytes; - return DigestInfoSha512; - } - else - { - Debug.Fail("Unknown digest algorithm"); - throw new CryptographicException(); + case HashAlgorithmNames.MD5: + digestLengthInBytes = MD5.HashSizeInBytes; + return DigestInfoMD5; + case HashAlgorithmNames.SHA1: + digestLengthInBytes = SHA1.HashSizeInBytes; + return DigestInfoSha1; + case HashAlgorithmNames.SHA256: + digestLengthInBytes = SHA256.HashSizeInBytes; + return DigestInfoSha256; + case HashAlgorithmNames.SHA384: + digestLengthInBytes = SHA384.HashSizeInBytes; + return DigestInfoSha384; + case HashAlgorithmNames.SHA512: + digestLengthInBytes = SHA512.HashSizeInBytes; + return DigestInfoSha512; + case HashAlgorithmNames.SHA3_256: + digestLengthInBytes = SHA3_256.HashSizeInBytes; + return DigestInfoSha3_256; + case HashAlgorithmNames.SHA3_384: + digestLengthInBytes = SHA3_384.HashSizeInBytes; + return DigestInfoSha3_384; + case HashAlgorithmNames.SHA3_512: + digestLengthInBytes = SHA3_512.HashSizeInBytes; + return DigestInfoSha3_512; + default: + Debug.Fail("Unknown digest algorithm"); + throw new CryptographicException(); } } From c735e7a680e8ad8ea02480c9b62a3b5b02d7d304 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sun, 21 May 2023 17:19:56 -0400 Subject: [PATCH 47/47] Fix hash algorithm support detection on Android --- .../Interop.Evp.DigestAlgs.cs | 19 +++++++++++++++++ .../Interop.EVP.DigestAlgs.cs | 21 +++++++++++++++++++ .../HashProviderDispenser.OpenSsl.cs | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs index 6f6a6fcd1e93e3..d7325ca8e8574c 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.DigestAlgs.cs @@ -56,5 +56,24 @@ internal static IntPtr EvpSha512() => throw new PlatformNotSupportedException(), _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)) }; + + internal static bool HashAlgorithmSupported(string hashAlgorithmId) + { + switch (hashAlgorithmId) + { + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + case HashAlgorithmNames.SHA384: + case HashAlgorithmNames.SHA512: + case HashAlgorithmNames.MD5: + return true; + case HashAlgorithmNames.SHA3_256: + case HashAlgorithmNames.SHA3_384: + case HashAlgorithmNames.SHA3_512: + return false; + default: + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); + } + } } } 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 2497614a1f2b66..dec9bdd84a5ddf 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 @@ -116,5 +116,26 @@ internal static IntPtr HashAlgorithmToEvp(string hashAlgorithmId) throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); }; } + + internal static bool HashAlgorithmSupported(string hashAlgorithmId) + { + switch (hashAlgorithmId) + { + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + 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; + default: + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); + } + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs index e6836fbbfc4d41..78b8cd632b4340 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs @@ -24,7 +24,7 @@ internal static HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlyS internal static bool HashSupported(string hashAlgorithmId) { - return Interop.Crypto.HashAlgorithmToEvp(hashAlgorithmId) != IntPtr.Zero; + return Interop.Crypto.HashAlgorithmSupported(hashAlgorithmId); } internal static bool MacSupported(string hashAlgorithmId) => HashSupported(hashAlgorithmId);