I need to use elliptic curve Diffie Hellman between a ARM cortex M3 and the PC. On the ARM, I use mbed TLS. On the PC side I want to us C# and the ECDiffieHellman(Cng) class.
I can do the ECDH on ARM vs ARM, but I do have trouble when I try to replace one side with the PC.
- Problem was the key exchange.
I found out, that the key is exported by mbed TLS as
<LEN><0x04><X><Y>
.
Thus, In C# I am importing the public key using
private static EC
DiffieHellmanPublicKey ToPublicKey(byte[] publicKey)
{
var keyLength = 32;
if (publicKey[0] != (2 + 2 * keyLength) - 1)
throw new ArgumentException("Invalid key length", nameof(publicKey));
if (publicKey[1] != 0x04)
throw new ArgumentException("Invalid key format", nameof(publicKey));
var parameters = new ECParameters()
{
Curve = ECCurve.NamedCurves.brainpoolP256r1,
Q = new ECPoint()
{
X = publicKey.Skip(2).Take(keyLength).ToArray(),
Y = publicKey.Skip(2 + keyLength).Take(keyLength).ToArray()
}
};
using (var tmp = ECDiffieHellman.Create(parameters))
{
return tmp.PublicKey;
}
}
- To generate the key I tried
var ecdh = new ECDiffieHellmanCng(ECCurve.NamedCurves.brainpoolP256r1);
ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Tls;
ecdh.Seed = new byte[32];
ecdh.Label = Encoding.ASCII.GetBytes("ECDiffieHellman");
new RNGCryptoServiceProvider().GetBytes(ecdh.Seed);
// ...
var sharedSecret = ecdh.DeriveKeyMaterial(peersPublicKey);
My problem is that the generated shared secret is of different length compared to the one generated by mbed TLS and does not match.
Did someone already solve this problem?
Thanks!
EDIT 1:
I forgot to mention, that I use bare ECDH on ARM. So I don't think there is any key derivation function executing. Is it sufficient to hash (SHA256) the result to match the C# side (when configuring SHA256 as KDF there)?