From 413fa38a458d2423f3e88164e3c287e589f31ae2 Mon Sep 17 00:00:00 2001 From: Sachin Parekh Date: Thu, 16 Feb 2023 18:11:38 +0530 Subject: [PATCH] hal/test_apps: Add no-os ecc test app --- components/hal/.build-test-rules.yml | 9 + components/hal/test_apps/ecc/CMakeLists.txt | 7 + components/hal/test_apps/ecc/README.md | 43 ++ .../hal/test_apps/ecc/main/CMakeLists.txt | 6 + components/hal/test_apps/ecc/main/app_main.c | 13 + components/hal/test_apps/ecc/main/test_ecc.c | 450 ++++++++++++++++++ .../hal/test_apps/ecc/main/test_params.h | 222 +++++++++ components/hal/test_apps/ecc/pytest_ecc.py | 12 + .../hal/test_apps/ecc/sdkconfig.defaults | 2 + 9 files changed, 764 insertions(+) create mode 100644 components/hal/.build-test-rules.yml create mode 100644 components/hal/test_apps/ecc/CMakeLists.txt create mode 100644 components/hal/test_apps/ecc/README.md create mode 100644 components/hal/test_apps/ecc/main/CMakeLists.txt create mode 100644 components/hal/test_apps/ecc/main/app_main.c create mode 100644 components/hal/test_apps/ecc/main/test_ecc.c create mode 100644 components/hal/test_apps/ecc/main/test_params.h create mode 100644 components/hal/test_apps/ecc/pytest_ecc.py create mode 100644 components/hal/test_apps/ecc/sdkconfig.defaults diff --git a/components/hal/.build-test-rules.yml b/components/hal/.build-test-rules.yml new file mode 100644 index 0000000000..4e02657514 --- /dev/null +++ b/components/hal/.build-test-rules.yml @@ -0,0 +1,9 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/hal/test_apps/ecc: + disable: + - if: SOC_ECC_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32c2" + temporary: true + reason: C2 ECC peripheral has a bug in ECC point verification, if value of K is zero the verification fails diff --git a/components/hal/test_apps/ecc/CMakeLists.txt b/components/hal/test_apps/ecc/CMakeLists.txt new file mode 100644 index 0000000000..5ca38f39c4 --- /dev/null +++ b/components/hal/test_apps/ecc/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(ecc_test) diff --git a/components/hal/test_apps/ecc/README.md b/components/hal/test_apps/ecc/README.md new file mode 100644 index 0000000000..51c6228f80 --- /dev/null +++ b/components/hal/test_apps/ecc/README.md @@ -0,0 +1,43 @@ +| Supported Targets | ESP32-C2 | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | -------- | + +## ECC peripheral test + +This application contains basic test cases for the ECC peripheral without using any OS functionality or higher abstraction layer. + +This contains tests for the following features of ECC peripheral: + +- ECC Point multiplication for P192 and P256 curve +- ECC Point verification for P192 and P256 curve +- ECC Point verify and multiply for P192 and P256 curve +- ECC Inverse multiplication for P192 and P256 + +If the hardware supports extended work modes then it also tests: +- ECC Jacobian multiplication for P192 and P256 curve +- ECC Jacobian verification for P192 and P256 curve +- ECC Point verification and Jacobian multiplication for P192 and P256 curve +- ECC Point addition for P192 and P256 curve +- Mod addition +- Mod subtraction +- Mod multiplication + +# Building + +```bash +idf.py set-target +idf.py build +``` + +# Running the app manually + +```bash +idf.py flash monitor +``` + +Enter the test that you want to run locally + +# Running tests + +```bash +pytest --target +``` diff --git a/components/hal/test_apps/ecc/main/CMakeLists.txt b/components/hal/test_apps/ecc/main/CMakeLists.txt new file mode 100644 index 0000000000..668d5be1ed --- /dev/null +++ b/components/hal/test_apps/ecc/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "app_main.c" + "test_ecc.c") + +idf_component_register(SRCS ${srcs} + REQUIRES unity + WHOLE_ARCHIVE) diff --git a/components/hal/test_apps/ecc/main/app_main.c b/components/hal/test_apps/ecc/main/app_main.c new file mode 100644 index 0000000000..ecde0a6c5d --- /dev/null +++ b/components/hal/test_apps/ecc/main/app_main.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/hal/test_apps/ecc/main/test_ecc.c b/components/hal/test_apps/ecc/main/test_ecc.c new file mode 100644 index 0000000000..a42ca80fe4 --- /dev/null +++ b/components/hal/test_apps/ecc/main/test_ecc.c @@ -0,0 +1,450 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "test_params.h" +#include "soc/soc_caps.h" +#include "hal/ecc_hal.h" +#include "hal/clk_gate_ll.h" + +#include "unity.h" + +#define _DEBUG_ 0 +#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]; + } +} + +static void ecc_enable_and_reset(void) +{ + periph_ll_enable_clk_clear_rst(PERIPH_ECC_MODULE); +} + +#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) +{ + ecc_enable_and_reset(); + + 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_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + ecc_hal_read_mul_result(res_x_le, res_y_le, len); +} + +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); + +#if _DEBUG_ + ESP_LOG_BUFFER_HEX("Expected X:", x_mul_le, 32); + ESP_LOG_BUFFER_HEX("Got X:", x_res_le, 32); + + ESP_LOG_BUFFER_HEX("Expected Y:", y_mul_le, 32); + ESP_LOG_BUFFER_HEX("Got Y:", y_res_le, 32); +#endif + + 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); + +#if _DEBUG_ + ESP_LOG_BUFFER_HEX("Expected X:", x_mul_le, 32); + ESP_LOG_BUFFER_HEX("Got X:", x_res_le, 32); + + ESP_LOG_BUFFER_HEX("Expected Y:", y_mul_le, 32); + ESP_LOG_BUFFER_HEX("Got Y:", y_res_le, 32); +#endif + + 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_CASE("ECC point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + test_ecc_point_mul_inner(false); +} +#endif + +#if SOC_ECC_SUPPORT_POINT_VERIFY +static int ecc_point_verify(const uint8_t *x_le, const uint8_t *y_le, uint8_t len) +{ + ecc_enable_and_reset(); + + ecc_hal_write_verify_param(x_le, y_le, len); + ecc_hal_set_mode(ECC_MODE_VERIFY); + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + return ecc_hal_read_verify_result(); +} + +TEST_CASE("ECC point verification on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + int res; + uint8_t x_le[32]; + uint8_t y_le[32]; + + /* P256 */ + ecc_be_to_le(ecc_p256_point_x, x_le, 32); + ecc_be_to_le(ecc_p256_point_y, y_le, 32); + + // Case 1: Correct point on curve + res = ecc_point_verify(x_le, y_le, 32); + TEST_ASSERT_EQUAL(1, res); + + // Case 2: Modify one byte from the point + x_le[6] = x_le[6] ^ 0xFF; + res = ecc_point_verify(x_le, y_le, 32); + TEST_ASSERT_EQUAL(0, res); + + /* P192 */ + ecc_be_to_le(ecc_p192_point_x, x_le, 24); + ecc_be_to_le(ecc_p192_point_y, y_le, 24); + + // Case 1: Correct point on curve + res = ecc_point_verify(x_le, y_le, 24); + TEST_ASSERT_EQUAL(1, res); + + // Case 2: Modify one byte from the point + x_le[6] = x_le[6] ^ 0xFF; + res = ecc_point_verify(x_le, y_le, 24); + TEST_ASSERT_EQUAL(0, res); +} +#endif + +#if SOC_ECC_SUPPORT_POINT_MULT && SOC_ECC_SUPPORT_POINT_VERIFY +TEST_CASE("ECC point verification and multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + test_ecc_point_mul_inner(true); +} +#endif + +#if SOC_ECC_SUPPORT_POINT_DIVISION +static void ecc_point_inv_mul(const uint8_t *num_le, const uint8_t *deno_le, uint8_t len, uint8_t *res_le) +{ + ecc_enable_and_reset(); + + uint8_t zero[32] = {0}; + ecc_hal_write_mul_param(zero, num_le, deno_le, len); + + ecc_hal_set_mode(ECC_MODE_INVERSE_MUL); + + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + ecc_hal_read_mul_result(zero, res_le, len); +} + +TEST_CASE("ECC inverse multiplication (or mod division) using SECP192R1 and SECP256R1 order of curve", "[ecc][hal]") +{ + uint8_t res[32] = {0}; + ecc_point_inv_mul(ecc256_num, ecc256_den, 32, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc256_inv_mul_res, res, 32, "P256 Inverse multiplication (or Mod division)"); + + ecc_point_inv_mul(ecc192_num, ecc192_den, 24, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc192_inv_mul_res, res, 24, "P192 Inverse multiplication (or Mod division)"); +} +#endif + +#if SOC_ECC_SUPPORT_JACOB_POINT_MULT +static void ecc_jacob_mul(uint8_t *k_le, uint8_t *x_le, uint8_t *y_le, uint8_t len, bool verify_first, + uint8_t *res_x_le, uint8_t *res_y_le, uint8_t *res_z_le) +{ + ecc_enable_and_reset(); + + ecc_hal_write_mul_param(k_le, x_le, y_le, len); + if (verify_first) { + ecc_hal_set_mode(ECC_MODE_POINT_VERIFY_JACOBIAN_MUL); + } else { + ecc_hal_set_mode(ECC_MODE_JACOBIAN_POINT_MUL); + } + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + ecc_hal_read_jacob_mul_result(res_x_le, res_y_le, res_z_le, len); +} + +static void test_ecc_jacob_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]; + uint8_t z_res_le[32]; + + ecc_jacob_mul(scalar_le, x_le, y_le, 32, verify_first, x_res_le, y_res_le, z_res_le); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc_p256_jacob_mul_res_x_le, x_res_le, 32, "X coordinate of P256 point jacobian multiplication "); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc_p256_jacob_mul_res_y_le, y_res_le, 32, "Y coordinate of P256 point jacobian multiplication "); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc_p256_jacob_mul_res_z_le, z_res_le, 32, "Z coordinate of P256 point jacobian multiplication "); + + memset(x_res_le, 0x0, 32); + memset(y_res_le, 0x0, 32); + memset(z_res_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_jacob_mul(scalar_le, x_le, y_le, 24, verify_first, x_res_le, y_res_le, z_res_le); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc_p192_jacob_mul_res_x_le, x_res_le, 24, "X coordinate of P192 point jacobian multiplication "); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc_p192_jacob_mul_res_y_le, y_res_le, 24, "Y coordinate of P192 point jacobian multiplication "); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc_p192_jacob_mul_res_z_le, z_res_le, 24, "Z coordinate of P192 point jacobian multiplication "); +} + +TEST_CASE("ECC jacobian point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + test_ecc_jacob_mul_inner(false); +} +#endif + +#if SOC_ECC_SUPPORT_JACOB_POINT_VERIFY +static int ecc_jacob_verify(const uint8_t *x_le, const uint8_t *y_le, const uint8_t *z_le, uint8_t len) +{ + ecc_enable_and_reset(); + + ecc_hal_write_jacob_verify_param(x_le, y_le, z_le, len); + + ecc_hal_set_mode(ECC_MODE_JACOBIAN_POINT_VERIFY); + + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + return ecc_hal_read_verify_result(); +} + +TEST_CASE("ECC jacobian point verification on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + int res; + /* P256 */ + res = ecc_jacob_verify(ecc_p256_jacob_mul_res_x_le, ecc_p256_jacob_mul_res_y_le, ecc_p256_jacob_mul_res_z_le, 32); + TEST_ASSERT_EQUAL(1, res); + + /* P192 */ + res = ecc_jacob_verify(ecc_p192_jacob_mul_res_x_le, ecc_p192_jacob_mul_res_y_le, ecc_p192_jacob_mul_res_z_le, 24); + TEST_ASSERT_EQUAL(1, res); +} +#endif + +#if SOC_ECC_SUPPORT_JACOB_POINT_MULT && SOC_ECC_SUPPORT_JACOB_POINT_VERIFY +TEST_CASE("ECC point verification and Jacobian point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + test_ecc_jacob_mul_inner(true); +} +#endif + +#if SOC_ECC_SUPPORT_POINT_ADDITION +static void ecc_point_addition(uint8_t *px_le, uint8_t *py_le, uint8_t *qx_le, uint8_t *qy_le, uint8_t *qz_le, + uint8_t len, bool jacob_output, + uint8_t *x_res_le, uint8_t *y_res_le, uint8_t *z_res_le) +{ + ecc_enable_and_reset(); + + ecc_hal_write_point_add_param(px_le, py_le, qx_le, qy_le, qz_le, len); + + ecc_hal_set_mode(ECC_MODE_POINT_ADD); + + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + ecc_hal_read_point_add_result(x_res_le, y_res_le, z_res_le, len, jacob_output); +} + +TEST_CASE("ECC point addition on SECP192R1 and SECP256R1", "[ecc][hal]") +{ + uint8_t scalar_le[32] = {0}; + uint8_t x_le[32] = {0}; + uint8_t y_le[32] = {0}; + uint8_t z_le[32] = {0}; + + /* P256 + * R = 2 * P + */ + ecc_be_to_le(ecc_p256_point_x, x_le, 32); + ecc_be_to_le(ecc_p256_point_y, y_le, 32); + + scalar_le[0] = 0x2; + + uint8_t x_res_le[32]; + uint8_t y_res_le[32]; + uint8_t z_res_le[32]; + + ecc_jacob_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le, z_res_le); + + uint8_t x_add_le[32]; + uint8_t y_add_le[32]; + uint8_t z_add_le[32]; + + z_le[0] = 0x1; + + ecc_point_addition(x_le, y_le, x_le, y_le, z_le, 32, 1, x_add_le, y_add_le, z_add_le); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(x_add_le, x_res_le, 32, "X coordinate of P256 point addition"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(y_add_le, y_res_le, 32, "Y coordinate of P256 point addition"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(z_add_le, z_res_le, 32, "Z coordinate of P256 point addition"); + + /* P192 + * R = 2 * P + */ + ecc_be_to_le(ecc_p192_point_x, x_le, 24); + ecc_be_to_le(ecc_p192_point_y, y_le, 24); + + scalar_le[0] = 0x2; + + ecc_jacob_mul(scalar_le, x_le, y_le, 24, 0, x_res_le, y_res_le, z_res_le); + + z_le[0] = 0x1; + + ecc_point_addition(x_le, y_le, x_le, y_le, z_le, 24, 1, x_add_le, y_add_le, z_add_le); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(x_add_le, x_res_le, 24, "X coordinate of P192 point addition"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(y_add_le, y_res_le, 24, "Y coordinate of P192 point addition"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(z_add_le, z_res_le, 24, "Z coordinate of P192 point addition"); +} +#endif + +#if SOC_ECC_SUPPORT_MOD_ADD || SOC_ECC_SUPPORT_MOD_SUB || SOC_ECC_SUPPORT_MOD_MUL +static void ecc_mod_op(ecc_mode_t mode, const uint8_t *a, const uint8_t *b, uint8_t len, uint8_t *res_le) +{ + ecc_enable_and_reset(); + + ecc_hal_write_mod_op_param(a, b, len); + + ecc_hal_set_mode(mode); + + ecc_hal_start_calc(); + + while (!ecc_hal_is_calc_finished()) { + ; + } + + ecc_hal_read_mod_op_result(res_le, len); +} +#endif + +#if SOC_ECC_SUPPORT_MOD_ADD +TEST_CASE("ECC mod addition using SECP192R1 and SECP256R1 order of curve", "[ecc][hal]") +{ + uint8_t res[32] = {0}; + ecc_mod_op(ECC_MODE_MOD_ADD, ecc256_x, ecc256_y, 32, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc256_add_res, res, 32, "P256 mod addition"); + + ecc_mod_op(ECC_MODE_MOD_ADD, ecc192_x, ecc192_y, 24, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc192_add_res, res, 24, "P192 mod addition"); +} +#endif + +#if SOC_ECC_SUPPORT_MOD_SUB +TEST_CASE("ECC mod subtraction using SECP192R1 and SECP256R1 order of curve", "[ecc][hal]") +{ + uint8_t res[32] = {0}; + ecc_mod_op(ECC_MODE_MOD_SUB, ecc256_x, ecc256_y, 32, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc256_sub_res, res, 32, "P256 mod subtraction"); + + ecc_mod_op(ECC_MODE_MOD_SUB, ecc192_x, ecc192_y, 24, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc192_sub_res, res, 24, "P192 mod subtraction"); +} +#endif + +#if SOC_ECC_SUPPORT_MOD_MUL +TEST_CASE("ECC mod multiplication using SECP192R1 and SECP256R1 order of curve", "[ecc][hal]") +{ + uint8_t res[32] = {0}; + ecc_mod_op(ECC_MODE_MOD_MUL, ecc256_x, ecc256_y, 32, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc256_mul_res, res, 32, "P256 mod multiplication"); + + ecc_mod_op(ECC_MODE_MOD_MUL, ecc192_x, ecc192_y, 24, res); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ecc192_mul_res, res, 24, "P192 mod multiplication"); +} +#endif diff --git a/components/hal/test_apps/ecc/main/test_params.h b/components/hal/test_apps/ecc/main/test_params.h new file mode 100644 index 0000000000..77aecedda9 --- /dev/null +++ b/components/hal/test_apps/ecc/main/test_params.h @@ -0,0 +1,222 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +static 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 +}; + +static 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 +}; + +static 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 +}; + +static 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, +}; + +static 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 +}; + +static 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 +}; + +static 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 +}; + +static 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, +}; + +static 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 +}; + +static 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 const uint8_t ecc_p256_jacob_mul_res_x_le[] = { + 0x9C, 0x79, 0x11, 0x19, 0x1B, 0x49, 0xAB, 0x51, + 0x5C, 0x57, 0x71, 0x7B, 0x14, 0x4A, 0xD4, 0xA8, + 0x70, 0xEA, 0x0E, 0x7D, 0x3A, 0x20, 0x94, 0x03, + 0xA3, 0x9E, 0x2D, 0x95, 0xAD, 0xC1, 0xD0, 0xB4 +}; + +static const uint8_t ecc_p256_jacob_mul_res_y_le[] = { + 0xA4, 0x46, 0xBA, 0x75, 0x20, 0x19, 0xF2, 0xDB, + 0x5D, 0x99, 0x3F, 0xE3, 0x8C, 0xDF, 0xFE, 0x6E, + 0xD9, 0x1F, 0x63, 0x63, 0xDB, 0x6F, 0xD6, 0xAF, + 0xE8, 0x5E, 0xED, 0x4F, 0x99, 0x05, 0x3C, 0x5A +}; + +static const uint8_t ecc_p256_jacob_mul_res_z_le[] = { + 0x7C, 0x7A, 0xB4, 0xBA, 0xD4, 0xB7, 0x86, 0xEB, + 0xDA, 0x79, 0x0F, 0xA1, 0xA8, 0xAB, 0x6A, 0xAB, + 0xCB, 0xF9, 0x05, 0xBE, 0x5C, 0x90, 0x15, 0x0E, + 0xA7, 0x2D, 0x6F, 0x0C, 0xAE, 0x68, 0xBB, 0x4A +}; + +static const uint8_t ecc_p192_jacob_mul_res_x_le[] = { + 0xE1, 0xB5, 0x3E, 0xB2, 0x85, 0xCA, 0x93, 0x25, + 0xCA, 0xB1, 0x6B, 0xCF, 0xC3, 0x6E, 0xB7, 0x66, + 0x9C, 0xB4, 0x83, 0x98, 0x8E, 0x7A, 0xA1, 0x55 +}; + +static const uint8_t ecc_p192_jacob_mul_res_y_le[] = { + 0xC7, 0xD3, 0xEA, 0x97, 0x87, 0x92, 0x98, 0xE5, + 0xA5, 0x30, 0xB1, 0xE4, 0x92, 0xD9, 0x71, 0x11, + 0x16, 0x63, 0x37, 0x56, 0x8D, 0xB1, 0xD4, 0xB8 +}; + +static const uint8_t ecc_p192_jacob_mul_res_z_le[] = { + 0xD1, 0xA5, 0x8D, 0x76, 0x17, 0x7B, 0xB3, 0x9F, + 0x0D, 0x78, 0x1B, 0x36, 0x59, 0x18, 0xD0, 0xF1, + 0x38, 0x8C, 0xD7, 0x13, 0xCB, 0x7A, 0x9B, 0xBF +}; + +/* Little endian */ +static const uint8_t ecc256_num[] = { + 0x20, 0x56, 0x14, 0xB6, 0xAF, 0x94, 0xA0, 0xB6, + 0x0C, 0xDF, 0x13, 0x1A, 0xE6, 0xBF, 0x57, 0x87, + 0xF1, 0x02, 0x73, 0x96, 0x53, 0x1A, 0xBC, 0xA9, + 0x0F, 0x5E, 0xA1, 0xFC, 0x0E, 0xFC, 0x9D, 0x9B +}; + +/* Little endian */ +static const uint8_t ecc256_den[] = { + 0x54, 0x3B, 0x11, 0x78, 0xC4, 0xCA, 0x52, 0xFD, + 0xCC, 0x89, 0x51, 0x0F, 0xFE, 0x7D, 0x37, 0x83, + 0x81, 0xD5, 0x2E, 0x58, 0x42, 0xF9, 0x4F, 0x19, + 0x9A, 0x79, 0x78, 0x98, 0xFA, 0x95, 0x40, 0x2E +}; + +/* Little endian */ +static const uint8_t ecc256_inv_mul_res[] = { + 0x33, 0xF3, 0x55, 0x3B, 0x46, 0x8A, 0x13, 0xC0, + 0x1D, 0x7E, 0x41, 0xA6, 0xFF, 0x53, 0xFD, 0x78, + 0xD5, 0xC0, 0xE5, 0x9F, 0x78, 0xD1, 0x86, 0x66, + 0x77, 0x3C, 0x6E, 0xEF, 0x58, 0xF6, 0x29, 0x34 +}; + +static const uint8_t ecc192_num[] = { + 0xBA, 0x0F, 0x2C, 0xD8, 0xBE, 0xCC, 0x2D, 0xD3, + 0xD5, 0x74, 0xBD, 0x8C, 0xF3, 0x3E, 0x3B, 0x7A, + 0xA4, 0xD0, 0x71, 0xEC, 0x85, 0xF6, 0x70, 0x00 +}; + +static const uint8_t ecc192_den[] = { + 0x15, 0xF9, 0x20, 0xD8, 0x46, 0x5C, 0x03, 0x97, + 0x4A, 0x10, 0xEF, 0x8A, 0xFB, 0x12, 0x2E, 0x65, + 0x6E, 0xD6, 0x79, 0x1E, 0x65, 0x6F, 0x3E, 0x64 +}; + +static const uint8_t ecc192_inv_mul_res[] = { + 0x6B, 0xB3, 0x6B, 0x2B, 0x56, 0x6A, 0xE5, 0xF7, + 0x75, 0x82, 0xF0, 0xCC, 0x93, 0x63, 0x40, 0xF8, + 0xEF, 0x35, 0x2A, 0xAF, 0xBD, 0x56, 0xE9, 0x29 +}; + +/* Little endian */ +static const uint8_t ecc256_x[] = { + 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4, + 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77, + 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8, + 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B +}; + +/* Little endian */ +static const uint8_t ecc256_y[] = { + 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB, + 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B, + 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E, + 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F +}; + +/* Little endian */ +static const uint8_t ecc256_add_res[] = { + 0x8B, 0x14, 0x58, 0x10, 0xAE, 0x79, 0x57, 0xC0, + 0x6F, 0x92, 0x1C, 0x99, 0xD8, 0xB0, 0xD1, 0xA2, + 0x08, 0xDF, 0xB3, 0xDF, 0x2F, 0xD2, 0xA4, 0x87, + 0xE3, 0xC1, 0x46, 0xDF, 0xD5, 0x14, 0xFB, 0xBA +}; + +/* Little endian */ +static const uint8_t ecc256_sub_res[] = { + 0xA1, 0x70, 0xD9, 0xA0, 0xDD, 0xF8, 0xEA, 0x28, + 0xD2, 0xD4, 0xB9, 0xC2, 0x29, 0x4A, 0x35, 0x4B, + 0xDC, 0xA2, 0x94, 0xE7, 0x9A, 0xFB, 0xD4, 0x69, + 0xAC, 0xC2, 0x11, 0xE3, 0x0F, 0x8F, 0x34, 0x1B +}; + +/* Little endian */ +static const uint8_t ecc256_mul_res[] = { + 0x18, 0x4D, 0xCE, 0xCC, 0x1A, 0xA8, 0xEC, 0x72, + 0xD7, 0x31, 0xDA, 0x41, 0x8C, 0x75, 0x6B, 0xF1, + 0x2A, 0x2E, 0x5B, 0x53, 0x8D, 0xCA, 0x79, 0x61, + 0x6B, 0x46, 0xF9, 0x2E, 0x27, 0xB5, 0x43, 0x15 +}; + +static const uint8_t ecc192_x[] = { + 0x1A, 0x80, 0xA1, 0x5F, 0x1F, 0xB7, 0x59, 0x1B, + 0x9F, 0xD7, 0xFB, 0xAE, 0xA9, 0xF9, 0x1E, 0xBA, + 0x67, 0xAE, 0x57, 0xB7, 0x27, 0x80, 0x9E, 0x1A +}; + +static const uint8_t ecc192_y[] = { + 0x59, 0xC6, 0x3D, 0xD3, 0xD7, 0xDF, 0xA3, 0x44, + 0x7C, 0x75, 0x52, 0xB4, 0x42, 0xF3, 0xFC, 0xA6, + 0x0F, 0xA8, 0x8A, 0x8D, 0x1F, 0xA3, 0xDF, 0x54 +}; + +static const uint8_t ecc192_add_res[] = { + 0x73, 0x46, 0xDF, 0x32, 0xF7, 0x96, 0xFD, 0x5F, + 0x1B, 0x4D, 0x4E, 0x63, 0xEC, 0xEC, 0x1B, 0x61, + 0x77, 0x56, 0xE2, 0x44, 0x47, 0x23, 0x7E, 0x6F +}; + +static const uint8_t ecc192_sub_res[] = { + 0xF2, 0xE1, 0x35, 0x41, 0xF9, 0xA0, 0x21, 0xEB, + 0x58, 0x5A, 0x88, 0x94, 0x66, 0x06, 0x22, 0x13, + 0x58, 0x06, 0xCD, 0x29, 0x08, 0xDD, 0xBE, 0xC5 +}; + +static const uint8_t ecc192_mul_res[] = { + 0xB5, 0xB9, 0xFF, 0xBC, 0x52, 0xC8, 0xB8, 0x36, + 0x8C, 0xFB, 0xA5, 0xCE, 0x1E, 0x7B, 0xE6, 0xF3, + 0x8F, 0x79, 0x71, 0xCF, 0xD6, 0xF3, 0x41, 0xE6 +}; diff --git a/components/hal/test_apps/ecc/pytest_ecc.py b/components/hal/test_apps/ecc/pytest_ecc.py new file mode 100644 index 0000000000..4210c9aa88 --- /dev/null +++ b/components/hal/test_apps/ecc/pytest_ecc.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +def test_ecc(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/hal/test_apps/ecc/sdkconfig.defaults b/components/hal/test_apps/ecc/sdkconfig.defaults new file mode 100644 index 0000000000..a4ba403514 --- /dev/null +++ b/components/hal/test_apps/ecc/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=n