From e66b6996fd767e4654e75b3a97d4aeee061028cd Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Sun, 22 Jun 2025 12:01:00 +0800 Subject: [PATCH 1/4] Use BCL MLKem --- Directory.Packages.props | 1 + src/Renci.SshNet/Renci.SshNet.csproj | 5 +- .../KeyExchangeMLKem768X25519Sha256.cs | 47 +++++++++++++++---- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 8138199d5..1f884229e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,6 +11,7 @@ + diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 446865229..45b2087ca 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -49,10 +49,11 @@ - - + + + True diff --git a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs index 606e3a250..0f31d3118 100644 --- a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs @@ -1,5 +1,6 @@ -using System.Globalization; -using System.Linq; +using System; +using System.Globalization; +using System.Security.Cryptography; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Kems; @@ -13,6 +14,8 @@ namespace Renci.SshNet.Security { internal sealed class KeyExchangeMLKem768X25519Sha256 : KeyExchangeECCurve25519 { + private readonly MLKemAlgorithm _mlkem768 = MLKemAlgorithm.MLKem768; + private MLKem _mlkem; private MLKemDecapsulator _mlkemDecapsulator; /// @@ -41,14 +44,23 @@ protected override void StartImpl() Session.KeyExchangeHybridReplyMessageReceived += Session_KeyExchangeHybridReplyMessageReceived; - var mlkem768KeyPairGenerator = new MLKemKeyPairGenerator(); - mlkem768KeyPairGenerator.Init(new MLKemKeyGenerationParameters(CryptoAbstraction.SecureRandom, MLKemParameters.ml_kem_768)); - var mlkem768KeyPair = mlkem768KeyPairGenerator.GenerateKeyPair(); + byte[] mlkem768PublicKey; + if (MLKem.IsSupported) + { + _mlkem = MLKem.GenerateKey(_mlkem768); + mlkem768PublicKey = _mlkem.ExportEncapsulationKey(); + } + else + { + var mlkem768KeyPairGenerator = new MLKemKeyPairGenerator(); + mlkem768KeyPairGenerator.Init(new MLKemKeyGenerationParameters(CryptoAbstraction.SecureRandom, MLKemParameters.ml_kem_768)); + var mlkem768KeyPair = mlkem768KeyPairGenerator.GenerateKeyPair(); - _mlkemDecapsulator = new MLKemDecapsulator(MLKemParameters.ml_kem_768); - _mlkemDecapsulator.Init(mlkem768KeyPair.Private); + _mlkemDecapsulator = new MLKemDecapsulator(MLKemParameters.ml_kem_768); + _mlkemDecapsulator.Init(mlkem768KeyPair.Private); - var mlkem768PublicKey = ((MLKemPublicKeyParameters)mlkem768KeyPair.Public).GetEncoded(); + mlkem768PublicKey = ((MLKemPublicKeyParameters)mlkem768KeyPair.Public).GetEncoded(); + } var x25519PublicKey = _impl.GenerateClientPublicKey(); @@ -109,11 +121,28 @@ private void HandleServerHybridReply(byte[] hostKey, byte[] serverExchangeValue, var mlkemSecret = new byte[_mlkemDecapsulator.SecretLength]; - _mlkemDecapsulator.Decapsulate(serverExchangeValue, 0, _mlkemDecapsulator.EncapsulationLength, mlkemSecret, 0, _mlkemDecapsulator.SecretLength); + if (MLKem.IsSupported) + { + _mlkem.Decapsulate(serverExchangeValue.AsSpan(0, _mlkem768.CiphertextSizeInBytes), mlkemSecret); + } + else + { + _mlkemDecapsulator.Decapsulate(serverExchangeValue, 0, _mlkemDecapsulator.EncapsulationLength, mlkemSecret, 0, _mlkemDecapsulator.SecretLength); + } var x25519Agreement = _impl.CalculateAgreement(serverExchangeValue.Take(_mlkemDecapsulator.EncapsulationLength, X25519PublicKeyParameters.KeySize)); SharedKey = CryptoAbstraction.HashSHA256(mlkemSecret.Concat(x25519Agreement)); } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _mlkem?.Dispose(); + } + + base.Dispose(disposing); + } } } From 9e68521a301cc4f46283ff7da7196dc3043a5baa Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Thu, 2 Oct 2025 11:48:06 +0800 Subject: [PATCH 2/4] Split into BclImpl and BouncyCastleImpl --- ...KeyExchangeMLKem768X25519Sha256.BclImpl.cs | 36 ++++++++++++++++ ...geMLKem768X25519Sha256.BouncyCastleImpl.cs | 36 ++++++++++++++++ .../KeyExchangeMLKem768X25519Sha256.cs | 43 +++++-------------- 3 files changed, 83 insertions(+), 32 deletions(-) create mode 100644 src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BclImpl.cs create mode 100644 src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BouncyCastleImpl.cs diff --git a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BclImpl.cs b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BclImpl.cs new file mode 100644 index 000000000..6cc22e522 --- /dev/null +++ b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BclImpl.cs @@ -0,0 +1,36 @@ +using System; +using System.Security.Cryptography; + +namespace Renci.SshNet.Security +{ + internal sealed partial class KeyExchangeMLKem768X25519Sha256 + { + private sealed class MLKemBclImpl : Impl + { + private MLKem _mlkem; + + public override byte[] GenerateClientPublicKey() + { + _mlkem = MLKem.GenerateKey(MLKemAlgorithm.MLKem768); + return _mlkem.ExportEncapsulationKey(); + } + + public override byte[] CalculateAgreement(byte[] serverPublicKey) + { + var mlkemSecret = new byte[MLKemAlgorithm.MLKem768.SharedSecretSizeInBytes]; + _mlkem.Decapsulate(serverPublicKey.AsSpan(0, MLKemAlgorithm.MLKem768.CiphertextSizeInBytes), mlkemSecret); + return mlkemSecret; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _mlkem?.Dispose(); + } + + base.Dispose(disposing); + } + } + } +} diff --git a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BouncyCastleImpl.cs b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BouncyCastleImpl.cs new file mode 100644 index 000000000..73eb3c08f --- /dev/null +++ b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.BouncyCastleImpl.cs @@ -0,0 +1,36 @@ +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Kems; +using Org.BouncyCastle.Crypto.Parameters; + +using Renci.SshNet.Abstractions; + +namespace Renci.SshNet.Security +{ + internal sealed partial class KeyExchangeMLKem768X25519Sha256 + { + private sealed class MLKemBouncyCastleImpl : Impl + { + private MLKemDecapsulator _mlkemDecapsulator; + + public override byte[] GenerateClientPublicKey() + { + var mlkem768KeyPairGenerator = new MLKemKeyPairGenerator(); + mlkem768KeyPairGenerator.Init(new MLKemKeyGenerationParameters(CryptoAbstraction.SecureRandom, MLKemParameters.ml_kem_768)); + var mlkem768KeyPair = mlkem768KeyPairGenerator.GenerateKeyPair(); + + _mlkemDecapsulator = new MLKemDecapsulator(MLKemParameters.ml_kem_768); + _mlkemDecapsulator.Init(mlkem768KeyPair.Private); + + return ((MLKemPublicKeyParameters)mlkem768KeyPair.Public).GetEncoded(); + } + + public override byte[] CalculateAgreement(byte[] serverPublicKey) + { + var mlkemSecret = new byte[_mlkemDecapsulator.SecretLength]; + _mlkemDecapsulator.Decapsulate(serverPublicKey, 0, _mlkemDecapsulator.EncapsulationLength, mlkemSecret, 0, _mlkemDecapsulator.SecretLength); + + return mlkemSecret; + } + } + } +} diff --git a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs index 0f31d3118..4b796f586 100644 --- a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs @@ -1,9 +1,6 @@ -using System; -using System.Globalization; +using System.Globalization; using System.Security.Cryptography; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.Crypto.Kems; using Org.BouncyCastle.Crypto.Parameters; using Renci.SshNet.Abstractions; @@ -12,11 +9,9 @@ namespace Renci.SshNet.Security { - internal sealed class KeyExchangeMLKem768X25519Sha256 : KeyExchangeECCurve25519 + internal sealed partial class KeyExchangeMLKem768X25519Sha256 : KeyExchangeECCurve25519 { - private readonly MLKemAlgorithm _mlkem768 = MLKemAlgorithm.MLKem768; - private MLKem _mlkem; - private MLKemDecapsulator _mlkemDecapsulator; + private Impl _mlkemImpl; /// /// Gets algorithm name. @@ -44,24 +39,17 @@ protected override void StartImpl() Session.KeyExchangeHybridReplyMessageReceived += Session_KeyExchangeHybridReplyMessageReceived; - byte[] mlkem768PublicKey; if (MLKem.IsSupported) { - _mlkem = MLKem.GenerateKey(_mlkem768); - mlkem768PublicKey = _mlkem.ExportEncapsulationKey(); + _mlkemImpl = new MLKemBclImpl(); } else { - var mlkem768KeyPairGenerator = new MLKemKeyPairGenerator(); - mlkem768KeyPairGenerator.Init(new MLKemKeyGenerationParameters(CryptoAbstraction.SecureRandom, MLKemParameters.ml_kem_768)); - var mlkem768KeyPair = mlkem768KeyPairGenerator.GenerateKeyPair(); - - _mlkemDecapsulator = new MLKemDecapsulator(MLKemParameters.ml_kem_768); - _mlkemDecapsulator.Init(mlkem768KeyPair.Private); - - mlkem768PublicKey = ((MLKemPublicKeyParameters)mlkem768KeyPair.Public).GetEncoded(); + _mlkemImpl = new MLKemBouncyCastleImpl(); } + var mlkem768PublicKey = _mlkemImpl.GenerateClientPublicKey(); + var x25519PublicKey = _impl.GenerateClientPublicKey(); _clientExchangeValue = mlkem768PublicKey.Concat(x25519PublicKey); @@ -112,25 +100,16 @@ private void HandleServerHybridReply(byte[] hostKey, byte[] serverExchangeValue, _hostKey = hostKey; _signature = signature; - if (serverExchangeValue.Length != _mlkemDecapsulator.EncapsulationLength + X25519PublicKeyParameters.KeySize) + if (serverExchangeValue.Length != MLKemAlgorithm.MLKem768.CiphertextSizeInBytes + X25519PublicKeyParameters.KeySize) { throw new SshConnectionException( string.Format(CultureInfo.CurrentCulture, "Bad S_Reply length: {0}.", serverExchangeValue.Length), DisconnectReason.KeyExchangeFailed); } - var mlkemSecret = new byte[_mlkemDecapsulator.SecretLength]; - - if (MLKem.IsSupported) - { - _mlkem.Decapsulate(serverExchangeValue.AsSpan(0, _mlkem768.CiphertextSizeInBytes), mlkemSecret); - } - else - { - _mlkemDecapsulator.Decapsulate(serverExchangeValue, 0, _mlkemDecapsulator.EncapsulationLength, mlkemSecret, 0, _mlkemDecapsulator.SecretLength); - } + var mlkemSecret = _mlkemImpl.CalculateAgreement(serverExchangeValue); - var x25519Agreement = _impl.CalculateAgreement(serverExchangeValue.Take(_mlkemDecapsulator.EncapsulationLength, X25519PublicKeyParameters.KeySize)); + var x25519Agreement = _impl.CalculateAgreement(serverExchangeValue.Take(MLKemAlgorithm.MLKem768.CiphertextSizeInBytes, X25519PublicKeyParameters.KeySize)); SharedKey = CryptoAbstraction.HashSHA256(mlkemSecret.Concat(x25519Agreement)); } @@ -139,7 +118,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - _mlkem?.Dispose(); + _mlkemImpl?.Dispose(); } base.Dispose(disposing); From e2ebbbfad7fca2e69e2b353147caefd166d42d9f Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Sun, 5 Oct 2025 21:12:51 +0800 Subject: [PATCH 3/4] More specific tests --- .github/workflows/build.yml | 90 +++++++++++++++++-- src/Renci.SshNet/Renci.SshNet.csproj | 4 + .../KeyExchangeMLKem768X25519Sha256.cs | 13 ++- 3 files changed, 100 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b3759d43..63855868e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: -p:CoverletOutput=../../coverlet/linux_unit_test_net_9_coverage.xml \ test/Renci.SshNet.Tests/ - - name: Run Integration Tests .NET + - name: Run Integration Tests .NET 1 run: | dotnet test \ -f net9.0 \ @@ -44,7 +44,33 @@ jobs: --logger GitHubActions \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ - -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage.xml \ + -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage_1.xml \ + test/Renci.SshNet.IntegrationTests/ + + - name: Run Integration Tests .NET 2 + run: | + dotnet test \ + -f net9.0 \ + --logger "console;verbosity=normal" \ + --logger GitHubActions \ + --filter "Name=MLKem768X25519Sha256" \ + -p:DefineConstants="$(DefineConstants);Test_BCL_MLKem" \ + -p:CollectCoverage=true \ + -p:CoverletOutputFormat=cobertura \ + -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage_2.xml \ + test/Renci.SshNet.IntegrationTests/ + + - name: Run Integration Tests .NET 3 + run: | + dotnet test \ + -f net9.0 \ + --logger "console;verbosity=normal" \ + --logger GitHubActions \ + --filter "Name=MLKem768X25519Sha256" \ + -p:DefineConstants="$(DefineConstants);Test_BouncyCastle_MLKem" \ + -p:CollectCoverage=true \ + -p:CoverletOutputFormat=cobertura \ + -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage_3.xml \ test/Renci.SshNet.IntegrationTests/ - name: Archive Coverlet Results @@ -128,15 +154,41 @@ jobs: podman build -t renci-ssh-tests-server-image -f test/Renci.SshNet.IntegrationTests/Dockerfile test/Renci.SshNet.IntegrationTests/ podman run --rm -h renci-ssh-tests-server -d -p 2222:22 renci-ssh-tests-server-image - - name: Run Integration Tests .NET Framework + - name: Run Integration Tests .NET Framework 1 + run: + dotnet test ` + -f net48 ` + --logger "console;verbosity=normal" ` + --logger GitHubActions ` + -p:CollectCoverage=true ` + -p:CoverletOutputFormat=cobertura ` + -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage_1.xml ` + test\Renci.SshNet.IntegrationTests\ + + - name: Run Integration Tests .NET Framework 2 run: dotnet test ` -f net48 ` --logger "console;verbosity=normal" ` --logger GitHubActions ` + --filter "Name=MLKem768X25519Sha256" ` + -p:DefineConstants="$(DefineConstants);Test_BCL_MLKem" ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` - -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage.xml ` + -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage_2.xml ` + test\Renci.SshNet.IntegrationTests\ + + - name: Run Integration Tests .NET Framework 3 + run: + dotnet test ` + -f net48 ` + --logger "console;verbosity=normal" ` + --logger GitHubActions ` + --filter "Name=MLKem768X25519Sha256" ` + -p:DefineConstants="$(DefineConstants);Test_BouncyCastle_MLKem" ` + -p:CollectCoverage=true ` + -p:CoverletOutputFormat=cobertura ` + -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage_3.xml ` test\Renci.SshNet.IntegrationTests\ - name: Archive Coverlet Results @@ -170,15 +222,41 @@ jobs: podman build -t renci-ssh-tests-server-image -f test/Renci.SshNet.IntegrationTests/Dockerfile test/Renci.SshNet.IntegrationTests/ podman run --rm -h renci-ssh-tests-server -d -p 2222:22 renci-ssh-tests-server-image - - name: Run Integration Tests .NET + - name: Run Integration Tests .NET 1 + run: + dotnet test ` + -f net9.0 ` + --logger "console;verbosity=normal" ` + --logger GitHubActions ` + -p:CollectCoverage=true ` + -p:CoverletOutputFormat=cobertura ` + -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage_1.xml ` + test\Renci.SshNet.IntegrationTests\ + + - name: Run Integration Tests .NET 2 + run: + dotnet test ` + -f net9.0 ` + --logger "console;verbosity=normal" ` + --logger GitHubActions ` + --filter "Name=MLKem768X25519Sha256" ` + -p:DefineConstants="$(DefineConstants);Test_BCL_MLKem" ` + -p:CollectCoverage=true ` + -p:CoverletOutputFormat=cobertura ` + -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage_2.xml ` + test\Renci.SshNet.IntegrationTests\ + + - name: Run Integration Tests .NET 3 run: dotnet test ` -f net9.0 ` --logger "console;verbosity=normal" ` --logger GitHubActions ` + --filter "Name=MLKem768X25519Sha256" ` + -p:DefineConstants="$(DefineConstants);Test_BouncyCastle_MLKem" ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` - -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage.xml ` + -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage_3.xml ` test\Renci.SshNet.IntegrationTests\ - name: Archive Coverlet Results diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 45b2087ca..b7fb361ee 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -40,6 +40,10 @@ true + + $(DefineConstants);Test_BCL_MLKem + + diff --git a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs index 4b796f586..77cf83b7a 100644 --- a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs @@ -11,7 +11,13 @@ namespace Renci.SshNet.Security { internal sealed partial class KeyExchangeMLKem768X25519Sha256 : KeyExchangeECCurve25519 { +#if Test_BCL_MLKem + private MLKemBclImpl _mlkemImpl; +#elif Test_BouncyCastle_MLKem + private MLKemBouncyCastleImpl _mlkemImpl; +#else private Impl _mlkemImpl; +#endif /// /// Gets algorithm name. @@ -39,6 +45,11 @@ protected override void StartImpl() Session.KeyExchangeHybridReplyMessageReceived += Session_KeyExchangeHybridReplyMessageReceived; +#if Test_BCL_MLKem + _mlkemImpl = new MLKemBclImpl(); +#elif Test_BouncyCastle_MLKem + _mlkemImpl = new MLKemBouncyCastleImpl(); +#else if (MLKem.IsSupported) { _mlkemImpl = new MLKemBclImpl(); @@ -47,7 +58,7 @@ protected override void StartImpl() { _mlkemImpl = new MLKemBouncyCastleImpl(); } - +#endif var mlkem768PublicKey = _mlkemImpl.GenerateClientPublicKey(); var x25519PublicKey = _impl.GenerateClientPublicKey(); From a7f122e3dd25a274d7fdb47b046d77937be88ef2 Mon Sep 17 00:00:00 2001 From: Scott Xu Date: Mon, 6 Oct 2025 11:45:10 +0800 Subject: [PATCH 4/4] x --- .github/workflows/build.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 63855868e..5f086f627 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v5 + with: + dotnet-version: '10.0.x' + dotnet-quality: 'preview' - name: Build Unit Tests .NET run: dotnet build -f net9.0 test/Renci.SshNet.Tests/ @@ -54,7 +57,7 @@ jobs: --logger "console;verbosity=normal" \ --logger GitHubActions \ --filter "Name=MLKem768X25519Sha256" \ - -p:DefineConstants="$(DefineConstants);Test_BCL_MLKem" \ + -p:DefineConstants="$(9);Test_BCL_MLKem" \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage_2.xml \ @@ -67,7 +70,7 @@ jobs: --logger "console;verbosity=normal" \ --logger GitHubActions \ --filter "Name=MLKem768X25519Sha256" \ - -p:DefineConstants="$(DefineConstants);Test_BouncyCastle_MLKem" \ + -p:DefineConstants="Test_BouncyCastle_MLKem" \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage_3.xml \ @@ -89,6 +92,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v5 + with: + dotnet-version: '10.0.x' + dotnet-quality: 'preview' - name: Build Solution run: dotnet build Renci.SshNet.sln @@ -140,6 +146,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v5 + with: + dotnet-version: '10.0.x' + dotnet-quality: 'preview' - name: Setup WSL2 uses: Vampire/setup-wsl@6a8db447be7ed35f2f499c02c6e60ff77ef11278 # v6.0.0 @@ -172,7 +181,7 @@ jobs: --logger "console;verbosity=normal" ` --logger GitHubActions ` --filter "Name=MLKem768X25519Sha256" ` - -p:DefineConstants="$(DefineConstants);Test_BCL_MLKem" ` + -p:DefineConstants="Test_BCL_MLKem" ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage_2.xml ` @@ -185,7 +194,7 @@ jobs: --logger "console;verbosity=normal" ` --logger GitHubActions ` --filter "Name=MLKem768X25519Sha256" ` - -p:DefineConstants="$(DefineConstants);Test_BouncyCastle_MLKem" ` + -p:DefineConstants="Test_BouncyCastle_MLKem" ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage_3.xml ` @@ -208,6 +217,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v5 + with: + dotnet-version: '10.0.x' + dotnet-quality: 'preview' - name: Setup WSL2 uses: Vampire/setup-wsl@6a8db447be7ed35f2f499c02c6e60ff77ef11278 # v6.0.0 @@ -240,7 +252,7 @@ jobs: --logger "console;verbosity=normal" ` --logger GitHubActions ` --filter "Name=MLKem768X25519Sha256" ` - -p:DefineConstants="$(DefineConstants);Test_BCL_MLKem" ` + -p:DefineConstants="Test_BCL_MLKem" ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage_2.xml ` @@ -253,7 +265,7 @@ jobs: --logger "console;verbosity=normal" ` --logger GitHubActions ` --filter "Name=MLKem768X25519Sha256" ` - -p:DefineConstants="$(DefineConstants);Test_BouncyCastle_MLKem" ` + -p:DefineConstants="Test_BouncyCastle_MLKem" ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage_3.xml `