From 52cc2a6368872eb2116bc3ed1066e884920e91fa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 22 Jun 2023 22:32:05 +0200 Subject: [PATCH] Use new mbedtls_ecp_keypair functions in sample programs This eliminates the use of MBEDTLS_PRIVATE in sample programs to access fields of an mbedtls_ecp_keypair structure. When displaying elliptic curve points, the program now display the coordinates in the standard form instead of the internal representation. The auxiliary function show_ecp_key is present in three programs. It's more complex than the previous code which was also triplicated. There's no good place for such auxiliary functions that don't belong in the library and are used in multiple sample programs. Signed-off-by: Gilles Peskine --- programs/pkey/ecdsa.c | 23 +++++---- programs/pkey/gen_key.c | 75 ++++++++++++++++++++++++--- programs/pkey/key_app.c | 94 ++++++++++++++++++++++++++-------- programs/pkey/key_app_writer.c | 82 +++++++++++++++++++++++++---- 4 files changed, 228 insertions(+), 46 deletions(-) diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c index afd6fb31a4..5664b8c4e5 100644 --- a/programs/pkey/ecdsa.c +++ b/programs/pkey/ecdsa.c @@ -60,8 +60,8 @@ static void dump_pubkey(const char *title, mbedtls_ecdsa_context *key) unsigned char buf[300]; size_t len; - if (mbedtls_ecp_point_write_binary(&key->MBEDTLS_PRIVATE(grp), &key->MBEDTLS_PRIVATE(Q), - MBEDTLS_ECP_PF_UNCOMPRESSED, &len, buf, sizeof(buf)) != 0) { + if (mbedtls_ecp_write_public_key(key, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, buf, sizeof(buf)) != 0) { mbedtls_printf("internal error\n"); return; } @@ -79,6 +79,8 @@ int main(int argc, char *argv[]) int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; mbedtls_ecdsa_context ctx_sign, ctx_verify; + mbedtls_ecp_point Q; + mbedtls_ecp_point_init(&Q); mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char message[100]; @@ -128,7 +130,10 @@ int main(int argc, char *argv[]) goto exit; } - mbedtls_printf(" ok (key size: %d bits)\n", (int) ctx_sign.MBEDTLS_PRIVATE(grp).pbits); + mbedtls_ecp_group_id grp_id = mbedtls_ecp_keypair_get_group_id(&ctx_sign); + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id(grp_id); + mbedtls_printf(" ok (key size: %d bits)\n", (int) curve_info->bit_size); dump_pubkey(" + Public key: ", &ctx_sign); @@ -174,16 +179,13 @@ int main(int argc, char *argv[]) mbedtls_printf(" . Preparing verification context..."); fflush(stdout); - if ((ret = - mbedtls_ecp_group_copy(&ctx_verify.MBEDTLS_PRIVATE(grp), - &ctx_sign.MBEDTLS_PRIVATE(grp))) != 0) { - mbedtls_printf(" failed\n ! mbedtls_ecp_group_copy returned %d\n", ret); + if ((ret = mbedtls_ecp_export(&ctx_sign, NULL, NULL, &Q)) != 0) { + mbedtls_printf(" failed\n ! mbedtls_ecp_export returned %d\n", ret); goto exit; } - if ((ret = - mbedtls_ecp_copy(&ctx_verify.MBEDTLS_PRIVATE(Q), &ctx_sign.MBEDTLS_PRIVATE(Q))) != 0) { - mbedtls_printf(" failed\n ! mbedtls_ecp_copy returned %d\n", ret); + if ((ret = mbedtls_ecp_set_public_key(grp_id, &ctx_verify, &Q)) != 0) { + mbedtls_printf(" failed\n ! mbedtls_ecp_set_public_key returned %d\n", ret); goto exit; } @@ -208,6 +210,7 @@ exit: mbedtls_ecdsa_free(&ctx_verify); mbedtls_ecdsa_free(&ctx_sign); + mbedtls_ecp_point_free(&Q); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index f6bb237877..cbdf5b7602 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -160,6 +160,71 @@ static int write_private_key(mbedtls_pk_context *key, const char *output_file) return 0; } +#if defined(MBEDTLS_ECP_C) +static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private) +{ + int ret = 0; + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( + mbedtls_ecp_keypair_get_group_id(ecp)); + mbedtls_printf("curve: %s\n", curve_info->name); + + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_mpi D; + mbedtls_mpi_init(&D); + mbedtls_ecp_point pt; + mbedtls_ecp_point_init(&pt); + mbedtls_mpi X, Y; + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); + + MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp, + (has_private ? &D : NULL), + &pt)); + + unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN]; + size_t len = 0; + MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary( + &grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, point_bin, sizeof(point_bin))); + switch (mbedtls_ecp_get_type(&grp)) { + case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS: + if ((len & 1) == 0 || point_bin[0] != 0x04) { + /* Point in an unxepected format. This shouldn't happen. */ + ret = -1; + goto cleanup; + } + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2)); + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL); + break; + case MBEDTLS_ECP_TYPE_MONTGOMERY: + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + break; + default: + mbedtls_printf( + "This program does not yet support listing coordinates for this curve type.\n"); + break; + } + + if (has_private) { + mbedtls_mpi_write_file("D: ", &D, 16, NULL); + } + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_mpi_free(&D); + mbedtls_ecp_point_free(&pt); + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); + return ret; +} +#endif + int main(int argc, char *argv[]) { int ret = 1; @@ -365,12 +430,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key); - mbedtls_printf("curve: %s\n", - mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); - mbedtls_mpi_write_file("X_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL); - mbedtls_mpi_write_file("Y_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL); - mbedtls_mpi_write_file("D: ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL); + if (show_ecp_key(mbedtls_pk_ec(key), 1) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto exit; + } } else #endif mbedtls_printf(" ! key type not supported\n"); diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c index 194c4102dd..e3a6966050 100644 --- a/programs/pkey/key_app.c +++ b/programs/pkey/key_app.c @@ -53,6 +53,71 @@ int main(void) #else +#if defined(MBEDTLS_ECP_C) +static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private) +{ + int ret = 0; + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( + mbedtls_ecp_keypair_get_group_id(ecp)); + mbedtls_printf("curve: %s\n", curve_info->name); + + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_mpi D; + mbedtls_mpi_init(&D); + mbedtls_ecp_point pt; + mbedtls_ecp_point_init(&pt); + mbedtls_mpi X, Y; + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); + + MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp, + (has_private ? &D : NULL), + &pt)); + + unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN]; + size_t len = 0; + MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary( + &grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, point_bin, sizeof(point_bin))); + switch (mbedtls_ecp_get_type(&grp)) { + case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS: + if ((len & 1) == 0 || point_bin[0] != 0x04) { + /* Point in an unxepected format. This shouldn't happen. */ + ret = -1; + goto cleanup; + } + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2)); + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL); + break; + case MBEDTLS_ECP_TYPE_MONTGOMERY: + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + break; + default: + mbedtls_printf( + "This program does not yet support listing coordinates for this curve type.\n"); + break; + } + + if (has_private) { + mbedtls_mpi_write_file("D: ", &D, 16, NULL); + } + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_mpi_free(&D); + mbedtls_ecp_point_free(&pt); + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); + return ret; +} +#endif + /* * global options */ @@ -219,17 +284,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("D : ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL)); + if (show_ecp_key(mbedtls_pk_ec(pk), 1) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto cleanup; + } } else #endif { @@ -269,16 +327,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, - NULL)); + if (show_ecp_key(mbedtls_pk_ec(pk), 0) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto cleanup; + } } else #endif { diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c index c07c56464e..cc4c4dc727 100644 --- a/programs/pkey/key_app_writer.c +++ b/programs/pkey/key_app_writer.c @@ -176,6 +176,71 @@ static int write_private_key(mbedtls_pk_context *key, const char *output_file) return 0; } +#if defined(MBEDTLS_ECP_C) +static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private) +{ + int ret = 0; + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( + mbedtls_ecp_keypair_get_group_id(ecp)); + mbedtls_printf("curve: %s\n", curve_info->name); + + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_mpi D; + mbedtls_mpi_init(&D); + mbedtls_ecp_point pt; + mbedtls_ecp_point_init(&pt); + mbedtls_mpi X, Y; + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); + + MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp, + (has_private ? &D : NULL), + &pt)); + + unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN]; + size_t len = 0; + MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary( + &grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, point_bin, sizeof(point_bin))); + switch (mbedtls_ecp_get_type(&grp)) { + case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS: + if ((len & 1) == 0 || point_bin[0] != 0x04) { + /* Point in an unxepected format. This shouldn't happen. */ + ret = -1; + goto cleanup; + } + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2)); + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL); + break; + case MBEDTLS_ECP_TYPE_MONTGOMERY: + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + break; + default: + mbedtls_printf( + "This program does not yet support listing coordinates for this curve type.\n"); + break; + } + + if (has_private) { + mbedtls_mpi_write_file("D: ", &D, 16, NULL); + } + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_mpi_free(&D); + mbedtls_ecp_point_free(&pt); + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); + return ret; +} +#endif + int main(int argc, char *argv[]) { int ret = 1; @@ -338,11 +403,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key); - mbedtls_mpi_write_file("Q(X): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL); - mbedtls_mpi_write_file("Q(Y): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL); - mbedtls_mpi_write_file("Q(Z): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, NULL); - mbedtls_mpi_write_file("D : ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL); + if (show_ecp_key(mbedtls_pk_ec(key), 1) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto exit; + } } else #endif mbedtls_printf("key type not supported yet\n"); @@ -384,10 +448,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key); - mbedtls_mpi_write_file("Q(X): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL); - mbedtls_mpi_write_file("Q(Y): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL); - mbedtls_mpi_write_file("Q(Z): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, NULL); + if (show_ecp_key(mbedtls_pk_ec(key), 0) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto exit; + } } else #endif mbedtls_printf("key type not supported yet\n");