I'm implementing a security exchange between a C# app and an embedded device programmed in C. System.Security.Cryptography doesn't have documentation on what any of its crypto algorithms do "under the hood". I need to know this in order to implement the same thing in C, for which I have much more basic libraries. Specifically, I'm wondering what ECDiffieHellman.DeriveKeyFromHash(HashAlgorithmName.SHA256) does.
I've tried following the API down, but it ends in a call to unmanaged NCryptDeriveKey in ncrypt.h.
The method does not appear to simply perform a SHA256 hash of the shared secret. I have done this on the C side, and I get a different value. I know that the Public Key received on the C# side is valid because otherwise, a previous method throws an exception. I'm guessing that data is appended or prepended, as prescribed by some NIST document, but is this the case? Or is there something else I'm missing?
EDIT: Turns out I was doing something wrong on the C side. The extra confirmation of the C# behavior helped narrow down the search.
ECDiffieHellmanCng ecdh = new ECDiffieHellmanCng(myEccKeys);
//This would throw an exception if PeerRawPublicKey was invalid.
var PeerPublicKey = ECDiffieHellmanCngPublicKey.FromByteArray(PeerRawPublicKey.ToArray(), CngKeyBlobFormat.EccPublicBlob);
//How is keyMaterial generated?
byte[] keyMaterial = ecdh.DeriveKeyFromHash(PeerPublicKey, HashAlgorithmName.SHA256, null, null);
It just computes Hash(prepend || Z || append)
, where Z is the X coordinate of the shared secret.
For each of prepend and append, null values are treated as empty.