programs: add helper functions for supported EC curves

- get full list, or
- get TLS ID from name

Signed-off-by: Valerio Setti <valerio.setti@nordicsemi.no>
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index e283ef3..2cd17b6 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5560,60 +5560,53 @@
 }
 #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
 
-#if defined(MBEDTLS_DEBUG_C)
-#define EC_NAME(_name_)     _name_
-#else
-#define EC_NAME(_name_)     NULL
-#endif
-
 static const struct {
     uint16_t tls_id;
     mbedtls_ecp_group_id ecp_group_id;
     psa_ecc_family_t psa_family;
     uint16_t bits;
-    const char *name;
 } tls_id_match_table[] =
 {
 #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521)
-    { 25, MBEDTLS_ECP_DP_SECP521R1, PSA_ECC_FAMILY_SECP_R1, 521, EC_NAME("secp521r1") },
+    { 25, MBEDTLS_ECP_DP_SECP521R1, PSA_ECC_FAMILY_SECP_R1, 521 },
 #endif
 #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
-    { 28, MBEDTLS_ECP_DP_BP512R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 512, EC_NAME("brainpoolP512r1") },
+    { 28, MBEDTLS_ECP_DP_BP512R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 512 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_384)
-    { 24, MBEDTLS_ECP_DP_SECP384R1, PSA_ECC_FAMILY_SECP_R1, 384, EC_NAME("secp384r1") },
+    { 24, MBEDTLS_ECP_DP_SECP384R1, PSA_ECC_FAMILY_SECP_R1, 384 },
 #endif
 #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
-    { 27, MBEDTLS_ECP_DP_BP384R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 384, EC_NAME("brainpoolP384r1") },
+    { 27, MBEDTLS_ECP_DP_BP384R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 384 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_256)
-    { 23, MBEDTLS_ECP_DP_SECP256R1, PSA_ECC_FAMILY_SECP_R1, 256, EC_NAME("secp256r1") },
+    { 23, MBEDTLS_ECP_DP_SECP256R1, PSA_ECC_FAMILY_SECP_R1, 256 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_256)
-    { 22, MBEDTLS_ECP_DP_SECP256K1, PSA_ECC_FAMILY_SECP_K1, 256, EC_NAME("secp256k1") },
+    { 22, MBEDTLS_ECP_DP_SECP256K1, PSA_ECC_FAMILY_SECP_K1, 256 },
 #endif
 #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
-    { 26, MBEDTLS_ECP_DP_BP256R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 256, EC_NAME("brainpoolP256r1") },
+    { 26, MBEDTLS_ECP_DP_BP256R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 256 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_224)
-    { 21, MBEDTLS_ECP_DP_SECP224R1, PSA_ECC_FAMILY_SECP_R1, 224, EC_NAME("secp224r1") },
+    { 21, MBEDTLS_ECP_DP_SECP224R1, PSA_ECC_FAMILY_SECP_R1, 224 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_224)
-    { 20, MBEDTLS_ECP_DP_SECP224K1, PSA_ECC_FAMILY_SECP_K1, 224, EC_NAME("secp224k1") },
+    { 20, MBEDTLS_ECP_DP_SECP224K1, PSA_ECC_FAMILY_SECP_K1, 224 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_192)
-    { 19, MBEDTLS_ECP_DP_SECP192R1, PSA_ECC_FAMILY_SECP_R1, 192, EC_NAME("secp192r1") },
+    { 19, MBEDTLS_ECP_DP_SECP192R1, PSA_ECC_FAMILY_SECP_R1, 192 },
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_192)
-    { 18, MBEDTLS_ECP_DP_SECP192K1, PSA_ECC_FAMILY_SECP_K1, 192, EC_NAME("secp192k1") },
+    { 18, MBEDTLS_ECP_DP_SECP192K1, PSA_ECC_FAMILY_SECP_K1, 192 },
 #endif
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_255)
-    { 29, MBEDTLS_ECP_DP_CURVE25519, PSA_ECC_FAMILY_MONTGOMERY, 255, EC_NAME("x25519") },
+    { 29, MBEDTLS_ECP_DP_CURVE25519, PSA_ECC_FAMILY_MONTGOMERY, 255 },
 #endif
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_448)
-    { 30, MBEDTLS_ECP_DP_CURVE448, PSA_ECC_FAMILY_MONTGOMERY, 448, EC_NAME("x448") },
+    { 30, MBEDTLS_ECP_DP_CURVE448, PSA_ECC_FAMILY_MONTGOMERY, 448 },
 #endif
