My target is to establish a shared secret key between the PC application (master) and (various, different, but always limited to 1 at a time) peripheral devices.
Each device has:
- Device specific ECC 256-bit private key, in PEM format, well parsed with
mbedtls_pk_parse_key
function when required. - Device specific certificate that belongs to the private key. Certificate is signed by the TrustCA. Parsing works well with
mbedtls_x509_crt_parse
- TrustCA’s certificate, used to validate the master device during communication, also used to check firmware signature in a secure boot part of the application
PC application has:
- Master application certificate, signed by TrustCA
- Private key of the PC application that belongs to master application certificate, in PEM format
- TrustCA’s certificate, used to validate device certificate during communication
Aim is to establish AES shared secret, by doing:
- Master sends authentication requests, random challenge, device performs hash + signs with private key. Returns certificate + signature of the challenge.
- Master uses TrustCA's certificate to check device's certificate and then checks the signature of the hash(challenge)
- Master sends its certificate to the slave, now both hold X509 certificates. At this point, device could also request authentication of the PC application
- A computation with its respective private key is needed on both sides, and we have common secret.
What is the correct way in mbedTLS, to get a public key from X509, that can be used in the ECDH module?
The way the ECDH module inside mbedTLS seems to be designed, there is no straight-forward way to export X5090’s public key, get its parameters and use them in ECDH module.
Instead, ECDH expects that random keypair will be generated every-time we want key exchange. Doing this, we risk man in the middle attack, since the other party doesn’t know where the key is actually coming from.
For the moment, the solution I see (which is not THAT elegant, or is it?), and to avoid man in the middle attack::
- Devices still exchange certificates, but only for authentication reason + certificate verification
- Every message that is sent between devices (for instance public keys exchange), must also be hashed & signed, so that another party can be sure message is coming from the device which shared the certificate just before (and certificate is signed by TrustCA)
- We need one exchange more to get shared secret.
Is this the proposed solution in this case? Is there a more elegant solution with the mbedTLS library for this problem?
Thanks