Merge branch 'h2/support-ecc' into 'master'

esp32h2: Add support for ECC hardware accelerator

See merge request espressif/esp-idf!22274
This commit is contained in:
Jiang Jiang Jian
2023-03-15 14:06:23 +08:00
22 changed files with 1238 additions and 13 deletions

View File

@@ -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

View File

@@ -5,6 +5,7 @@
*/
#include "hal/ecc_hal.h"
#include "hal/ecc_ll.h"
#include "soc/soc_caps.h"
void ecc_hal_set_mode(ecc_mode_t mode)
{
@@ -34,6 +35,11 @@ static void clear_param_registers(void)
ecc_ll_write_param(ECC_PARAM_PX, buf, sizeof(buf));
ecc_ll_write_param(ECC_PARAM_PY, buf, sizeof(buf));
ecc_ll_write_param(ECC_PARAM_K, buf, sizeof(buf));
#if SOC_ECC_EXTENDED_MODES_SUPPORTED
ecc_ll_write_param(ECC_PARAM_QX, buf, sizeof(buf));
ecc_ll_write_param(ECC_PARAM_QY, buf, sizeof(buf));
ecc_ll_write_param(ECC_PARAM_QZ, buf, sizeof(buf));
#endif
}
void ecc_hal_write_mul_param(const uint8_t *k, const uint8_t *px, const uint8_t *py, uint16_t len)
@@ -80,3 +86,94 @@ int ecc_hal_read_verify_result(void)
{
return ecc_ll_get_verification_result();
}
#if SOC_ECC_EXTENDED_MODES_SUPPORTED
void ecc_hal_set_mod_base(ecc_mod_base_t base)
{
ecc_ll_set_mod_base(base);
}
void ecc_hal_write_jacob_verify_param(const uint8_t *qx, const uint8_t *qy, const uint8_t *qz, uint16_t len)
{
ecc_curve_t curve = len == 32 ? ECC_CURVE_SECP256R1 : ECC_CURVE_SECP192R1;
ecc_ll_set_curve(curve);
clear_param_registers();
ecc_ll_write_param(ECC_PARAM_QX, qx, len);
ecc_ll_write_param(ECC_PARAM_QY, qy, len);
ecc_ll_write_param(ECC_PARAM_QZ, qz, len);
}
int ecc_hal_read_jacob_mul_result(uint8_t *rx, uint8_t *ry, uint8_t *rz, uint16_t len)
{
ecc_mode_t mode = ecc_ll_get_mode();
if (mode == ECC_MODE_POINT_VERIFY_JACOBIAN_MUL) {
if (!ecc_ll_get_verification_result()) {
memset(rx, 0x0, len);
memset(ry, 0x0, len);
memset(rz, 0x0, len);
return -1;
}
}
ecc_ll_read_param(ECC_PARAM_QX, rx, len);
ecc_ll_read_param(ECC_PARAM_QY, ry, len);
ecc_ll_read_param(ECC_PARAM_QZ, rz, len);
return 0;
}
void ecc_hal_write_point_add_param(const uint8_t *px, const uint8_t *py, const uint8_t *qx, const uint8_t *qy, const uint8_t *qz, uint16_t len)
{
ecc_curve_t curve = len == 32 ? ECC_CURVE_SECP256R1 : ECC_CURVE_SECP192R1;
ecc_ll_set_curve(curve);
clear_param_registers();
ecc_ll_write_param(ECC_PARAM_PX, px, len);
ecc_ll_write_param(ECC_PARAM_PY, py, len);
ecc_ll_write_param(ECC_PARAM_QX, qx, len);
ecc_ll_write_param(ECC_PARAM_QY, qy, len);
ecc_ll_write_param(ECC_PARAM_QZ, qz, len);
}
int ecc_hal_read_point_add_result(uint8_t *rx, uint8_t *ry, uint8_t *rz, uint16_t len, bool read_jacob)
{
if (read_jacob) {
ecc_ll_read_param(ECC_PARAM_QX, rx, len);
ecc_ll_read_param(ECC_PARAM_QY, ry, len);
ecc_ll_read_param(ECC_PARAM_QZ, rz, len);
} else {
ecc_ll_read_param(ECC_PARAM_PX, rx, len);
ecc_ll_read_param(ECC_PARAM_PY, ry, len);
}
return 0;
}
void ecc_hal_write_mod_op_param(const uint8_t *a, const uint8_t *b, uint16_t len)
{
ecc_curve_t curve = len == 32 ? ECC_CURVE_SECP256R1 : ECC_CURVE_SECP192R1;
ecc_ll_set_curve(curve);
clear_param_registers();
ecc_ll_write_param(ECC_PARAM_PX, a, len);
ecc_ll_write_param(ECC_PARAM_PY, b, len);
}
int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len)
{
ecc_mode_t mode = ecc_ll_get_mode();
if (mode == ECC_MODE_MOD_ADD || mode == ECC_MODE_MOD_SUB) {
ecc_ll_read_param(ECC_PARAM_PX, r, len);
} else if (mode == ECC_MODE_MOD_MUL || mode == ECC_MODE_INVERSE_MUL) {
ecc_ll_read_param(ECC_PARAM_PY, r, len);
} else {
return -1;
}
return 0;
}
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */

