Merge pull request #6893 from tom-daubney-arm/modify_generate_errors_script

Make generate_errors.pl handle directory names containing spaces when opening files
diff --git a/ChangeLog.d/fix-iar-warnings.txt b/ChangeLog.d/fix-iar-warnings.txt
new file mode 100644
index 0000000..244e863
--- /dev/null
+++ b/ChangeLog.d/fix-iar-warnings.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix IAR compiler warnings. Contributed by Glenn Strauss in #3835.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 677be87..1efabdc 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -860,6 +860,10 @@
 #error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && !defined(MBEDTLS_X509_CRT_PARSE_C)
+#error "MBEDTLS_SSL_ASYNC_PRIVATE defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) ||     \
     ( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) )
 #error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
@@ -1009,6 +1013,11 @@
 #error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) && \
+            ( !defined(MBEDTLS_X509_CRT_PARSE_C) )
+#error "MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)
 #error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously"
 #endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 092152d..8a4a0d2 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1408,6 +1408,7 @@
  * module to perform private key operations instead of performing the
  * operation inside the library.
  *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
  */
 //#define MBEDTLS_SSL_ASYNC_PRIVATE
 
@@ -2012,6 +2013,8 @@
  * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and
  * `mbedtls_ssl_conf_ca_cb()` for more information.
  *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
  * Uncomment to enable trusted certificate callbacks.
  */
 //#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index f030bea..f2f5400 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -264,22 +264,6 @@
 #define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \
     PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE( PSA_VENDOR_ECC_MAX_CURVE_BITS )
 
-/* This function transforms an ECC group identifier from
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
- * into a PSA ECC group identifier. */
-#if defined(MBEDTLS_ECP_C)
-static inline psa_key_type_t mbedtls_psa_parse_tls_ecc_group(
-    uint16_t tls_ecc_grp_reg_id, size_t *bits )
-{
-    const mbedtls_ecp_curve_info *curve_info =
-        mbedtls_ecp_curve_info_from_tls_id( tls_ecc_grp_reg_id );
-    if( curve_info == NULL )
-        return( 0 );
-    return( PSA_KEY_TYPE_ECC_KEY_PAIR(
-                mbedtls_ecc_group_to_psa( curve_info->grp_id, bits ) ) );
-}
-#endif /* MBEDTLS_ECP_C */
-
 /* Expose whatever RNG the PSA subsystem uses to applications using the
  * mbedtls_xxx API. The declarations and definitions here need to be
  * consistent with the implementation in library/psa_crypto_random_impl.h.
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index cf8a7b2..ff50f7e 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -58,6 +58,13 @@
  * value, check with the Arm PSA framework group to pick one that other
  * domains aren't already using. */
 
+/* Tell uncrustify not to touch the constant definitions, otherwise
+ * it might change the spacing to something that is not PSA-compliant
+ * (e.g. adding a space after casts).
+ *
+ * *INDENT-OFF*
+ */
+
 /** The action was completed successfully. */
 #define PSA_SUCCESS ((psa_status_t)0)
 
@@ -328,6 +335,8 @@
  */
 #define PSA_ERROR_DATA_INVALID          ((psa_status_t)-153)
 
+/* *INDENT-ON* */
+
 /**@}*/
 
 /** \defgroup crypto_types Key and algorithm types
@@ -883,7 +892,9 @@
      (alg) & PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG)
 
 /** An invalid algorithm identifier value. */
+/* *INDENT-OFF* (https://github.com/ARM-software/psa-arch-tests/issues/337) */
 #define PSA_ALG_NONE                            ((psa_algorithm_t)0)
+/* *INDENT-ON* */
 
 #define PSA_ALG_HASH_MASK                       ((psa_algorithm_t)0x000000ff)
 /** MD5 */
@@ -2378,7 +2389,9 @@
 
 /** The null key identifier.
  */
+/* *INDENT-OFF* (https://github.com/ARM-software/psa-arch-tests/issues/337) */
 #define PSA_KEY_ID_NULL                         ((psa_key_id_t)0)
+/* *INDENT-ON* */
 /** The minimum value for a key identifier chosen by the application.
  */
 #define PSA_KEY_ID_USER_MIN                     ((psa_key_id_t)0x00000001)