-    { 0, MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
+    { 0, MBEDTLS_ECP_DP_NONE, 0, 0 },
 };
 
 int mbedtls_ssl_get_psa_curve_info_from_tls_id(uint16_t tls_id,
@@ -5659,11 +5652,32 @@
 }
 
 #if defined(MBEDTLS_DEBUG_C)
+static const struct {
+    uint16_t tls_id;
+    const char *name;
+} tls_id_curve_name_table[] =
+{
+    { 25, "secp521r1" },
+    { 28, "brainpoolP512r1" },
+    { 24, "secp384r1" },
+    { 27, "brainpoolP384r1" },
+    { 23, "secp256r1" },
+    { 22, "secp256k1" },
+    { 26, "brainpoolP256r1" },
+    { 21, "secp224r1" },
+    { 20, "secp224k1" },
+    { 19, "secp192r1" },
+    { 18, "secp192k1" },
+    { 29, "x25519" },
+    { 30, "x448" },
+    { 0, NULL },
+};
+
 const char *mbedtls_ssl_get_curve_name_from_tls_id(uint16_t tls_id)
 {
-    for (int i = 0; tls_id_match_table[i].tls_id != 0; i++) {
-        if (tls_id_match_table[i].tls_id == tls_id) {
-            return tls_id_match_table[i].name;
+    for (int i = 0; tls_id_curve_name_table[i].tls_id != 0; i++) {
+        if (tls_id_curve_name_table[i].tls_id == tls_id) {
+            return tls_id_curve_name_table[i].name;
         }
     }
 
@@ -7344,7 +7358,7 @@
      * Secondary checks: always done, but change 'ret' only if it was 0
      */
 
-#if defined(MBEDTLS_ECP_LIGHT)
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     {
         const mbedtls_pk_context *pk = &chain->pk;
 
@@ -7371,7 +7385,7 @@
             }
         }
     }
-#endif /* MBEDTLS_ECP_LIGHT */
+#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
 
     if (mbedtls_ssl_check_cert_usage(chain,
                                      ciphersuite_info,
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index c7124cd..7c2c818 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -261,7 +261,7 @@
 #define USAGE_ALPN ""
 #endif /* MBEDTLS_SSL_ALPN */
 
-#if defined(MBEDTLS_ECP_LIGHT) || \
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) || \
     (defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
     defined(PSA_WANT_ALG_FFDH))
 #define USAGE_GROUPS \
@@ -1901,7 +1901,7 @@
     }
 #endif  /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
 
-#if defined(MBEDTLS_ECP_LIGHT) || \
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) || \
     (defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
     defined(PSA_WANT_ALG_FFDH))
     if (opt.groups != NULL &&
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 474f2d9..58c2f1e 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -446,7 +446,7 @@
 #define USAGE_EARLY_DATA ""
 #endif /* MBEDTLS_SSL_EARLY_DATA */
 
-#if defined(MBEDTLS_ECP_LIGHT) || \
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) || \
     (defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
     defined(PSA_WANT_ALG_FFDH))
 #define USAGE_GROUPS \
@@ -3095,7 +3095,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_ECP_LIGHT) || \
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) || \
     (defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
     defined(PSA_WANT_ALG_FFDH))
     if (opt.groups != NULL &&
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index 2ce4f1a..57bfdf8 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -30,6 +30,8 @@
 
 #if !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
 
+#define ARRAY_LENGTH(x)     (sizeof(x)/sizeof(x[0]))
+
 void my_debug(void *ctx, int level,
               const char *file, int line,
               const char *str)
@@ -508,7 +510,118 @@
 }
 #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED && PSA_WANT_ALG_FFDH */
 