View File

@@ -41,9 +41,6 @@ static inline void ecc_ll_set_mode(ecc_mode_t mode)
case ECC_MODE_POINT_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
break;
case ECC_MODE_INVERSE_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 1);
break;
case ECC_MODE_VERIFY:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
break;

View File

@@ -41,9 +41,6 @@ static inline void ecc_ll_set_mode(ecc_mode_t mode)
case ECC_MODE_POINT_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
break;
case ECC_MODE_INVERSE_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 1);
break;
case ECC_MODE_VERIFY:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
break;

View File

@@ -63,6 +63,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
return PCR_AES_CLK_EN;
case PERIPH_SHA_MODULE:
return PCR_SHA_CLK_EN;
case PERIPH_ECC_MODULE:
return PCR_ECC_CLK_EN;
case PERIPH_RSA_MODULE:
return PCR_RSA_CLK_EN;
case PERIPH_HMAC_MODULE:
@@ -136,6 +138,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
return PCR_PARL_RST_EN;
case PERIPH_TEMPSENSOR_MODULE:
return PCR_TSENS_RST_EN;
case PERIPH_ECC_MODULE:
return PCR_ECC_RST_EN;
case PERIPH_AES_MODULE:
if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset
@@ -231,6 +235,8 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
return PCR_SHA_CONF_REG;
case PERIPH_ECC_MODULE:
return PCR_ECC_CONF_REG;
case PERIPH_RSA_MODULE:
return PCR_RSA_CONF_REG;
case PERIPH_HMAC_MODULE:
@@ -292,6 +298,8 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
return PCR_SHA_CONF_REG;
case PERIPH_ECC_MODULE:
return PCR_ECC_CONF_REG;
case PERIPH_RSA_MODULE:
return PCR_RSA_CONF_REG;
case PERIPH_HMAC_MODULE:

View File