diff --git a/library/bignum.c b/library/bignum.c
index fc4ddf6..62eb007 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1197,9 +1197,9 @@
      */
     if( 0 == d || u1 >= d )
     {
-        if (r != NULL) *r = ~0;
+        if (r != NULL) *r = ~(mbedtls_mpi_uint)0u;
 
-        return ( ~0 );
+        return ( ~(mbedtls_mpi_uint)0u );
     }
 
 #if defined(MBEDTLS_HAVE_UDBL)
@@ -1338,7 +1338,7 @@
     for( i = n; i > t ; i-- )
     {
         if( X.p[i] >= Y.p[t] )
-            Z.p[i - t - 1] = ~0;
+            Z.p[i - t - 1] = ~(mbedtls_mpi_uint)0u;
         else
         {
             Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 92137ba..925d0c2 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -262,15 +262,17 @@
             ( mbedtls_ssl_conf_is_tls12_enabled( ssl->conf ) &&
               mbedtls_ssl_tls12_named_group_is_ecdhe( *group_list ) ) )
         {
-            const mbedtls_ecp_curve_info *curve_info;
-            curve_info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
-            if( curve_info == NULL )
+            if( mbedtls_ssl_get_ecp_group_id_from_tls_id( *group_list ) ==
+                MBEDTLS_ECP_DP_NONE )
+            {
                 continue;
+            }
             MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
             MBEDTLS_PUT_UINT16_BE( *group_list, p, 0 );
             p += 2;
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "NamedGroup: %s ( %x )",
-                                curve_info->name, *group_list ) );
+                        mbedtls_ssl_get_curve_name_from_tls_id( *group_list ),
+                        *group_list ) );
         }
 #endif /* MBEDTLS_ECP_C */
         /* Add DHE groups here */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 1012b3a..d558e38 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -787,7 +787,7 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) ||      \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-    const mbedtls_ecp_curve_info **curves;      /*!<  Supported elliptic curves */
+    uint16_t *curves_tls_id;      /*!<  List of TLS IDs of supported elliptic curves */
 #endif
 
 #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
@@ -1576,6 +1576,55 @@
 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
 #endif
 
+/**
+ * \brief Return PSA EC info for the specified TLS ID.
+ *
+ * \param tls_id    The TLS ID to look for
+ * \param family    If the TLD ID is supported, then proper \c psa_ecc_family_t
+ *                  value is returned here. Can be NULL.
+ * \param bits      If the TLD ID is supported, then proper bit size is returned
+ *                  here. Can be NULL.
+ * \return          PSA_SUCCESS if the TLS ID is supported,
+ *                  PSA_ERROR_NOT_SUPPORTED otherwise
+ *
+ * \note            If either \c family or \c bits parameters are NULL, then
+ *                  the corresponding value is not returned.
+ *                  The function can be called with both parameters as NULL
+ *                  simply to check if a specific TLS ID is supported.
+ */
+int mbedtls_ssl_get_psa_curve_info_from_tls_id( uint16_t tls_id,
+                                                psa_ecc_family_t *family,
+                                                size_t* bits );
+
+/**
+ * \brief Return \c mbedtls_ecp_group_id for the specified TLS ID.
+ *
+ * \param tls_id    The TLS ID to look for
+ * \return          Proper \c mbedtls_ecp_group_id if the TLS ID is supported,
+ *                  or MBEDTLS_ECP_DP_NONE otherwise
+ */
+mbedtls_ecp_group_id mbedtls_ssl_get_ecp_group_id_from_tls_id( uint16_t tls_id );
+
+/**
+ * \brief Return TLS ID for the specified \c mbedtls_ecp_group_id.
+ *
+ * \param grp_id    The \c mbedtls_ecp_group_id ID to look for
+ * \return          Proper TLS ID if the \c mbedtls_ecp_group_id is supported,
+ *                  or 0 otherwise
+ */
+uint16_t mbedtls_ssl_get_tls_id_from_ecp_group_id( mbedtls_ecp_group_id grp_id );
+
+#if defined(MBEDTLS_DEBUG_C)
+/**
+ * \brief Return EC's name for the specified TLS ID.
+ *
+ * \param tls_id    The TLS ID to look for
+ * \return          A pointer to a const string with the proper name. If TLS
+ *                  ID is not supported, a NULL pointer is returned instead.
+ */
+const char* mbedtls_ssl_get_curve_name_from_tls_id( uint16_t tls_id );
+#endif
+
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
                                                     ( const uint16_t srtp_profile_value )
