Conversation
|
Tagging subscribers to this area: @bartonjs, @vcsjones, @dotnet/area-system-security |
There was a problem hiding this comment.
Pull request overview
Implements the proposed X25519DiffieHellman API across Windows (CNG), Apple platforms (CryptoKit via Swift bindings), and OpenSSL, with extensive conformance/contract tests and supporting native interop glue.
Changes:
- Adds new public
System.Security.Cryptography.X25519DiffieHellmanAPI (ref + implementation) with import/export (raw, SPKI, PKCS#8, PEM) and raw secret derivation. - Introduces platform-specific implementations (Windows/CNG, Apple/CryptoKit, OpenSSL) plus new native entrypoints/bindings for OpenSSL and Apple.
- Adds a comprehensive test suite (vectors, key round-tripping, PEM/PKCS#8 behavior, supported vs not-supported gating) and factors shared PKCS#8 test validation into a helper.
Show a summary per file
| File | Description |
|---|---|
| src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_x25519.h | Declares OpenSSL PAL entrypoints for X25519 import/export/generate. |
| src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_x25519.c | Implements OpenSSL PAL wrappers for raw key import/export and keygen. |
| src/native/libs/System.Security.Cryptography.Native/opensslshim.h | Adds OpenSSL shim bindings for raw X25519 key APIs. |
| src/native/libs/System.Security.Cryptography.Native/entrypoints.c | Registers new OpenSSL-side native exports for X25519. |
| src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt | Includes the new OpenSSL X25519 PAL source in the native build. |
| src/native/libs/System.Security.Cryptography.Native.Apple/pal_swiftbindings.swift | Adds CryptoKit-backed Swift entrypoints for X25519 operations. |
| src/native/libs/System.Security.Cryptography.Native.Apple/pal_swiftbindings.h | Declares Swift binding entrypoints for X25519 for P/Invoke table. |
| src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c | Registers AppleCryptoNative X25519 entrypoints. |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanTests.cs | Adds API-level tests for import/export, ASN.1 validation, PEM behavior. |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanTestData.cs | Adds RFC 7748 vectors and encoded test blobs (SPKI/PKCS#8/etc.). |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanNotSupportedTests.cs | Adds tests asserting PNSE behavior when X25519 isn’t supported. |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanKeyTests.cs | Adds key roundtrip tests, scalar clamping preservation checks, vectors. |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanImplementationTests.cs | Hooks base test suite to the public X25519DiffieHellman implementation. |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanContractTests.cs | Adds contract tests for base-class behavior (dispose, buffer sizing, etc.). |
| src/libraries/System.Security.Cryptography/tests/X25519DiffieHellmanBaseTests.cs | Adds shared behavioral tests (vectors, PEM/PKCS#8 export/import patterns). |
| src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj | Wires new X25519 test files + shared PKCS#8 helper into test build. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X25519DiffieHellmanImplementation.Windows.cs | Implements X25519 over CNG (key import/export + secret agreement). |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X25519DiffieHellmanImplementation.OpenSsl.cs | Implements X25519 over OpenSSL handles + PAL entrypoints. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X25519DiffieHellmanImplementation.NotSupported.cs | Provides the not-supported fallback implementation. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X25519DiffieHellmanImplementation.Apple.cs | Implements X25519 using AppleCrypto interop (CryptoKit). |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X25519DiffieHellman.cs | Adds the public API surface and shared PKCS#8/SPKI/PEM glue logic. |
| src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj | Adds new sources + platform interop files to the library build. |
| src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs | Adds reference assembly surface for X25519DiffieHellman. |
| src/libraries/Common/tests/System/Security/Cryptography/Pkcs8TestHelpers.cs | Introduces shared PKCS#8-encryption structure validation helper for tests. |
| src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs | Refactors PKCS#8 encryption assertions to reuse Pkcs8TestHelpers. |
| src/libraries/Common/src/System/Security/Cryptography/Oids.cs | Adds the X25519 OID constant for use in encoding/decoding. |
| src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeBCryptSecretHandle.cs | Adds SafeHandle wrapper for BCrypt secret agreement handles. |
| src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSecretAgreement.cs | Adds BCryptSecretAgreement P/Invoke wrapper returning SafeBCryptSecretHandle. |
| src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptDestroySecret.cs | Adds BCryptDestroySecret P/Invoke for SafeHandle release. |
| src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptDeriveKey.cs | Adds BCryptDeriveKey P/Invoke wrapper used by X25519 derivation on Windows. |
| src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.X25519.cs | Adds Unix/OpenSSL interop wrappers for X25519 PAL entrypoints. |
| src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.X25519.cs | Adds AppleCrypto interop + SafeX25519KeyHandle definition. |
| THIRD-PARTY-NOTICES.TXT | Adds Wycheproof Apache-2.0 license notice for included test vectors. |
Copilot's findings
Comments suppressed due to low confidence (2)
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X25519DiffieHellman.cs:1276
- ImportFromEncryptedPem(ReadOnlySpan, ReadOnlySpan) also doesn't call ThrowIfNotSupported() before attempting to parse the PEM. This can result in non-PlatformNotSupportedException failures when X25519 isn't available. Add an early ThrowIfNotSupported() for consistent platform-guard behavior.
public static X25519DiffieHellman ImportFromEncryptedPem(ReadOnlySpan<char> source, ReadOnlySpan<byte> passwordBytes)
{
return PemKeyHelpers.ImportEncryptedFactoryPem<X25519DiffieHellman, byte>(
source,
passwordBytes,
ImportEncryptedPkcs8PrivateKey);
}
src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs:575
- After switching AssertEncryptedPkcs8PrivateKeyContents to call Pkcs8TestHelpers, GetHashAlgorithmFromPbkdf2Params is now unused in this file. Please remove the dead method (and any now-unused usings) to avoid analyzer warnings / warnings-as-errors in test builds.
private static void AssertEncryptedPkcs8PrivateKeyContents(PbeParameters pbeParameters, ReadOnlyMemory<byte> contents)
{
Pkcs8TestHelpers.AssertEncryptedPkcs8PrivateKeyContents(pbeParameters, contents);
}
private static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(in ValuePbkdf2Params pbkdf2Params)
{
return pbkdf2Params.Prf.Algorithm switch
{
"1.2.840.113549.2.7" => HashAlgorithmName.SHA1,
"1.2.840.113549.2.9" => HashAlgorithmName.SHA256,
"1.2.840.113549.2.10" => HashAlgorithmName.SHA384,
"1.2.840.113549.2.11" => HashAlgorithmName.SHA512,
string other => throw new XunitException($"Unknown hash algorithm OID '{other}'."),
};
}
- Files reviewed: 33/33 changed files
- Comments generated: 3
There was a problem hiding this comment.
Copilot's findings
Comments suppressed due to low confidence (1)
src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs:574
GetHashAlgorithmFromPbkdf2Paramsis now unused after moving the encrypted PKCS#8 parsing assertions intoPkcs8TestHelpers. If warnings are treated as errors for this test project, this will break the build. Remove the unused method (and any now-unneeded usings) or use it fromPkcs8TestHelpersinstead of duplicating logic there.
private static void AssertEncryptedPkcs8PrivateKeyContents(PbeParameters pbeParameters, ReadOnlyMemory<byte> contents)
{
Pkcs8TestHelpers.AssertEncryptedPkcs8PrivateKeyContents(pbeParameters, contents);
}
private static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(in ValuePbkdf2Params pbkdf2Params)
{
return pbkdf2Params.Prf.Algorithm switch
{
"1.2.840.113549.2.7" => HashAlgorithmName.SHA1,
"1.2.840.113549.2.9" => HashAlgorithmName.SHA256,
"1.2.840.113549.2.10" => HashAlgorithmName.SHA384,
"1.2.840.113549.2.11" => HashAlgorithmName.SHA512,
string other => throw new XunitException($"Unknown hash algorithm OID '{other}'."),
};
- Files reviewed: 33/33 changed files
- Comments generated: 2
bartonjs
left a comment
There was a problem hiding this comment.
I made it through the main (non-native) implementation parts, stopped before the tests. I'll look more tomorrow.
This implements X25519 Diffie-Hellman on Windows 10+, Apple macOS, iOS / tvOS by way of CryptoKit, and OpenSSL.
What will be follow up pull requests
Contributes to #126206