The following is the code to drive public keys from certificates and private key files, which are generated based on ECC curve MBEDTLS_ECP_DP_SECP521R1. It is implemented with mbedtls v.3.3.0.
Where are mistakes in the following code?
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "mbedtls/platform.h"#include "mbedtls/error.h"#include "mbedtls/ecdh.h"#include "mbedtls/entropy.h"#include "mbedtls/ctr_drbg.h"#include "mbedtls/pk.h"#include "mbedtls/x509_crt.h"static void hexdump(void const *bptr, size_t bytes){ unsigned char *origin = (unsigned char *)(bptr); unsigned block = 0x10; size_t offset = 0; size_t lower = block * (offset / block); size_t upper = block + lower; size_t index = 0; char buffer[ADDRSIZE + 72]; char *output; while (lower < bytes) { output = buffer + ADDRSIZE; for (index = lower; output-- > buffer; index >>= 4) { *output = DIGITS_HEX[index & 0x0F]; } output = buffer + ADDRSIZE; for (index = lower; index < upper; index++) { *output++ = ''; if (index < offset) { *output++ = ''; *output++ = ''; } else if (index < bytes) { *output++ = DIGITS_HEX[(origin[index] >> 4) & 0x0F]; *output++ = DIGITS_HEX[(origin[index] >> 0) & 0x0F]; } else { *output++ = ''; *output++ = ''; } } *output++ = ''; for (index = lower; index < upper; index++) { if (index < offset) { *output++ = ''; } else if (index < bytes) { unsigned c = origin[index]; *output++ = isprint(c) ? c : '.'; } else { *output++ = ''; } } *output++ = '\n'; *output++ = '\0'; printf("%s", buffer); // fputs (buffer, stdout); lower += block; upper += block; } if (bytes) { output = buffer; *output++ = '\n'; *output++ = '\0'; printf("%s", buffer); // fputs (buffer, stdout); } // fflush (stdout); return;}int main(int argc, char *argv[]){ mbedtls_ecdh_context ctx_bob, ctx_pub_bob; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_pk_context pk_bob; mbedtls_x509_crt crt_bob; int ret; mbedtls_ecdh_init(&ctx_bob); mbedtls_ecdh_init(&ctx_pub_bob); mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_pk_init(&pk_bob); mbedtls_x509_crt_init(&crt_bob); // Initialize RNG and entropy source if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%04X\n", -ret); goto cleanup; } if ((ret = mbedtls_pk_parse_keyfile(&pk_bob, KEY_FILE, NULL, mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { mbedtls_printf(" failed\n ! mbedtls_pk_parse_keyfile returned -0x%04X\n", -ret); goto cleanup; } mbedtls_ecp_keypair *bob_keypair = mbedtls_pk_ec(pk_bob); if ((ret = mbedtls_ecdh_get_params(&ctx_bob, bob_keypair, MBEDTLS_ECDH_OURS)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ecdh_get_params returned -0x%04X\n", -ret); goto cleanup; } if ((ret = mbedtls_ecdh_gen_public(&ctx_bob.grp, &ctx_bob.d, &ctx_bob.Q, mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ecdh_make_public returned -0x%04X\n", -ret); goto cleanup; } // Exchange public keys between SA and EVCC // In a real-world scenario, this would be done over a communication channel // Here we just simulate it by copying the public keys to each other's context // EVCC Public Key Context if ((ret = mbedtls_x509_crt_parse_file(&crt_bob, CRTIFICATE_FILE)) != 0) { mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%04X\n", -ret); goto cleanup; } mbedtls_ecp_keypair *bob_pub_keypair = mbedtls_pk_ec(crt_bob.pk); if ((ret = mbedtls_ecdh_get_params(&ctx_pub_bob, bob_pub_keypair, MBEDTLS_ECDH_OURS)) != 0) { mbedtls_printf("%d: failed\n ! mbedtls_ecdh_get_params returned -0x%04X\n", __LINE__, -ret); goto cleanup; } printf("%d: ctx_bob public key\n", __LINE__); printf("%d: d\n", __LINE__); hexdump(&ctx_bob.d, sizeof(mbedtls_mpi)); printf("%d: Q\n", __LINE__); hexdump(&ctx_bob.Q, sizeof(mbedtls_ecp_point)); printf("%d: grp\n", __LINE__); hexdump(&ctx_bob.grp, sizeof(mbedtls_ecp_group)); printf("%d: ctx_pub_bob public key\n", __LINE__); printf("%d: d\n", __LINE__); hexdump(&ctx_pub_bob.d, sizeof(mbedtls_mpi)); printf("%d: Q\n", __LINE__); hexdump(&ctx_pub_bob.Q, sizeof(mbedtls_ecp_point)); printf("%d: grp\n", __LINE__); hexdump(&ctx_pub_bob.grp, sizeof(mbedtls_ecp_group)); cleanup: mbedtls_ecdh_free(&ctx_bob); mbedtls_entropy_free(&entropy); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_pk_free(&pk_bob); mbedtls_x509_crt_free(&crt_bob); return 0;}
Two public keys ctx_bob.Q and ctx_pub_bob.Q printed out should be equal.