@@ -2179,9 +2228,8 @@
 #if defined(MBEDTLS_ECDH_C)
     if( mbedtls_ssl_tls13_named_group_is_ecdhe( named_group ) )
     {
-        const mbedtls_ecp_curve_info *curve_info =
-            mbedtls_ecp_curve_info_from_tls_id( named_group );
-        if( curve_info != NULL )
+        if( mbedtls_ssl_get_ecp_group_id_from_tls_id( named_group ) !=
+                        MBEDTLS_ECP_DP_NONE )
             return( 1 );
     }
 #else
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index d25a439..35565de 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1076,14 +1076,14 @@
 
         for( size_t i = 0; i < length; i++ )
         {
-            const mbedtls_ecp_curve_info *info =
-                        mbedtls_ecp_curve_info_from_grp_id( curve_list[i] );
-            if ( info == NULL )
+            uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
+                                curve_list[i] );
+            if ( tls_id == 0 )
             {
                 mbedtls_free( group_list );
                 return( MBEDTLS_ERR_SSL_BAD_CONFIG );
             }
-            group_list[i] = info->tls_id;
+            group_list[i] = tls_id;
         }
 
         group_list[length] = 0;
@@ -4065,7 +4065,7 @@
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
     /* explicit void pointer cast for buggy MS compiler */
-    mbedtls_free( (void *) handshake->curves );
+    mbedtls_free( (void *) handshake->curves_tls_id );
 #endif
 
 #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
@@ -5490,18 +5490,126 @@
  */
 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
 {
-    const mbedtls_ecp_curve_info *grp_info =
-        mbedtls_ecp_curve_info_from_grp_id( grp_id );
+    uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( grp_id );
 
-    if ( grp_info == NULL )
+    if ( tls_id == 0 )
         return -1;
 
-    uint16_t tls_id = grp_info->tls_id;
-
     return mbedtls_ssl_check_curve_tls_id( ssl, tls_id );
 }
 #endif /* MBEDTLS_ECP_C */
 
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#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" ) },
+#endif
+    { 0, MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
+};
+
+int mbedtls_ssl_get_psa_curve_info_from_tls_id( uint16_t tls_id,
+                                                psa_ecc_family_t *family,
+                                                size_t* bits )
+{
+    for( int i = 0; tls_id_match_table[i].tls_id != 0; i++ )
+    {
+        if( tls_id_match_table[i].tls_id == tls_id )
+        {
+            if( family != NULL )
+                *family = tls_id_match_table[i].psa_family;
+            if( bits != NULL )
+                *bits = tls_id_match_table[i].bits;
+            return PSA_SUCCESS;
+        }
+    }
+
+    return PSA_ERROR_NOT_SUPPORTED;
+}
+
+mbedtls_ecp_group_id mbedtls_ssl_get_ecp_group_id_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].ecp_group_id;
+    }
+
+    return MBEDTLS_ECP_DP_NONE;
+}
+
+uint16_t mbedtls_ssl_get_tls_id_from_ecp_group_id( mbedtls_ecp_group_id grp_id )
+{
+    for( int i = 0; tls_id_match_table[i].ecp_group_id != MBEDTLS_ECP_DP_NONE;
+            i++ )
+    {
+        if( tls_id_match_table[i].ecp_group_id == grp_id )
+            return tls_id_match_table[i].tls_id;
+    }
+
+    return 0;
+}
+
+#if defined(MBEDTLS_DEBUG_C)
+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;
+    }
+
+    return NULL;
+}
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
                           const mbedtls_ssl_ciphersuite_t *ciphersuite,
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 76588d3..30b6481 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -1800,9 +1800,10 @@
                                              unsigned char *end )
 {
     uint16_t tls_id;
-    size_t ecdh_bits = 0;
     uint8_t ecpoint_len;
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+    psa_ecc_family_t ec_psa_family = 0;
+    size_t ec_bits = 0;
 
     /*
      * struct {
@@ -1836,13 +1837,14 @@
         return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
-    /* Convert EC group to PSA key type. */
-    if( ( handshake->ecdh_psa_type =
-          mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
+    /* Convert EC's TLS ID to PSA key type. */
+    if( mbedtls_ssl_get_psa_curve_info_from_tls_id( tls_id, &ec_psa_family,
+                    &ec_bits ) == PSA_ERROR_NOT_SUPPORTED )
     {
         return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
-    handshake->ecdh_bits = ecdh_bits;
+    handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR( ec_psa_family );
+    handshake->ecdh_bits = ec_bits;
 
     /* Keep a copy of the peer's public key */
     ecpoint_len = *(*p)++;
@@ -1870,7 +1872,7 @@
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
 {
-    const mbedtls_ecp_curve_info *curve_info;
+    uint16_t tls_id;
     mbedtls_ecp_group_id grp_id;
 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     grp_id = ssl->handshake->ecdh_ctx.grp.id;
@@ -1878,14 +1880,15 @@
     grp_id = ssl->handshake->ecdh_ctx.grp_id;
 #endif
 
-    curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
-    if( curve_info == NULL )
+    tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( grp_id );
+    if( tls_id == 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
     }
 
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s",
+                mbedtls_ssl_get_curve_name_from_tls_id( tls_id ) ) );
 
     if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 )
         return( -1 );
@@ -2104,8 +2107,9 @@
     peer_key = mbedtls_pk_ec( *peer_pk );
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    size_t ecdh_bits = 0;
     size_t olen = 0;
+    uint16_t tls_id = 0;
+    psa_ecc_family_t ecc_family;
 
     if( mbedtls_ssl_check_curve( ssl, peer_key->grp.id ) != 0 )
     {
@@ -2113,17 +2117,20 @@
         return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
     }
 
-    ssl->handshake->ecdh_psa_type =
-        PSA_KEY_TYPE_ECC_KEY_PAIR( mbedtls_ecc_group_to_psa( peer_key->grp.id,
-                                                             &ecdh_bits ) );
-
-    if( ssl->handshake->ecdh_psa_type == 0 || ecdh_bits > 0xffff )
+    tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( peer_key->grp.id );
+    if( tls_id == 0 )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Invalid ecc group conversion to psa." ) );
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ECC group %u not suported",
+                                peer_key->grp.id ) );
         return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
