Merge pull request #7582 from xkqian/bignum/test_add_sub_named_moduli

[Bignum] Add add_sub test cases for named moduli curves
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index ba5844f..0917bf7 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -87,6 +87,18 @@
 #define MBEDTLS_MD_C
 #endif
 
+/* PSA crypto specific configuration options
+ * - If config_psa.h reads a configuration option in preprocessor directive,
+ *   this symbol should be set before its inclusion. (e.g. MBEDTLS_MD_C)
+ * - If config_psa.h writes a configuration option in conditional directive,
+ *   this symbol should be consulted after its inclusion.
+ *   (e.g. MBEDTLS_MD_LIGHT)
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
+    defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
+#include "mbedtls/config_psa.h"
+#endif
+
 /* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C.
  * This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C.
  */
@@ -185,11 +197,6 @@
 
 /* Make sure all configuration symbols are set before including check_config.h,
  * even the ones that are calculated programmatically. */
-#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
-    defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
-#include "mbedtls/config_psa.h"
-#endif
-
 #include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_BUILD_INFO_H */
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index ec2a251..ffd1b73 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -202,6 +202,27 @@
 #define MBEDTLS_PK_CAN_ECDH
 #endif
 
+/* Internal helper to define which fields in the pk_context structure below
+ * should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly)
+ * format. It should be noticed that this only affect how data is stored, not
+ * which functions are used for various operations. The overall picture looks
+ * like this:
+ * - if ECP_C is defined then use legacy functions
+ * - if USE_PSA is defined and
+ *     - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly
+ *       format and use PSA functions
+ *     - if !ECP_C then use new raw data and PSA functions directly.
+ *
+ * The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long
+ * as ECP_C is defined mbedtls_pk_ec() gives the user a read/write access to the
+ * ecp_keypair structure inside the pk_context so he/she can modify it using
+ * ECP functions which are not under PK module's control.
+ */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_ECP_C) && \
+    defined(MBEDTLS_ECP_LIGHT)
+#define MBEDTLS_PK_USE_PSA_EC_DATA
+#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_ECP_C */
+
 /**
  * \brief           Types for interfacing with the debug module
  */
@@ -209,6 +230,7 @@
     MBEDTLS_PK_DEBUG_NONE = 0,
     MBEDTLS_PK_DEBUG_MPI,
     MBEDTLS_PK_DEBUG_ECP,
+    MBEDTLS_PK_DEBUG_PSA_EC,
 } mbedtls_pk_debug_type;
 
 /**
@@ -232,19 +254,47 @@
  */
 typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
 
+#define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \
+    PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
 /**
  * \brief           Public key container
- *
- * \note            The priv_id is guarded by MBEDTLS_PSA_CRYPTO_C and not
- *                  by MBEDTLS_USE_PSA_CRYPTO because it can be used also
- *                  in mbedtls_pk_sign_ext for RSA keys.
  */
 typedef struct mbedtls_pk_context {
     const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info);    /**< Public key information         */
     void *MBEDTLS_PRIVATE(pk_ctx);                        /**< Underlying public key context  */
+    /* When MBEDTLS_PSA_CRYPTO_C is enabled then the following priv_id field is
+     * used to store the ID of the opaque key.
+     * This priv_id is guarded by MBEDTLS_PSA_CRYPTO_C and not by
+     * MBEDTLS_USE_PSA_CRYPTO because it can be used also in mbedtls_pk_sign_ext
+     * for RSA keys. */
 #if defined(MBEDTLS_PSA_CRYPTO_C)
     mbedtls_svc_key_id_t MBEDTLS_PRIVATE(priv_id);      /**< Key ID for opaque keys */
 #endif /* MBEDTLS_PSA_CRYPTO_C */
+    /* The following fields are meant for storing the public key in raw format
+     * which is handy for:
+     * - easily importing it into the PSA context
+     * - reducing the ECP module dependencies in the PK one.
+     *
+     * When MBEDTLS_PK_USE_PSA_EC_DATA is enabled:
+     * - the pk_ctx above is not used anymore for storing the public key
+     *   inside the ecp_keypair structure (only the private part, but also this
+     *   one is going to change in the future)
+     * - the following fields are used for all public key operations: signature
+     *   verify, key pair check and key write.
+     * Of course, when MBEDTLS_PK_USE_PSA_EC_DATA is not enabled, the legacy
+     * ecp_keypair structure is used for storing the public key and performing
+     * all the operations.
+     *
+     * Note: This new public key storing solution only works for EC keys, not
+     *       other ones. The latters still use pk_ctx to store their own
+     *       context.
+     */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    uint8_t MBEDTLS_PRIVATE(pub_raw)[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; /**< Raw public key   */
+    size_t MBEDTLS_PRIVATE(pub_raw_len);            /**< Valid bytes in "pub_raw" */
+    psa_ecc_family_t MBEDTLS_PRIVATE(ec_family);    /**< EC family of pk */
+    size_t MBEDTLS_PRIVATE(ec_bits);                /**< Curve's bits of pk */
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
 } mbedtls_pk_context;
 
 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index f651587..768c756 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -139,6 +139,8 @@
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
     defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
+#undef mbedtls_free
+#undef mbedtls_calloc
 #define mbedtls_free       MBEDTLS_PLATFORM_FREE_MACRO
 #define mbedtls_calloc     MBEDTLS_PLATFORM_CALLOC_MACRO
 #else
@@ -160,6 +162,8 @@
                                      void (*free_func)(void *));
 #endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
 #else /* !MBEDTLS_PLATFORM_MEMORY */
+#undef mbedtls_free
+#undef mbedtls_calloc
 #define mbedtls_free       free
 #define mbedtls_calloc     calloc
 #endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
@@ -184,6 +188,7 @@
 int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *stream, const char *,
                                                      ...));
 #else
+#undef mbedtls_fprintf
 #if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
 #define mbedtls_fprintf    MBEDTLS_PLATFORM_FPRINTF_MACRO
 #else
@@ -208,6 +213,7 @@
  */
 int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...));
 #else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
+#undef mbedtls_printf
 #if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
 #define mbedtls_printf     MBEDTLS_PLATFORM_PRINTF_MACRO
 #else
@@ -243,6 +249,7 @@
 int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n,
                                                        const char *format, ...));
 #else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#undef mbedtls_snprintf
 #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
 #define mbedtls_snprintf   MBEDTLS_PLATFORM_SNPRINTF_MACRO
 #else
@@ -279,6 +286,7 @@
 int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n,
                                                          const char *format, va_list arg));
 #else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+#undef mbedtls_vsnprintf
 #if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
 #define mbedtls_vsnprintf   MBEDTLS_PLATFORM_VSNPRINTF_MACRO
 #else
@@ -320,7 +328,9 @@
  */
 int mbedtls_platform_set_setbuf(void (*setbuf_func)(
                                     FILE *stream, char *buf));
-#elif defined(MBEDTLS_PLATFORM_SETBUF_MACRO)
+#else
+#undef mbedtls_setbuf
+#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO)
 /**
  * \brief                  Macro defining the function for the library to
  *                         call for `setbuf` functionality (changing the
@@ -334,7 +344,8 @@
 #define mbedtls_setbuf    MBEDTLS_PLATFORM_SETBUF_MACRO
 #else
 #define mbedtls_setbuf    setbuf
-#endif /* MBEDTLS_PLATFORM_SETBUF_ALT / MBEDTLS_PLATFORM_SETBUF_MACRO */
+#endif /* MBEDTLS_PLATFORM_SETBUF_MACRO */
+#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */
 
 /*
  * The function pointers for exit
@@ -353,6 +364,7 @@
  */
 int mbedtls_platform_set_exit(void (*exit_func)(int status));
 #else
+#undef mbedtls_exit
 #if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
 #define mbedtls_exit   MBEDTLS_PLATFORM_EXIT_MACRO
 #else
@@ -405,6 +417,8 @@
     int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len)
     );
 #else
+#undef mbedtls_nv_seed_read
+#undef mbedtls_nv_seed_write
 #if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
     defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
 #define mbedtls_nv_seed_read    MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
diff --git a/library/base64.c b/library/base64.c
index 4170610..3eb9e7c 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -17,6 +17,8 @@
  *  limitations under the License.
  */
 
+#include <limits.h>
+
 #include "common.h"
 
 #if defined(MBEDTLS_BASE64_C)
@@ -31,8 +33,6 @@
 #include "mbedtls/platform.h"
 #endif /* MBEDTLS_SELF_TEST */
 
