using System; using System.Runtime.InteropServices; namespace SHARP { public static class BCrypt { [DllImport("bcrypt.dll")] public static extern uint BCryptOpenAlgorithmProvider(out IntPtr phAlgorithm, [MarshalAs(UnmanagedType.LPWStr)] string pszAlgId, [MarshalAs(UnmanagedType.LPWStr)] string pszImplementation, uint dwFlags); [DllImport("bcrypt.dll")] public static extern uint BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, uint flags); [DllImport("bcrypt.dll")] public static extern uint BCryptGetProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbOutput, int cbOutput, ref int pcbResult, uint flags); [DllImport("bcrypt.dll", EntryPoint = "BCryptSetProperty")] internal static extern uint BCryptSetAlgorithmProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbInput, int cbInput, int dwFlags); [DllImport("bcrypt.dll")] public static extern uint BCryptImportKey(IntPtr hAlgorithm, IntPtr hImportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, out IntPtr phKey, IntPtr pbKeyObject, int cbKeyObject, byte[] pbInput, int cbInput, uint dwFlags); [DllImport("bcrypt.dll")] public static extern uint BCryptDestroyKey(IntPtr hKey); [DllImport("bcrypt.dll")] public static extern uint BCryptEncrypt(IntPtr hKey, byte[] pbInput, int cbInput, ref BCrypt.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO pPaddingInfo, byte[] pbIV, int cbIV, byte[] pbOutput, int cbOutput, ref int pcbResult, uint dwFlags); [DllImport("bcrypt.dll")] internal static extern uint BCryptDecrypt(IntPtr hKey, byte[] pbInput, int cbInput, ref BCrypt.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO pPaddingInfo, byte[] pbIV, int cbIV, byte[] pbOutput, int cbOutput, ref int pcbResult, int dwFlags); // Note: this type is marked as 'beforefieldinit'. static BCrypt() { } public const uint ERROR_SUCCESS = 0U; public const uint BCRYPT_PAD_PSS = 8U; public const uint BCRYPT_PAD_OAEP = 4U; public static readonly byte[] BCRYPT_KEY_DATA_BLOB_MAGIC = BitConverter.GetBytes(1296188491); public static readonly string BCRYPT_OBJECT_LENGTH = "ObjectLength"; public static readonly string BCRYPT_CHAIN_MODE_GCM = "ChainingModeGCM"; public static readonly string BCRYPT_AUTH_TAG_LENGTH = "AuthTagLength"; public static readonly string BCRYPT_CHAINING_MODE = "ChainingMode"; public static readonly string BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"; public static readonly string BCRYPT_AES_ALGORITHM = "AES"; public static readonly string MS_PRIMITIVE_PROVIDER = "Microsoft Primitive Provider"; public static readonly int BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG = 1; public static readonly int BCRYPT_INIT_AUTH_MODE_INFO_VERSION = 1; public static readonly uint STATUS_AUTH_TAG_MISMATCH = 3221266434U; public struct BCRYPT_PSS_PADDING_INFO { public BCRYPT_PSS_PADDING_INFO(string pszAlgId, int cbSalt) { this.pszAlgId = pszAlgId; this.cbSalt = cbSalt; } [MarshalAs(UnmanagedType.LPWStr)] public string pszAlgId; public int cbSalt; } public struct BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO : IDisposable { public BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(byte[] iv, byte[] aad, byte[] tag) { this = default(BCrypt.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO); this.dwInfoVersion = BCrypt.BCRYPT_INIT_AUTH_MODE_INFO_VERSION; this.cbSize = Marshal.SizeOf(typeof(BCrypt.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO)); if (iv != null) { this.cbNonce = iv.Length; this.pbNonce = Marshal.AllocHGlobal(this.cbNonce); Marshal.Copy(iv, 0, this.pbNonce, this.cbNonce); } if (aad != null) { this.cbAuthData = aad.Length; this.pbAuthData = Marshal.AllocHGlobal(this.cbAuthData); Marshal.Copy(aad, 0, this.pbAuthData, this.cbAuthData); } if (tag != null) { this.cbTag = tag.Length; this.pbTag = Marshal.AllocHGlobal(this.cbTag); Marshal.Copy(tag, 0, this.pbTag, this.cbTag); this.cbMacContext = tag.Length; this.pbMacContext = Marshal.AllocHGlobal(this.cbMacContext); } } public void Dispose() { if (this.pbNonce != IntPtr.Zero) { Marshal.FreeHGlobal(this.pbNonce); } if (this.pbTag != IntPtr.Zero) { Marshal.FreeHGlobal(this.pbTag); } if (this.pbAuthData != IntPtr.Zero) { Marshal.FreeHGlobal(this.pbAuthData); } if (this.pbMacContext != IntPtr.Zero) { Marshal.FreeHGlobal(this.pbMacContext); } } public int cbSize; public int dwInfoVersion; public IntPtr pbNonce; public int cbNonce; public IntPtr pbAuthData; public int cbAuthData; public IntPtr pbTag; public int cbTag; public IntPtr pbMacContext; public int cbMacContext; public int cbAAD; public long cbData; public int dwFlags; } public struct BCRYPT_KEY_LENGTHS_STRUCT { public int dwMinLength; public int dwMaxLength; public int dwIncrement; } public struct BCRYPT_OAEP_PADDING_INFO { public BCRYPT_OAEP_PADDING_INFO(string alg) { this.pszAlgId = alg; this.pbLabel = IntPtr.Zero; this.cbLabel = 0; } [MarshalAs(UnmanagedType.LPWStr)] public string pszAlgId; public IntPtr pbLabel; public int cbLabel; } } }