-int parse_groups(const char *groups, uint16_t *group_list, size_t group_list_len)
+static const struct {
+    uint16_t tls_id;
+    const char *name;
+    uint8_t is_supported;
+} tls_id_curve_name_table[] =
+{
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521)
+    { 25, "secp521r1", 1 },
+#else
+    { 25, "secp521r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
+    { 28, "brainpoolP512r1", 1 },
+#else
+    { 28, "brainpoolP512r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_384)
+    { 24, "secp384r1", 1 },
+#else
+    { 24, "secp384r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
+    { 27, "brainpoolP384r1", 1 },
+#else
+    { 27, "brainpoolP384r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_256)
+    { 23, "secp256r1", 1 },
+#else
+    { 23, "secp256r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_256)
+    { 22, "secp256k1", 1 },
+#else
+    { 22, "secp256k1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
+    { 26, "brainpoolP256r1", 1 },
+#else
+    { 26, "brainpoolP256r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_224)
+    { 21, "secp224r1", 1 },
+#else
+    { 21, "secp224r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_224)
+    { 20, "secp224k1", 1 },
+#else
+    { 20, "secp224k1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_192)
+    { 19, "secp192r1", 1 },
+#else
+    { 19, "secp192r1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_192)
+    { 18, "secp192k1", 1 },
+#else
+    { 18, "secp192k1", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_255)
+    { 29, "x25519", 1 },
+#else
+    { 29, "x25519", 0 },
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_448)
+    { 30, "x448", 1 },
+#else
+    { 30, "x448", 0 },
+#endif
+    { 0, NULL, 0 },
+};
+
+static uint16_t mbedtls_ssl_get_curve_tls_id_from_name(const char *name)
+{
+    if (name == NULL) {
+        return 0;
+    }
+
+    for (int i = 0; tls_id_curve_name_table[i].tls_id != 0; i++) {
+        if (strcmp(tls_id_curve_name_table[i].name, name) == 0) {
+            return tls_id_curve_name_table[i].tls_id;
+        }
+    }
+
+    return 0;
+}
+
+static const char **mbedtls_ssl_get_supported_curves_list(void)
+{
+    const char **supported_list = NULL;
+    int i = 0, j = 0;
+
+    /* The allocated area might be bigger than strictly required (because not
+     * all the curves might be supported), but it is enough to contain all the
+     * pointers when all curves are enabled. */
+    supported_list = mbedtls_calloc(ARRAY_LENGTH(tls_id_curve_name_table),
+                                    sizeof(char *));
+    for (i = 0; tls_id_curve_name_table[i].tls_id != 0; i++) {
+        if (tls_id_curve_name_table[i].is_supported == 1) {
+            supported_list[j] = tls_id_curve_name_table[i].name;
+            j++;
+        }
+    }
+    // Keep NULL as last element as guard for end-of-array.
+    supported_list[j] = NULL;
+
+    return supported_list;
+}
+
+int parse_curves(const char *curves, uint16_t *group_list, size_t group_list_len)
 {
     char *p = (char *) groups;
     char *q = NULL;
@@ -524,9 +637,8 @@
             defined(PSA_WANT_ALG_FFDH)
             uint16_t ffdh_group = 0;
 #endif
-#if defined(MBEDTLS_ECP_LIGHT)
-            const mbedtls_ecp_curve_info *curve_cur = NULL;
-#endif
+            uint16_t curve_tls_id;
+
             /* Terminate the current string */
             while (*p != ',' && *p != '\0') {
                 p++;
@@ -535,11 +647,9 @@
                 *p++ = '\0';
             }
 
-#if defined(MBEDTLS_ECP_LIGHT)
-            if ((curve_cur = mbedtls_ecp_curve_info_from_name(q)) != NULL) {
-                group_list[i++] = curve_cur->tls_id;
+            if ((curve_tls_id = mbedtls_ssl_get_curve_tls_id_from_name(q)) != 0) {
+                group_list[i++] = curve_tls_id;
             } else
-#endif
 #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
             defined(PSA_WANT_ALG_FFDH)
             if ((ffdh_group = mbedtls_ssl_ffdh_group_from_name(q)) != 0) {
@@ -547,15 +657,15 @@
             } else
 #endif
             {
-                mbedtls_printf("unknown group %s\n", q);
-                mbedtls_printf("supported groups: ");
-#if defined(MBEDTLS_ECP_LIGHT)
-                for (curve_cur = mbedtls_ecp_curve_list();
-                     curve_cur->grp_id != MBEDTLS_ECP_DP_NONE;
-                     curve_cur++) {
-                    mbedtls_printf("%s ", curve_cur->name);
+                mbedtls_printf("unknown curve %s\n", q);
+                mbedtls_printf("supported curves: ");
+                const char **supported_curves = mbedtls_ssl_get_supported_curves_list();
+                for (int index = 0;
+                     supported_curves[index] != NULL;
+                     index++) {
+                    mbedtls_printf("%s ", supported_curves[index]);
                 }
-#endif
+                mbedtls_free((char *) supported_curves);
 #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
                 defined(PSA_WANT_ALG_FFDH)
                 const uint16_t *supported_ffdh_group = mbedtls_ssl_ffdh_supported_groups();