In TLS 1.3, one half of an ECDH exchange is defined as a "key entry", coded as:
struct { NamedGroup group; opaque key_exchange<1..2^16-1>; } KeyShareEntry;
The opaque data is typically encoded as a one byte format (e.g., 0x04, no compression), and then the encoding of either one or two points: 32 bytes for one point with CURVE25519, 64 bytes for two points with SECP256R1.
The encoding for the "public key" output of mbedtls_ecdh_make_params is different: 1 byte of length, followed by 2 bytes of curve ID, followed by the raw encoding of the point or points. The related encoding of the server public key output of mbedtls_ecdh_make_public is also different: 1 byte of length, followed by 2 bytes of curve ID, followed by the raw encoding of the point or points.
To make that work, I need some reformatting: strip out 3 bytes for the client public key, write a single 0x04 byte instead; strip out one byte from the key-exchange data received at the server and write 3 bytes of length and curve ID instead. Also, make sure to reset the strings to the unmodified value before calling mbedtls_ecdh_calc_secret, which probably means maintaining two copies, thus twice the memory.
This is a bit messy, and probably unnecessary. The extra parameters "length" is already passed through the API (the &olen argument) and the "group_id" could easily be passed as well.
Or maybe I am looking at the wrong API...
-- Christian Huitema