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 <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2023-06-22 22:32:05 +02:00
parent 62e33bcc64
commit 52cc2a6368
4 changed files with 228 additions and 46 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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
{

View File

@ -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");