From e719129476acfc49870dfcde951f2d547df2b781 Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Fri, 11 Sep 2026 18:32:13 +0800 Subject: [PATCH 1/2] fix(bt): fixed multiple CVE issues for Bluetooth Classic Controller - fixed multiple CVE bugs of Bluetooth Classic controller on ESP32-S31 - coex: improved BR/EDR ACL active scheduling in case of Wi-Fi coexistence - SCO: reject unexpected LMP PDU received in SCO related LMP procedures --- components/bt/controller/esp32s31/btdm_broker.c | 8 ++++++-- components/bt/controller/lib_esp32s31/esp32s31-bt-lib | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/esp32s31/btdm_broker.c b/components/bt/controller/esp32s31/btdm_broker.c index 85f9f0bc845..090aac88d30 100644 --- a/components/bt/controller/esp32s31/btdm_broker.c +++ b/components/bt/controller/esp32s31/btdm_broker.c @@ -239,6 +239,7 @@ extern int btdm_common_sched_bredr_on_sched_hw_list_done(void *param); extern int hci_tl_bredr_on_rx_cmd_c2h_num_pkt(void *param); extern int hci_tl_bredr_on_rx_cmd_set_c2h_flow_ctrl(void *param); extern int odm_afh_on_coex_wifi_channel_change(void *param); +extern int olc_acl_on_coex_schm_update(void *param); extern int olc_intc_on_hal_exit_isr(void *param); extern int olc_sleep_on_sched_actual_time_get(void *param); extern int olc_sleep_on_sched_get_earlist_ticks(void *param); @@ -406,11 +407,14 @@ const void * const _base_linear_broker_flash[] = BTDM_BROKER_NODE_DEF_FLASH( #endif /* UC_BT_CTRL_BLE_IS_ENABLE */ const void * const _btdm_coex_linear_broker_flash[] = BTDM_BROKER_NODE_DEF_FLASH( -#if UC_BT_CTRL_BLE_IS_ENABLE [1] = BTDM_BROKER_ENTRY_DEF_FLASH( +#if UC_BT_CTRL_BLE_IS_ENABLE brk_sym_coexHook_WcEp3uxRHd6HYgB0pn0L, - ), #endif /* UC_BT_CTRL_BLE_IS_ENABLE */ +#if UC_BT_CTRL_BR_EDR_IS_ENABLE + olc_acl_on_coex_schm_update, +#endif /* UC_BT_CTRL_BR_EDR_IS_ENABLE */ + ), [2] = BTDM_BROKER_ENTRY_DEF_FLASH( #if UC_BT_CTRL_BLE_IS_ENABLE brk_sym_coexHook_wiWNhAUWlHyTZ7Z5ZC5Z, diff --git a/components/bt/controller/lib_esp32s31/esp32s31-bt-lib b/components/bt/controller/lib_esp32s31/esp32s31-bt-lib index 20e84f6ebe5..6c9006063d8 160000 --- a/components/bt/controller/lib_esp32s31/esp32s31-bt-lib +++ b/components/bt/controller/lib_esp32s31/esp32s31-bt-lib @@ -1 +1 @@ -Subproject commit 20e84f6ebe5f278a9d72f8a2676206e0c40d26be +Subproject commit 6c9006063d8e9e09915416cbda267e01cf2248be From 8dc1fd60aa1332c290cc2b5e1f4e592e508b1ecf Mon Sep 17 00:00:00 2001 From: liqigan Date: Tue, 18 Aug 2026 15:05:54 +0800 Subject: [PATCH 2/2] fix(bt): Check the peer ECDH public key when using mbedtls --- .../porting_btdm/controller/bredr/src/bredr.c | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/components/bt/porting_btdm/controller/bredr/src/bredr.c b/components/bt/porting_btdm/controller/bredr/src/bredr.c index 50caaa53e22..4ff407bcf42 100644 --- a/components/bt/porting_btdm/controller/bredr/src/bredr.c +++ b/components/bt/porting_btdm/controller/bredr/src/bredr.c @@ -295,6 +295,41 @@ static int bredr_psa_gen_keypair(bool p256, uint8_t *public_key, uint8_t *privat return 0; } +/* + * CVE-2018-5383: validate the peer's public key is a valid point on the curve + * before using it in the DH computation. PSA validates the point (rejects the + * point at infinity and out-of-range coordinates) when importing it as a public key. + */ +static int bredr_psa_validate_peer_pubkey(bool p256, const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y) +{ + const size_t coord_len = p256 ? BREDR_P256_COORD_LEN : BREDR_P192_COORD_LEN; + const size_t pub_len = p256 ? BREDR_PUB_KEY_LEN_P256 : BREDR_PUB_KEY_LEN_P192; + + uint8_t pk[BREDR_PUB_KEY_LEN_P256]; /* uncompressed: 0x04 || X || Y */ + + pk[0] = 0x04; + btdm_swap_buf(&pk[1], peer_pub_key_x, coord_len); + btdm_swap_buf(&pk[1 + coord_len], peer_pub_key_y, coord_len); + + psa_key_attributes_t pub_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t pub_key_id = 0; + psa_status_t pub_status; + + psa_set_key_type(&pub_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&pub_attr, p256 ? 256 : 192); + psa_set_key_usage_flags(&pub_attr, 0); + + pub_status = psa_import_key(&pub_attr, pk, pub_len, &pub_key_id); + psa_reset_key_attributes(&pub_attr); + if (pub_status != PSA_SUCCESS) { + ESP_LOGE(TAG_BREDR_CRYPTO, "invalid peer public key: psa_import_key failed: %d", (int)pub_status); + return -1; + } + + psa_destroy_key(pub_key_id); + return 0; +} + static int bredr_psa_gen_dhkey(bool p256, const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey) { @@ -306,11 +341,18 @@ static int bredr_psa_gen_dhkey(bool p256, const uint8_t *peer_pub_key_x, const u uint8_t pk[65]; uint8_t dh[32]; - btdm_swap_buf(priv, our_priv_key, priv_len); + /* Validate the peer's public key before using it in the DH computation. */ + if (bredr_psa_validate_peer_pubkey(p256, peer_pub_key_x, peer_pub_key_y) != 0) { + return -1; + } + + /* Reconstruct the peer public key in uncompressed form (0x04 || X || Y). */ pk[0] = 0x04; btdm_swap_buf(&pk[1], peer_pub_key_x, coord_len); btdm_swap_buf(&pk[1 + coord_len], peer_pub_key_y, coord_len); + btdm_swap_buf(priv, our_priv_key, priv_len); + psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; psa_key_id_t key_id = 0; psa_status_t status;