@@ -0,0 +1,209 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/ecc_mult_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ECC_PARAM_PX = 0x0,
ECC_PARAM_PY,
ECC_PARAM_K,
ECC_PARAM_QX,
ECC_PARAM_QY,
ECC_PARAM_QZ,
} ecc_ll_param_t;
static inline void ecc_ll_enable_interrupt(void)
{
REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1);
}
static inline void ecc_ll_disable_interrupt(void)
{
REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 0);
}
static inline void ecc_ll_clear_interrupt(void)
{
REG_SET_FIELD(ECC_MULT_INT_CLR_REG, ECC_MULT_CALC_DONE_INT_CLR, 1);
}
static inline void ecc_ll_set_mode(ecc_mode_t mode)
{
switch(mode) {
case ECC_MODE_POINT_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
break;
case ECC_MODE_VERIFY:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
break;
case ECC_MODE_VERIFY_THEN_POINT_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 3);
break;
case ECC_MODE_JACOBIAN_POINT_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 4);
break;
case ECC_MODE_POINT_ADD:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 5);
break;
case ECC_MODE_JACOBIAN_POINT_VERIFY:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 6);
break;
case ECC_MODE_POINT_VERIFY_JACOBIAN_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 7);
break;
case ECC_MODE_MOD_ADD:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 8);
break;
case ECC_MODE_MOD_SUB:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 9);
break;
case ECC_MODE_MOD_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 10);
break;
case ECC_MODE_INVERSE_MUL:
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 11);
break;
default:
HAL_ASSERT(false && "Unsupported mode");
break;
}
}
static inline void ecc_ll_set_curve(ecc_curve_t curve)
{
switch(curve) {
case ECC_CURVE_SECP256R1:
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
break;
case ECC_CURVE_SECP192R1:
REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
break;
default:
HAL_ASSERT(false && "Unsupported curve");
return;
}
}
static inline void ecc_ll_set_mod_base(ecc_mod_base_t base)
{
switch(base) {
case ECC_MOD_N:
REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
break;
case ECC_MOD_P:
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
break;
default:
HAL_ASSERT(false && "Unsupported curve");
return;
}
}
static inline void ecc_ll_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
{
uint32_t reg;
uint32_t word;
switch (param) {
case ECC_PARAM_PX:
reg = ECC_MULT_PX_MEM;
break;
case ECC_PARAM_PY:
reg = ECC_MULT_PY_MEM;
break;
case ECC_PARAM_K:
reg = ECC_MULT_K_MEM;
break;
case ECC_PARAM_QX:
reg = ECC_MULT_QX_MEM;
break;
case ECC_PARAM_QY:
reg = ECC_MULT_QY_MEM;
break;
case ECC_PARAM_QZ:
reg = ECC_MULT_QZ_MEM;
break;
default:
HAL_ASSERT(false && "Invalid parameter");
return;
}
for (int i = 0; i < len; i += 4) {
memcpy(&word, buf + i, 4);
REG_WRITE(reg + i, word);
}
}
static inline void ecc_ll_start_calc(void)
{
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_START);
}
static inline int ecc_ll_is_calc_finished(void)
{
return REG_GET_FIELD(ECC_MULT_INT_RAW_REG, ECC_MULT_CALC_DONE_INT_RAW);
}
static inline ecc_mode_t ecc_ll_get_mode(void)
{
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE);
}
static inline int ecc_ll_get_verification_result(void)
{
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_VERIFICATION_RESULT);
}
static inline ecc_curve_t ecc_ll_get_curve(void)
{
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
}
static inline ecc_mod_base_t ecc_ll_get_mod_base(void)
{
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
}
static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
{
uint32_t reg;
switch (param) {
case ECC_PARAM_PX:
reg = ECC_MULT_PX_MEM;
break;
case ECC_PARAM_PY:
reg = ECC_MULT_PY_MEM;
break;
case ECC_PARAM_K:
reg = ECC_MULT_K_MEM;
break;
case ECC_PARAM_QX:
reg = ECC_MULT_QX_MEM;
break;
case ECC_PARAM_QY:
reg = ECC_MULT_QY_MEM;
break;
case ECC_PARAM_QZ:
reg = ECC_MULT_QZ_MEM;
break;
default:
HAL_ASSERT(false && "Invalid parameter");
return;
}
memcpy(buf, (void *)reg, len);
}
#ifdef __cplusplus
}
#endif

View File