-    ssl->handshake->ecdh_bits = (uint16_t) ecdh_bits;
+    /* If the above conversion to TLS ID was fine, then also this one will be,
+       so there is no need to check the return value here */
+    mbedtls_ssl_get_psa_curve_info_from_tls_id( tls_id, &ecc_family,
+                                &ssl->handshake->ecdh_bits );
+
+    ssl->handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR( ecc_family );
 
     /* Store peer's public key in psa format. */
     ret = mbedtls_ecp_point_write_binary( &peer_key->grp, &peer_key->Q,
@@ -2346,16 +2353,16 @@
          * that TLS ID here
          */
         uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE( p, 1 );
-        const mbedtls_ecp_curve_info *curve_info;
+        uint16_t exp_tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
+                                    MBEDTLS_ECP_DP_SECP256R1 );
 
-        if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id(
-                                MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL )
+        if( exp_tls_id == 0 )
         {
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
         }
 
         if( ( *p != MBEDTLS_ECP_TLS_NAMED_CURVE ) ||
-            ( read_tls_id != curve_info->tls_id ) )
+            ( read_tls_id != exp_tls_id ) )
         {
             return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 5cdbcc0..a28cd67 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -180,7 +180,7 @@
 {
     size_t list_size, our_size;
     const unsigned char *p;
-    const mbedtls_ecp_curve_info *curve_info, **curves;
+    uint16_t *curves_tls_id;
 
     if ( len < 2 ) {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
@@ -199,7 +199,7 @@
     }
 
     /* Should never happen unless client duplicates the extension */
-    if( ssl->handshake->curves != NULL )
+    if( ssl->handshake->curves_tls_id != NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -213,23 +213,25 @@
     if( our_size > MBEDTLS_ECP_DP_MAX )
         our_size = MBEDTLS_ECP_DP_MAX;
 
-    if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL )
+    if( ( curves_tls_id = mbedtls_calloc( our_size,
+                                sizeof( *curves_tls_id ) ) ) == NULL )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
     }
 
-    ssl->handshake->curves = curves;
+    ssl->handshake->curves_tls_id = curves_tls_id;
 
     p = buf + 2;
     while( list_size > 0 && our_size > 1 )
     {
-        curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] );
+        uint16_t curr_tls_id = MBEDTLS_GET_UINT16_BE( p, 0 );
 