-#define BASE64_SIZE_T_MAX   ((size_t) -1)   /* SIZE_T_MAX is not standard */
-
 /*
  * Encode a buffer into base64 format
  */
@@ -50,8 +50,8 @@
 
     n = slen / 3 + (slen % 3 != 0);
 
-    if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
-        *olen = BASE64_SIZE_T_MAX;
+    if (n > (SIZE_MAX - 1) / 4) {
+        *olen = SIZE_MAX;
         return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
     }
 
diff --git a/library/bignum.c b/library/bignum.c
index e686a1b..36effaf 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -54,8 +54,6 @@
 #define MPI_VALIDATE(cond)                                           \
     MBEDTLS_INTERNAL_VALIDATE(cond)
 
-#define MPI_SIZE_T_MAX  ((size_t) -1)   /* SIZE_T_MAX is not standard */
-
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_mpi_zeroize(mbedtls_mpi_uint *v, size_t n)
 {
@@ -416,7 +414,7 @@
     slen = strlen(s);
 
     if (radix == 16) {
-        if (slen > MPI_SIZE_T_MAX >> 2) {
+        if (slen > SIZE_MAX >> 2) {
             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
         }
 
diff --git a/library/debug.c b/library/debug.c
index e3dfaef..0f02929 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -203,6 +203,52 @@
 #endif /* MBEDTLS_ECP_LIGHT */
 
 #if defined(MBEDTLS_BIGNUM_C)
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const char *text, const mbedtls_pk_context *pk)
+{
+    char str[DEBUG_BUF_SIZE];
+    mbedtls_mpi mpi;
+    const uint8_t *mpi_start;
+    size_t mpi_len;
+    int ret;
+
+    if (NULL == ssl              ||
+        NULL == ssl->conf        ||
+        NULL == ssl->conf->f_dbg ||
+        level > debug_threshold) {
+        return;
+    }
+
+    /* For the description of pk->pk_raw content please refer to the description
+     * psa_export_public_key() function. */
+    mpi_len = (pk->pub_raw_len - 1)/2;
+
+    /* X coordinate */
+    mbedtls_mpi_init(&mpi);
+    mpi_start = pk->pub_raw + 1;
+    ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
+    if (ret != 0) {
+        return;
+    }
+    mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
+    mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
+    mbedtls_mpi_free(&mpi);
+
+    /* Y coordinate */
+    mbedtls_mpi_init(&mpi);
+    mpi_start = mpi_start + mpi_len;
+    ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
+    if (ret != 0) {
+        return;
+    }
+    mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
+    mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
+    mbedtls_mpi_free(&mpi);
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
 void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
                              const char *file, int line,
                              const char *text, const mbedtls_mpi *X)
@@ -286,6 +332,11 @@
             mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
         } else
 #endif
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+        if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) {
+            mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value);
+        } else
+#endif
         { debug_send_line(ssl, level, file, line,
                           "should not happen\n"); }
     }
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index b07753a..6573f89 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -4613,17 +4613,17 @@
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
 static int ecp_mod_p192k1(mbedtls_mpi *);
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p192k1(mbedtls_mpi *);
+int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
 static int ecp_mod_p224k1(mbedtls_mpi *);
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p224k1(mbedtls_mpi *);
+int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
 static int ecp_mod_p256k1(mbedtls_mpi *);
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p256k1(mbedtls_mpi *);
+int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
 #endif
 
 #if defined(ECP_LOAD_GROUP)
@@ -5532,7 +5532,7 @@
  * Fast quasi-reduction modulo P = 2^s - R,
  * with R about 33 bits, used by the Koblitz curves.
  *
- * Write N as A0 + 2^224 A1, return A0 + R * A1.
+ * Write X as A0 + 2^224 A1, return A0 + R * A1.
  */
 #define P_KOBLITZ_R     (8 / sizeof(mbedtls_mpi_uint))            // Limbs in R
 
@@ -5629,81 +5629,95 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t expected_width = 2 * ((192 + biL - 1) / biL);
     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
-    ret = mbedtls_ecp_mod_p192k1(N);
+    ret = mbedtls_ecp_mod_p192k1_raw(N->p, expected_width);
 
 cleanup:
     return ret;
 }
 
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
 {
     static mbedtls_mpi_uint Rp[] = {
-        MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
-                                  0x00)
+        MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00,
+                                  0x01, 0x00, 0x00, 0x00)
     };
 
-    return ecp_mod_koblitz(N->p, N->n, Rp, 192);
+    if (X_limbs != 2 * ((192 + biL - 1) / biL)) {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    return ecp_mod_koblitz(X, X_limbs, Rp, 192);
 }
 
 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
 
+/*
+ * Fast quasi-reduction modulo p224k1 = 2^224 - R,
+ * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
+ */
 static int ecp_mod_p224k1(mbedtls_mpi *N)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t expected_width =  2 * 224 / biL;
     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
-    ret = mbedtls_ecp_mod_p224k1(N);
+    ret = mbedtls_ecp_mod_p224k1_raw(N->p, expected_width);
 
 cleanup:
     return ret;
 }
 
-/*
- * Fast quasi-reduction modulo p224k1 = 2^224 - R,
- * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
- */
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
 {
     static mbedtls_mpi_uint Rp[] = {
-        MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
-                                  0x00)
+        MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00,
+                                  0x01, 0x00, 0x00, 0x00)
     };
 
-    return ecp_mod_koblitz(N->p, N->n, Rp, 224);
+    if (X_limbs != 2 * 224 / biL) {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    return ecp_mod_koblitz(X, X_limbs, Rp, 224);
 }
 
 #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
 
+/*
+ * Fast quasi-reduction modulo p256k1 = 2^256 - R,
+ * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
+ */
 static int ecp_mod_p256k1(mbedtls_mpi *N)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t expected_width = 2 * ((256 + biL - 1) / biL);
     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
-    ret = mbedtls_ecp_mod_p256k1(N);
+    ret = mbedtls_ecp_mod_p256k1_raw(N->p, expected_width);
 
 cleanup:
     return ret;
 }
 
-/*
- * Fast quasi-reduction modulo p256k1 = 2^256 - R,
- * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
- */
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
 {
     static mbedtls_mpi_uint Rp[] = {
-        MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
-                                  0x00)
+        MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00,
+                                  0x01, 0x00, 0x00, 0x00)
     };
-    return ecp_mod_koblitz(N->p, N->n, Rp, 256);
+
+    if (X_limbs != 2 * ((256 + biL - 1) / biL)) {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    return ecp_mod_koblitz(X, X_limbs, Rp, 256);
 }
+
 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
 
 #if defined(MBEDTLS_TEST_HOOKS)
diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h
index 68187ac..aadcdbc 100644
--- a/library/ecp_invasive.h
+++ b/library/ecp_invasive.h
@@ -171,25 +171,73 @@
 
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
 
-/*
- * Fast quasi-reduction modulo p192k1 = 2^192 - R,
- * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
+/** Fast quasi-reduction modulo p192k1 = 2^192 - R,
+ * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
+ *
+ * \param[in,out]   X       The address of the MPI to be converted.
+ *                          Must have exact limb size that stores a 384-bit MPI
+ *                          (double the bitlength of the modulus).
+ *                          Upon return holds the reduced value which is
+ *                          in range `0 <= X < 2 * N` (where N is the modulus).
+ *                          The bitlength of the reduced value is the same as
+ *                          that of the modulus (192 bits).
+ * \param[in]       X_limbs The length of \p X in limbs.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ *                  twice as many limbs as the modulus.
+ * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
  */
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
 
 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+
 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
 
+/** Fast quasi-reduction modulo p224k1 = 2^224 - R,
+ * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
+ *
+ * \param[in,out]   X       The address of the MPI to be converted.
+ *                          Must have exact limb size that stores a 448-bit MPI
+ *                          (double the bitlength of the modulus).
+ *                          Upon return holds the reduced value which is
+ *                          in range `0 <= X < 2 * N` (where N is the modulus).
+ *                          The bitlength of the reduced value is the same as
+ *                          that of the modulus (224 bits).
+ * \param[in]       X_limbs The length of \p X in limbs.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ *                  twice as many limbs as the modulus.
+ * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
+ */
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
 
 #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
 
