Skip to content

Commit e9aedae

Browse files
authored
Merge branch 'espressif:release/v5.4' into release/v5.4
2 parents 45074db + bcb3c32 commit e9aedae

File tree

269 files changed

+5108
-1653
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

269 files changed

+5108
-1653
lines changed

components/bootloader/Kconfig.projbuild

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,44 @@ menu "Security features"
11341134

11351135
If not set, the app does not care if the flash encryption eFuse bit is set or not.
11361136

1137+
config SECURE_FLASH_PSEUDO_ROUND_FUNC
1138+
bool "Permanently enable XTS-AES's pseudo rounds function"
1139+
default y
1140+
depends on SECURE_FLASH_ENCRYPTION_MODE_RELEASE && SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
1141+
help
1142+
If set (default), the bootloader will permanently enable the XTS-AES peripheral's pseudo rounds function.
1143+
Note: Enabling this config would burn an efuse.
1144+
1145+
choice SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH
1146+
prompt "Strength of the pseudo rounds function"
1147+
depends on SECURE_FLASH_PSEUDO_ROUND_FUNC
1148+
default SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_LOW
1149+
help
1150+
The strength of the pseudo rounds functions can be configured to low, medium and high,
1151+
each denoting the values that would be stored in the efuses field.
1152+
By default the value to set to low.
1153+
You can configure the strength of the pseudo rounds functions according to your use cases,
1154+
for example, increasing the strength would provide higher security but would slow down the
1155+
flash encryption/decryption operations.
1156+
For more info regarding the performance impact, please checkout the pseudo round function section of the
1157+
security guide documentation.
1158+
1159+
config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_LOW
1160+
bool "Low"
1161+
1162+
config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_MEDIUM
1163+
bool "Medium"
1164+
1165+
config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_HIGH
1166+
bool "High"
1167+
endchoice
1168+
1169+
config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH
1170+
int
1171+
default 1 if SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_LOW
1172+
default 2 if SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_MEDIUM
1173+
default 3 if SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_HIGH
1174+
11371175
config SECURE_ROM_DL_MODE_ENABLED
11381176
bool
11391177
default y if SOC_SUPPORTS_SECURE_DL_MODE && !SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT

components/bootloader_support/src/esp32h2/flash_encryption_secure_features.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <stdint.h>
78
#include <strings.h>
89
#include "esp_flash_encrypt.h"
910
#include "esp_secure_boot.h"
1011
#include "esp_efuse.h"
1112
#include "esp_efuse_table.h"
1213
#include "esp_log.h"
14+
#include "hal/spi_flash_encrypted_ll.h"
15+
#include "soc/soc_caps.h"
1316
#include "sdkconfig.h"
1417

1518
static __attribute__((unused)) const char *TAG = "flash_encrypt";
@@ -33,6 +36,14 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
3336

3437
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
3538

39+
#if defined(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE) && defined(SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND)
40+
if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) {
41+
ESP_LOGI(TAG, "Enable XTS-AES pseudo rounds function...");
42+
uint8_t xts_pseudo_level = CONFIG_SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH;
43+
esp_efuse_write_field_blob(ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL, &xts_pseudo_level, ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[0]->bit_count);
44+
}
45+
#endif
46+
3647
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
3748
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
3849
// otherwise the Flash Encryption key cannot be read protected

components/bootloader_support/src/flash_encrypt.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -12,6 +12,9 @@
1212
#include "esp_flash_encrypt.h"
1313
#include "esp_secure_boot.h"
1414
#include "hal/efuse_hal.h"
15+
#include "hal/spi_flash_encrypted_ll.h"
16+
#include "hal/spi_flash_encrypt_hal.h"
17+
#include "soc/soc_caps.h"
1518

1619
#if CONFIG_IDF_TARGET_ESP32
1720
#define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT
@@ -207,6 +210,13 @@ void esp_flash_encryption_set_release_mode(void)
207210
#endif // CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED
208211
#endif // !CONFIG_IDF_TARGET_ESP32
209212

213+
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
214+
if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) {
215+
uint8_t xts_pseudo_level = ESP_XTS_AES_PSEUDO_ROUNDS_LOW;
216+
esp_efuse_write_field_blob(ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL, &xts_pseudo_level, ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[0]->bit_count);
217+
}
218+
#endif
219+
210220
#ifdef CONFIG_IDF_TARGET_ESP32
211221
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_DIS_CACHE);
212222
#else
@@ -468,6 +478,17 @@ bool esp_flash_encryption_cfg_verify_release_mode(void)
468478
}
469479
result &= secure;
470480