-        if( curve_info != NULL )
+        if( mbedtls_ssl_get_ecp_group_id_from_tls_id( curr_tls_id ) !=
+                                        MBEDTLS_ECP_DP_NONE )
         {
-            *curves++ = curve_info;
+            *curves_tls_id++ = curr_tls_id;
             our_size--;
         }
 
@@ -685,16 +687,18 @@
 #if defined(MBEDTLS_ECDSA_C)
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_key_curve( mbedtls_pk_context *pk,
-                                const mbedtls_ecp_curve_info **curves )
+                                uint16_t *curves_tls_id )
 {
-    const mbedtls_ecp_curve_info **crv = curves;
+    uint16_t *curr_tls_id = curves_tls_id;
     mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id;
+    mbedtls_ecp_group_id curr_grp_id;
 
-    while( *crv != NULL )
+    while( *curr_tls_id != 0 )
     {
-        if( (*crv)->grp_id == grp_id )
+        curr_grp_id = mbedtls_ssl_get_ecp_group_id_from_tls_id( *curr_tls_id );
+        if( curr_grp_id == grp_id )
             return( 0 );
-        crv++;
+        curr_tls_id++;
     }
 
     return( -1 );
@@ -789,7 +793,8 @@
 
 #if defined(MBEDTLS_ECDSA_C)
         if( pk_alg == MBEDTLS_PK_ECDSA &&
-            ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
+            ssl_check_key_curve( &cur->cert->pk,
+                            ssl->handshake->curves_tls_id ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
             continue;
@@ -857,8 +862,8 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
     if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
-        ( ssl->handshake->curves == NULL ||
-          ssl->handshake->curves[0] == NULL ) )
+        ( ssl->handshake->curves_tls_id == NULL ||
+          ssl->handshake->curves_tls_id[0] == 0 ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
                             "no common elliptic curve" ) );
@@ -2654,7 +2659,8 @@
     unsigned char buf[
         PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
     psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
-    size_t ecdh_bits = 0;
+    uint16_t tls_id = 0;
+    psa_ecc_family_t ecc_family;
     size_t key_len;
     mbedtls_pk_context *pk;
     mbedtls_ecp_keypair *key;
@@ -2698,15 +2704,19 @@
         if( key == NULL )
             return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
-        /* Convert EC group to PSA key type. */
-        if( ( ssl->handshake->ecdh_psa_type =
-                    mbedtls_ecc_group_to_psa( key->grp.id,
-                                              &ecdh_bits ) ) == 0 )
+        tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( key->grp.id );
+        if( tls_id == 0 )
         {
+            /* This elliptic curve is not supported */
             return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
-        ssl->handshake->ecdh_bits = ecdh_bits;
+        /* If the above conversion to TLS ID was fine, then also this one will
+           be, so there is no need to check the return value here */
+        mbedtls_ssl_get_psa_curve_info_from_tls_id( tls_id, &ecc_family,
+                                &ssl->handshake->ecdh_bits );
+
+        ssl->handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR( ecc_family );
 
         key_attributes = psa_key_attributes_init();
         psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
@@ -2849,7 +2859,6 @@
                                ssl->out_msglen;
         size_t output_offset = 0;
         size_t output_len = 0;
-        const mbedtls_ecp_curve_info *curve_info;
 
         /*
          * The first 3 bytes are:
@@ -2859,13 +2868,14 @@
          * However since we only support secp256r1 for now, we hardcode its
          * TLS ID here
          */
-        if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id(
-                                    MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL )
+        uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
+                                    MBEDTLS_ECP_DP_SECP256R1 );
+        if( tls_id ==0 )
         {
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
         }
         *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE;
-        MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p, 1 );
+        MBEDTLS_PUT_UINT16_BE( tls_id, out_p, 1 );
         output_offset += 3;
 
         ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx,
@@ -2986,50 +2996,52 @@
          *     ECPoint      public;
          * } ServerECDHParams;
          */
-        const mbedtls_ecp_curve_info **curve = NULL;
+        uint16_t *curr_tls_id = ssl->handshake->curves_tls_id;
         const uint16_t *group_list = mbedtls_ssl_get_groups( ssl );
         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
         size_t len = 0;
 
         /* Match our preference list against the offered curves */
