From 32a6550e871b443bf405c4ff718c78b2f3afa630 Mon Sep 17 00:00:00 2001 From: Sachin Parekh Date: Wed, 5 Jan 2022 22:55:28 +0530 Subject: [PATCH] mbedtls: Added ECC hardware accelerator support on ESP32C2 ESP32C2 has a ECC hardware accelerator capable of performing point multiplication and point verification with a significant performance boost --- components/mbedtls/CMakeLists.txt | 5 + components/mbedtls/Kconfig | 16 ++ components/mbedtls/port/ecc/ecc_alt.c | 129 +++++++++++++ components/mbedtls/port/ecc/esp_ecc.c | 78 ++++++++ components/mbedtls/port/include/ecc_impl.h | 60 +++++++ components/mbedtls/port/include/mbedtls/ecp.h | 32 ++++ .../mbedtls/port/include/mbedtls/esp_config.h | 19 ++ components/mbedtls/test/test_ecp.c | 170 ++++++++++++++++++ 8 files changed, 509 insertions(+) create mode 100644 components/mbedtls/port/ecc/ecc_alt.c create mode 100644 components/mbedtls/port/ecc/esp_ecc.c create mode 100644 components/mbedtls/port/include/ecc_impl.h create mode 100644 components/mbedtls/port/include/mbedtls/ecp.h diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index a58f9373a6..67cf597c03 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -182,6 +182,11 @@ if(CONFIG_MBEDTLS_HARDWARE_GCM) target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") endif() +if(CONFIG_MBEDTLS_HARDWARE_ECC) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" + "${COMPONENT_DIR}/port/ecc/ecc_alt.c") +endif() + if(CONFIG_MBEDTLS_ROM_MD5) target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/md/esp_md.c") endif() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 01570e5005..6d114475c7 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -414,6 +414,22 @@ menu "mbedTLS" SHA hardware acceleration is faster than software in some situations but slower in others. You should benchmark to find the best setting for you. + config MBEDTLS_HARDWARE_ECC + bool "Enable hardware ECC acceleration" + default y + depends on SOC_ECC_SUPPORTED + help + Enable hardware accelerated ECC point multiplication and point verification for points + on curve SECP192R1 and SECP256R1 in mbedTLS + + config MBEDTLS_ECC_OTHER_CURVES_SOFT_FALLBACK + bool "Fallback to software implementation for curves not supported in hardware" + depends on MBEDTLS_HARDWARE_ECC + default y + help + Fallback to software implementation of ECC point multiplication and point verification + for curves not supported in hardware. + config MBEDTLS_ROM_MD5 bool "Use MD5 implementation in ROM" default y diff --git a/components/mbedtls/port/ecc/ecc_alt.c b/components/mbedtls/port/ecc/ecc_alt.c new file mode 100644 index 0000000000..646df7f5d3 --- /dev/null +++ b/components/mbedtls/port/ecc/ecc_alt.c @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/hwcrypto_periph.h" +#include "ecc_impl.h" + +/* TBD: Remove this and use proper getter/setter methods to access + * private members of EC data structures once they are available + * in mbedTLS stack */ +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + +#include "mbedtls/ecp.h" +#include "mbedtls/platform_util.h" + +#define ECP_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) +#define ECP_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + +#if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) + +#define MAX_SIZE 32 // 256 bits + +static int esp_mbedtls_ecp_point_multiply(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P) +{ + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + uint8_t x_tmp[MAX_SIZE]; + uint8_t y_tmp[MAX_SIZE]; + + ecc_point_t p_pt = {0}; + ecc_point_t r_pt = {0}; + + p_pt.len = grp->pbits / 8; + + memcpy(&p_pt.x, P->X.p, mbedtls_mpi_size(&P->X)); + memcpy(&p_pt.y, P->Y.p, mbedtls_mpi_size(&P->Y)); + + ret = esp_ecc_point_multiply(&p_pt, (uint8_t *)m->p, &r_pt, false); + + for (int i = 0; i < MAX_SIZE; i++) { + x_tmp[MAX_SIZE - i - 1] = r_pt.x[i]; + y_tmp[MAX_SIZE - i - 1] = r_pt.y[i]; + } + + mbedtls_mpi_read_binary(&R->X, x_tmp, MAX_SIZE); + mbedtls_mpi_read_binary(&R->Y, y_tmp, MAX_SIZE); + mbedtls_mpi_lset(&R->Z, 1); + return ret; +} + +/* + * Restartable multiplication R = m * P + */ +int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx ) +{ + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + + if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) { +#if defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) + return mbedtls_ecp_mul_restartable_soft(grp, R, m, P, f_rng, p_rng, rs_ctx); +#else + return ret; +#endif + } + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( R != NULL ); + ECP_VALIDATE_RET( m != NULL ); + ECP_VALIDATE_RET( P != NULL ); + + /* Common sanity checks */ + MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); + + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + /* MBEDTLS_MPI_CHK macro assigns the return value of the function to + * `ret` variable + */ + MBEDTLS_MPI_CHK( esp_mbedtls_ecp_point_multiply(grp, R, m, P) ); +cleanup: + return( ret ); +} +#endif /* defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) */ + +#if defined(MBEDTLS_ECP_VERIFY_ALT) || defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) + +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt ) +{ + int res; + ecc_point_t point; + + if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) { +#if defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) + return mbedtls_ecp_check_pubkey_soft(grp, pt); +#else + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +#endif + } + + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( pt != NULL ); + + /* Must use affine coordinates */ + if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + + mbedtls_platform_zeroize((void *)&point, sizeof(ecc_point_t)); + + memcpy(&point.x, pt->X.p, mbedtls_mpi_size(&pt->X)); + memcpy(&point.y, pt->Y.p, mbedtls_mpi_size(&pt->Y)); + + point.len = grp->pbits / 8; + + res = esp_ecc_point_verify(&point); + if (res == 1) { + return 0; + } else { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } +} +#endif /* defined(MBEDTLS_ECP_VERIFY_ALT) || defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) */ diff --git a/components/mbedtls/port/ecc/esp_ecc.c b/components/mbedtls/port/ecc/esp_ecc.c new file mode 100644 index 0000000000..59b16d0961 --- /dev/null +++ b/components/mbedtls/port/ecc/esp_ecc.c @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "soc/ecc_mult_reg.h" +#include "soc/system_reg.h" + +#include "esp_private/periph_ctrl.h" +#include "ecc_impl.h" +#include "hal/ecc_hal.h" + +static _lock_t s_crypto_ecc_lock; + +static void esp_ecc_acquire_hardware(void) +{ + _lock_acquire(&s_crypto_ecc_lock); + + periph_module_enable(PERIPH_ECC_MODULE); +} + +static void esp_ecc_release_hardware(void) +{ + periph_module_disable(PERIPH_ECC_MODULE); + + _lock_release(&s_crypto_ecc_lock); +} + +int esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_point_t *result, bool verify_first) +{ + int ret = -1; + uint16_t len = point->len; + ecc_mode_t work_mode = verify_first ? ECC_MODE_VERIFY_THEN_POINT_MUL : ECC_MODE_POINT_MUL; + + esp_ecc_acquire_hardware(); + + ecc_hal_write_mul_param(scalar, point->x, point->y, len); + ecc_hal_set_mode(work_mode); + ecc_hal_start_calc(); + + memset(result, 0, sizeof(ecc_point_t)); + + result->len = len; + + while (!ecc_hal_is_calc_finished()) { + ; + } + + ret = ecc_hal_read_mul_result(result->x, result->y, len); + + esp_ecc_release_hardware(); + + return ret; +} + +int esp_ecc_point_verify(const ecc_point_t *point) +{ + int result; + + esp_ecc_acquire_hardware(); + ecc_hal_write_verify_param(point->x, point->y, point->len); + ecc_hal_set_mode(ECC_MODE_VERIFY); + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + result = ecc_hal_read_verify_result(); + + esp_ecc_release_hardware(); + + return result; +} diff --git a/components/mbedtls/port/include/ecc_impl.h b/components/mbedtls/port/include/ecc_impl.h new file mode 100644 index 0000000000..c52c988195 --- /dev/null +++ b/components/mbedtls/port/include/ecc_impl.h @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define P256_LEN (256/8) +#define P192_LEN (192/8) + +/* Note: x & y are stored in little endian order (same as CPU byte order, and order used internally by most libraries). + + This is the same order used in hardware + + Note this is opposite to most byte string formats used to represent keys, which are often big endian +*/ +typedef struct { + uint8_t x[P256_LEN]; /* Little endian order */ + uint8_t y[P256_LEN]; /* Little endian order */ + unsigned len; /* P192_LEN or P256_LEN */ +} ecc_point_t; + +/** + * @brief Perform ECC point multiplication (R = K * (Px, Py)) + * + * @param point ECC point (multiplicand) + * @param scalar Integer represented in byte array format (multiplier) + * @param result Result of the multiplication + * @param verify_first Verify that the point is on the curve before performing multiplication + * + * @return - 0 if the multiplication was successful + * - -1 otherwise + * + * @note 'scalar' is expected as a byte array in little endian order. + * Most byte string formats used to represent keys are in big endian order. + */ +int esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_point_t *result, bool verify_first); + +/** + * @brief Perform ECC point verification, + * i.e check whether the point (Px, Py) lies on the curve + * + * @param point ECC point that needs to be verified + * + * @return - 1, if point lies on the curve + * - 0, otherwise + * + */ +int esp_ecc_point_verify(const ecc_point_t *point); + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/include/mbedtls/ecp.h b/components/mbedtls/port/include/mbedtls/ecp.h new file mode 100644 index 0000000000..7340615b86 --- /dev/null +++ b/components/mbedtls/port/include/mbedtls/ecp.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include_next "mbedtls/ecp.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) + +int mbedtls_ecp_mul_restartable_soft(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx ); + +#endif + +#if defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) + +int mbedtls_ecp_check_pubkey_soft(const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt ); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 89bcd93972..8fcf82be4e 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -178,6 +178,25 @@ #define MBEDTLS_ECDSA_VERIFY_ALT #endif +#ifdef CONFIG_MBEDTLS_HARDWARE_ECC +#ifdef CONFIG_MBEDTLS_ECC_OTHER_CURVES_SOFT_FALLBACK + /* Use hardware accelerator for SECP192R1 and SECP256R1 curves, + * software implementation for rest of the curves + */ + #define MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK + #define MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK +#else + /* Only hardware accelerator support */ + #define MBEDTLS_ECP_MUL_ALT + #define MBEDTLS_ECP_VERIFY_ALT +#endif + +#else +#undef MBEDTLS_ECP_MUL_ALT +#undef MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK +#undef MBEDTLS_ECP_VERIFY_ALT +#undef MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK +#endif /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT * diff --git a/components/mbedtls/test/test_ecp.c b/components/mbedtls/test/test_ecp.c index 2ba9423d2d..b439718986 100644 --- a/components/mbedtls/test/test_ecp.c +++ b/components/mbedtls/test/test_ecp.c @@ -84,3 +84,173 @@ TEST_CASE("mbedtls ECP mul w/ koblitz", "[mbedtls]") mbedtls_ctr_drbg_free(&ctxRandom); mbedtls_entropy_free(&ctxEntropy); } + +#if CONFIG_MBEDTLS_HARDWARE_ECC +/* + * Coordinates and integers stored in big endian format + */ +const uint8_t ecc_p192_point_x[] = { + 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, + 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, + 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12 +}; + +const uint8_t ecc_p192_point_y[] = { + 0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, + 0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5, + 0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11 +}; + +const uint8_t ecc_p192_scalar[] = { + 0x6f, 0x18, 0x34, 0xeb, 0x16, 0xb7, 0xac, 0x9f, + 0x3c, 0x77, 0x71, 0xb3, 0x02, 0x30, 0x70, 0x48, + 0x75, 0x87, 0xbb, 0x6f, 0x80, 0x34, 0x8d, 0x5e +}; + +const uint8_t ecc_p192_mul_res_x[] = { + 0x3F, 0xEE, 0x6F, 0x1F, 0x99, 0xDC, 0xCB, 0x78, + 0xB7, 0x47, 0x1C, 0x2A, 0xF5, 0xA0, 0xAC, 0xE6, + 0xEC, 0x24, 0x82, 0x37, 0x6C, 0xC0, 0x27, 0xC5, +}; + +const uint8_t ecc_p192_mul_res_y[] = { + 0xDF, 0xF3, 0x9E, 0x76, 0x24, 0xF4, 0xF6, 0xB4, + 0xF0, 0x0A, 0x18, 0xE1, 0x0B, 0xD2, 0xD9, 0x83, + 0xE8, 0x29, 0x5E, 0xD9, 0x46, 0x54, 0xC3, 0xE1 +}; + +const uint8_t ecc_p256_point_x[] = { + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, + 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, + 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 +}; + +const uint8_t ecc_p256_point_y[] = { + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, + 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, + 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; + +const uint8_t ecc_p256_scalar[] = { + 0xB2, 0xC5, 0x9E, 0x92, 0x64, 0xCD, 0x5F, 0x66, + 0x9E, 0xC8, 0x83, 0x6D, 0x99, 0x61, 0x18, 0x72, + 0xC8, 0x60, 0x83, 0x1E, 0xE5, 0x79, 0xCC, 0x73, + 0xA9, 0xB4, 0x74, 0x85, 0x70, 0x11, 0x2D, 0xA2, +}; + +const uint8_t ecc_p256_mul_res_x[] = { + 0x26, 0x1A, 0x0F, 0xBD, 0xA5, 0xE5, 0x1E, 0xE7, + 0xB3, 0xC3, 0xB7, 0x09, 0xD1, 0x4A, 0x7A, 0x2A, + 0x16, 0x69, 0x4B, 0xAF, 0x76, 0x5C, 0xD4, 0x0E, + 0x93, 0x57, 0xB8, 0x67, 0xF9, 0xA1, 0xE5, 0xE8 +}; + +const uint8_t ecc_p256_mul_res_y[] = { + 0xA0, 0xF4, 0x2E, 0x62, 0x36, 0x25, 0x9F, 0xE0, + 0xF2, 0xA0, 0x41, 0x42, 0xD2, 0x95, 0x89, 0x41, + 0x38, 0xF0, 0xEB, 0x6E, 0xA7, 0x96, 0x29, 0x24, + 0xC7, 0xD4, 0x0C, 0x90, 0xA1, 0xC9, 0xD3, 0x3A +}; + +static int rng_wrapper(void *ctx, unsigned char *buf, size_t len) +{ + esp_fill_random(buf, len); + return 0; +} + +static void test_ecp_mul(mbedtls_ecp_group_id id, const uint8_t *x_coord, const uint8_t *y_coord, const uint8_t *scalar, + const uint8_t *result_x_coord, const uint8_t *result_y_coord) +{ + uint8_t x[32]; + uint8_t y[32]; + int size; + int ret; + + mbedtls_ecp_group grp; + mbedtls_ecp_point R; + mbedtls_ecp_point P; + mbedtls_mpi m; + + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&R); + mbedtls_ecp_point_init(&P); + mbedtls_mpi_init(&m); + + mbedtls_ecp_group_load(&grp, id); + + size = grp.pbits / 8; + + mbedtls_mpi_read_binary(&m, scalar, size); + + mbedtls_mpi_read_binary(&P.X, x_coord, size); + mbedtls_mpi_read_binary(&P.Y, y_coord, size); + + mbedtls_mpi_lset(&P.Z, 1); + + ret = mbedtls_ecp_mul(&grp, &R, &m, &P, rng_wrapper, NULL); + + TEST_ASSERT_EQUAL(0, ret); + + mbedtls_mpi_write_binary(&R.X, x, mbedtls_mpi_size(&R.X)); + mbedtls_mpi_write_binary(&R.Y, y, mbedtls_mpi_size(&R.Y)); + + TEST_ASSERT_EQUAL(0, memcmp(x, result_x_coord, mbedtls_mpi_size(&R.X))); + TEST_ASSERT_EQUAL(0, memcmp(y, result_y_coord, mbedtls_mpi_size(&R.Y))); + + mbedtls_ecp_point_free(&R); + mbedtls_ecp_point_free(&P); + mbedtls_mpi_free(&m); + mbedtls_ecp_group_free(&grp); +} + +TEST_CASE("mbedtls ECP point multiply with SECP192R1", "[mbedtls]") +{ + test_ecp_mul(MBEDTLS_ECP_DP_SECP192R1, ecc_p192_point_x, ecc_p192_point_y, ecc_p192_scalar, + ecc_p192_mul_res_x, ecc_p192_mul_res_y); +} + +TEST_CASE("mbedtls ECP point multiply with SECP256R1", "[mbedtls]") +{ + test_ecp_mul(MBEDTLS_ECP_DP_SECP256R1, ecc_p256_point_x, ecc_p256_point_y, ecc_p256_scalar, + ecc_p256_mul_res_x, ecc_p256_mul_res_y); +} + +static void test_ecp_verify(mbedtls_ecp_group_id id, const uint8_t *x_coord, const uint8_t *y_coord) +{ + int size; + int ret; + + mbedtls_ecp_group grp; + mbedtls_ecp_point P; + + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&P); + + mbedtls_ecp_group_load(&grp, id); + + size = grp.pbits / 8; + + mbedtls_mpi_read_binary(&P.X, x_coord, size); + mbedtls_mpi_read_binary(&P.Y, y_coord, size); + mbedtls_mpi_lset(&P.Z, 1); + + ret = mbedtls_ecp_check_pubkey(&grp, &P); + + TEST_ASSERT_EQUAL(0, ret); + + mbedtls_ecp_point_free(&P); + mbedtls_ecp_group_free(&grp); +} + +TEST_CASE("mbedtls ECP point verify with SECP192R1", "[mbedtls]") +{ + test_ecp_verify(MBEDTLS_ECP_DP_SECP192R1, ecc_p192_mul_res_x, ecc_p192_mul_res_y); +} + +TEST_CASE("mbedtls ECP point verify with SECP256R1", "[mbedtls]") +{ + test_ecp_verify(MBEDTLS_ECP_DP_SECP256R1, ecc_p256_mul_res_x, ecc_p256_mul_res_y); +} +#endif /* CONFIG_MBEDTLS_HARDWARE_ECC */