@@ -13,6 +13,8 @@
#pragma once
#include "stdint.h"
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "hal/ecc_types.h"
#ifdef __cplusplus
@@ -96,6 +98,103 @@ int ecc_hal_read_mul_result(uint8_t *rx, uint8_t *ry, uint16_t len);
*/
int ecc_hal_read_verify_result(void);
#if SOC_ECC_EXTENDED_MODES_SUPPORTED
/**
* @brief Set the mod base value used in MOD operation
*
* @param base Identifier of the base to use
*/
void ecc_hal_set_mod_base(ecc_mod_base_t base);
/**
* @brief Write parameters for Jacobian verification
* i.e Check whether (Qx, Qy, Qz) is a point on selected curve
*
* @param qx X coordinate of the ECC point in jacobian form
* @param qy Y coordinate of the ECC point in jacobian form
* @param qz Z coordinate of the ECC point in jacobian form
* @param len Length (in bytes) of the ECC point
* - 32 bytes for SECP256R1
* - 24 bytes for SECP192R1
*/
void ecc_hal_write_jacob_verify_param(const uint8_t *qx, const uint8_t *qy, const uint8_t *qz, uint16_t len);
/**
* @brief Read ECC point multiplication result in jacobian form
*
* @param rx X coordinate of the multiplication result
* @param ry Y coordinate of the multiplication result
* @param rz Z coordinate of the multiplication result
* @param len Length (in bytes) of the ECC point
* - 32 for SECP256R1
* - 24 for SECP192R1
*
* @return - 0 if the operation was successful
* - -1 if the operation was not successful
*
* In case the operation is not successful, rx, ry, and rz will contain
* all zeros
*/
int ecc_hal_read_jacob_mul_result(uint8_t *rx, uint8_t *ry, uint8_t *rz, uint16_t len);
/**
* @brief Write parameters for ECC point addition ((Px, Py, 1) + (Qx, Qy, Qz))
*
* @param px X coordinate of the 1st addend ECC point
* @param py Y coordinate of the 1st addend ECC point
* @param qx X coordinate of the 2nd addend ECC point in jacobian form
* @param qy Y coordinate of the 2nd addend ECC point in jacobian form
* @param qz Z coordinate of the 2nd addend ECC point in jacobian form
* @param len Length (in bytes) of the ECC point
* - 32 bytes for SECP256R1
* - 24 bytes for SECP192R1
*/
void ecc_hal_write_point_add_param(const uint8_t *px, const uint8_t *py, const uint8_t *qx, const uint8_t *qy, const uint8_t *qz, uint16_t len);
/**
* @brief Read ECC point addition result
*
* @param rx X coordinate of the addition result
* @param ry Y coordinate of the addition result
* @param rz Z coordinate of the addition result
* @param len Length (in bytes) of the ECC point
* - 32 for SECP256R1
* - 24 for SECP192R1
* @param read_jacob Read the result in Jacobian form
*
* @return - 0 if the operation was successful
* - -1 otherwise
*/
int ecc_hal_read_point_add_result(uint8_t *rx, uint8_t *ry, uint8_t *rz, uint16_t len, bool read_jacob);
/**
* @brief Write parameters for mod operations
* i.e mod add, mod sub, mod mul, mod inverse mul (or mod division)
*
* @param a Value of operand 1
* @param b Value of operand 2
* @param len Length (in bytes) of the ECC point
* - 32 bytes for SECP256R1
* - 24 bytes for SECP192R1
*/
void ecc_hal_write_mod_op_param(const uint8_t *a, const uint8_t *b, uint16_t len);
/**
* @brief Read result of mod operations
* i.e mod add, mod sub, mod mul, mod inverse mul (or mod division)
*
* @param r Result of the mod operation
* @param len Length (in bytes) of the ECC point
* - 32 bytes for SECP256R1
* - 24 bytes for SECP192R1
*
* @return - 0 if operation successful
* - -1 otherwise
*/
int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len);
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
#ifdef __cplusplus
}
#endif

View File

@@ -6,13 +6,25 @@
#pragma once
typedef enum {
ECC_MODE_POINT_MUL = 0x0, // (Rx, Ry) = K * (Px, Py)
ECC_MODE_INVERSE_MUL, // R = K^(-1) * Py
ECC_MODE_VERIFY, // Check if (Px, Py) are points on the curve
ECC_MODE_VERIFY_THEN_POINT_MUL, // Verify and then perform point multiplication
ECC_MODE_POINT_MUL = 0x0, // (Rx, Ry) = K * (Px, Py)
ECC_MODE_INVERSE_MUL, // R = K^(-1) * Py
ECC_MODE_VERIFY, // Check if (Px, Py) are points on the curve
ECC_MODE_VERIFY_THEN_POINT_MUL, // Verify and then perform point multiplication
ECC_MODE_JACOBIAN_POINT_MUL,
ECC_MODE_POINT_ADD,
ECC_MODE_JACOBIAN_POINT_VERIFY,
ECC_MODE_POINT_VERIFY_JACOBIAN_MUL,
ECC_MODE_MOD_ADD,
ECC_MODE_MOD_SUB,
ECC_MODE_MOD_MUL,
} ecc_mode_t;
typedef enum {
ECC_CURVE_SECP192R1 = 0x0,
ECC_CURVE_SECP256R1,
} ecc_curve_t;
typedef enum {
ECC_MOD_N, // Order of the curve
ECC_MOD_P, // Prime modulus
} ecc_mod_base_t;

View File

@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.16)
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ecc_test)

View File