481+
#if SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
482+
if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) {
483+
uint8_t xts_pseudo_level = 0;
484+
esp_efuse_read_field_blob(ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL, &xts_pseudo_level, ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[0]->bit_count);
485+
if (!xts_pseudo_level) {
486+
result &= false;
487+
ESP_LOGW(TAG, "Not enabled XTS-AES pseudo rounds function (set XTS_DPA_PSEUDO_LEVEL->1 or more)");
488+
}
489+
}
490+
#endif
491+
471492
return result;
472493
}
473494
#endif // not CONFIG_IDF_TARGET_ESP32

components/bt/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(common_include_dirs
2424
common/btc/profile/esp/blufi/include
2525
common/btc/profile/esp/include
2626
common/hci_log/include
27+
common/ble_log/include
2728
)
2829

2930
set(ble_mesh_include_dirs
@@ -132,6 +133,10 @@ if(CONFIG_BT_ENABLED)
132133
"porting/mem/bt_osi_mem.c"
133134
)
134135

136+
if(CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED)
137+
list(APPEND srcs "common/ble_log/ble_log_spi_out.c")
138+
endif()
139+
135140
# Host Bluedroid
136141
if(CONFIG_BT_BLUEDROID_ENABLED)
137142

@@ -857,6 +862,7 @@ idf_component_register(SRCS "${srcs}"
857862
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
858863
REQUIRES esp_timer esp_wifi
859864
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls esp_driver_uart vfs esp_ringbuf
865+
esp_driver_spi
860866
LDFRAGMENTS "${ldscripts}")
861867

