mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(esp_rom): Patch ets_ecdsa_verify() to include signature bounds check
This commit is contained in:
@@ -59,6 +59,10 @@ if(CONFIG_ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP)
|
||||
list(APPEND sources "patches/esp_rom_cache_writeback_esp32c5_esp32c61_esp32h4.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_ROM_ECDSA_VERIFY_PATCH)
|
||||
list(APPEND sources "patches/esp_rom_ecdsa.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${sources}
|
||||
INCLUDE_DIRS ${include_dirs}
|
||||
PRIV_REQUIRES ${private_required_comp}
|
||||
|
||||
@@ -119,6 +119,10 @@ config ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_BOOTLOADER_OFFSET_FLASH
|
||||
hex
|
||||
default 0x2000
|
||||
|
||||
@@ -35,5 +35,6 @@
|
||||
#define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access.
|
||||
#define ESP_ROM_DELAY_US_PATCH (1) // ROM ets_delay_us needs patch for U-mode operation
|
||||
#define ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP (1) // ROM supports the secure boot fast wakeup feature
|
||||
#define ESP_ROM_ECDSA_VERIFY_PATCH (1) // ROM ets_ecdsa_verify API requires a software patch
|
||||
#define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x2000) // Bootloader offset in flash determined by the ROM bootloader
|
||||
#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, no map parameter
|
||||
|
||||
@@ -412,7 +412,7 @@ esp_rom_km_huk_risk = 0x40000898;
|
||||
/* Functions */
|
||||
ets_emsa_pss_verify = 0x4000089c;
|
||||
ets_rsa_pss_verify = 0x400008a0;
|
||||
ets_ecdsa_verify = 0x400008a4;
|
||||
_rom_ets_ecdsa_verify = 0x400008a4;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x400008a8;
|
||||
ets_secure_boot_verify_signature = 0x400008ac;
|
||||
ets_secure_boot_read_key_digests = 0x400008b0;
|
||||
|
||||
@@ -107,6 +107,10 @@ config ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_DELAY_US_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define ESP_ROM_USB_OTG_NUM (-1) // No USB_OTG CDC in the ROM, set -1 for Kconfig usage.
|
||||
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
|
||||
#define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access.
|
||||
#define ESP_ROM_ECDSA_VERIFY_PATCH (1) // ROM ets_ecdsa_verify API requires a software patch
|
||||
#define ESP_ROM_DELAY_US_PATCH (1) // ROM ets_delay_us needs patch for U-mode operation
|
||||
#define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x0) // Bootloader offset in flash determined by the ROM bootloader
|
||||
#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, no map parameter
|
||||
|
||||
@@ -370,7 +370,7 @@ ets_efuse_usb_device_disabled = 0x40000808;
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
ets_ecdsa_verify = 0x40000810;
|
||||
_rom_ets_ecdsa_verify = 0x40000810;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x40000814;
|
||||
ets_secure_boot_verify_signature = 0x40000818;
|
||||
ets_secure_boot_read_key_digests = 0x4000081c;
|
||||
|
||||
@@ -115,6 +115,10 @@ config ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_BOOTLOADER_OFFSET_FLASH
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
@@ -34,4 +34,5 @@
|
||||
#define ESP_ROM_NO_USB_SERIAL_OUTPUT_API (1) // ROM does not export the usb-serial-jtag write char function
|
||||
#define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access.
|
||||
#define ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP (1) // ROM supports the secure boot fast wakeup feature
|
||||
#define ESP_ROM_ECDSA_VERIFY_PATCH (1) // ROM ets_ecdsa_verify API requires a software patch
|
||||
#define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x0) // Bootloader offset in flash determined by the ROM bootloader
|
||||
|
||||
@@ -361,7 +361,7 @@ ets_efuse_secure_boot_fast_wake_enabled = 0x40000830;
|
||||
/* Functions */
|
||||
ets_emsa_pss_verify = 0x40000834;
|
||||
ets_rsa_pss_verify = 0x40000838;
|
||||
ets_ecdsa_verify = 0x4000083c;
|
||||
_rom_ets_ecdsa_verify = 0x4000083c;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x40000840;
|
||||
ets_secure_boot_verify_signature = 0x40000844;
|
||||
ets_secure_boot_read_key_digests = 0x40000848;
|
||||
|
||||
@@ -71,6 +71,10 @@ config ESP_ROM_RAM_APP_NEEDS_MMU_INIT
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_BOOTLOADER_OFFSET_FLASH
|
||||
hex
|
||||
default 0x2000
|
||||
|
||||
@@ -23,5 +23,6 @@
|
||||
#define ESP_ROM_USB_OTG_NUM (-1) // No USB_OTG CDC in the ROM, set -1 for Kconfig usage.
|
||||
#define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock
|
||||
#define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init
|
||||
#define ESP_ROM_ECDSA_VERIFY_PATCH (1) // ROM ets_ecdsa_verify API requires a software patch
|
||||
#define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x2000) // Bootloader offset in flash determined by the ROM bootloader
|
||||
#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_NO_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, no map parameter
|
||||
|
||||
@@ -385,7 +385,7 @@ esp_rom_recover_key = 0x400007cc;
|
||||
***************************************/
|
||||
|
||||
/* Functions */
|
||||
ets_ecdsa_verify = 0x400007d0;
|
||||
_rom_ets_ecdsa_verify = 0x400007d0;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x400007d4;
|
||||
ets_secure_boot_verify_signature = 0x400007d8;
|
||||
ets_secure_boot_read_key_digests = 0x400007dc;
|
||||
|
||||
@@ -87,6 +87,10 @@ config ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_BOOTLOADER_OFFSET_FLASH
|
||||
hex
|
||||
default 0x2000
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
#define ESP_ROM_CLIC_INT_TYPE_PATCH (1) // ROM api esprv_intc_int_set_type configuring edge type interrupt (old revisions)
|
||||
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
|
||||
#define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access.
|
||||
#define ESP_ROM_ECDSA_VERIFY_PATCH (1) // ROM ets_ecdsa_verify API requires a software patch
|
||||
#define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x2000) // Bootloader offset in flash determined by the ROM bootloader
|
||||
#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, need map parameter
|
||||
|
||||
@@ -450,7 +450,7 @@ esp_rom_km_huk_risk = 0x4fc0071c;
|
||||
/* Functions */
|
||||
ets_emsa_pss_verify = 0x4fc00720;
|
||||
ets_rsa_pss_verify = 0x4fc00724;
|
||||
ets_ecdsa_verify = 0x4fc00728;
|
||||
_rom_ets_ecdsa_verify = 0x4fc00728;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x4fc0072c;
|
||||
ets_secure_boot_verify_signature = 0x4fc00730;
|
||||
ets_secure_boot_read_key_digests = 0x4fc00734;
|
||||
|
||||
@@ -448,7 +448,7 @@ esp_rom_km_huk_risk = 0x4fc00710;
|
||||
/* Functions */
|
||||
ets_emsa_pss_verify = 0x4fc00714;
|
||||
ets_rsa_pss_verify = 0x4fc00718;
|
||||
ets_ecdsa_verify = 0x4fc0071c;
|
||||
_rom_ets_ecdsa_verify = 0x4fc0071c;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x4fc00720;
|
||||
ets_secure_boot_verify_signature = 0x4fc00724;
|
||||
ets_secure_boot_read_key_digests = 0x4fc00728;
|
||||
|
||||
@@ -91,6 +91,10 @@ config ESP_ROM_PRINTS_LOCKUP_STATUS
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_BOOTLOADER_OFFSET_FLASH
|
||||
hex
|
||||
default 0x2000
|
||||
|
||||
@@ -29,5 +29,6 @@
|
||||
#define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information
|
||||
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
|
||||
#define ESP_ROM_PRINTS_LOCKUP_STATUS (1) // ROM bootloader already prints CPU lockup diagnostic status
|
||||
#define ESP_ROM_ECDSA_VERIFY_PATCH (1) // ROM ets_ecdsa_verify API requires a software patch
|
||||
#define ESP_ROM_BOOTLOADER_OFFSET_FLASH (0x2000) // Bootloader offset in flash determined by the ROM bootloader
|
||||
#define ESP_ROM_CACHE_WRITEBACK_NEEDS_SYNC_TWICE_MAP (1) // ROM cache writeback related needs patch to avoid sync loss, need map parameter
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -13,10 +13,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */
|
||||
#define ETS_DIGEST_SHA256_LEN 32 /* SHA-256, bytes */
|
||||
#define ETS_DIGEST_SHA384_LEN 48 /* SHA-384, bytes */
|
||||
|
||||
typedef enum {
|
||||
ECDSA_CURVE_P192 = 1,
|
||||
ECDSA_CURVE_P256 = 2
|
||||
ECDSA_CURVE_P256 = 2,
|
||||
ECDSA_CURVE_P384 = 3
|
||||
} ECDSA_CURVE;
|
||||
|
||||
int ets_ecdsa_verify(const uint8_t *key, const uint8_t *sig, ECDSA_CURVE curve_id, const uint8_t *digest, uint8_t *verified_digest);
|
||||
|
||||
@@ -467,7 +467,7 @@ esp_rom_recover_key = 0x2f8008b8;
|
||||
/* Functions */
|
||||
ets_emsa_pss_verify = 0x2f8008bc;
|
||||
ets_rsa_pss_verify = 0x2f8008c0;
|
||||
ets_ecdsa_verify = 0x2f8008c4;
|
||||
_rom_ets_ecdsa_verify = 0x2f8008c4;
|
||||
ets_secure_boot_verify_bootloader_with_keys = 0x2f8008c8;
|
||||
ets_secure_boot_verify_signature = 0x2f8008cc;
|
||||
ets_secure_boot_read_key_digests = 0x2f8008d0;
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_rom_caps.h"
|
||||
#if ESP_ROM_ECDSA_VERIFY_PATCH
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_fault.h"
|
||||
#include "rom/ecdsa.h"
|
||||
|
||||
#define VALID_MAGIC_OK 0x6A6A6A6AU
|
||||
#define VALID_MAGIC_FAIL 0x95959595U
|
||||
|
||||
static const uint32_t ecdsa_n_p192[6] = {
|
||||
0xb4d22831U, 0x146bc9b1U, 0x99def836U, 0xffffffffU, 0xffffffffU, 0xffffffffU,
|
||||
};
|
||||
|
||||
static const uint32_t ecdsa_n_p256[8] = {
|
||||
0xfc632551U, 0xf3b9cac2U, 0xa7179e84U, 0xbce6faadU, 0xffffffffU, 0xffffffffU, 0x00000000U, 0xffffffffU,
|
||||
};
|
||||
|
||||
#if SOC_ECDSA_SUPPORT_CURVE_P384
|
||||
static const uint32_t ecdsa_n_p384[12] = {
|
||||
0xccc52973U, 0xecec196aU, 0x48b0a77aU, 0x581a0db2U, 0xf4372ddfU, 0xc7634d81U,
|
||||
0xffffffffU, 0xffffffffU, 0xffffffffU, 0xffffffffU, 0xffffffffU, 0xffffffffU,
|
||||
};
|
||||
#endif
|
||||
|
||||
static uint32_t ecdsa_mpi_isZero(const uint32_t *mpi, int num_words)
|
||||
{
|
||||
uint32_t bits = 0;
|
||||
for (int i = 0; i < num_words; ++i) {
|
||||
bits |= mpi[i];
|
||||
}
|
||||
return (bits == 0);
|
||||
}
|
||||
|
||||
static int ecdsa_mpi_cmp_unsafe(const uint32_t *left, const uint32_t *right, int num_words)
|
||||
{
|
||||
for (int i = num_words - 1; i >= 0; --i) {
|
||||
if (left[i] > right[i]) {
|
||||
return 1;
|
||||
} else if (left[i] < right[i]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ecdsa_scalars_in_range(const uint32_t *r, const uint32_t *s, const uint32_t *n, int num_words, uint32_t *result)
|
||||
{
|
||||
volatile uint32_t verdict = VALID_MAGIC_FAIL;
|
||||
if (ecdsa_mpi_isZero(r, num_words) == 0 && ecdsa_mpi_cmp_unsafe(n, r, num_words) == 1 && ecdsa_mpi_isZero(s, num_words) == 0
|
||||
&& ecdsa_mpi_cmp_unsafe(n, s, num_words) == 1) {
|
||||
verdict = VALID_MAGIC_OK;
|
||||
}
|
||||
if (verdict != VALID_MAGIC_OK) {
|
||||
return false;
|
||||
}
|
||||
ESP_FAULT_ASSERT(verdict == VALID_MAGIC_OK);
|
||||
|
||||
*result = VALID_MAGIC_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
extern int _rom_ets_ecdsa_verify(const uint8_t *key, const uint8_t *sig,
|
||||
ECDSA_CURVE curve_id, const uint8_t *image_digest,
|
||||
uint8_t *verified_digest);
|
||||
|
||||
int ets_ecdsa_verify(const uint8_t *key, const uint8_t *sig,
|
||||
ECDSA_CURVE curve_id, const uint8_t *image_digest,
|
||||
uint8_t *verified_digest)
|
||||
{
|
||||
int words;
|
||||
int bytes;
|
||||
const uint32_t *n;
|
||||
|
||||
if (curve_id == ECDSA_CURVE_P256) {
|
||||
words = 8;
|
||||
bytes = 32;
|
||||
n = ecdsa_n_p256;
|
||||
}
|
||||
#if SOC_ECDSA_SUPPORT_CURVE_P384
|
||||
else if (curve_id == ECDSA_CURVE_P384) {
|
||||
words = 12;
|
||||
bytes = 48;
|
||||
n = ecdsa_n_p384;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
// curve_id == ECDSA_CURVE_P192
|
||||
words = 6;
|
||||
bytes = 24;
|
||||
n = ecdsa_n_p192;
|
||||
}
|
||||
|
||||
uint32_t r[12] = { 0 };
|
||||
uint32_t s[12] = { 0 };
|
||||
memcpy(r, &sig[0], bytes);
|
||||
memcpy(s, &sig[bytes], bytes);
|
||||
|
||||
uint32_t ret_status = VALID_MAGIC_FAIL;
|
||||
bool ok = ecdsa_scalars_in_range(r, s, n, words, &ret_status);
|
||||
if (!ok || ret_status != VALID_MAGIC_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ESP_FAULT_ASSERT(ok && ret_status == VALID_MAGIC_OK);
|
||||
|
||||
int ret = _rom_ets_ecdsa_verify(key, sig, curve_id, image_digest, verified_digest);
|
||||
|
||||
if (ret == 1) {
|
||||
ESP_FAULT_ASSERT(ret_status == VALID_MAGIC_OK);
|
||||
int sig_diff = (memcmp(r, &sig[0], bytes) | memcmp(s, &sig[bytes], bytes));
|
||||
ESP_FAULT_ASSERT(sig_diff == 0);
|
||||
ESP_FAULT_ASSERT(ret == 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* ESP_ROM_ECDSA_VERIFY_PATCH */
|
||||
Reference in New Issue
Block a user