@@ -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 <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 <TARGET>
```

View File

@@ -0,0 +1,6 @@
set(srcs "app_main.c"
"test_ecc.c")
idf_component_register(SRCS ${srcs}
REQUIRES unity
WHOLE_ARCHIVE)

View File

@@ -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();
}

View File

@@ -0,0 +1,450 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#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

View File

@@ -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
};

View File

@@ -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()

View File

@@ -0,0 +1,2 @@
CONFIG_ESP_TASK_WDT_EN=y
CONFIG_ESP_TASK_WDT_INIT=n

View File

@@ -18,6 +18,14 @@
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 45000
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 670000
#define IDF_PERFORMANCE_MAX_ECP_P192_POINT_MULTIPLY_OP 11000
#define IDF_PERFORMANCE_MAX_ECP_P192_POINT_VERIFY_OP 300
#define IDF_PERFORMANCE_MAX_ECP_P256_POINT_MULTIPLY_OP 19000
#define IDF_PERFORMANCE_MAX_ECP_P256_POINT_VERIFY_OP 300
#define IDF_PERFORMANCE_MAX_ECDSA_P192_VERIFY_OP 44000
#define IDF_PERFORMANCE_MAX_ECDSA_P256_VERIFY_OP 67000
#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 26*1000*1000
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 28
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 24

View File

@@ -131,6 +131,14 @@ config SOC_DIG_SIGN_SUPPORTED
bool
default y
config SOC_ECC_SUPPORTED
bool
default y
config SOC_ECC_EXTENDED_MODES_SUPPORTED
bool
default y
config SOC_FLASH_ENC_SUPPORTED
bool
default y

View File

@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -162,6 +162,24 @@ extern "C" {
#define ECC_MULT_PY_MEM (DR_REG_ECC_MULT_BASE + 0x140)
#define ECC_MULT_PY_MEM_SIZE_BYTES 32
/** ECC_MULT_QX_MEM register
* The memory that stores Qx.
*/
#define ECC_MULT_QX_MEM (DR_REG_ECC_MULT_BASE + 0x160)
#define ECC_MULT_QX_MEM_SIZE_BYTES 32
/** ECC_MULT_QY_MEM register
* The memory that stores Qy.
*/
#define ECC_MULT_QY_MEM (DR_REG_ECC_MULT_BASE + 0x180)
#define ECC_MULT_QY_MEM_SIZE_BYTES 32
/** ECC_MULT_QZ_MEM register
* The memory that stores Qz.
*/
#define ECC_MULT_QZ_MEM (DR_REG_ECC_MULT_BASE + 0x1A0)
#define ECC_MULT_QZ_MEM_SIZE_BYTES 32
#ifdef __cplusplus
}
#endif

View File

@@ -1,11 +1,13 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -151,12 +153,15 @@ typedef struct {
volatile uint32_t k[8];
volatile uint32_t px[8];
volatile uint32_t py[8];
volatile uint32_t qx[8];
volatile uint32_t qy[8];
volatile uint32_t qz[8];
} ecc_mult_dev_t;
extern ecc_mult_dev_t ECC;
#ifndef __cplusplus
_Static_assert(sizeof(ecc_mult_dev_t) == 0x160, "Invalid size of ecc_mult_dev_t structure");
_Static_assert(sizeof(ecc_mult_dev_t) == 0x1C0, "Invalid size of ecc_mult_dev_t structure");
#endif
#ifdef __cplusplus

View File

@@ -35,6 +35,7 @@ typedef enum {
PERIPH_RSA_MODULE,
PERIPH_AES_MODULE,
PERIPH_SHA_MODULE,
PERIPH_ECC_MODULE,
PERIPH_HMAC_MODULE,
PERIPH_DS_MODULE,
PERIPH_GDMA_MODULE,

View File

@@ -58,6 +58,8 @@
#define SOC_SHA_SUPPORTED 1
#define SOC_HMAC_SUPPORTED 1
#define SOC_DIG_SIGN_SUPPORTED 1
#define SOC_ECC_SUPPORTED 1
#define SOC_ECC_EXTENDED_MODES_SUPPORTED 1
#define SOC_FLASH_ENC_SUPPORTED 1
#define SOC_SECURE_BOOT_SUPPORTED 1
#define SOC_BOD_SUPPORTED 1