/* * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ #include #include #include #include #include "sdkconfig.h" #include "esp_crypto_periph_clk.h" #include "esp_log.h" #include "ecc_params.h" #include "soc/soc_caps.h" #include "hal/ecc_hal.h" #include "hal/ecc_ll.h" #include "memory_checks.h" #include "unity_fixture.h" #include "ccomp_timer.h" #define SOC_ECC_SUPPORT_POINT_MULT 1 #define SOC_ECC_SUPPORT_POINT_VERIFY 1 #if SOC_ECC_EXTENDED_MODES_SUPPORTED #define SOC_ECC_SUPPORT_POINT_DIVISION 1 #define SOC_ECC_SUPPORT_JACOB_POINT_MULT 1 #define SOC_ECC_SUPPORT_JACOB_POINT_VERIFY 1 #define SOC_ECC_SUPPORT_POINT_ADDITION 1 #define SOC_ECC_SUPPORT_MOD_ADD 1 #define SOC_ECC_SUPPORT_MOD_SUB 1 #define SOC_ECC_SUPPORT_MOD_MUL 1 #endif static void ecc_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len) { /* When the size is 24 bytes, it should be padded with 0 bytes*/ memset(le_point, 0x0, 32); for (int i = 0; i < len; i++) { le_point[i] = be_point[len - i - 1]; } } TEST_GROUP(ecc); TEST_SETUP(ecc) { test_utils_record_free_mem(); TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); } TEST_TEAR_DOWN(ecc) { test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); } #if SOC_ECC_SUPPORT_POINT_MULT static void ecc_point_mul(const uint8_t *k_le, const uint8_t *x_le, const uint8_t *y_le, uint8_t len, bool verify_first, uint8_t *res_x_le, uint8_t *res_y_le) { esp_crypto_ecc_enable_periph_clk(true); ecc_hal_write_mul_param(k_le, x_le, y_le, len); if (verify_first) { ecc_hal_set_mode(ECC_MODE_VERIFY_THEN_POINT_MUL); } else { ecc_hal_set_mode(ECC_MODE_POINT_MUL); } ecc_hal_enable_constant_time_point_mul(true); ecc_hal_start_calc(); while (!ecc_hal_is_calc_finished()) { ; } ecc_hal_read_mul_result(res_x_le, res_y_le, len); esp_crypto_ecc_enable_periph_clk(false); } static void test_ecc_point_mul_inner(bool verify_first) { uint8_t scalar_le[32]; uint8_t x_le[32]; uint8_t y_le[32]; /* P256 */ ecc_be_to_le(ecc_p256_scalar, scalar_le, 32); ecc_be_to_le(ecc_p256_point_x, x_le, 32); ecc_be_to_le(ecc_p256_point_y, y_le, 32); uint8_t x_res_le[32]; uint8_t y_res_le[32]; ecc_point_mul(scalar_le, x_le, y_le, 32, verify_first, x_res_le, y_res_le); uint8_t x_mul_le[32]; uint8_t y_mul_le[32]; ecc_be_to_le(ecc_p256_mul_res_x, x_mul_le, 32); ecc_be_to_le(ecc_p256_mul_res_y, y_mul_le, 32); ESP_LOG_BUFFER_HEXDUMP("Expected X:", x_mul_le, 32, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP("Got X:", x_res_le, 32, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP("Expected Y:", y_mul_le, 32, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP("Got Y:", y_res_le, 32, ESP_LOG_DEBUG); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(x_mul_le, x_res_le, 32, "X coordinate of P256 point multiplication "); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(y_mul_le, y_res_le, 32, "Y coordinate of P256 point multiplication "); memset(x_res_le, 0x0, 32); memset(y_res_le, 0x0, 32); memset(x_mul_le, 0x0, 32); memset(y_mul_le, 0x0, 32); /* P192 */ ecc_be_to_le(ecc_p192_scalar, scalar_le, 24); ecc_be_to_le(ecc_p192_point_x, x_le, 24); ecc_be_to_le(ecc_p192_point_y, y_le, 24); ecc_point_mul(scalar_le, x_le, y_le, 24, verify_first, x_res_le, y_res_le); ecc_be_to_le(ecc_p192_mul_res_x, x_mul_le, 24); ecc_be_to_le(ecc_p192_mul_res_y, y_mul_le, 24); ESP_LOG_BUFFER_HEXDUMP("Expected X:", x_mul_le, 32, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP("Got X:", x_res_le, 32, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP("Expected Y:", y_mul_le, 32, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP("Got Y:", y_res_le, 32, ESP_LOG_DEBUG); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(x_mul_le, x_res_le, 24, "X coordinate of P192 point multiplication "); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(y_mul_le, y_res_le, 24, "Y coordinate of P192 point multiplication "); } TEST(ecc, ecc_point_multiplication_on_SECP192R1_and_SECP256R1) { test_ecc_point_mul_inner(false); } #if SOC_ECC_CONSTANT_TIME_POINT_MUL #define CONST_TIME_DEVIATION_PERCENT 0.0025 static void test_ecc_point_mul_inner_constant_time(void) { #if CONFIG_IDF_TARGET_ESP32H2 if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { TEST_IGNORE_MESSAGE("Skipping test, not supported on ESP32-H2