public unsafe void DeriveSecret(IHashProvider hashProvider, HashType hashType, void *salt, int saltSize, void *output, int outputSize) { SafeBCryptSecretHandle returnPtr; ExceptionHelper.CheckReturnCode(BCryptSecretAgreement(_key, _peerKey, out returnPtr, 0)); var buffDescription = new BCryptBufferDesc(); var bufferArray = stackalloc BCryptBuffer[2]; var algId = System.Text.Encoding.Unicode.GetBytes(hashType.ToString().ToUpper() + "\0"); buffDescription.pBuffers = (IntPtr)bufferArray; buffDescription.cBuffers = 2; fixed(byte *algPtr = algId) { bufferArray[0] = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.KDF_HASH_ALGORITHM, cbBuffer = algId.Length, pvBuffer = algPtr }; bufferArray[1] = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.KDF_HMAC_KEY, cbBuffer = saltSize, pvBuffer = salt }; int sizeOfResult; ExceptionHelper.CheckReturnCode(BCryptDeriveKey(returnPtr, BCRYPT_KDF_HMAC, &buffDescription, (IntPtr)output, outputSize, out sizeOfResult, 0)); returnPtr.Dispose(); Dispose(); } }
public unsafe void DeriveMasterSecretTls12(IHashProvider hashProvider, HashType hashType, void *seed, int seedLength, void *output, int outputLength) { uint version = 0x0303; var buffDescription = new BCryptBufferDesc(); var bufferArray = stackalloc BCryptBuffer[4]; var algId = Encoding.Unicode.GetBytes(hashType.ToString() + "\0"); fixed(void *algPtr = algId) { bufferArray[0] = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.KDF_HASH_ALGORITHM, cbBuffer = algId.Length, pvBuffer = algPtr }; bufferArray[1] = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.KDF_TLS_PRF_LABEL, cbBuffer = Tls13.Internal.Tls1_2Consts.MasterSecretLabelSize, pvBuffer = (void *)Tls13.Internal.Tls1_2Consts.MasterSecretLabelPointer }; bufferArray[2] = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.KDF_TLS_PRF_SEED, cbBuffer = seedLength, pvBuffer = seed }; bufferArray[3] = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.KDF_TLS_PRF_PROTOCOL, cbBuffer = 4, pvBuffer = &version }; buffDescription.cBuffers = 4; buffDescription.pBuffers = (IntPtr)bufferArray; int sizeOfResult; SafeBCryptSecretHandle secretPointer; ExceptionHelper.CheckReturnCode(BCryptSecretAgreement(_key, _peerKey, out secretPointer, 0)); ExceptionHelper.CheckReturnCode( BCryptDeriveKey(secretPointer, BCRYPT_KDF_TLS_PRF, &buffDescription, (IntPtr)output, outputLength, out sizeOfResult, 0)); secretPointer.Dispose(); Dispose(); } }
public unsafe static void Main(string[] args) { var thumb = "48026c976caaf7f3a72d38c17d16ce69d04a6053".ToUpper(); var cert = LoadCertificateFromStore(thumb, false, StoreLocation.CurrentUser, StoreName.My); var privKey = cert.GetECDsaPrivateKey(); var curve = privKey.ExportParameters(true); List <byte> currentSection = null; var lines = ecdsaKeyPEM.Split('\n'); for (int i = 0; i < lines.Length; i++) { if (lines[i].StartsWith("-----BEGIN")) { //Starting a block string blockName = lines[i].Substring("-----BEGIN ".Length, lines[i].LastIndexOf("-----") - "-----BEGIN ".Length); currentSection = new List <byte>(); _sections.Add(blockName, currentSection); continue; } else if (lines[i].StartsWith("-----END")) { //ending block currentSection = null; } currentSection?.AddRange(Convert.FromBase64String(lines[i].Trim())); } IntPtr prov, key; var res = NCryptOpenStorageProvider(out prov, "Microsoft Software Key Storage Provider", 0); //ECDSA_P521 var size = sizeof(BCRYPT_ECCKEY_BLOB); var blobHeader = new BCRYPT_ECCKEY_BLOB() { Magic = KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC, cbKey = _sections["EC PRIVATE KEY"].Count }; var desc = new BCryptBufferDesc() { cBuffers = 1 }; var buff = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME, cbBuffer = "ECDSA_P521\0".Length * 2, pvBuffer = Marshal.StringToHGlobalUni("ECDSA_P521\0") }; var buffPtr = Marshal.AllocHGlobal(sizeof(BCryptBuffer)); Marshal.StructureToPtr(buff, buffPtr, true); desc.pBuffers = buffPtr; var descPtr = Marshal.AllocHGlobal(sizeof(BCryptBufferDesc)); Marshal.StructureToPtr(desc, descPtr, true); var bytes = new byte[size + blobHeader.cbKey]; _sections["EC PRIVATE KEY"].ToArray().CopyTo(bytes, size); fixed(void *blobPtr = bytes) { Unsafe.Copy(blobPtr, ref blobHeader); res = NCryptImportKey(prov, IntPtr.Zero, "ECCPRIVATEBLOB", descPtr, out key, (IntPtr)blobPtr, (uint)bytes.Length, 0); } }