-        if( group_list == NULL )
+        if( ( group_list == NULL ) || ( curr_tls_id == NULL ) )
             return( MBEDTLS_ERR_SSL_BAD_CONFIG );
         for( ; *group_list != 0; group_list++ )
-            for( curve = ssl->handshake->curves; *curve != NULL; curve++ )
-                if( (*curve)->tls_id == *group_list )
+            for( curr_tls_id = ssl->handshake->curves_tls_id;
+                 *curr_tls_id != 0; curr_tls_id++ )
+                if( *curr_tls_id == *group_list )
                     goto curve_matching_done;
 
 curve_matching_done:
-        if( curve == NULL || *curve == NULL )
+        if( *curr_tls_id == 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
             return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s",
+                    mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id) ) );
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
         psa_key_attributes_t key_attributes;
         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
-        size_t ecdh_bits = 0;
         uint8_t *p = ssl->out_msg + ssl->out_msglen;
         const size_t header_size = 4; // curve_type(1), namedcurve(2),
                                       // data length(1)
         const size_t data_length_size = 1;
+        psa_ecc_family_t ec_psa_family = 0;
+        size_t ec_bits = 0;
 
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based ECDH computation." ) );
 
-        /* Convert EC group to PSA key type. */
-        handshake->ecdh_psa_type = mbedtls_psa_parse_tls_ecc_group(
-                    (*curve)->tls_id, &ecdh_bits );
-
-        if( handshake->ecdh_psa_type == 0 )
+        /* Convert EC's TLS ID to PSA key type. */
+        if( mbedtls_ssl_get_psa_curve_info_from_tls_id( *curr_tls_id,
+                &ec_psa_family, &ec_bits ) == PSA_ERROR_NOT_SUPPORTED )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Invalid ecc group parse." ) );
             return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
-        handshake->ecdh_bits = ecdh_bits;
+        handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR( ec_psa_family );
+        handshake->ecdh_bits = ec_bits;
 
         key_attributes = psa_key_attributes_init();
         psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
@@ -3047,7 +3059,7 @@
         /*
          * Next two bytes are the namedcurve value
          */
-        MBEDTLS_PUT_UINT16_BE( (*curve)->tls_id, p, 0 );
+        MBEDTLS_PUT_UINT16_BE( *curr_tls_id, p, 0 );
         p += 2;
 
         /* Generate ECDH private key. */
@@ -3093,8 +3105,11 @@
         /* Determine full message length. */
         len += header_size;
 #else
+        mbedtls_ecp_group_id curr_grp_id =
+                    mbedtls_ssl_get_ecp_group_id_from_tls_id( *curr_tls_id );
+
         if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx,