+/** Fast quasi-reduction modulo p256k1 = 2^256 - R,
+ * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
+ *
+ * \param[in,out]   X       The address of the MPI to be converted.
+ *                          Must have exact limb size that stores a 512-bit MPI
+ *                          (double the bitlength of the modulus).
+ *                          Upon return holds the reduced value which is
+ *                          in range `0 <= X < 2 * N` (where N is the modulus).
+ *                          The bitlength of the reduced value is the same as
+ *                          that of the modulus (256 bits).
+ * \param[in]       X_limbs The length of \p X in limbs.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ *                  twice as many limbs as the modulus.
+ * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
+ */
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
 
 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
 
diff --git a/library/pk.c b/library/pk.c
index 7e77282..9c4aa16 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -64,6 +64,12 @@
 #if defined(MBEDTLS_PSA_CRYPTO_C)
     ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
 #endif /* MBEDTLS_PSA_CRYPTO_C */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw));
+    ctx->pub_raw_len = 0;
+    ctx->ec_family = 0;
+    ctx->ec_bits = 0;
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
 }
 
 /*
@@ -190,6 +196,42 @@
 }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+int mbedtls_pk_update_public_key_from_keypair(mbedtls_pk_context *pk,
+                                              mbedtls_ecp_keypair *ecp_keypair)
+{
+    int ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
+
+    if (pk == NULL) {
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+    }
+    /* The raw public key storing mechanism is only supported for EC keys so
+     * we fail silently for other ones. */
+    if ((pk->pk_info->type != MBEDTLS_PK_ECKEY) &&
+        (pk->pk_info->type != MBEDTLS_PK_ECKEY_DH) &&
+        (pk->pk_info->type != MBEDTLS_PK_ECDSA)) {
+        return 0;
+    }
+
+    ret = mbedtls_ecp_point_write_binary(&ecp_keypair->grp, &ecp_keypair->Q,
+                                         MBEDTLS_ECP_PF_UNCOMPRESSED,
+                                         &pk->pub_raw_len,
+                                         pk->pub_raw,
+                                         MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
+    if (ret != 0) {
+        return ret;
+    }
+
+    pk->ec_family = mbedtls_ecc_group_to_psa(ecp_keypair->grp.id,
+                                             &pk->ec_bits);
+    if (pk->ec_family == 0) {
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+    }
+
+    return 0;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
 /*
  * Initialize an RSA-alt context
diff --git a/library/pk_internal.h b/library/pk_internal.h
index 7c4f285..dbb7bc1 100644
--- a/library/pk_internal.h
+++ b/library/pk_internal.h
@@ -23,18 +23,24 @@
 #ifndef MBEDTLS_PK_INTERNAL_H
 #define MBEDTLS_PK_INTERNAL_H
 
+#include "mbedtls/pk.h"
+
 #if defined(MBEDTLS_ECP_LIGHT)
 #include "mbedtls/ecp.h"
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif
+
 #if defined(MBEDTLS_ECP_LIGHT)
 /**
  * Public function mbedtls_pk_ec() can be used to get direct access to the
- * wrapped ecp_keypair strucure pointed to the pk_ctx. However this is not
- * ideal because it bypasses the PK module on the control of its internal's
+ * wrapped ecp_keypair structure pointed to the pk_ctx. However this is not
+ * ideal because it bypasses the PK module on the control of its internal
  * structure (pk_context) fields.
  * For backward compatibility we keep mbedtls_pk_ec() when ECP_C is defined, but
- * we provide 2 very similar function when only ECP_LIGHT is enabled and not
+ * we provide 2 very similar functions when only ECP_LIGHT is enabled and not
  * ECP_C.
  * These variants embed the "ro" or "rw" keywords in their name to make the
  * usage of the returned pointer explicit. Of course the returned value is
@@ -63,6 +69,41 @@
             return NULL;
     }
 }
+
+/* Helpers for Montgomery curves */
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_PK_HAVE_RFC8410_CURVES
+
+static inline int mbedtls_pk_is_rfc8410_curve(mbedtls_ecp_group_id id)
+{
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+    if (id == MBEDTLS_ECP_DP_CURVE25519) {
+        return 1;
+    }
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+    if (id == MBEDTLS_ECP_DP_CURVE448) {
+        return 1;
+    }
+#endif
+    return 0;
+}
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED || MBEDTLS_ECP_DP_CURVE448_ENABLED */
 #endif /* MBEDTLS_ECP_LIGHT */
 
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/**
+ * \brief   Copy the public key content in raw format from "ctx->pk_ctx"
+ *          (which is an ecp_keypair) into the internal "ctx->pub_raw" buffer.
+ *
+ * \note    This is a temporary function that can be removed as soon as the pk
+ *          module is free from ECP_C
+ *
+ * \param pk   It is the pk_context which is going to be updated. It acts both
+ *             as input and output.
+ */
+int mbedtls_pk_update_public_key_from_keypair(mbedtls_pk_context *pk,
+                                              mbedtls_ecp_keypair *ecp_keypair);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
 #endif /* MBEDTLS_PK_INTERNAL_H */
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 0e5e120..3a3d399 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -23,6 +23,7 @@
 
 #if defined(MBEDTLS_PK_C)
 #include "pk_wrap.h"
+#include "pk_internal.h"
 #include "mbedtls/error.h"
 
 /* Even if RSA not activated, for the sake of RSA-alt */
@@ -653,8 +654,12 @@
 
 static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
 {
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    return pk->ec_bits;
+#else
     mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
     return ecp->grp.pbits;
+#endif
 }
 
 #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
@@ -724,11 +729,20 @@
                              const unsigned char *hash, size_t hash_len,
                              const unsigned char *sig, size_t sig_len)
 {
-    mbedtls_ecp_keypair *ctx = pk->pk_ctx;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
     psa_status_t status;
+    unsigned char *p;
+    psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
+    size_t signature_len;
+    ((void) md_alg);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    unsigned char buf[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
+    psa_ecc_family_t curve = pk->ec_family;
+    size_t curve_bits = pk->ec_bits;
+#else
+    mbedtls_ecp_keypair *ctx = pk->pk_ctx;
     size_t key_len;
     /* This buffer will initially contain the public key and then the signature
      * but at different points in time. For all curves except secp224k1, which
@@ -736,13 +750,10 @@
      * (header byte + 2 numbers, while the signature is only 2 numbers),
      * so use that as the buffer size. */
     unsigned char buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
-    unsigned char *p;
-    psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
     size_t curve_bits;
     psa_ecc_family_t curve =
         mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
-    const size_t signature_part_size = (ctx->grp.nbits + 7) / 8;
-    ((void) md_alg);
+#endif
 
     if (curve == 0) {
         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@@ -752,6 +763,11 @@
     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
     psa_set_key_algorithm(&attributes, psa_sig_md);
 
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    status = psa_import_key(&attributes,
+                            pk->pub_raw, pk->pub_raw_len,
+                            &key_id);
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
     ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q,
                                          MBEDTLS_ECP_PF_UNCOMPRESSED,
                                          &key_len, buf, sizeof(buf));
@@ -762,27 +778,30 @@
     status = psa_import_key(&attributes,
                             buf, key_len,
                             &key_id);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
     if (status != PSA_SUCCESS) {
         ret = PSA_PK_TO_MBEDTLS_ERR(status);
         goto cleanup;
     }
 
-    /* We don't need the exported key anymore and can
-     * reuse its buffer for signature extraction. */
-    if (2 * signature_part_size > sizeof(buf)) {
+    signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
+    if (signature_len > sizeof(buf)) {
         ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
         goto cleanup;
     }
 
     p = (unsigned char *) sig;
+    /* extract_ecdsa_sig's last parameter is the size
+     * of each integer to be parsed, so it's actually half
+     * the size of the signature. */
     if ((ret = extract_ecdsa_sig(&p, sig + sig_len, buf,
-                                 signature_part_size)) != 0) {
+                                 signature_len/2)) != 0) {
         goto cleanup;
     }
 
     status = psa_verify_hash(key_id, psa_sig_md,
                              hash, hash_len,
-                             buf, 2 * signature_part_size);
+                             buf, signature_len);
     if (status != PSA_SUCCESS) {
         ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
         goto cleanup;
@@ -1112,26 +1131,34 @@
 {
     psa_status_t status, destruction_status;
     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
-    mbedtls_ecp_keypair *prv_ctx = prv->pk_ctx;
-    mbedtls_ecp_keypair *pub_ctx = pub->pk_ctx;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     /* We are using MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH for the size of this
      * buffer because it will be used to hold the private key at first and
      * then its public part (but not at the same time). */
     uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
     size_t prv_key_len;
+    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    const psa_ecc_family_t curve = prv->ec_family;
+    const size_t curve_bits = prv->ec_bits;
+#else /* !MBEDTLS_PK_USE_PSA_EC_DATA */
     uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
     size_t pub_key_len;
-    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
     size_t curve_bits;
     const psa_ecc_family_t curve =
-        mbedtls_ecc_group_to_psa(prv_ctx->grp.id, &curve_bits);
+        mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits);
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
     const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
 
+    if (curve == 0) {
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+    }
+
     psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
     psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
 
-    ret = mbedtls_mpi_write_binary(&prv_ctx->d, prv_key_buf, curve_bytes);
+    ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d,
+                                   prv_key_buf, curve_bytes);
     if (ret != 0) {
         return ret;
     }
