Skip to content

Commit e303672

Browse files
Add MLDsaCng into Microsoft.Bcl.Cryptography (#116678)
1 parent 647b4f5 commit e303672

27 files changed

+854
-363
lines changed

src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptExportKey.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Diagnostics;
56
using System.Runtime.InteropServices;
67
using System.Security.Cryptography;
78

@@ -36,10 +37,78 @@ internal static ArraySegment<byte> BCryptExportKey(SafeBCryptKeyHandle key, stri
3637

3738
if (ntStatus != NTSTATUS.STATUS_SUCCESS)
3839
{
40+
CryptoPool.Return(rented);
3941
throw CreateCryptographicException(ntStatus);
4042
}
4143

4244
return new ArraySegment<byte>(rented, 0, numBytesNeeded);
4345
}
46+
47+
internal static T BCryptExportKey<T>(SafeBCryptKeyHandle key, string blobType, Func<byte[], T> callback)
48+
{
49+
int numBytesNeeded;
50+
NTSTATUS ntStatus = BCryptExportKey(key, IntPtr.Zero, blobType, null, 0, out numBytesNeeded, 0);
51+
52+
if (ntStatus != NTSTATUS.STATUS_SUCCESS)
53+
{
54+
throw CreateCryptographicException(ntStatus);
55+
}
56+
57+
// Array must be precisely-sized, so no renting.
58+
byte[] destination = new byte[numBytesNeeded];
59+
60+
using (PinAndClear.Track(destination))
61+
{
62+
ntStatus = BCryptExportKey(key, IntPtr.Zero, blobType, destination, numBytesNeeded, out numBytesNeeded, 0);
63+
64+
if (ntStatus != NTSTATUS.STATUS_SUCCESS)
65+
{
66+
throw CreateCryptographicException(ntStatus);
67+
}
68+
69+
if (numBytesNeeded != destination.Length)
70+
{
71+
Debug.Fail("Written byte count does not match required byte count.");
72+
throw new CryptographicException();
73+
}
74+
75+
return callback(destination);
76+
}
77+
}
78+
79+
internal delegate T ExportKeyCallback<T>(ReadOnlySpan<byte> keyBytes);
80+
81+
internal static T BCryptExportKey<T>(SafeBCryptKeyHandle key, string blobType, ExportKeyCallback<T> callback)
82+
{
83+
int numBytesNeeded;
84+
NTSTATUS ntStatus = BCryptExportKey(key, IntPtr.Zero, blobType, null, 0, out numBytesNeeded, 0);
85+
86+
if (ntStatus != NTSTATUS.STATUS_SUCCESS)
87+
{
88+
throw CreateCryptographicException(ntStatus);
89+
}
90+
91+
byte[] rented = CryptoPool.Rent(numBytesNeeded);
92+
93+
try
94+
{
95+
using (PinAndClear.Track(rented))
96+
{
97+
ntStatus = BCryptExportKey(key, IntPtr.Zero, blobType, rented, numBytesNeeded, out numBytesNeeded, 0);
98+
99+
if (ntStatus != NTSTATUS.STATUS_SUCCESS)
100+
{
101+
throw CreateCryptographicException(ntStatus);
102+
}
103+
104+
return callback(rented.AsSpan(0, numBytesNeeded));
105+
}
106+
}
107+
finally
108+
{
109+
// PinAndClear will clear
110+
CryptoPool.Return(rented, clearSize: 0);
111+
}
112+
}
44113
}
45114
}

src/libraries/Common/src/Interop/Windows/NCrypt/Interop.SignVerify.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ internal static unsafe ErrorCode NCryptSignHash(SafeNCryptKeyHandle hKey, void*
2323
}
2424

2525
[LibraryImport(Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)]
26-
internal static unsafe partial ErrorCode NCryptVerifySignature(SafeNCryptKeyHandle hKey, void* pPaddingInfo, ReadOnlySpan<byte> pbHashValue, int cbHashValue, ReadOnlySpan<byte> pbSignature, int cbSignature, AsymmetricPaddingMode dwFlags);
26+
private static unsafe partial ErrorCode NCryptVerifySignature(SafeNCryptKeyHandle hKey, void* pPaddingInfo, byte* pbHashValue, int cbHashValue, byte* pbSignature, int cbSignature, AsymmetricPaddingMode dwFlags);
27+
28+
internal static unsafe ErrorCode NCryptVerifySignature(SafeNCryptKeyHandle hKey, void* pPaddingInfo, ReadOnlySpan<byte> pbHashValue, int cbHashValue, ReadOnlySpan<byte> pbSignature, int cbSignature, AsymmetricPaddingMode dwFlags)
29+
{
30+
fixed (byte* pHash = &Helpers.GetNonNullPinnableReference(pbHashValue))
31+
fixed (byte* pSignature = &Helpers.GetNonNullPinnableReference(pbSignature))
32+
{
33+
return NCryptVerifySignature(hKey, pPaddingInfo, pHash, cbHashValue, pSignature, cbSignature, dwFlags);
34+
}
35+
}
2736
}
2837
}
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
54
using System.Diagnostics;
6-
using Internal.Cryptography;
75
using Microsoft.Win32.SafeHandles;
86
using AsymmetricPaddingMode = Interop.NCrypt.AsymmetricPaddingMode;
97
using ErrorCode = Interop.NCrypt.ErrorCode;
108

119
namespace System.Security.Cryptography
1210
{
13-
internal static partial class CngCommon
11+
internal static partial class CngHelpers
1412
{
1513
private const int StatusUnsuccessfulRetryCount = 1;
1614

0 commit comments

Comments
 (0)