11 internal static class BCrypt
13 private struct BCRYPT_KEY_DATA_BLOB_HEADER
31 internal struct BCRYPT_OAEP_PADDING_INFO
40 internal struct BCRYPT_PKCS1_PADDING_INFO
45 internal struct BCRYPT_PSS_PADDING_INFO
80 internal struct BCRYPT_RSAKEY_BLOB
82 internal KeyBlobMagicNumber
Magic;
95 internal struct BCRYPT_DSA_KEY_BLOB
97 internal KeyBlobMagicNumber
Magic;
101 internal unsafe fixed
byte Count[4];
103 internal unsafe fixed
byte Seed[20];
105 internal unsafe fixed
byte q[20];
108 internal struct BCRYPT_DSA_KEY_BLOB_V2
110 internal KeyBlobMagicNumber
Magic;
122 internal unsafe fixed
byte Count[4];
138 internal struct BCRYPT_ECCKEY_BLOB
140 internal KeyBlobMagicNumber
Magic;
157 internal struct BCRYPT_ECCFULLKEY_BLOB
159 internal KeyBlobMagicNumber
Magic;
198 internal struct BCryptBuffer
207 internal struct BCryptBufferDesc
216 internal struct BCRYPT_ECC_PARAMETER_HEADER
247 internal static class BCryptAlgorithmCache
261 this =
default(
Entry);
265 Unsafe.SkipInit(out
int hashSizeInBytes);
276 private static volatile Entry[]
_cache =
Array.Empty<Entry>();
282 for (
int i = 0; i < array2.Length; i++)
284 Entry entry = array2[i];
285 if (entry.HashAlgorithmId == hashAlgorithmId && entry.Flags == flags)
287 hashSizeInBytes = entry.HashSizeInBytes;
298 Entry entry2 =
new Entry(hashAlgorithmId, flags, phAlgorithm);
299 array[^1] =
new Entry(hashAlgorithmId, flags, phAlgorithm);
301 hashSizeInBytes = entry2.HashSizeInBytes;
302 return entry2.Handle;
310 byte[]
array =
new byte[num];
311 fixed (
byte* ptr =
array)
314 ptr2->dwMagic = 1296188491u;
315 ptr2->dwVersion = 1u;
316 ptr2->cbKeyData = (uint)
length;
333 fixed (
byte* pbInput =
input)
335 fixed (
byte* pbOutput = output)
350 fixed (
byte* pbInput =
input)
352 fixed (
byte* pbOutput = output)
380 for (
int i =
offset; i < num; i++)
405 int hr = (int)(ntStatus | (
NTSTATUS)16777216u);
406 return hr.ToCryptographicException();
448 internal struct CRYPT_OID_INFO
482 intPtr = keyType
switch
502 if (fallBackToAllGroups && group != 0)
527 return group ==
OidGroup.KeyDerivationFunction;
540 int pvKey = (int)algId;
552 internal static class NCrypt
577 internal struct CRYPT_PKCS12_PBE_PARAMS
584 internal struct PBE_PARAMS
586 internal CRYPT_PKCS12_PBE_PARAMS
Params;
588 internal unsafe fixed
byte rgbSalt[8];
611 internal struct NCryptBuffer
620 internal struct NCryptBufferDesc
703 nCryptBuffer.cbBuffer = (hashAlgorithm.Length + 1) * 2;
704 nCryptBuffer.BufferType =
BufferType.KdfHashAlgorithm;
705 nCryptBuffer.pvBuffer = intPtr;
706 span[num] = nCryptBuffer;
708 fixed (
byte* ptr = hmacKey)
710 fixed (
byte* ptr2 = secretPrepend)
712 fixed (
byte* ptr3 = secretAppend)
717 nCryptBuffer2.cbBuffer = hmacKey.Length;
718 nCryptBuffer2.BufferType =
BufferType.KdfHmacKey;
719 nCryptBuffer2.pvBuffer =
new IntPtr(ptr);
720 span[num] = nCryptBuffer2;
726 nCryptBuffer3.cbBuffer = secretPrepend.Length;
727 nCryptBuffer3.BufferType =
BufferType.KdfSecretPrepend;
728 nCryptBuffer3.pvBuffer =
new IntPtr(ptr2);
729 span[num] = nCryptBuffer3;
735 nCryptBuffer4.cbBuffer = secretAppend.Length;
736 nCryptBuffer4.BufferType =
BufferType.KdfSecretAppend;
737 nCryptBuffer4.pvBuffer =
new IntPtr(ptr3);
738 span[num] = nCryptBuffer4;
760 pParameterList.ulVersion = 0;
761 pParameterList.cBuffers = parameters.
Length;
764 if (errorCode != 0 && errorCode !=
ErrorCode.NTE_BUFFER_TOO_SMALL)
766 throw errorCode.ToCryptographicException();
768 byte[]
array =
new byte[pcbResult];
772 throw errorCode.ToCryptographicException();
781 return DeriveKeyMaterial(secretAgreement,
"HASH", hashAlgorithm,
null, secretPrepend, secretAppend, flags);
786 return DeriveKeyMaterial(secretAgreement,
"HMAC", hashAlgorithm, hmacKey, secretPrepend, secretAppend, flags);
792 fixed (
byte*
value = label)
794 fixed (
byte* value2 = seed)
797 nCryptBuffer.cbBuffer = label.Length;
798 nCryptBuffer.BufferType =
BufferType.KdfTlsLabel;
800 span[0] = nCryptBuffer;
802 nCryptBuffer2.cbBuffer = seed.Length;
803 nCryptBuffer2.BufferType =
BufferType.KdfTlsSeed;
804 nCryptBuffer2.pvBuffer =
new IntPtr(value2);
805 span[1] = nCryptBuffer2;
811 [DllImport(
"ncrypt.dll")]
820 throw errorCode.ToCryptographicException();
833 fixed (
int* pbOutput = &result)
859 [DllImport(
"kernel32.dll", BestFitMapping =
true,
CharSet =
CharSet.Unicode, EntryPoint =
"FormatMessageW", ExactSpelling =
true,
SetLastError =
true)]
860 private unsafe
static extern int FormatMessage(
int dwFlags,
IntPtr lpSource, uint dwMessageId,
int dwLanguageId,
void* lpBuffer,
int nSize,
IntPtr arguments);
875 fixed (
char* lpBuffer = span)
899 return $
"Unknown error (0x{errorCode:x})";
905 while (num > 0 &&
buffer[num - 1] <=
' ')
909 return buffer.Slice(0, num).ToString();
static volatile Entry[] _cache
static Microsoft.Win32.SafeHandles.SafeBCryptAlgorithmHandle GetCachedBCryptAlgorithmHandle(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, out int hashSizeInBytes)
static NTSTATUS BCryptDestroyHash(IntPtr hHash)
static unsafe int BCryptEncrypt(SafeKeyHandle hKey, ReadOnlySpan< byte > input, byte[] iv, Span< byte > output)
static unsafe Internal.NativeCrypto.SafeKeyHandle BCryptImportKey(Internal.NativeCrypto.SafeAlgorithmHandle hAlg, ReadOnlySpan< byte > key)
static Exception CreateCryptographicException(NTSTATUS ntStatus)
static unsafe NTSTATUS BCryptGetProperty(Microsoft.Win32.SafeHandles.SafeBCryptHandle hObject, string pszProperty, void *pbOutput, int cbOutput, out int pcbResult, int dwFlags)
@ DSA_HASH_ALGORITHM_SHA1
@ DSA_HASH_ALGORITHM_SHA256
@ DSA_HASH_ALGORITHM_SHA512
@ STATUS_AUTH_TAG_MISMATCH
@ STATUS_INVALID_PARAMETER
static unsafe NTSTATUS BCryptEncrypt(Internal.NativeCrypto.SafeKeyHandle hKey, byte *pbInput, int cbInput, IntPtr paddingInfo, [In][Out] byte[] pbIV, int cbIV, byte *pbOutput, int cbOutput, out int cbResult, int dwFlags)
static NTSTATUS BCryptOpenAlgorithmProvider(out Microsoft.Win32.SafeHandles.SafeBCryptAlgorithmHandle phAlgorithm, string pszAlgId, string pszImplementation, BCryptOpenAlgorithmProviderFlags dwFlags)
static NTSTATUS BCryptHashData(Microsoft.Win32.SafeHandles.SafeBCryptHashHandle hHash, ref byte pbInput, int cbInput, int dwFlags)
static void EmitBigEndian(byte[] blob, ref int offset, int value)
@ BCRYPT_HASH_REUSABLE_FLAG
static NTSTATUS BCryptCreateHash(Microsoft.Win32.SafeHandles.SafeBCryptAlgorithmHandle hAlgorithm, out Microsoft.Win32.SafeHandles.SafeBCryptHashHandle phHash, IntPtr pbHashObject, int cbHashObject, ref byte pbSecret, int cbSecret, BCryptCreateHashFlags dwFlags)
@ NCRYPTBUFFER_ECC_CURVE_NAME
static unsafe NTSTATUS BCryptDecrypt(Internal.NativeCrypto.SafeKeyHandle hKey, byte *pbInput, int cbInput, IntPtr paddingInfo, [In][Out] byte[] pbIV, int cbIV, byte *pbOutput, int cbOutput, out int cbResult, int dwFlags)
static NTSTATUS BCryptImportKey(Internal.NativeCrypto.SafeAlgorithmHandle hAlgorithm, IntPtr hImportKey, string pszBlobType, out Internal.NativeCrypto.SafeKeyHandle hKey, IntPtr pbKeyObject, int cbKeyObject, byte[] pbInput, int cbInput, int dwFlags)
@ BCRYPT_ECC_PRIME_MONTGOMERY_CURVE
@ BCRYPT_ECC_PRIME_SHORT_WEIERSTRASS_CURVE
@ BCRYPT_ECC_PRIME_TWISTED_EDWARDS_CURVE
BCryptOpenAlgorithmProviderFlags
@ BCRYPT_ALG_HANDLE_HMAC_FLAG
static NTSTATUS BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, int dwFlags)
static void EmitByte(byte[] blob, ref int offset, byte value, int count=1)
static unsafe SafeKeyHandle BCryptImportKey(SafeAlgorithmHandle hAlg, ReadOnlySpan< byte > key)
static NTSTATUS BCryptCreateHash(SafeBCryptAlgorithmHandle hAlgorithm, out SafeBCryptHashHandle phHash, IntPtr pbHashObject, int cbHashObject, ReadOnlySpan< byte > secret, int cbSecret, BCryptCreateHashFlags dwFlags)
static NTSTATUS BCryptFinishHash(Microsoft.Win32.SafeHandles.SafeBCryptHashHandle hHash, Span< byte > pbOutput, int cbOutput, int dwFlags)
static unsafe int BCryptDecrypt(Internal.NativeCrypto.SafeKeyHandle hKey, ReadOnlySpan< byte > input, byte[] iv, Span< byte > output)
static byte[] Consume(byte[] blob, ref int offset, int count)
static unsafe int BCryptEncrypt(Internal.NativeCrypto.SafeKeyHandle hKey, ReadOnlySpan< byte > input, byte[] iv, Span< byte > output)
static NTSTATUS BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle phAlgorithm, string pszAlgId, string pszImplementation, BCryptOpenAlgorithmProviderFlags dwFlags)
static NTSTATUS BCryptHashData(Microsoft.Win32.SafeHandles.SafeBCryptHashHandle hHash, ReadOnlySpan< byte > pbInput, int cbInput, int dwFlags)
static unsafe int BCryptDecrypt(SafeKeyHandle hKey, ReadOnlySpan< byte > input, byte[] iv, Span< byte > output)
@ BCRYPT_ECDH_PUBLIC_P521_MAGIC
@ BCRYPT_DSA_PRIVATE_MAGIC
@ BCRYPT_ECDH_PRIVATE_P256_MAGIC
@ BCRYPT_RSAFULLPRIVATE_MAGIC
@ BCRYPT_ECDSA_PUBLIC_P384_MAGIC
@ BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC
@ BCRYPT_ECDH_PUBLIC_P256_MAGIC
@ BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC
@ BCRYPT_ECDH_PRIVATE_P384_MAGIC
@ BCRYPT_ECDH_PRIVATE_P521_MAGIC
@ BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC
@ BCRYPT_ECDSA_PUBLIC_P256_MAGIC
@ BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC
@ BCRYPT_ECDH_PUBLIC_P384_MAGIC
@ BCRYPT_DSA_PUBLIC_MAGIC_V2
@ BCRYPT_DSA_PRIVATE_MAGIC_V2
@ BCRYPT_KEY_DATA_BLOB_MAGIC
@ BCRYPT_DSA_PUBLIC_MAGIC
@ BCRYPT_ECDSA_PUBLIC_P521_MAGIC
@ BCRYPT_ECDSA_PRIVATE_P256_MAGIC
@ BCRYPT_ECDSA_PRIVATE_P521_MAGIC
@ BCRYPT_RSAPRIVATE_MAGIC
@ BCRYPT_ECDSA_PRIVATE_P384_MAGIC
static NTSTATUS BCryptFinishHash(SafeBCryptHashHandle hHash, Span< byte > pbOutput, int cbOutput, int dwFlags)
static unsafe NTSTATUS BCryptGetProperty(SafeBCryptHandle hObject, string pszProperty, void *pbOutput, int cbOutput, out int pcbResult, int dwFlags)
static NTSTATUS BCryptHashData(SafeBCryptHashHandle hHash, ReadOnlySpan< byte > pbInput, int cbInput, int dwFlags)
@ BCRYPT_NO_CURVE_GENERATION_ALG_ID
static NTSTATUS BCryptCreateHash(Microsoft.Win32.SafeHandles.SafeBCryptAlgorithmHandle hAlgorithm, out Microsoft.Win32.SafeHandles.SafeBCryptHashHandle phHash, IntPtr pbHashObject, int cbHashObject, ReadOnlySpan< byte > secret, int cbSecret, BCryptCreateHashFlags dwFlags)
static void Emit(byte[] blob, ref int offset, byte[] value)
static NTSTATUS BCryptFinishHash(Microsoft.Win32.SafeHandles.SafeBCryptHashHandle hHash, ref byte pbOutput, int cbOutput, int dwFlags)
static CRYPT_OID_INFO FindOidInfo(CryptOidInfoKeyType keyType, string key, OidGroup group, bool fallBackToAllGroups)
@ CRYPT_OID_INFO_NAME_KEY
@ CRYPT_OID_INFO_CNG_SIGN_KEY
@ CRYPT_OID_INFO_SIGN_KEY
@ CRYPT_OID_INFO_CNG_ALGID_KEY
@ CRYPT_OID_INFO_ALGID_KEY
static IntPtr CryptFindOIDInfo(CryptOidInfoKeyType dwKeyType, ref int pvKey, OidGroup group)
static IntPtr CryptFindOIDInfo(CryptOidInfoKeyType dwKeyType, IntPtr pvKey, OidGroup group)
static bool OidGroupWillNotUseActiveDirectory(OidGroup group)
static CRYPT_OID_INFO FindAlgIdOidInfo(BCrypt.ECC_CURVE_ALG_ID_ENUM algId)
static unsafe string GetMessage(int errorCode, IntPtr moduleHandle)
static void SetLastError(int errorCode)
static string GetMessage(int errorCode)
static unsafe int FormatMessage(int dwFlags, IntPtr lpSource, uint dwMessageId, int dwLanguageId, void *lpBuffer, int nSize, IntPtr arguments)
static string GetAndTrimString(Span< char > buffer)
static unsafe ErrorCode NCryptDecrypt(SafeNCryptKeyHandle hKey, ReadOnlySpan< byte > pbInput, int cbInput, void *pPaddingInfo, Span< byte > pbOutput, int cbOutput, out int pcbResult, AsymmetricPaddingMode dwFlags)
static ErrorCode NCryptExportKey(SafeNCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, IntPtr pParameterList, [Out] byte[] pbOutput, int cbOutput, out int pcbResult, int dwFlags)
static ErrorCode NCryptExportKey(SafeNCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, ref NCryptBufferDesc pParameterList, ref byte pbOutput, int cbOutput, out int pcbResult, int dwFlags)
static unsafe ErrorCode NCryptGetIntProperty(SafeNCryptHandle hObject, string pszProperty, ref int result)
static byte[] DeriveKeyMaterialHmac(SafeNCryptSecretHandle secretAgreement, string hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend, SecretAgreementFlags flags)
static unsafe ErrorCode NCryptSignHash(SafeNCryptKeyHandle hKey, void *pPaddingInfo, ref byte pbHashValue, int cbHashValue, ref byte pbSignature, int cbSignature, out int pcbResult, AsymmetricPaddingMode dwFlags)
static unsafe byte[] DeriveKeyMaterial(SafeNCryptSecretHandle secretAgreement, string kdf, string hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend, SecretAgreementFlags flags)
static unsafe byte[] DeriveKeyMaterialTls(SafeNCryptSecretHandle secretAgreement, byte[] label, byte[] seed, SecretAgreementFlags flags)
static unsafe ErrorCode NCryptSetProperty(SafeNCryptHandle hObject, string pszProperty, [In] void *pbInput, int cbInput, CngPropertyOptions dwFlags)
static unsafe ErrorCode NCryptEncrypt(SafeNCryptKeyHandle hKey, ref byte pbInput, int cbInput, void *pPaddingInfo, ref byte pbOutput, int cbOutput, out int pcbResult, AsymmetricPaddingMode dwFlags)
static ErrorCode NCryptImportKey(SafeNCryptProviderHandle hProvider, IntPtr hImportKey, string pszBlobType, IntPtr pParameterList, out SafeNCryptKeyHandle phKey, ref byte pbData, int cbData, int dwFlags)
static unsafe ErrorCode NCryptGetProperty(SafeNCryptHandle hObject, string pszProperty, [Out] void *pbOutput, int cbOutput, out int pcbResult, CngPropertyOptions dwFlags)
static ErrorCode NCryptSecretAgreement(SafeNCryptKeyHandle hPrivKey, SafeNCryptKeyHandle hPubKey, out SafeNCryptSecretHandle phSecret, int dwFlags)
static ErrorCode NCryptOpenStorageProvider(out SafeNCryptProviderHandle phProvider, string pszProviderName, int dwFlags)
static byte[] DeriveKeyMaterialHash(SafeNCryptSecretHandle secretAgreement, string hashAlgorithm, byte[] secretPrepend, byte[] secretAppend, SecretAgreementFlags flags)
static ErrorCode NCryptCreatePersistedKey(SafeNCryptProviderHandle hProvider, out SafeNCryptKeyHandle phKey, string pszAlgId, string pszKeyName, int dwLegacyKeySpec, CngKeyCreationOptions dwFlags)
static unsafe ErrorCode NCryptDecrypt(SafeNCryptKeyHandle hKey, ref byte pbInput, int cbInput, void *pPaddingInfo, ref byte pbOutput, int cbOutput, out int pcbResult, AsymmetricPaddingMode dwFlags)
static unsafe ErrorCode NCryptEncrypt(SafeNCryptKeyHandle hKey, ReadOnlySpan< byte > pbInput, int cbInput, void *pPaddingInfo, Span< byte > pbOutput, int cbOutput, out int pcbResult, AsymmetricPaddingMode dwFlags)
static SafeNCryptSecretHandle DeriveSecretAgreement(SafeNCryptKeyHandle privateKey, SafeNCryptKeyHandle otherPartyPublicKey)
static ErrorCode NCryptDeleteKey(SafeNCryptKeyHandle hKey, int dwFlags)
static ErrorCode NCryptOpenKey(SafeNCryptProviderHandle hProvider, out SafeNCryptKeyHandle phKey, string pszKeyName, int dwLegacyKeySpec, CngKeyOpenOptions dwFlags)
static ErrorCode NCryptImportKey(SafeNCryptProviderHandle hProvider, IntPtr hImportKey, string pszBlobType, ref NCryptBufferDesc pParameterList, out SafeNCryptKeyHandle phKey, ref byte pbData, int cbData, int dwFlags)
static ErrorCode NCryptExportKey(SafeNCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, IntPtr pParameterList, ref byte pbOutput, int cbOutput, out int pcbResult, int dwFlags)
static unsafe ErrorCode NCryptVerifySignature(SafeNCryptKeyHandle hKey, void *pPaddingInfo, ref byte pbHashValue, int cbHashValue, ref byte pbSignature, int cbSignature, AsymmetricPaddingMode dwFlags)
static ErrorCode NCryptFinalizeKey(SafeNCryptKeyHandle hKey, int dwFlags)
static unsafe ErrorCode NCryptVerifySignature(SafeNCryptKeyHandle hKey, void *pPaddingInfo, ReadOnlySpan< byte > pbHashValue, int cbHashValue, ReadOnlySpan< byte > pbSignature, int cbSignature, AsymmetricPaddingMode dwFlags)
static ErrorCode NCryptFreeObject(IntPtr hObject)
static unsafe ErrorCode NCryptSignHash(SafeNCryptKeyHandle hKey, void *pPaddingInfo, ReadOnlySpan< byte > pbHashValue, int cbHashValue, Span< byte > pbSignature, int cbSignature, out int pcbResult, AsymmetricPaddingMode dwFlags)
static unsafe byte[] DeriveKeyMaterial(SafeNCryptSecretHandle secretAgreement, string kdf, ReadOnlySpan< NCryptBuffer > parameters, SecretAgreementFlags flags)
static ErrorCode NCryptDeriveKey(SafeNCryptSecretHandle hSharedSecret, string pwszKDF, [In] ref NCryptBufferDesc pParameterList, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pbDerivedKey, int cbDerivedKey, out int pcbResult, SecretAgreementFlags dwFlags)
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
static byte Min(byte val1, byte val2)
static unsafe IntPtr StringToCoTaskMemUni(string? s)
static void FreeHGlobal(IntPtr hglobal)
static void FreeCoTaskMem(IntPtr ptr)
static unsafe? string PtrToStringUni(IntPtr ptr)
static int GetLastWin32Error()
static ? object PtrToStructure(IntPtr ptr, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors|DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type structureType)
static unsafe IntPtr StringToCoTaskMemAnsi(string? s)
unsafe fixed byte Count[4]
DSAFIPSVERSION_ENUM standardVersion
HASHALGORITHM_ENUM hashAlgorithm
unsafe fixed byte Count[4]
unsafe fixed byte Seed[20]
ECC_CURVE_TYPE_ENUM CurveType
ECC_CURVE_ALG_ID_ENUM CurveGenerationAlgId
unsafe Entry(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, Microsoft.Win32.SafeHandles.SafeBCryptAlgorithmHandle handle)
SafeBCryptAlgorithmHandle Handle
CngBufferDescriptors BufferType
CngUIProtectionLevels dwFlags
unsafe fixed byte rgbSalt[8]
CRYPT_PKCS12_PBE_PARAMS Params
static readonly IntPtr Zero
Span< T > Slice(int start)