@@ -1154,7 +1181,13 @@
         return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
     }
 
-    ret = mbedtls_ecp_point_write_binary(&pub_ctx->grp, &pub_ctx->Q,
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) {
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+    }
+#else
+    ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp,
+                                         &mbedtls_pk_ec_rw(*pub)->Q,
                                          MBEDTLS_ECP_PF_UNCOMPRESSED,
                                          &pub_key_len, pub_key_buf,
                                          sizeof(pub_key_buf));
@@ -1165,6 +1198,7 @@
     if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     }
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
 
     return 0;
 }
@@ -1206,10 +1240,16 @@
 
 static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
 {
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    items->type = MBEDTLS_PK_DEBUG_PSA_EC;
+    items->name = "eckey.Q";
+    items->value = pk;
+#else
     mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
     items->type = MBEDTLS_PK_DEBUG_ECP;
     items->name = "eckey.Q";
     items->value = &(ecp->Q);
+#endif
 }
 
 const mbedtls_pk_info_t mbedtls_eckey_info = {
diff --git a/library/pkparse.c b/library/pkparse.c
index 87b707d..9bc8801 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -37,6 +37,9 @@
 #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
 #include "pkwrite.h"
 #endif
+#if defined(MBEDTLS_ECP_LIGHT)
+#include "pk_internal.h"
+#endif
 #if defined(MBEDTLS_ECDSA_C)
 #include "mbedtls/ecdsa.h"
 #endif
@@ -455,6 +458,29 @@
 }
 #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
 
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/* Functions pk_use_ecparams() and pk_use_ecparams_rfc8410() update the
+ * ecp_keypair structure with proper group ID. The purpose of this helper
+ * function is to update ec_family and ec_bits accordingly. */
+static int pk_update_psa_ecparams(mbedtls_pk_context *pk,
+                                  mbedtls_ecp_group_id grp_id)
+{
+    psa_ecc_family_t ec_family;
+    size_t bits;
+
+    ec_family = mbedtls_ecc_group_to_psa(grp_id, &bits);
+
+    if ((pk->ec_family != 0) && (pk->ec_family != ec_family)) {
+        return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
+    }
+
+    pk->ec_family = ec_family;
+    pk->ec_bits = bits;
+
+    return 0;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
 /*
  * Use EC parameters to initialise an EC group
  *
@@ -463,7 +489,7 @@
  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
  *   -- implicitCurve   NULL
  */
-static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp)
+static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *pk)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_group_id grp_id;
@@ -482,39 +508,41 @@
 #endif
     }
 
-    /*
-     * grp may already be initialized; if so, make sure IDs match
-     */
-    if (grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id) {
+    /* grp may already be initialized; if so, make sure IDs match */
+    if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
+        mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
     }
 
-    if ((ret = mbedtls_ecp_group_load(grp, grp_id)) != 0) {
+    if ((ret = mbedtls_ecp_group_load(&(mbedtls_pk_ec_rw(*pk)->grp),
+                                      grp_id)) != 0) {
         return ret;
     }
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    ret = pk_update_psa_ecparams(pk, grp_id);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
 
-    return 0;
+    return ret;
 }
 
-#if defined(MBEDTLS_ECP_LIGHT)
 /*
  * Helper function for deriving a public key from its private counterpart.
  */
-static int pk_derive_public_key(mbedtls_ecp_keypair *eck,
+static int pk_derive_public_key(mbedtls_pk_context *pk,
                                 const unsigned char *d, size_t d_len,
                                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
 {
     int ret;
+    mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status, destruction_status;
     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
     size_t curve_bits;
     psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
-    /* This buffer is used to store the private key at first and then the
-     * public one (but not at the same time). Therefore we size it for the
-     * latter since it's bigger. */
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     unsigned char key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
     size_t key_len;
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
 
     (void) f_rng;
@@ -529,9 +557,12 @@
         return ret;
     }
 
-    mbedtls_platform_zeroize(key_buf, sizeof(key_buf));
-
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    status = psa_export_public_key(key_id, pk->pub_raw, sizeof(pk->pub_raw),
+                                   &pk->pub_raw_len);
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
     status = psa_export_public_key(key_id, key_buf, sizeof(key_buf), &key_len);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
     ret = psa_pk_status_to_mbedtls(status);
     destruction_status = psa_destroy_key(key_id);
     if (ret != 0) {
@@ -539,8 +570,9 @@
     } else if (destruction_status != PSA_SUCCESS) {
         return psa_pk_status_to_mbedtls(destruction_status);
     }
-
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     ret = mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, key_buf, key_len);
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
 #else /* MBEDTLS_USE_PSA_CRYPTO */
     (void) d;
     (void) d_len;
@@ -557,13 +589,24 @@
  */
 static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params,
                                    mbedtls_ecp_group_id grp_id,
-                                   mbedtls_ecp_group *grp)
+                                   mbedtls_pk_context *pk)
 {
+    mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
+    int ret;
+
     if (params->tag != 0 || params->len != 0) {
         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
     }
 
-    return mbedtls_ecp_group_load(grp, grp_id);
+    ret = mbedtls_ecp_group_load(&(ecp->grp), grp_id);
+    if (ret != 0) {
+        return ret;
+    }
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    ret = pk_update_psa_ecparams(pk, grp_id);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+    return ret;
 }
 
 /*
@@ -571,10 +614,11 @@
  *
  * CurvePrivateKey ::= OCTET STRING
  */
-static int pk_parse_key_rfc8410_der(mbedtls_ecp_keypair *eck,
+static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
                                     unsigned char *key, size_t keylen, const unsigned char *end,
                                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
 {
+    mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t len;
 
@@ -591,10 +635,10 @@
         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     }
 
-    // pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
-    // which never contain a public key. As such, derive the public key
-    // unconditionally.
-    if ((ret = pk_derive_public_key(eck, key, len, f_rng, p_rng)) != 0) {
+    /* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
+     * which never contain a public key. As such, derive the public key
+     * unconditionally. */
+    if ((ret = pk_derive_public_key(pk, key, len, f_rng, p_rng)) != 0) {
         mbedtls_ecp_keypair_free(eck);
         return ret;
     }
@@ -607,7 +651,42 @@
     return 0;
 }
 #endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-#endif /* MBEDTLS_ECP_LIGHT */
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/*
+ * Create a temporary ecp_keypair for converting an EC point in compressed
+ * format to an uncompressed one
+ */
+static int pk_convert_compressed_ec(mbedtls_pk_context *pk,
+                                    const unsigned char *in_start, size_t in_len,
+                                    size_t *out_buf_len, unsigned char *out_buf,
+                                    size_t out_buf_size)
+{
+    mbedtls_ecp_keypair ecp_key;
+    mbedtls_ecp_group_id ecp_group_id;
+    int ret;
+
+    ecp_group_id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
+
+    mbedtls_ecp_keypair_init(&ecp_key);
+    ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
+    if (ret != 0) {
+        return ret;
+    }
+    ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
+                                        in_start, in_len);
+    if (ret != 0) {
+        goto exit;
+    }
+    ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
+                                         MBEDTLS_ECP_PF_UNCOMPRESSED,
+                                         out_buf_len, out_buf, out_buf_size);
+
+exit:
+    mbedtls_ecp_keypair_free(&ecp_key);
+    return ret;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
 
 /*
  * EC public key is an EC point
@@ -617,15 +696,61 @@
  * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
  */
 static int pk_get_ecpubkey(unsigned char **p, const unsigned char *end,
-                           mbedtls_ecp_keypair *key)
+                           mbedtls_pk_context *pk)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if ((ret = mbedtls_ecp_point_read_binary(&key->grp, &key->Q,
-                                             (const unsigned char *) *p, end - *p)) == 0) {
-        ret = mbedtls_ecp_check_pubkey(&key->grp, &key->Q);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    mbedtls_svc_key_id_t key;
+    psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
+    size_t len = (end - *p);
+
+    if (len > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) {
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     }
 
+    /* Compressed point format are not supported yet by PSA crypto. As a
+     * consequence ecp functions are used to "convert" the point to
+     * uncompressed format */
+    if ((**p == 0x02) || (**p == 0x03)) {
+        ret = pk_convert_compressed_ec(pk, *p, len,
+                                       &(pk->pub_raw_len), pk->pub_raw,
+                                       PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
+        if (ret != 0) {
+            return ret;
+        }
+    } else {
+        /* Uncompressed format */
+        if ((end - *p) > MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN) {
+            return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
+        }
+        memcpy(pk->pub_raw, *p, (end - *p));
+        pk->pub_raw_len = end - *p;
+    }
+
+    /* Validate the key by trying to importing it */
+    psa_set_key_usage_flags(&key_attrs, 0);
+    psa_set_key_algorithm(&key_attrs, PSA_ALG_ECDSA_ANY);
+    psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
+    psa_set_key_bits(&key_attrs, pk->ec_bits);
+
+    if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
+                        &key) != PSA_SUCCESS) ||
+        (psa_destroy_key(key) != PSA_SUCCESS)) {
+        mbedtls_platform_zeroize(pk->pub_raw, MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
+        pk->pub_raw_len = 0;
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+    }
+    ret = 0;
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+    mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
+    if ((ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q,
+                                             (const unsigned char *) *p,
+                                             end - *p)) == 0) {
+        ret = mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
+    }
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
     /*
      * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
      */