862868
if(CONFIG_BT_ENABLED)
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include "ble_log/ble_log_spi_out.h"
7+
8+
// Private defines
9+
#define SPI_OUT_BUS SPI2_HOST
10+
11+
// Private typedefs
12+
typedef struct spi_out_trans
13+
{
14+
spi_transaction_t trans;
15+
struct spi_out_trans *next;
16+
} spi_out_trans_t;
17+
18+
// Private variables
19+
static spi_device_handle_t spi_handle = NULL;
20+
static spi_out_trans_t *trans_head = NULL;
21+
static SemaphoreHandle_t mutex_handle = NULL;
22+
static bool spi_out_inited = false;
23+
24+
// Private function declarations
25+
static void spi_out_init_trans(void);
26+
static void spi_out_deinit_trans(void);
27+
static void spi_out_recycle_trans(uint32_t ms_to_wait);
28+
static void spi_out_append_trans(void);
29+
30+
// Private functions
31+
static void spi_out_init_trans(void)
32+
{
33+
for (int i = 0; i < CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_QUEUE_SIZE; i++)
34+
{
35+
// Allocate memory for SPI transaction
36+
uint8_t *buf = (uint8_t *)spi_bus_dma_memory_alloc(SPI_OUT_BUS, CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_TRANS_BUF_SIZE, 0);
37+
assert(buf);
38+
39+
// Initialize new trans
40+
spi_out_trans_t *new_trans = (spi_out_trans_t *)malloc(sizeof(spi_out_trans_t));
41+
assert(new_trans);
42+
memset(new_trans, 0, sizeof(spi_out_trans_t));
43+
new_trans->trans.tx_buffer = buf;
44+
new_trans->trans.length = 0;
45+
46+
// Append new trans to free trans list
47+
new_trans->next = trans_head;
48+
trans_head = new_trans;
49+
}
50+
return;
51+
}
52+
53+
static void spi_out_deinit_trans(void)
54+
{
55+
// Wait up to QUEUE_SIZE * 100 ms for all transactions to complete and be recycled
56+
spi_out_recycle_trans(100);
57+
58+
// Release memory
59+
spi_out_trans_t *next;
60+
while (trans_head != NULL)
61+
{
62+
next = trans_head->next;
63+
free((uint8_t *)trans_head->trans.tx_buffer);
64+
free(trans_head);
65+
trans_head = next;
66+
}
67+
trans_head = NULL;
68+
return;
69+
}
70+
71+
IRAM_ATTR static void spi_out_recycle_trans(uint32_t ms_to_wait)
72+
{
73+
// Try to recycle transaction
74+
spi_transaction_t *ret_trans;
75+
spi_out_trans_t *recycled_trans;
76+
while (ESP_OK == spi_device_get_trans_result(spi_handle, &ret_trans, pdMS_TO_TICKS(ms_to_wait)))
77+
{
78+
recycled_trans = __containerof(ret_trans, spi_out_trans_t, trans);
79+
recycled_trans->next = trans_head;
80+
trans_head = recycled_trans;
81+
trans_head->trans.length = 0;
82+
}
83+
}
84+
85+
IRAM_ATTR static void spi_out_append_trans(void)
86+
{
87+
// Transaction head shall not be NULL for appending
88+
assert(trans_head);
89+
90+
// Detach transaction head
91+
spi_out_trans_t *trans_to_append = trans_head;
92+
trans_head = trans_head->next;
93+
trans_to_append->next = NULL;
94+
95+
// CRITICAL: Length unit conversion from bytes to bits
96+
trans_to_append->trans.length *= 8;
97+
assert(ESP_OK == spi_device_queue_trans(spi_handle, &trans_to_append->trans, 0));
98+
99+
// Try to recycle trans
100+
spi_out_recycle_trans(0);
101+
}
102+
103+
// Public functions
104+
void ble_log_spi_out_init(void)
105+
{
106+
// Avoid double init
107+
if (spi_out_inited)
108+
{
109+
return;
110+
}
111+
112+
// Initialize SPI
113+
spi_bus_config_t bus_config = {
114+
.miso_io_num = -1,
115+
.mosi_io_num = CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_MOSI_IO_NUM,
116+
.sclk_io_num = CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_SCLK_IO_NUM,
117+
.quadwp_io_num = -1,
118+
.quadhd_io_num = -1,
119+
.max_transfer_sz = 10240
120+
};
121+
spi_device_interface_config_t dev_config = {
122+
.clock_speed_hz = SPI_MASTER_FREQ_20M,
123+
.mode = 0,
124+
.spics_io_num = CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_CS_IO_NUM,
125+
.queue_size = CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_QUEUE_SIZE
126+
};
127+
ESP_ERROR_CHECK(spi_bus_initialize(SPI_OUT_BUS, &bus_config, SPI_DMA_CH_AUTO));
128+
ESP_ERROR_CHECK(spi_bus_add_device(SPI_OUT_BUS, &dev_config, &spi_handle));
129+
130+
// Initialize transaction link nodes
131+
spi_out_init_trans();
132+
133+
// Initialize mutex
134+
mutex_handle = xSemaphoreCreateMutex();
135+
136+
// Set init flag
137+
spi_out_inited = true;
138+
}
139+
140+
void ble_log_spi_out_deinit(void)
141+
{
142+
// Avoid double deinit
143+
if (!spi_out_inited)
144+
{
145+
return;
146+
}
147+
148+
// Deinitialize transaction link nodes
149+
spi_out_deinit_trans();
150+
151+
// Deinitialize SPI
152+
ESP_ERROR_CHECK(spi_bus_remove_device(spi_handle));
153+
ESP_ERROR_CHECK(spi_bus_free(SPI_OUT_BUS));
154+
spi_handle = NULL;
155+
156+
// Deinitialize mutex
157+
vSemaphoreDelete(mutex_handle);
158+
mutex_handle = NULL;
159+
160+
// Reset init flag
161+
spi_out_inited = false;
162+
}
163+
164+
IRAM_ATTR void ble_log_spi_out_write(uint32_t len, const uint8_t *addr, spi_out_source_t source)
165+
{
166+
// Take semaphore
167+
assert(xSemaphoreTake(mutex_handle, portMAX_DELAY) == pdTRUE);
168+
169+
// Recycle trans if free buffer list is empty
170+
if (!trans_head)
171+
{
172+
spi_out_recycle_trans(0);
173+
}
174+
175+
// Length of 0 means flush out
176+
if (!len)
177+
{
178+
assert(trans_head);
179+
if (trans_head->trans.length)
180+
{
181+
spi_out_append_trans();
182+
}
183+
goto release;
184+
}
185+
186+
// Copy user data to buffer
187+
uint32_t copy_buf_len;
188+
uint32_t data_left_len = len;
189+
uint32_t empty_buf_len = CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_TRANS_BUF_SIZE - trans_head->trans.length;
190+
while (data_left_len)
191+
{
192+
// There shall always be available buffer in free buffer list during write operation
193+
assert(trans_head);
194+
195+
// Copy data to buffer and update length
196+
copy_buf_len = (data_left_len > empty_buf_len) ? empty_buf_len : data_left_len;
197+
memcpy((uint8_t *)trans_head->trans.tx_buffer + trans_head->trans.length, addr + (len - data_left_len), copy_buf_len);
198+
trans_head->trans.length += copy_buf_len;
199+
data_left_len -= copy_buf_len;
200+
201+
// Transaction buffer length shall never exceed buffer size
202+
assert(trans_head->trans.length <= CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_TRANS_BUF_SIZE);
203+
204+
// If buffer is full, append transaction and reset buffer length
205+
if (trans_head->trans.length == CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_TRANS_BUF_SIZE)
206+
{
207+
spi_out_append_trans();
208+
empty_buf_len = CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_TRANS_BUF_SIZE;
209+
}
210+
}
211+
212+
release:
213+
xSemaphoreGive(mutex_handle);
214+
return;
215+
}
216+
217+
IRAM_ATTR void ble_log_spi_out_write_esp(uint32_t len, const uint8_t *addr, bool end)
218+
{
219+
ble_log_spi_out_write(len, addr, esp_controller);
220+
}

0 commit comments

Comments
 (0)