Can't drive any matched public keys in "mbedtls_ecdh_context" from certificate and private key file using mbedtls

37 Views Asked by At

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. I like to put the correct public key into mbedtls_ecdh_context structures using mbedtls api functions. 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.

0

There are 0 best solutions below