@@ -796,14 +921,14 @@
     if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) {
 #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
         if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
-            ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, &mbedtls_pk_ec_rw(*pk)->grp);
+            ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, pk);
         } else
 #endif
         {
-            ret = pk_use_ecparams(&alg_params, &mbedtls_pk_ec_rw(*pk)->grp);
+            ret = pk_use_ecparams(&alg_params, pk);
         }
         if (ret == 0) {
-            ret = pk_get_ecpubkey(p, end, mbedtls_pk_ec_rw(*pk));
+            ret = pk_get_ecpubkey(p, end, pk);
         }
     } else
 #endif /* MBEDTLS_ECP_LIGHT */
@@ -1014,7 +1139,7 @@
 /*
  * Parse a SEC1 encoded private EC key
  */
-static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
+static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
                                  const unsigned char *key, size_t keylen,
                                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
 {
@@ -1026,6 +1151,7 @@
     unsigned char *d;
     unsigned char *end = p + keylen;
     unsigned char *end2;
+    mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
 
     /*
      * RFC 5915, or SEC1 Appendix C.4
@@ -1074,7 +1200,7 @@
                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
                                         0)) == 0) {
             if ((ret = pk_get_ecparams(&p, p + len, &params)) != 0 ||
-                (ret = pk_use_ecparams(&params, &eck->grp)) != 0) {
+                (ret = pk_use_ecparams(&params, pk)) != 0) {
                 mbedtls_ecp_keypair_free(eck);
                 return ret;
             }
@@ -1103,7 +1229,7 @@
                                          MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
             }
 
-            if ((ret = pk_get_ecpubkey(&p, end2, eck)) == 0) {
+            if ((ret = pk_get_ecpubkey(&p, end2, pk)) == 0) {
                 pubkey_done = 1;
             } else {
                 /*
@@ -1121,7 +1247,7 @@
     }
 
     if (!pubkey_done) {
-        if ((ret = pk_derive_public_key(eck, d, d_len, f_rng, p_rng)) != 0) {
+        if ((ret = pk_derive_public_key(pk, d, d_len, f_rng, p_rng)) != 0) {
             mbedtls_ecp_keypair_free(eck);
             return ret;
         }
@@ -1232,10 +1358,10 @@
     if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) {
 #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
         if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
-            if ((ret = pk_use_ecparams_rfc8410(&params, ec_grp_id,
-                                               &mbedtls_pk_ec_rw(*pk)->grp)) != 0 ||
+            if ((ret =
+                     pk_use_ecparams_rfc8410(&params, ec_grp_id, pk)) != 0 ||
                 (ret =
-                     pk_parse_key_rfc8410_der(mbedtls_pk_ec_rw(*pk), p, len, end, f_rng,
+                     pk_parse_key_rfc8410_der(pk, p, len, end, f_rng,
                                               p_rng)) != 0) {
                 mbedtls_pk_free(pk);
                 return ret;
@@ -1243,8 +1369,8 @@
         } else
 #endif
         {
-            if ((ret = pk_use_ecparams(&params, &mbedtls_pk_ec_rw(*pk)->grp)) != 0 ||
-                (ret = pk_parse_key_sec1_der(mbedtls_pk_ec_rw(*pk), p, len, f_rng, p_rng)) != 0) {
+            if ((ret = pk_use_ecparams(&params, pk)) != 0 ||
+                (ret = pk_parse_key_sec1_der(pk, p, len, f_rng, p_rng)) != 0) {
                 mbedtls_pk_free(pk);
                 return ret;
             }
@@ -1431,7 +1557,7 @@
         pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
 
         if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
-            (ret = pk_parse_key_sec1_der(mbedtls_pk_ec_rw(*pk),
+            (ret = pk_parse_key_sec1_der(pk,
                                          pem.buf, pem.buflen,
                                          f_rng, p_rng)) != 0) {
             mbedtls_pk_free(pk);
@@ -1555,18 +1681,18 @@
 #if defined(MBEDTLS_ECP_LIGHT)
     pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
     if (mbedtls_pk_setup(pk, pk_info) == 0 &&
-        pk_parse_key_sec1_der(mbedtls_pk_ec_rw(*pk),
+        pk_parse_key_sec1_der(pk,
                               key, keylen, f_rng, p_rng) == 0) {
         return 0;
     }
     mbedtls_pk_free(pk);
 #endif /* MBEDTLS_ECP_LIGHT */
 
-    /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
+    /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_LIGHT isn't,
      * it is ok to leave the PK context initialized but not
      * freed: It is the caller's responsibility to call pk_init()
      * before calling this function, and to call pk_free()
-     * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
+     * when it fails. If MBEDTLS_ECP_LIGHT is defined but MBEDTLS_RSA_C
      * isn't, this leads to mbedtls_pk_free() being called
      * twice, once here and once by the caller, but this is
      * also ok and in line with the mbedtls_pk_free() calls
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 1f606a4..3577fa1 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -38,7 +38,10 @@
 #include "mbedtls/ecp.h"
 #include "mbedtls/platform_util.h"
 #endif
-#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
+#if defined(MBEDTLS_ECP_LIGHT)
+#include "pk_internal.h"
+#endif
+#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_LIGHT)
 #include "pkwrite.h"
 #endif
 #if defined(MBEDTLS_ECDSA_C)
@@ -100,15 +103,24 @@
 #endif /* MBEDTLS_RSA_C */
 
 #if defined(MBEDTLS_ECP_LIGHT)
-/*
- * EC public key is an EC point
- */
 static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
-                              mbedtls_ecp_keypair *ec)
+                              const mbedtls_pk_context *pk)
 {
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t len = 0;
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    len = pk->pub_raw_len;
+
+    if (*p < start || (size_t) (*p - start) < len) {
+        return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+    }
+
+    memcpy(*p - len, pk->pub_raw, len);
+    *p -= len;
+#else
     unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
+    mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
     if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
                                               MBEDTLS_ECP_PF_UNCOMPRESSED,
@@ -122,6 +134,7 @@
 
     *p -= len;
     memcpy(*p, buf, len);
+#endif
 
     return (int) len;
 }
@@ -183,7 +196,7 @@
 #endif
 #if defined(MBEDTLS_ECP_LIGHT)
     if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
-        MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, mbedtls_pk_ec_rw(*key)));
+        MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key));
     } else
 #endif
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -324,7 +337,7 @@
 #if defined(MBEDTLS_ECP_LIGHT)
 #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
 /*
- * RFC8410
+ * RFC8410 section 7
  *
  * OneAsymmetricKey ::= SEQUENCE {
  *    version Version,
@@ -335,7 +348,7 @@
  *    [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
  *    ...
  * }
- *
+ * ...
  * CurvePrivateKey ::= OCTET STRING
  */
 static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf,
