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>
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 194c410..e3a6966 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -53,6 +53,71 @@
 #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 @@
 #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 @@
 #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
         {