-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Implement HKDF with CryptoKit on Apple #119998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
5294cb6
Start CryptoKit bring up of HKDF
vcsjones e0033bf
Finish derive key
vcsjones 43f4b4c
Add missing MD5 Expand test case
vcsjones 7c67a35
Add tests for MD5 extract
vcsjones 3e1fbe0
Add missing tests for DeriveKey MD5
vcsjones 81888c6
Add missing test cases for SHA-384 and SHA-512
vcsjones d6dcded
Copy over docs fix
vcsjones ed73036
Add explicit return since Copilot wants it
vcsjones 30d5f6c
Fix typos.
vcsjones f95a29b
Add debugging logs
vcsjones 54a9a45
See if this is the Swift copyBytes bug
vcsjones 1b5aa6e
Merge branch 'main' into hkdf-cryptokit
vcsjones bcbb434
Revert data copying.
vcsjones 09c8cef
Try not using swift structs at p/invoke boundary
vcsjones 06ed5d3
Remove logging / diagnostics
vcsjones File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
140 changes: 140 additions & 0 deletions
140
...ibraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.HKDF.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using System.Runtime.InteropServices.Swift; | ||
using System.Runtime.Versioning; | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.Apple; | ||
using Swift.Runtime; | ||
|
||
#pragma warning disable CS3016 // Arrays as attribute arguments are not CLS Compliant | ||
|
||
internal static partial class Interop | ||
{ | ||
internal static partial class AppleCrypto | ||
{ | ||
internal static unsafe void HkdfExpand( | ||
HashAlgorithmName hashAlgorithm, | ||
ReadOnlySpan<byte> prk, | ||
ReadOnlySpan<byte> info, | ||
Span<byte> destination) | ||
{ | ||
Debug.Assert(!destination.IsEmpty); | ||
Debug.Assert(!prk.IsEmpty); | ||
|
||
PAL_HashAlgorithm algorithm = PalAlgorithmFromAlgorithmName(hashAlgorithm); | ||
|
||
int ret = AppleCryptoNative_HKDFExpand( | ||
algorithm, | ||
prk, | ||
prk.Length, | ||
info, | ||
info.Length, | ||
destination, | ||
destination.Length); | ||
|
||
if (ret < 0) | ||
{ | ||
throw new CryptographicException(); | ||
} | ||
|
||
Debug.Assert(ret == destination.Length); | ||
} | ||
|
||
internal static unsafe void HKDFExtract( | ||
HashAlgorithmName hashAlgorithm, | ||
ReadOnlySpan<byte> ikm, | ||
ReadOnlySpan<byte> salt, | ||
Span<byte> destination) | ||
{ | ||
Debug.Assert(!destination.IsEmpty); | ||
|
||
PAL_HashAlgorithm algorithm = PalAlgorithmFromAlgorithmName(hashAlgorithm); | ||
|
||
int ret = AppleCryptoNative_HKDFExtract( | ||
algorithm, | ||
ikm, | ||
ikm.Length, | ||
salt, | ||
salt.Length, | ||
destination, | ||
destination.Length); | ||
|
||
if (ret < 0) | ||
{ | ||
throw new CryptographicException(); | ||
} | ||
|
||
Debug.Assert(ret == destination.Length); | ||
} | ||
|
||
internal static unsafe void HKDFDeriveKey( | ||
HashAlgorithmName hashAlgorithm, | ||
ReadOnlySpan<byte> ikm, | ||
ReadOnlySpan<byte> salt, | ||
ReadOnlySpan<byte> info, | ||
Span<byte> destination) | ||
{ | ||
Debug.Assert(!destination.IsEmpty); | ||
|
||
PAL_HashAlgorithm algorithm = PalAlgorithmFromAlgorithmName(hashAlgorithm); | ||
|
||
int ret = AppleCryptoNative_HKDFDeriveKey( | ||
algorithm, | ||
ikm, | ||
ikm.Length, | ||
salt, | ||
salt.Length, | ||
info, | ||
info.Length, | ||
destination, | ||
destination.Length); | ||
|
||
if (ret < 0) | ||
{ | ||
throw new CryptographicException(); | ||
} | ||
|
||
Debug.Assert(ret == destination.Length); | ||
} | ||
|
||
[LibraryImport(Libraries.AppleCryptoNative)] | ||
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])] | ||
private static partial int AppleCryptoNative_HKDFExpand( | ||
PAL_HashAlgorithm hashAlgorithm, | ||
ReadOnlySpan<byte> prkPtr, | ||
int prkLength, | ||
ReadOnlySpan<byte> infoPtr, | ||
int infoLength, | ||
Span<byte> destinationPtr, | ||
int destinationLength); | ||
|
||
[LibraryImport(Libraries.AppleCryptoNative)] | ||
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])] | ||
private static partial int AppleCryptoNative_HKDFExtract( | ||
PAL_HashAlgorithm hashAlgorithm, | ||
ReadOnlySpan<byte> ikmPtr, | ||
int ikmLength, | ||
ReadOnlySpan<byte> saltPtr, | ||
int saltLength, | ||
Span<byte> destinationPtr, | ||
int destinationLength); | ||
|
||
[LibraryImport(Libraries.AppleCryptoNative)] | ||
[UnmanagedCallConv(CallConvs = [ typeof(CallConvSwift) ])] | ||
private static partial int AppleCryptoNative_HKDFDeriveKey( | ||
PAL_HashAlgorithm hashAlgorithm, | ||
ReadOnlySpan<byte> ikmPtr, | ||
int ikmLength, | ||
ReadOnlySpan<byte> saltPtr, | ||
int saltLength, | ||
ReadOnlySpan<byte> infoPtr, | ||
int infoLength, | ||
Span<byte> destinationPtr, | ||
int destinationLength); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.Apple.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Diagnostics; | ||
|
||
namespace System.Security.Cryptography | ||
{ | ||
public static partial class HKDF | ||
{ | ||
private static readonly bool s_hasCryptoKitImplementation = | ||
OperatingSystem.IsMacOS() || | ||
OperatingSystem.IsMacCatalyst() || | ||
OperatingSystem.IsIOSVersionAtLeast(14) || | ||
OperatingSystem.IsTvOSVersionAtLeast(14); | ||
|
||
private static void Extract( | ||
HashAlgorithmName hashAlgorithmName, | ||
int hashLength, | ||
ReadOnlySpan<byte> ikm, | ||
ReadOnlySpan<byte> salt, | ||
Span<byte> prk) | ||
{ | ||
ThrowForUnsupportedHashAlgorithm(hashAlgorithmName); | ||
|
||
if (s_hasCryptoKitImplementation) | ||
{ | ||
Interop.AppleCrypto.HKDFExtract(hashAlgorithmName, ikm, salt, prk); | ||
} | ||
else | ||
{ | ||
HKDFManagedImplementation.Extract(hashAlgorithmName, hashLength, ikm, salt, prk); | ||
} | ||
} | ||
|
||
private static void Expand( | ||
HashAlgorithmName hashAlgorithmName, | ||
int hashLength, | ||
ReadOnlySpan<byte> prk, | ||
Span<byte> output, | ||
ReadOnlySpan<byte> info) | ||
{ | ||
ThrowForUnsupportedHashAlgorithm(hashAlgorithmName); | ||
|
||
if (s_hasCryptoKitImplementation) | ||
{ | ||
Interop.AppleCrypto.HkdfExpand(hashAlgorithmName, prk, info, output); | ||
} | ||
else | ||
{ | ||
HKDFManagedImplementation.Expand(hashAlgorithmName, hashLength, prk, output, info); | ||
} | ||
} | ||
|
||
private static void DeriveKeyCore( | ||
HashAlgorithmName hashAlgorithmName, | ||
int hashLength, | ||
ReadOnlySpan<byte> ikm, | ||
Span<byte> output, | ||
ReadOnlySpan<byte> salt, | ||
ReadOnlySpan<byte> info) | ||
{ | ||
ThrowForUnsupportedHashAlgorithm(hashAlgorithmName); | ||
|
||
if (s_hasCryptoKitImplementation) | ||
{ | ||
Interop.AppleCrypto.HKDFDeriveKey(hashAlgorithmName, ikm, salt, info, output); | ||
} | ||
else | ||
{ | ||
HKDFManagedImplementation.DeriveKey(hashAlgorithmName, hashLength, ikm, output, salt, info); | ||
} | ||
} | ||
|
||
private static void ThrowForUnsupportedHashAlgorithm(HashAlgorithmName hashAlgorithmName) | ||
{ | ||
if (hashAlgorithmName == HashAlgorithmName.SHA3_256 || hashAlgorithmName == HashAlgorithmName.SHA3_384 || | ||
hashAlgorithmName == HashAlgorithmName.SHA3_512) | ||
{ | ||
throw new PlatformNotSupportedException(); | ||
} | ||
|
||
// Unknown algorithms are handled outside of this as a CryptographicException. SHA-3 is known, it's just | ||
// not supported. | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.