Add managed Composite ML-KEM implementation - #132659
Conversation
Implement the shared OpenSSL-backed managed provider for RSA-OAEP, ECDH, and X25519 composites, including draft-compliant key serialization and secret combination. Add official draft vectors and managed implementation coverage for key formats, rejection behavior, disposal, and round trips. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 02fe9eac-5557-460a-aa50-d6a60a546192
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Adds a managed implementation of Composite ML-KEM (hybrid ML-KEM + traditional KEM) for the OpenSSL-backed build, wiring it into System.Security.Cryptography and extending the shared test suite with IETF test vectors.
Changes:
- Add managed Composite ML-KEM implementation (
CompositeMLKemManaged*) and route OpenSSL implementation entrypoints to it. - Extend Composite ML-KEM tests with implementation tests, base test coverage, and IETF vector data.
- Expand supporting infrastructure (RSA PKCS#1 decode rule set parameter, BER DER utilities, new SR string).
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj | Includes shared Composite ML-KEM test files in the System.Security.Cryptography test project. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLKemImplementation.OpenSsl.cs | Adds per-algorithm support probing for OpenSSL ML-KEM. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLKemImplementation.OpenSsl.cs | Routes Composite ML-KEM OpenSSL implementation hooks to the managed implementation. |
| src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj | Adds Composite ML-KEM managed sources and swaps in OpenSSL composite implementation file. |
| src/libraries/System.Security.Cryptography/src/Resources/Strings.resx | Adds an SR string for RSA-OAEP decapsulation length mismatch. |
| src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj | Includes shared Composite ML-KEM test vector/types in the BCL test project. |
| src/libraries/Common/tests/System/Security/Cryptography/AsnUtils.cs | Updates DER→BER helper to take ReadOnlySpan<byte> and use Slice. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemTestVector.cs | Adds a test-vector wrapper that parses SPKI from a certificate. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemTestsBase.cs | Adds a shared behavioral test base covering encapsulate/decapsulate and import/export failure modes. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemTestData.cs | Adds vector-driven MemberData helpers and component metadata used by tests. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemTestData.Raw.cs | Adds IETF test vectors (generated) used by Composite ML-KEM tests. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemImplementationTests.cs | Adds tests asserting returned runtime types are internal and validating import/export behavior against vectors. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemFactoryTests.cs | Updates support checks and adds successful import tests and PKCS#8/Encrypted PKCS#8 coverage. |
| src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLKem/CompositeMLKemContractTests.cs | Strengthens contract tests to ensure secrets are cleared on exceptions and call counts are correct. |
| src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs | Adds an AsnEncodingRules parameter to PKCS#1 decode helpers (default BER). |
| src/libraries/Common/src/System/Security/Cryptography/MLKemImplementation.Windows.cs | Adds IsAlgorithmSupported helper for Windows implementation. |
| src/libraries/Common/src/System/Security/Cryptography/MLKemImplementation.NotSupported.cs | Adds IsAlgorithmSupported helper for NotSupported implementation. |
| src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.XDiffieHellman.cs | Implements the X25519-based traditional KEM portion for the managed composite KEM. |
| src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.RSA.cs | Implements the RSA-OAEP traditional KEM portion and adds a dedicated decapsulation failure SR message. |
| src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.ECDiffieHellman.cs | Implements the ECDH traditional KEM portion and DER-only key import/export logic. |
| src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs | Implements the managed composite KEM logic (support probing, key gen/import, encaps/decaps, combiner). |
| src/libraries/Common/src/System/Security/Cryptography/CompositeMLKem.cs | Clears shared-secret buffers on exceptions in encapsulate/decapsulate wrapper methods. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 02fe9eac-5557-460a-aa50-d6a60a546192
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:488
- The X25519 algorithm metadata uses a 6-byte label value that doesn’t match the ASCII label style used for the other Composite ML-KEM algorithms in this table (e.g., "MLKEM768-RSAOAEP2048", "MLKEM1024-X448"). Since the label is part of the combiner input (and should be stable / spec-defined), this looks like an accidental placeholder and would change the derived shared secret.
CompositeMLKemAlgorithm.MLKem768WithX25519,
new(MLKemAlgorithm.MLKem768, new XDiffieHellmanKemAlgorithm(IsX25519: true), [0x5C, 0x2E, 0x2F, 0x2F, 0x5E, 0x5C])
},
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:443
TraditionalKemdeclares abstract members but is declared with the non-existent keywordclosed, which will not compile. This should be anabstractbase type (matching the pattern used byCompositeMLDsaManaged.ComponentAlgorithm).
private closed class TraditionalKem : IDisposable
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 11ffe761-e9d2-47c2-ace0-857272c52b10
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated no new comments.
Suppressed comments (2)
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:443
TraditionalKemdeclares abstract members but the type itself is not abstract. This won’t compile (non-abstract types can’t contain abstract members).
private closed class TraditionalKem : IDisposable
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:537
TraditionalKemAlgorithmhas an abstract member (SharedSecretSizeInBytes) but the record itself is not abstract. This won’t compile.
private closed record TraditionalKemAlgorithm
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 11ffe761-e9d2-47c2-ace0-857272c52b10
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated no new comments.
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:488
- The X25519 label is currently hard-coded to the byte sequence
\ . / / ^ \([0x5C, 0x2E, 0x2F, 0x2F, 0x5E, 0x5C]), which is inconsistent with the other labels (UTF-8 text) and is very likely incorrect per the composite KEM spec label inputs. Use a UTF-8 string label consistent with the other algorithms (e.g., "MLKEM768-X25519").
{
CompositeMLKemAlgorithm.MLKem768WithX25519,
new(MLKemAlgorithm.MLKem768, new XDiffieHellmanKemAlgorithm(IsX25519: true), [0x5C, 0x2E, 0x2F, 0x2F, 0x5E, 0x5C])
},
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:450
TraditionalKemdeclares abstract members but is currently declared asclosed class, which is not a valid C# modifier and will not compile. This should beabstract(orsealedwith no abstract members).
private closed class TraditionalKem : IDisposable
{
private bool _disposed;
internal abstract void Encapsulate(Span<byte> ciphertext, Span<byte> sharedSecret);
internal abstract void Decapsulate(ReadOnlySpan<byte> ciphertext, Span<byte> sharedSecret);
internal abstract int ExportPublicKey(Span<byte> destination);
internal abstract int ExportPrivateKey(Span<byte> destination);
src/libraries/Common/src/System/Security/Cryptography/CompositeMLKemManaged.cs:540
TraditionalKemAlgorithmhas an abstract member but is declared asclosed record, which is not a valid C# modifier and will not compile. Make the base recordabstractso derived algorithm records can override the abstract property.
private closed record TraditionalKemAlgorithm
{
internal abstract int SharedSecretSizeInBytes { get; }
}
Managed Composite ML-KEM. This implementation is just for OpenSSL. Windows will have a native implementation added in a future PR.
Contributes to #129633