@@ -491,7 +504,7 @@
          */
 
         /* publicKey */
-        MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(&c, buf, ec));
+        MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(&c, buf, key));
 
         if (c - buf < 1) {
             return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
@@ -527,7 +540,7 @@
         MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED |
                                                          MBEDTLS_ASN1_SEQUENCE));
     } else
-#endif /* MBEDTLS_ECP_C */
+#endif /* MBEDTLS_ECP_LIGHT */
     return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
 
     return (int) len;
diff --git a/library/pkwrite.h b/library/pkwrite.h
index 537bd0f..8db2333 100644
--- a/library/pkwrite.h
+++ b/library/pkwrite.h
@@ -73,7 +73,7 @@
 
 #endif /* MBEDTLS_RSA_C */
 
-#if defined(MBEDTLS_ECP_C)
+#if defined(MBEDTLS_ECP_LIGHT)
 /*
  * EC public keys:
  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {      1 + 2
@@ -98,34 +98,10 @@
  */
 #define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES    (29 + 3 * MBEDTLS_ECP_MAX_BYTES)
 
-#else /* MBEDTLS_ECP_C */
+#else /* MBEDTLS_ECP_LIGHT */
 
 #define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES   0
 #define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES   0
 
-#endif /* MBEDTLS_ECP_C */
-
-#if defined(MBEDTLS_ECP_LIGHT)
-#include "mbedtls/ecp.h"
-
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
-#define MBEDTLS_PK_HAVE_RFC8410_CURVES
-
-static inline int mbedtls_pk_is_rfc8410_curve(mbedtls_ecp_group_id id)
-{
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
-    if (id == MBEDTLS_ECP_DP_CURVE25519) {
-        return 1;
-    }
-#endif
-#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
-    if (id == MBEDTLS_ECP_DP_CURVE448) {
-        return 1;
-    }
-#endif
-    return 0;
-}
-#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED || MBEDTLS_ECP_DP_CURVE448_ENABLED */
 #endif /* MBEDTLS_ECP_LIGHT */
-
 #endif /* MBEDTLS_PK_WRITE_H */
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index ba25389..6d54300 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -364,10 +364,7 @@
     cur_time = ctx->serial;
 #endif
 
-    cookie_time = ((unsigned long) cookie[0] << 24) |
-                  ((unsigned long) cookie[1] << 16) |
-                  ((unsigned long) cookie[2] <<  8) |
-                  ((unsigned long) cookie[3]);
+    cookie_time = (unsigned long) MBEDTLS_GET_UINT32_BE(cookie, 0);
 
     if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) {
         ret = -1;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index fe666e8..be7742f 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4613,10 +4613,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    session_len = ((size_t) p[0] << 24) |
-                  ((size_t) p[1] << 16) |
-                  ((size_t) p[2] <<  8) |
-                  ((size_t) p[3]);
+    session_len = MBEDTLS_GET_UINT32_BE(p, 0);
     p += 4;
 
     /* This has been allocated by ssl_handshake_init(), called by
@@ -4711,10 +4708,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    ssl->badmac_seen = ((uint32_t) p[0] << 24) |
-                       ((uint32_t) p[1] << 16) |
-                       ((uint32_t) p[2] <<  8) |
-                       ((uint32_t) p[3]);
+    ssl->badmac_seen = MBEDTLS_GET_UINT32_BE(p, 0);
     p += 4;
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
@@ -4722,24 +4716,10 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    ssl->in_window_top = ((uint64_t) p[0] << 56) |
-                         ((uint64_t) p[1] << 48) |
-                         ((uint64_t) p[2] << 40) |
-                         ((uint64_t) p[3] << 32) |
-                         ((uint64_t) p[4] << 24) |
-                         ((uint64_t) p[5] << 16) |
-                         ((uint64_t) p[6] <<  8) |
-                         ((uint64_t) p[7]);
+    ssl->in_window_top = MBEDTLS_GET_UINT64_BE(p, 0);
     p += 8;
 
-    ssl->in_window = ((uint64_t) p[0] << 56) |
-                     ((uint64_t) p[1] << 48) |
-                     ((uint64_t) p[2] << 40) |
-                     ((uint64_t) p[3] << 32) |
-                     ((uint64_t) p[4] << 24) |
-                     ((uint64_t) p[5] << 16) |
-                     ((uint64_t) p[6] <<  8) |
-                     ((uint64_t) p[7]);
+    ssl->in_window = MBEDTLS_GET_UINT64_BE(p, 0);
     p += 8;
 #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
 
@@ -9102,14 +9082,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    start = ((uint64_t) p[0] << 56) |
-            ((uint64_t) p[1] << 48) |
-            ((uint64_t) p[2] << 40) |
-            ((uint64_t) p[3] << 32) |
-            ((uint64_t) p[4] << 24) |
-            ((uint64_t) p[5] << 16) |
-            ((uint64_t) p[6] <<  8) |
-            ((uint64_t) p[7]);
+    start = MBEDTLS_GET_UINT64_BE(p, 0);
     p += 8;
 
     session->start = (time_t) start;
@@ -9132,10 +9105,7 @@
     memcpy(session->master, p, 48);
     p += 48;
 
-    session->verify_result = ((uint32_t) p[0] << 24) |
-                             ((uint32_t) p[1] << 16) |
-                             ((uint32_t) p[2] <<  8) |
-                             ((uint32_t) p[3]);
+    session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
     p += 4;
 
     /* Immediately clear invalid pointer values that have been read, in case
@@ -9254,10 +9224,7 @@
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    session->ticket_lifetime = ((uint32_t) p[0] << 24) |
-                               ((uint32_t) p[1] << 16) |
-                               ((uint32_t) p[2] <<  8) |
-                               ((uint32_t) p[3]);
+    session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
     p += 4;
 #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
 
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 0940bdb..070583b 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2010,7 +2010,6 @@
     peer_key = mbedtls_pk_ec_ro(*peer_pk);
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    size_t olen = 0;
     uint16_t tls_id = 0;
     psa_ecc_family_t ecc_family;
 
@@ -2034,6 +2033,12 @@
     ssl->handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family);
 
     /* Store peer's public key in psa format. */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    memcpy(ssl->handshake->ecdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len);
+    ssl->handshake->ecdh_psa_peerkey_len = peer_pk->pub_raw_len;
+    ret = 0;
+#else
+    size_t olen = 0;
     ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q,
                                          MBEDTLS_ECP_PF_UNCOMPRESSED, &olen,
                                          ssl->handshake->ecdh_psa_peerkey,
@@ -2043,8 +2048,8 @@
         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret);
         return ret;
     }
-
     ssl->handshake->ecdh_psa_peerkey_len = olen;
