diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs index a425f7366b6212..a4b3b9270acc84 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs @@ -37,8 +37,17 @@ internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm al return CompositeMLDsaManaged.IsAlgorithmSupportedImpl(algorithm); } - internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => - throw new PlatformNotSupportedException(); + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) + { +#if !NETFRAMEWORK + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new PlatformNotSupportedException(); + } +#endif + + return CompositeMLDsaManaged.GenerateKeyImpl(algorithm); + } internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs index 7755d12fd6a271..7388ba650e9bbe 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs @@ -35,8 +35,28 @@ private RsaComponent(RSA rsa, HashAlgorithmName hashAlgorithmName, RSASignatureP #if NETFRAMEWORK // RSA-PSS requires RSACng on .NET Framework private static RSACng CreateRSA() => new RSACng(); + private static RSACng CreateRSA(int keySizeInBits) => new RSACng(keySizeInBits); +#elif NETSTANDARD2_0 + private static RSA CreateRSA() => RSA.Create(); + + private static RSA CreateRSA(int keySizeInBits) + { + RSA rsa = RSA.Create(); + + try + { + rsa.KeySize = keySizeInBits; + return rsa; + } + catch + { + rsa.Dispose(); + throw; + } + } #else private static RSA CreateRSA() => RSA.Create(); + private static RSA CreateRSA(int keySizeInBits) => RSA.Create(keySizeInBits); #endif internal override int SignData( @@ -80,8 +100,25 @@ internal override bool VerifyData( #endif } - public static RsaComponent GenerateKey(RsaAlgorithm algorithm) => - throw new NotImplementedException(); + public static RsaComponent GenerateKey(RsaAlgorithm algorithm) + { + RSA? rsa = null; + + try + { + rsa = CreateRSA(algorithm.KeySizeInBits); + + // RSA key generation is lazy, so we need to force it to happen eagerly. + _ = rsa.ExportParameters(includePrivateParameters: false); + + return new RsaComponent(rsa, algorithm.HashAlgorithmName, algorithm.Padding); + } + catch (CryptographicException) + { + rsa?.Dispose(); + throw; + } + } public static RsaComponent ImportPrivateKey(RsaAlgorithm algorithm, ReadOnlySpan source) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs index 2484a31c5f3186..0468bdee6253ce 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs @@ -52,8 +52,82 @@ internal static bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) }); } - internal static CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => - throw new PlatformNotSupportedException(); + internal static CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) + { + Debug.Assert(IsAlgorithmSupportedImpl(algorithm)); + + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + // draft-ietf-lamps-pq-composite-sigs-latest (July 7, 2025), 4.1 + // 1. Generate component keys + // + // mldsaSeed = Random(32) + // (mldsaPK, _) = ML-DSA.KeyGen(mldsaSeed) + // (tradPK, tradSK) = Trad.KeyGen() + + MLDsa? mldsaKey = null; + ComponentAlgorithm? tradKey = null; + + try + { + mldsaKey = MLDsaImplementation.GenerateKey(metadata.MLDsaAlgorithm); + } + catch (CryptographicException) + { + } + + try + { + tradKey = metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.GenerateKey(rsaAlgorithm), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.GenerateKey(ecdsaAlgorithm), + _ => FailAndGetNull(), + }; + + static ComponentAlgorithm? FailAndGetNull() + { + Debug.Fail("Only supported algorithms should reach here."); + return null; + } + } + catch (CryptographicException) + { + } + + // 2. Check for component key gen failure + // + // if NOT (mldsaPK, mldsaSK) or NOT (tradPK, tradSK): + // output "Key generation error" + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + static bool KeyGenFailed([NotNullWhen(false)] MLDsa? mldsaKey, [NotNullWhen(false)] ComponentAlgorithm? tradKey) => + (mldsaKey is null) | (tradKey is null); + + if (KeyGenFailed(mldsaKey, tradKey)) + { + try + { + Debug.Assert(mldsaKey is null || tradKey is null); + + mldsaKey?.Dispose(); + tradKey?.Dispose(); + } + catch (CryptographicException) + { + } + + throw new CryptographicException(); + } + + // 3. Output the composite public and private keys + // + // pk = SerializePublicKey(mldsaPK, tradPK) + // sk = SerializePrivateKey(mldsaSeed, tradSK) + // return (pk, sk) + + return new CompositeMLDsaManaged(algorithm, mldsaKey, tradKey); + } internal static CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs index 69b7838be7bf7f..d5997d722d8b85 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs @@ -13,6 +13,7 @@ public static class CompositeMLDsaFactoryTests [Fact] public static void NullArgumentValidation() { + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.GenerateKey(null)); AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.IsAlgorithmSupported(null)); AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(null, Array.Empty())); AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(null, ReadOnlySpan.Empty)); @@ -169,6 +170,17 @@ private static void AssertImportBadPublicKey(CompositeMLDsaAlgorithm algorithm, key); } + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorithm) + { + AssertThrowIfNotSupported(() => + { + using CompositeMLDsa dsa = CompositeMLDsa.GenerateKey(algorithm); + Assert.Equal(algorithm, dsa.Algorithm); + }); + } + [Theory] [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) @@ -186,7 +198,7 @@ public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsa public static void IsSupported_AgreesWithPlatform() { // Composites are supported everywhere MLDsa is supported - Assert.Equal(MLDsa.IsSupported && !PlatformDetection.IsLinux, CompositeMLDsa.IsSupported); + Assert.Equal(MLDsa.IsSupported, CompositeMLDsa.IsSupported); } [Theory] @@ -195,7 +207,7 @@ public static void IsAlgorithmSupported_AgreesWithPlatform(CompositeMLDsaAlgorit { bool supported = CompositeMLDsaTestHelpers.ExecuteComponentFunc( algorithm, - _ => MLDsa.IsSupported && !PlatformDetection.IsLinux, + _ => MLDsa.IsSupported, _ => false, _ => false); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs index 2842370bb018e7..03ac1315b541ff 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs @@ -8,6 +8,13 @@ namespace System.Security.Cryptography.Tests [ConditionalClass(typeof(CompositeMLDsa), nameof(CompositeMLDsa.IsSupported))] public sealed class CompositeMLDsaImplementationTests : CompositeMLDsaTestsBase { + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void CompositeMLDsaIsOnlyPublicAncestor_GenerateKey(CompositeMLDsaAlgorithm algorithm) + { + AssertCompositeMLDsaIsOnlyPublicAncestor(() => CompositeMLDsa.GenerateKey(algorithm)); + } + [Theory] [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] public static void CompositeMLDsaIsOnlyPublicAncestor_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector info) @@ -32,6 +39,66 @@ private static void AssertCompositeMLDsaIsOnlyPublicAncestor(Func + { + // Roundtrip using public key. First export it. + byte[] exportedPublicKey = export(dsa); + CompositeMLDsaTestHelpers.AssertImportPublicKey( + import => + { + // Then import it. + using CompositeMLDsa roundTrippedDsa = import(); + + // Verify the roundtripped object has the same key + Assert.Equal(algorithm, roundTrippedDsa.Algorithm); + AssertExtensions.SequenceEqual(dsa.ExportCompositeMLDsaPublicKey(), roundTrippedDsa.ExportCompositeMLDsaPublicKey()); + Assert.Throws(() => roundTrippedDsa.ExportCompositeMLDsaPrivateKey()); + }, + algorithm, + exportedPublicKey); + }); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Export_Import_PrivateKey(CompositeMLDsaAlgorithm algorithm) + { + // Generate new key + using CompositeMLDsa dsa = GenerateKey(algorithm); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => + { + // Roundtrip using secret key. First export it. + byte[] exportedSecretKey = export(dsa); + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => + { + // Then import it. + using CompositeMLDsa roundTrippedDsa = import(); + + // Verify the roundtripped object has the same key + Assert.Equal(algorithm, roundTrippedDsa.Algorithm); + AssertExtensions.SequenceEqual(dsa.ExportCompositeMLDsaPrivateKey(), roundTrippedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(dsa.ExportCompositeMLDsaPublicKey(), roundTrippedDsa.ExportCompositeMLDsaPublicKey()); + }, + algorithm, + exportedSecretKey); + }); + } + + #endregion Roundtrip by exporting then importing + #region Roundtrip by importing then exporting [Theory] @@ -60,6 +127,9 @@ public void RoundTrip_Import_Export_PrivateKey(CompositeMLDsaTestData.CompositeM #endregion Roundtrip by importing then exporting + protected override CompositeMLDsa GenerateKey(CompositeMLDsaAlgorithm algorithm) => + CompositeMLDsa.GenerateKey(algorithm); + protected override CompositeMLDsa ImportPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, source); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs index 6dc346fcbb1a74..e6bf7084e25a8b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs @@ -71,6 +71,9 @@ internal CompositeMLDsaTestVector(string tcId, CompositeMLDsaAlgorithm algo, str public static IEnumerable AllAlgorithmsTestData => AllAlgorithms.Select(v => new object[] { v }); + public static IEnumerable SupportedAlgorithmsTestData => + AllAlgorithms.Where(CompositeMLDsa.IsAlgorithmSupported).Select(v => new object[] { v }); + internal static MLDsaKeyInfo GetMLDsaIetfTestVector(CompositeMLDsaAlgorithm algorithm) { MLDsaAlgorithm mldsaAlgorithm = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm]; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs index 0420014503628d..a7d9fe129b90e8 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs @@ -8,9 +8,113 @@ namespace System.Security.Cryptography.Tests [ConditionalClass(typeof(CompositeMLDsa), nameof(CompositeMLDsa.IsSupported))] public abstract class CompositeMLDsaTestsBase { + protected abstract CompositeMLDsa GenerateKey(CompositeMLDsaAlgorithm algorithm); protected abstract CompositeMLDsa ImportPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); protected abstract CompositeMLDsa ImportPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyWithPublicKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] signature; + byte[] data = [0, 1, 2, 3]; + byte[] exportedPublicKey; + + using (CompositeMLDsa generatedKey = GenerateKey(algorithm)) + { + signature = generatedKey.SignData(data); + + ExerciseSuccessfulVerify(generatedKey, data, signature, []); + + exportedPublicKey = generatedKey.ExportCompositeMLDsaPublicKey(); + } + + using (CompositeMLDsa publicKey = ImportPublicKey(algorithm, exportedPublicKey)) + { + ExerciseSuccessfulVerify(publicKey, data, signature, []); + + Assert.Throws(() => publicKey.SignData(data)); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyWithPrivateKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] signature; + byte[] data = [0, 1, 2, 3]; + byte[] exportedPrivateKey; + + using (CompositeMLDsa generatedKey = GenerateKey(algorithm)) + { + signature = generatedKey.SignData(data); + exportedPrivateKey = generatedKey.ExportCompositeMLDsaPrivateKey(); + } + + using (CompositeMLDsa privateKey = ImportPrivateKey(algorithm, exportedPrivateKey)) + { + ExerciseSuccessfulVerify(privateKey, data, signature, []); + + signature.AsSpan().Clear(); + privateKey.SignData(data, signature, []); + + ExerciseSuccessfulVerify(privateKey, data, signature, []); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyNoContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] data = [1, 2, 3, 4, 5]; + byte[] signature = dsa.SignData(data); + ExerciseSuccessfulVerify(dsa, data, signature, []); + + signature.AsSpan().Clear(); + dsa.SignData(data, signature, Array.Empty()); + ExerciseSuccessfulVerify(dsa, data, signature, Array.Empty()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyWithContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] context = [1, 1, 3, 5, 6]; + byte[] data = [1, 2, 3, 4, 5]; + + byte[] signature = dsa.SignData(data, context); + ExerciseSuccessfulVerify(dsa, data, signature, context); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyEmptyMessageNoContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] signature = dsa.SignData([]); + ExerciseSuccessfulVerify(dsa, [], signature, []); + + signature.AsSpan().Clear(); + dsa.SignData(Array.Empty(), signature, Array.Empty()); + ExerciseSuccessfulVerify(dsa, [], signature, []); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyEmptyMessageWithContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] context = [1, 1, 3, 5, 6]; + byte[] signature = dsa.SignData([], context); + ExerciseSuccessfulVerify(dsa, [], signature, context); + + signature.AsSpan().Clear(); + dsa.SignData(Array.Empty(), signature, context); + ExerciseSuccessfulVerify(dsa, [], signature, context); + } + [Theory] [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] public void ImportExportVerify(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) @@ -87,6 +191,56 @@ public void ImportPrivateKey_Export(CompositeMLDsaTestData.CompositeMLDsaTestVec export => CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(vector.Algorithm, vector.SecretKey, export(dsa))); } + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void Generate_Export_Import_PublicKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] exportedPublicKey; + + using (CompositeMLDsa dsa = GenerateKey(algorithm)) + { + exportedPublicKey = dsa.ExportCompositeMLDsaPublicKey(); + + using (CompositeMLDsa importedDsa = ImportPublicKey(algorithm, exportedPublicKey)) + { + Assert.Throws(() => importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + using (CompositeMLDsa importedDsa = ImportPublicKey(algorithm, exportedPublicKey)) + { + Assert.Throws(() => importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void Generate_Export_Import_PrivateKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] exportedPrivateKey; + byte[] exportedPublicKey; + + using (CompositeMLDsa dsa = GenerateKey(algorithm)) + { + exportedPrivateKey = dsa.ExportCompositeMLDsaPrivateKey(); + exportedPublicKey = dsa.ExportCompositeMLDsaPublicKey(); + + using (CompositeMLDsa importedDsa = ImportPrivateKey(algorithm, exportedPrivateKey)) + { + AssertExtensions.SequenceEqual(exportedPrivateKey, importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + using (CompositeMLDsa importedDsa = ImportPrivateKey(algorithm, exportedPrivateKey)) + { + AssertExtensions.SequenceEqual(exportedPrivateKey, importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + [Theory] [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] public void SignData_PublicKeyOnlyThrows(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) 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 640909a1d691d2..d0e2e5c11807fb 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -1031,8 +1031,10 @@ Link="Common\System\IO\PersistedFiles.Names.Unix.cs" /> - + + + diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLDsaImplementation.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLDsaImplementation.OpenSsl.cs new file mode 100644 index 00000000000000..92fd2990ca0cc9 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLDsaImplementation.OpenSsl.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaImplementation : CompositeMLDsa + { + private CompositeMLDsaImplementation(CompositeMLDsaAlgorithm algorithm) + : base(algorithm) + { + throw new PlatformNotSupportedException(); + } + + internal static partial bool SupportsAny() => CompositeMLDsaManaged.SupportsAny(); + + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) => + CompositeMLDsaManaged.IsAlgorithmSupportedImpl(algorithm); + + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => + CompositeMLDsaManaged.GenerateKeyImpl(algorithm); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsaManaged.ImportCompositeMLDsaPublicKeyImpl(algorithm, source); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsaManaged.ImportCompositeMLDsaPrivateKeyImpl(algorithm, source); + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportCompositeMLDsaPublicKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportCompositeMLDsaPrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + } +}