From a2bb04951bf4fe7e65f929745f5db245a3419c78 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Tue, 7 Apr 2026 16:42:08 +0300 Subject: [PATCH] host/sm: Reject Legacy pairing confirm reflection attack When the responder mirrors the initiator's confirm and random values (Sconfirm=Mconfirm, Srand=Mrand), the c1 check passes trivially, bypassing mismatch detection and causing an HCI encryption failure (0x06) instead of Pairing Failed (0x04). Detect Srand==Mrand in ble_sm_lgcy_random_rx and abort with LE_SM_ERR_CONFIRM_MISMATCH. Fixes SM/CEN/JW/BI-06-C and SM/CEN/PKE/BI-03-C --- nimble/host/src/ble_sm_lgcy.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nimble/host/src/ble_sm_lgcy.c b/nimble/host/src/ble_sm_lgcy.c index 1a500fb746..bd4c928ed5 100644 --- a/nimble/host/src/ble_sm_lgcy.c +++ b/nimble/host/src/ble_sm_lgcy.c @@ -215,6 +215,18 @@ ble_sm_lgcy_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) ble_sm_ia_ra(proc, &iat, ia, &rat, ra); + /* If the peer echoed our own random back (Srand == Mrand), the c1 check + * would trivially pass because the peer also mirrored Mconfirm. + * Reject this immediately with Confirm Value Failed. + */ + if ((proc->flags & BLE_SM_PROC_F_INITIATOR) && + memcmp(ble_sm_peer_pair_rand(proc), ble_sm_our_pair_rand(proc), 16) == 0) { + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CONFIRM_MISMATCH); + res->sm_err = BLE_SM_ERR_CONFIRM_MISMATCH; + res->enc_cb = 1; + return; + } + rc = ble_sm_alg_c1(proc->tk, ble_sm_peer_pair_rand(proc), proc->pair_req, proc->pair_rsp, iat, rat, ia, ra, confirm_val); if (rc != 0) {