+#endif /* MBEDTLS_ECP_C */
 #else
     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key,
                                        MBEDTLS_ECDH_THEIRS)) != 0) {
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index aa3e306..a377d80 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -1088,9 +1088,7 @@
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
             /* This couldn't be done in ssl_prepare_handshake_record() */
-            unsigned int cli_msg_seq = (ssl->in_msg[4] << 8) |
-                                       ssl->in_msg[5];
-
+            unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
             if (cli_msg_seq != ssl->handshake->in_msg_seq) {
                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
                                           "%u (expected %u)", cli_msg_seq,
@@ -1102,8 +1100,7 @@
         } else
 #endif
         {
-            unsigned int cli_msg_seq = (ssl->in_msg[4] << 8) |
-                                       ssl->in_msg[5];
+            unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
             ssl->handshake->out_msg_seq = cli_msg_seq;
             ssl->handshake->in_msg_seq  = cli_msg_seq + 1;
         }
diff --git a/programs/psa/key_ladder_demo.sh b/programs/psa/key_ladder_demo.sh
index 67de085..e21d1ab 100755
--- a/programs/psa/key_ladder_demo.sh
+++ b/programs/psa/key_ladder_demo.sh
@@ -17,9 +17,27 @@
 
 set -e -u
 
-program="${0%/*}"/key_ladder_demo
+program_name="key_ladder_demo"
+program="${0%/*}/$program_name"
 files_to_clean=
 
+if [ ! -e "$program" ]; then
+    # Look for programs in the current directory and the directories above it
+    for dir in "." ".." "../.."; do
+        program="$dir/programs/psa/$program_name"
+        if [ -e "$program" ]; then
+            break
+        fi
+    done
+    if [ ! -e "$program" ]; then
+        echo "Could not find $program_name executable"
+
+        echo "If building out-of-tree, this script must be run" \
+             "from the project build directory."
+        exit 1
+    fi
+fi
+
 run () {
     echo
     echo "# $1"
diff --git a/programs/test/dlopen_demo.sh b/programs/test/dlopen_demo.sh
index 2dde3eb..a6a9022 100755
--- a/programs/test/dlopen_demo.sh
+++ b/programs/test/dlopen_demo.sh
@@ -20,8 +20,29 @@
 
 set -e -u
 
+program_name="dlopen"
 program_dir="${0%/*}"
-program="$program_dir/dlopen"
+program="$program_dir/$program_name"
+
+if [ ! -e "$program" ]; then
+    # Look for programs in the current directory and the directories above it
+    for dir in "." ".." "../.."; do
+        program_dir="$dir/programs/test"
+        program="$program_dir/$program_name"
+        if [ -e "$program" ]; then
+            break
+        fi
+    done
+    if [ ! -e "$program" ]; then
+        echo "Could not find $program_name program"
+
+        echo "Make sure that Mbed TLS is built as a shared library." \
+             "If building out-of-tree, this script must be run" \
+             "from the project build directory."
+        exit 1
+    fi
+fi
+
 top_dir="$program_dir/../.."
 library_dir="$top_dir/library"
 
diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py
index 5f0efcf..c9fb5e5 100644
--- a/scripts/mbedtls_dev/ecp.py
+++ b/scripts/mbedtls_dev/ecp.py
@@ -494,8 +494,8 @@
                    EcpTarget):
     """Test cases for ECP P192K1 fast reduction."""
     symbol = "-"
-    test_function = "ecp_mod_p192k1"
-    test_name = "ecp_mod_p192k1"
+    test_function = "ecp_mod_p_generic_raw"
+    test_name = "ecp_mod_p192k1_raw"
     input_style = "fixed"
     arity = 1
     dependencies = ["MBEDTLS_ECP_DP_SECP192K1_ENABLED"]
@@ -557,13 +557,17 @@
     def is_valid(self) -> bool:
         return True
 
+    def arguments(self):
+        args = super().arguments()
+        return  ["MBEDTLS_ECP_DP_SECP192K1"] + args
+
 
 class EcpP224K1Raw(bignum_common.ModOperationCommon,
                    EcpTarget):
     """Test cases for ECP P224 fast reduction."""
     symbol = "-"
-    test_function = "ecp_mod_p224k1"
-    test_name = "ecp_mod_p224k1"
+    test_function = "ecp_mod_p_generic_raw"
+    test_name = "ecp_mod_p224k1_raw"
     input_style = "fixed"
     arity = 1
     dependencies = ["MBEDTLS_ECP_DP_SECP224K1_ENABLED"]
@@ -582,7 +586,7 @@
         # 2^224 - 1
         "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
 
-        # Maximum canonical P224 multiplication result
+        # Maximum canonical P224K1 multiplication result
         ("fffffffffffffffffffffffffffffffffffffffffffffffdffffcad8"
          "00000000000000000000000000000000000000010000352802c26590"),
 
@@ -626,13 +630,17 @@
     def is_valid(self) -> bool:
         return True
 
+    def arguments(self):
+        args = super().arguments()
+        return  ["MBEDTLS_ECP_DP_SECP224K1"] + args
+
 
 class EcpP256K1Raw(bignum_common.ModOperationCommon,
                    EcpTarget):
     """Test cases for ECP P256 fast reduction."""
     symbol = "-"
-    test_function = "ecp_mod_p256k1"
-    test_name = "ecp_mod_p256k1"
+    test_function = "ecp_mod_p_generic_raw"
+    test_name = "ecp_mod_p256k1_raw"
     input_style = "fixed"
     arity = 1
     dependencies = ["MBEDTLS_ECP_DP_SECP256K1_ENABLED"]
@@ -651,9 +659,13 @@
         # 2^256 - 1
         "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
 
-        # Maximum canonical P256 multiplication result
-        ("fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85c0"
-         "00000000000000000000000000000000000000000000001000007a4000e9844"),
+        # Maximum canonical P256K1 multiplication result
+        ("fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85c"
+         "000000000000000000000000000000000000000000000001000007a4000e9844"),
+
+        # Test case for overflow during addition
+        ("0000fffffc2f000e90a0c86a0a63234e5ba641f43a7e4aecc4040e67ec850562"
+         "00000000000000000000000000000000000000000000000000000000585674fd"),
 
         # Test case for overflow during addition
         ("0000fffffc2f000e90a0c86a0a63234e5ba641f43a7e4aecc4040e67ec850562"
@@ -694,6 +706,10 @@
     def is_valid(self) -> bool:
         return True
 
+    def arguments(self):
+        args = super().arguments()
+        return  ["MBEDTLS_ECP_DP_SECP256K1"] + args
+
 
 class EcpP448Raw(bignum_common.ModOperationCommon,
                  EcpTarget):
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 2bc17fb..3d2d5dc 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -41,8 +41,8 @@
 test_ca_pwd_rsa = PolarSSLTest
 test_ca_config_file = test-ca.opensslconf
 
-$(test_ca_key_file_rsa):$(test_ca_pwd_rsa)
-    $(OPENSSL) genrsa -aes-128-cbc -passout pass:$< -out $@ 2048
+$(test_ca_key_file_rsa):
+	$(OPENSSL) genrsa -aes-128-cbc -passout pass:$(test_ca_pwd_rsa) -out $@ 2048
 all_final += $(test_ca_key_file_rsa)
 
 test-ca.req.sha256: $(test_ca_key_file_rsa)
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index da91f44..b961040 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -167,11 +167,11 @@
     mbedtls_ssl_config conf;
     struct buffer_data buffer;
 
-    MD_PSA_INIT();
-
     mbedtls_ssl_init(&ssl);
     mbedtls_ssl_config_init(&conf);
     mbedtls_x509_crt_init(&crt);
+    MD_OR_USE_PSA_INIT();
+
     memset(buffer.buf, 0, 2000);
     buffer.ptr = buffer.buf;
 
@@ -193,7 +193,7 @@
     mbedtls_x509_crt_free(&crt);
     mbedtls_ssl_free(&ssl);
     mbedtls_ssl_config_free(&conf);
-    MD_PSA_DONE();
+    MD_OR_USE_PSA_DONE();
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index dbb7b3c..eb85dc2 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1328,6 +1328,27 @@
             curve_func = &mbedtls_ecp_mod_p521_raw;
             break;
 #endif
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP192K1:
+            limbs = 2 * limbs_N;
+            curve_bits = 192;
+            curve_func = &mbedtls_ecp_mod_p192k1_raw;
+            break;
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP224K1:
+            limbs = 448 / biL;
+            curve_bits = 224;
+            curve_func = &mbedtls_ecp_mod_p224k1_raw;
+            break;
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP256K1:
+            limbs = 2 * limbs_N;
+            curve_bits = 256;
+            curve_func = &mbedtls_ecp_mod_p256k1_raw;
+            break;
+#endif
         default:
             mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__);
             goto exit;
@@ -1355,123 +1376,6 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP192K1_ENABLED */
-void ecp_mod_p192k1(char *input_N,
-                    char *input_X,
-                    char *result)
-{
-    mbedtls_mpi X;
-    mbedtls_mpi N;
-    mbedtls_mpi res;
-
-    mbedtls_mpi_init(&X);
-    mbedtls_mpi_init(&N);
-    mbedtls_mpi_init(&res);
-
-    TEST_EQUAL(mbedtls_test_read_mpi(&X,   input_X), 0);
-    TEST_EQUAL(mbedtls_test_read_mpi(&N,   input_N), 0);
-    TEST_EQUAL(mbedtls_test_read_mpi(&res, result),  0);
-
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
-
-    size_t limbs = N.n;
-    size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
-
-    TEST_EQUAL(X.n, 2 * limbs);
-    TEST_EQUAL(res.n, limbs);
-
-    TEST_EQUAL(mbedtls_ecp_mod_p192k1(&X), 0);
-    TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
-    TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 192);
-    ASSERT_COMPARE(X.p, bytes, res.p, bytes);
-
-exit:
-    mbedtls_mpi_free(&X);
-    mbedtls_mpi_free(&N);
-    mbedtls_mpi_free(&res);
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP224K1_ENABLED */
-void ecp_mod_p224k1(char *input_N,
-                    char *input_X,
-                    char *result)
-{
-    mbedtls_mpi X;
-    mbedtls_mpi N;
-    mbedtls_mpi res;
-
-    mbedtls_mpi_init(&X);
-    mbedtls_mpi_init(&N);
-    mbedtls_mpi_init(&res);
-
-    TEST_EQUAL(mbedtls_test_read_mpi(&X,   input_X), 0);
-    TEST_EQUAL(mbedtls_test_read_mpi(&N,   input_N), 0);
-    TEST_EQUAL(mbedtls_test_read_mpi(&res, result),  0);
-
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
-
-    size_t limbs = N.n;
-    size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
-
-    TEST_LE_U(X.n, 448 / biL);
-    TEST_EQUAL(res.n, limbs);
-
-    TEST_EQUAL(mbedtls_ecp_mod_p224k1(&X), 0);
-    TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
-    TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 224);
-    ASSERT_COMPARE(X.p, bytes, res.p, bytes);
-
-exit:
-    mbedtls_mpi_free(&X);
-    mbedtls_mpi_free(&N);
-    mbedtls_mpi_free(&res);
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP256K1_ENABLED */
-void ecp_mod_p256k1(char *input_N,
-                    char *input_X,
-                    char *result)
-{
-    mbedtls_mpi X;
-    mbedtls_mpi N;
-    mbedtls_mpi res;
-
-    mbedtls_mpi_init(&X);
-    mbedtls_mpi_init(&N);
-    mbedtls_mpi_init(&res);
-
-    TEST_EQUAL(mbedtls_test_read_mpi(&X,   input_X), 0);
-    TEST_EQUAL(mbedtls_test_read_mpi(&N,   input_N), 0);
-    TEST_EQUAL(mbedtls_test_read_mpi(&res, result),  0);
-
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
-    TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
-
-    size_t limbs = N.n;
-    size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
-
-    TEST_LE_U(X.n, 2 * limbs);
-    TEST_EQUAL(res.n, limbs);
-
-    TEST_EQUAL(mbedtls_ecp_mod_p256k1(&X), 0);
-    TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
-    TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 256);
-    ASSERT_COMPARE(X.p, bytes, res.p, bytes);
-
-exit:
-    mbedtls_mpi_free(&X);
-    mbedtls_mpi_free(&N);
-    mbedtls_mpi_free(&res);
-}
-/* END_CASE */
-
 /* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_CURVE448_ENABLED */
 void ecp_mod_p448(char *input_N,
                   char *input_X,
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index f36c6be..7227f92 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -1,5 +1,6 @@
 /* BEGIN_HEADER */
 #include "mbedtls/pk.h"
+#include "pk_internal.h"
 
 /* For error codes */
 #include "mbedtls/asn1.h"
@@ -24,20 +25,23 @@
 #define RSA_KEY_SIZE 512
 #define RSA_KEY_LEN   64
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECP_LIGHT)
-static int pk_genkey_ec(mbedtls_ecp_group *grp,
-                        mbedtls_mpi *d, mbedtls_ecp_point *Q)
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+static int pk_genkey_ec(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
 {
     psa_status_t status;
+    mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
     size_t curve_bits;
-    psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(grp->id,
-                                                      &curve_bits);
+    psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(grp_id, &curve_bits);
     unsigned char key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
     size_t key_len;
     int ret;
 
+    if (curve == 0) {
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+    }
+
     psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
     psa_set_key_bits(&key_attr, curve_bits);
     psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
@@ -53,26 +57,33 @@
         goto exit;
     }
 
-    ret = mbedtls_mpi_read_binary(d, key_buf, key_len);
+    ret = mbedtls_mpi_read_binary(&eck->d, key_buf, key_len);
     if (ret != 0) {
         goto exit;
     }
 
-    status = psa_export_public_key(key_id, key_buf, sizeof(key_buf),
-                                   &key_len);
+    status = psa_export_public_key(key_id, pk->pub_raw, sizeof(pk->pub_raw),
+                                   &pk->pub_raw_len);
     if (status != PSA_SUCCESS) {
         ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
         goto exit;
     }
 
-    ret = mbedtls_ecp_point_read_binary(grp, Q, key_buf, key_len);
+    pk->ec_family = curve;
+    pk->ec_bits = curve_bits;
+
+    status = psa_destroy_key(key_id);
+    if (status != PSA_SUCCESS) {
+        return psa_pk_status_to_mbedtls(status);
+    }
+
+    return 0;
 
 exit:
-    psa_destroy_key(key_id);
-
-    return ret;
+    status = psa_destroy_key(key_id);
+    return (ret != 0) ? ret : psa_pk_status_to_mbedtls(status);
 }
