internal static byte[] DeriveKeyMaterialTls( SafeNCryptSecretHandle secretAgreement, byte[] label, byte[] seed, SecretAgreementFlags flags) { Span <NCryptBuffer> buffers = stackalloc NCryptBuffer[2]; unsafe { fixed(byte *pLabel = label, pSeed = seed) { NCryptBuffer labelBuffer = default; labelBuffer.cbBuffer = label.Length; labelBuffer.BufferType = BufferType.KdfTlsLabel; labelBuffer.pvBuffer = new IntPtr(pLabel); buffers[0] = labelBuffer; NCryptBuffer seedBuffer = default; seedBuffer.cbBuffer = seed.Length; seedBuffer.BufferType = BufferType.KdfTlsSeed; seedBuffer.pvBuffer = new IntPtr(pSeed); buffers[1] = seedBuffer; return(DeriveKeyMaterial( secretAgreement, BCryptNative.KeyDerivationFunction.Tls, buffers, flags)); } } }
private static extern ErrorCode NCryptDeriveKey( SafeNCryptSecretHandle hSharedSecret, string pwszKDF, [In] ref NCryptBufferDesc pParameterList, [Out, MarshalAs(UnmanagedType.LPArray)] byte[]?pbDerivedKey, int cbDerivedKey, [Out] out int pcbResult, SecretAgreementFlags dwFlags);
private static unsafe byte[] DeriveKeyMaterial( SafeNCryptSecretHandle secretAgreement, string kdf, ReadOnlySpan <NCryptBuffer> parameters, SecretAgreementFlags flags) { fixed(NCryptBuffer *pParameters = &MemoryMarshal.GetReference(parameters)) { NCryptBufferDesc parameterDesc = default; parameterDesc.ulVersion = 0; parameterDesc.cBuffers = parameters.Length; parameterDesc.pBuffers = new IntPtr(pParameters); // Figure out how big the key material is ErrorCode error = NCryptDeriveKey( secretAgreement, kdf, ref parameterDesc, null, 0, out int keySize, flags); if (error != ErrorCode.ERROR_SUCCESS && error != ErrorCode.NTE_BUFFER_TOO_SMALL) { throw error.ToCryptographicException(); } // Allocate memory for the key material and generate it byte[] keyMaterial = new byte[keySize]; error = NCryptDeriveKey( secretAgreement, kdf, ref parameterDesc, keyMaterial, keyMaterial.Length, out keySize, flags); if (error != ErrorCode.ERROR_SUCCESS) { throw error.ToCryptographicException(); } // Just in case it shrank the answer once it had a buffer. Array.Resize(ref keyMaterial, Math.Min(keySize, keyMaterial.Length)); return(keyMaterial); } }
internal static byte[] DeriveKeyMaterialHash( SafeNCryptSecretHandle secretAgreement, string hashAlgorithm, byte[]?secretPrepend, byte[]?secretAppend, SecretAgreementFlags flags) { return(DeriveKeyMaterial( secretAgreement, BCryptNative.KeyDerivationFunction.Hash, hashAlgorithm, null, secretPrepend, secretAppend, flags)); }
private static byte[] DeriveKeyMaterial( SafeNCryptSecretHandle secretAgreement, string kdf, string hashAlgorithm, byte[]?hmacKey, byte[]?secretPrepend, byte[]?secretAppend, SecretAgreementFlags flags) { // First marshal the hash algoritm IntPtr hashAlgorithmString = IntPtr.Zero; try { hashAlgorithmString = Marshal.StringToCoTaskMemUni(hashAlgorithm); Span <NCryptBuffer> parameters = stackalloc NCryptBuffer[4]; int parameterCount = 0; // We always need to marshal the hashing function NCryptBuffer hashAlgorithmBuffer = default; hashAlgorithmBuffer.cbBuffer = (hashAlgorithm.Length + 1) * sizeof(char); hashAlgorithmBuffer.BufferType = BufferType.KdfHashAlgorithm; hashAlgorithmBuffer.pvBuffer = hashAlgorithmString; parameters[parameterCount] = hashAlgorithmBuffer; parameterCount++; unsafe { fixed(byte *pHmacKey = hmacKey, pSecretPrepend = secretPrepend, pSecretAppend = secretAppend) { // // Now marshal the other parameters // if (pHmacKey != null) { NCryptBuffer hmacKeyBuffer = default; hmacKeyBuffer.cbBuffer = hmacKey !.Length; hmacKeyBuffer.BufferType = BufferType.KdfHmacKey; hmacKeyBuffer.pvBuffer = new IntPtr(pHmacKey); parameters[parameterCount] = hmacKeyBuffer; parameterCount++; } if (pSecretPrepend != null) { NCryptBuffer secretPrependBuffer = default; secretPrependBuffer.cbBuffer = secretPrepend !.Length; secretPrependBuffer.BufferType = BufferType.KdfSecretPrepend; secretPrependBuffer.pvBuffer = new IntPtr(pSecretPrepend); parameters[parameterCount] = secretPrependBuffer; parameterCount++; } if (pSecretAppend != null) { NCryptBuffer secretAppendBuffer = default; secretAppendBuffer.cbBuffer = secretAppend !.Length; secretAppendBuffer.BufferType = BufferType.KdfSecretAppend; secretAppendBuffer.pvBuffer = new IntPtr(pSecretAppend); parameters[parameterCount] = secretAppendBuffer; parameterCount++; } return(DeriveKeyMaterial( secretAgreement, kdf, parameters.Slice(0, parameterCount), flags)); } } } finally { if (hashAlgorithmString != IntPtr.Zero) { Marshal.FreeCoTaskMem(hashAlgorithmString); } } }
private static unsafe byte[] DeriveKeyMaterial(SafeNCryptSecretHandle secretAgreement, string kdf, string hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend, SecretAgreementFlags flags) { byte[] buffer5; List <NCryptBuffer> list = new List <NCryptBuffer>(); IntPtr zero = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { zero = Marshal.StringToCoTaskMemUni(hashAlgorithm); } NCryptBuffer item = new NCryptBuffer { cbBuffer = (hashAlgorithm.Length + 1) * 2, BufferType = BufferType.KdfHashAlgorithm, pvBuffer = zero }; list.Add(item); try { fixed(byte *numRef = hmacKey) { fixed(byte *numRef2 = secretPrepend) { fixed(byte *numRef3 = secretAppend) { if (numRef != IntPtr.Zero) { NCryptBuffer buffer2 = new NCryptBuffer { cbBuffer = hmacKey.Length, BufferType = BufferType.KdfHmacKey, pvBuffer = new IntPtr((void *)numRef) }; list.Add(buffer2); } if (numRef2 != IntPtr.Zero) { NCryptBuffer buffer3 = new NCryptBuffer { cbBuffer = secretPrepend.Length, BufferType = BufferType.KdfSecretPrepend, pvBuffer = new IntPtr((void *)numRef2) }; list.Add(buffer3); } if (numRef3 != IntPtr.Zero) { NCryptBuffer buffer4 = new NCryptBuffer { cbBuffer = secretAppend.Length, BufferType = BufferType.KdfSecretAppend, pvBuffer = new IntPtr((void *)numRef3) }; list.Add(buffer4); } return(DeriveKeyMaterial(secretAgreement, kdf, list.ToArray(), flags)); } } } } finally { numRef = null; numRef2 = null; numRef3 = null; } } finally { if (zero != IntPtr.Zero) { Marshal.FreeCoTaskMem(zero); } } return(buffer5); }
private static unsafe byte[] DeriveKeyMaterial(SafeNCryptSecretHandle secretAgreement, string kdf, NCryptBuffer[] parameters, SecretAgreementFlags flags) { fixed(NCryptBuffer *bufferRef = parameters) { NCryptBufferDesc pParameterList = new NCryptBufferDesc { ulVersion = 0, cBuffers = parameters.Length, pBuffers = new IntPtr((void *)bufferRef) }; int pcbResult = 0; ErrorCode code = UnsafeNativeMethods.NCryptDeriveKey(secretAgreement, kdf, ref pParameterList, null, 0, out pcbResult, flags); if ((code != ErrorCode.Success) && (code != ErrorCode.BufferTooSmall)) { throw new CryptographicException((int)code); } byte[] pbDerivedKey = new byte[pcbResult]; code = UnsafeNativeMethods.NCryptDeriveKey(secretAgreement, kdf, ref pParameterList, pbDerivedKey, pbDerivedKey.Length, out pcbResult, flags); if (code != ErrorCode.Success) { throw new CryptographicException((int)code); } return(pbDerivedKey); } }
internal static unsafe byte[] DeriveKeyMaterialTls(SafeNCryptSecretHandle secretAgreement, byte[] label, byte[] seed, SecretAgreementFlags flags) { NCryptBuffer[] parameters = new NCryptBuffer[2]; fixed(byte *numRef = label) { fixed(byte *numRef2 = seed) { NCryptBuffer buffer = new NCryptBuffer { cbBuffer = label.Length, BufferType = BufferType.KdfTlsLabel, pvBuffer = new IntPtr((void *)numRef) }; parameters[0] = buffer; NCryptBuffer buffer2 = new NCryptBuffer { cbBuffer = seed.Length, BufferType = BufferType.KdfTlsSeed, pvBuffer = new IntPtr((void *)numRef2) }; parameters[1] = buffer2; return(DeriveKeyMaterial(secretAgreement, "TLS_PRF", parameters, flags)); } } }
internal static byte[] DeriveKeyMaterialHmac(SafeNCryptSecretHandle secretAgreement, string hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend, SecretAgreementFlags flags) { return(DeriveKeyMaterial(secretAgreement, "HMAC", hashAlgorithm, hmacKey, secretPrepend, secretAppend, flags)); }
internal static byte[] DeriveKeyMaterialHash(SafeNCryptSecretHandle secretAgreement, string hashAlgorithm, byte[] secretPrepend, byte[] secretAppend, SecretAgreementFlags flags) { return(DeriveKeyMaterial(secretAgreement, "HASH", hashAlgorithm, null, secretPrepend, secretAppend, flags)); }