-                                        (*curve)->grp_id ) ) != 0 )
+                                        curr_grp_id ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret );
             return( ret );
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 08d4924..f07c8b6 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -230,9 +230,8 @@
 
     for ( ; *group_list != 0; group_list++ )
     {
-        const mbedtls_ecp_curve_info *curve_info;
-        curve_info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
-        if( curve_info != NULL &&
+        if( ( mbedtls_ssl_get_psa_curve_info_from_tls_id( *group_list,
+                            NULL, NULL ) == PSA_SUCCESS ) &&
             mbedtls_ssl_tls13_named_group_is_ecdhe( *group_list ) )
         {
             *group_id = *group_list;
@@ -385,7 +384,6 @@
                                               const unsigned char *end )
 {
 #if defined(MBEDTLS_ECDH_C)
-    const mbedtls_ecp_curve_info *curve_info = NULL;
     const unsigned char *p = buf;
     int selected_group;
     int found = 0;
@@ -412,8 +410,9 @@
      */
     for( ; *group_list != 0; group_list++ )
     {
-        curve_info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
-        if( curve_info == NULL || curve_info->tls_id != selected_group )
+        if( ( mbedtls_ssl_get_psa_curve_info_from_tls_id( *group_list,
+                NULL, NULL ) == PSA_ERROR_NOT_SUPPORTED ) ||
+                *group_list != selected_group )
             continue;
 
         /* We found a match */
@@ -493,15 +492,15 @@
 #if defined(MBEDTLS_ECDH_C)
     if( mbedtls_ssl_tls13_named_group_is_ecdhe( group ) )
     {
-        const mbedtls_ecp_curve_info *curve_info =
-            mbedtls_ecp_curve_info_from_tls_id( group );
-        if( curve_info == NULL )
+        if( mbedtls_ssl_get_psa_curve_info_from_tls_id( group, NULL, NULL )
+                    == PSA_ERROR_NOT_SUPPORTED )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "Invalid TLS curve group id" ) );
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
 
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s",
+                    mbedtls_ssl_get_curve_name_from_tls_id( group ) ) );
 
         ret = mbedtls_ssl_tls13_read_public_ecdhe_share( ssl, p, end - p );
         if( ret != 0 )
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 0aecb35..121ff43 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -1516,16 +1516,19 @@
     psa_key_attributes_t key_attributes;
     size_t own_pubkey_len;
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
-    size_t ecdh_bits = 0;
+    psa_ecc_family_t ec_psa_family = 0;
+    size_t ec_bits = 0;
 
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based ECDH computation." ) );
 
-    /* Convert EC group to PSA key type. */
-    if( ( handshake->ecdh_psa_type =
-        mbedtls_psa_parse_tls_ecc_group( named_group, &ecdh_bits ) ) == 0 )
-            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
-
-    ssl->handshake->ecdh_bits = ecdh_bits;
+    /* Convert EC's TLS ID to PSA key type. */
+    if( mbedtls_ssl_get_psa_curve_info_from_tls_id( named_group,
+                &ec_psa_family, &ec_bits ) == PSA_ERROR_NOT_SUPPORTED )
+    {
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+    handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR( ec_psa_family );
+    ssl->handshake->ecdh_bits = ec_bits;
 
     key_attributes = psa_key_attributes_init();
     psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index d166f77..ddbfdc3 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -939,6 +939,19 @@
 
     msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
     tests/context-info.sh
+
+    msg "test: check direct ECP dependencies in TLS and X.509"
+    docs/architecture/psa-migration/syms.sh full
+
+    # TODO: replace "mbedtls_ecp_curve" with "mbedtls_ecp" also for
+    # "full-tls-external" once Issue6839 is completed
+    not grep mbedtls_ecp_curve full-tls-external
+    not grep mbedtls_ecp full-x509-external
+
+    rm  full-tls-external \
+        full-tls-modules \
+        full-x509-external \
+        full-x509-modules
 }
 
 component_test_psa_crypto_key_id_encodes_owner () {
@@ -1277,6 +1290,57 @@
     make test
 }
 
+component_test_full_no_bignum () {
+    msg "build: full minus bignum"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_BIGNUM_C
+    # Direct dependencies of bignum
+    scripts/config.py unset MBEDTLS_ECP_C
+    scripts/config.py unset MBEDTLS_RSA_C
+    scripts/config.py unset MBEDTLS_DHM_C
+    # Direct dependencies of ECP
+    scripts/config.py unset MBEDTLS_ECDH_C
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+    # Indirect dependencies of ECP
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+    # Direct dependencies of DHM
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+    # Direct dependencies of RSA
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    # PK and its dependencies
+    scripts/config.py unset MBEDTLS_PK_C
+    scripts/config.py unset MBEDTLS_PK_PARSE_C
+    scripts/config.py unset MBEDTLS_PK_WRITE_C
+    scripts/config.py unset MBEDTLS_X509_USE_C
+    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_CRL_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_CSR_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_CREATE_C
+    scripts/config.py unset MBEDTLS_X509_CRT_WRITE_C
+    scripts/config.py unset MBEDTLS_X509_CSR_WRITE_C
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
+    scripts/config.py unset MBEDTLS_SSL_ASYNC_PRIVATE
+    scripts/config.py unset MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+
+    make
+
+    msg "test: full minus bignum"
+    make test
+}
+
 component_test_tls1_2_default_stream_cipher_only () {
     msg "build: default with only stream cipher"
 
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 1b5e44b..3059e7f 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -3547,3 +3547,6 @@
 EC-JPAKE set opaque password
 depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 ssl_ecjpake_set_password:1
+
+Test Elliptic curves' info parsing
+elliptic_curve_get_properties
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 274a894..b0b9136 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -2597,6 +2597,25 @@
                                         pwd_string, pwd_len );  \
     TEST_EQUAL( ret, exp_ret_val )
 #endif
+
+#define TEST_AVAILABLE_ECC( tls_id_, group_id_, psa_family_, psa_bits_ )   \
+    TEST_EQUAL( mbedtls_ssl_get_ecp_group_id_from_tls_id( tls_id_ ),       \
+                    group_id_ );                                           \
+    TEST_EQUAL( mbedtls_ssl_get_tls_id_from_ecp_group_id( group_id_ ),     \
+                    tls_id_ );                                             \
+    TEST_EQUAL( mbedtls_ssl_get_psa_curve_info_from_tls_id( tls_id_,       \
+                    &psa_family, &psa_bits), PSA_SUCCESS );                \
+    TEST_EQUAL( psa_family_, psa_family );                                 \
+    TEST_EQUAL( psa_bits_, psa_bits );
+
+#define TEST_UNAVAILABLE_ECC( tls_id_, group_id_, psa_family_, psa_bits_ ) \
+    TEST_EQUAL( mbedtls_ssl_get_ecp_group_id_from_tls_id( tls_id_ ),       \
+                    MBEDTLS_ECP_DP_NONE );                                 \
+    TEST_EQUAL( mbedtls_ssl_get_tls_id_from_ecp_group_id( group_id_ ),     \
+                    0 );                                                   \
+    TEST_EQUAL( mbedtls_ssl_get_psa_curve_info_from_tls_id( tls_id_,       \
+                    &psa_family, &psa_bits), PSA_ERROR_NOT_SUPPORTED );
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -6094,3 +6113,81 @@
     USE_PSA_DONE( );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void elliptic_curve_get_properties( )
+{
+    psa_ecc_family_t psa_family;
+    size_t psa_bits;
+
+    USE_PSA_INIT( );
+
+#if defined( MBEDTLS_ECP_DP_SECP521R1_ENABLED ) || defined(PSA_WANT_ECC_SECP_R1_521)
+    TEST_AVAILABLE_ECC( 25, MBEDTLS_ECP_DP_SECP521R1, PSA_ECC_FAMILY_SECP_R1, 521 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 28, MBEDTLS_ECP_DP_BP512R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 512 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 24, MBEDTLS_ECP_DP_SECP384R1, PSA_ECC_FAMILY_SECP_R1, 384 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 27, MBEDTLS_ECP_DP_BP384R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 384 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 23, MBEDTLS_ECP_DP_SECP256R1, PSA_ECC_FAMILY_SECP_R1, 256 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 22, MBEDTLS_ECP_DP_SECP256K1, PSA_ECC_FAMILY_SECP_K1, 256 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 26, MBEDTLS_ECP_DP_BP256R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 256 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 21, MBEDTLS_ECP_DP_SECP224R1, PSA_ECC_FAMILY_SECP_R1, 224 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 20, MBEDTLS_ECP_DP_SECP224K1, PSA_ECC_FAMILY_SECP_K1, 224 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 19, MBEDTLS_ECP_DP_SECP192R1, PSA_ECC_FAMILY_SECP_R1, 192 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 18, MBEDTLS_ECP_DP_SECP192K1, PSA_ECC_FAMILY_SECP_K1, 192 );
+#else
+    TEST_UNAVAILABLE_ECC( 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)
+    TEST_AVAILABLE_ECC( 29, MBEDTLS_ECP_DP_CURVE25519, PSA_ECC_FAMILY_MONTGOMERY, 255 );
+#else
+    TEST_UNAVAILABLE_ECC( 29, MBEDTLS_ECP_DP_CURVE25519, PSA_ECC_FAMILY_MONTGOMERY, 255 );
+#endif
+#if defined( MBEDTLS_ECP_DP_CURVE448_ENABLED ) || defined(PSA_WANT_ECC_MONTGOMERY_448)
+    TEST_AVAILABLE_ECC( 30, MBEDTLS_ECP_DP_CURVE448, PSA_ECC_FAMILY_MONTGOMERY, 448 );
+#else
+    TEST_UNAVAILABLE_ECC( 30, MBEDTLS_ECP_DP_CURVE448, PSA_ECC_FAMILY_MONTGOMERY, 448 );
+#endif
+
+    USE_PSA_DONE( );
+}
+/* END_CASE */