-#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_ECP_LIGHT */
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
 
 /** Generate a key of the desired type.
  *
@@ -102,22 +113,36 @@
         mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY_DH ||
         mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECDSA) {
         int ret;
-        if ((ret = mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(*pk)->grp,
-                                          parameter)) != 0) {
+
+        ret = mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(*pk)->grp, parameter);
+        if (ret != 0) {
             return ret;
         }
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-        return pk_genkey_ec(&mbedtls_pk_ec_rw(*pk)->grp,
-                            &mbedtls_pk_ec_rw(*pk)->d,
-                            &mbedtls_pk_ec_rw(*pk)->Q);
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+        mbedtls_ecp_group grp;
+        /* Duplicating the mbedtls_ecp_group_load call to make this part
+         * more future future proof for when ECP_C will not be defined. */
+        mbedtls_ecp_group_init(&grp);
+        ret = mbedtls_ecp_group_load(&grp, parameter);
+        if (ret != 0) {
+            return ret;
+        }
+        ret = pk_genkey_ec(pk, grp.id);
+        if (ret != 0) {
+            return ret;
+        }
+        mbedtls_ecp_group_free(&grp);
+
+        return 0;
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
 #if defined(MBEDTLS_ECP_C)
         return mbedtls_ecp_gen_keypair(&mbedtls_pk_ec_rw(*pk)->grp,
                                        &mbedtls_pk_ec_rw(*pk)->d,
                                        &mbedtls_pk_ec_rw(*pk)->Q,
                                        mbedtls_test_rnd_std_rand, NULL);
 #endif /* MBEDTLS_ECP_C */
+
     }
 #endif /* MBEDTLS_ECP_LIGHT */
     return -1;
@@ -702,7 +727,6 @@
                     data_t *sig, int ret)
 {
     mbedtls_pk_context pk;
-    mbedtls_ecp_keypair *eckey;
 
     mbedtls_pk_init(&pk);
     USE_PSA_INIT();
@@ -710,11 +734,23 @@
     TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0);
 
     TEST_ASSERT(mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECDSA));
-    eckey = mbedtls_pk_ec_rw(pk);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+    mbedtls_ecp_keypair ecp;
+    mbedtls_ecp_keypair_init(&ecp);
+
+    TEST_ASSERT(mbedtls_ecp_group_load(&ecp.grp, id) == 0);
+    TEST_ASSERT(mbedtls_ecp_point_read_binary(&ecp.grp, &ecp.Q,
+                                              key->x, key->len) == 0);
+    TEST_ASSERT(mbedtls_pk_update_public_key_from_keypair(&pk, &ecp) == 0);
+
+    mbedtls_ecp_keypair_free(&ecp);
+#else
+    mbedtls_ecp_keypair *eckey = (mbedtls_ecp_keypair *) mbedtls_pk_ec(pk);
 
     TEST_ASSERT(mbedtls_ecp_group_load(&eckey->grp, id) == 0);
     TEST_ASSERT(mbedtls_ecp_point_read_binary(&eckey->grp, &eckey->Q,
                                               key->x, key->len) == 0);
+#endif
 
     // MBEDTLS_MD_NONE is used since it will be ignored.
     TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_NONE,
diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function
index e0e3300..a49b6d3 100644
--- a/tests/suites/test_suite_pkparse.function
+++ b/tests/suites/test_suite_pkparse.function
@@ -84,10 +84,16 @@
     TEST_ASSERT(res == result);
 
     if (res == 0) {
-        const mbedtls_ecp_keypair *eckey;
         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY));
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+        /* No need to check whether the parsed public point is on the curve or
+         * not because this is already done by the internal "pk_get_ecpubkey()"
+         * function */
+#else
+        const mbedtls_ecp_keypair *eckey;
         eckey = mbedtls_pk_ec_ro(ctx);
         TEST_ASSERT(mbedtls_ecp_check_pubkey(&eckey->grp, &eckey->Q) == 0);
+#endif
     }
 
 exit: