This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
The following commit(s) were added to refs/heads/master by this push:
new 4c5c48e7 nimble/ll: Fix MIC failure during encryption start
4c5c48e7 is described below
commit 4c5c48e70be93c987c30467cdcddf67923b496f9
Author: Andrzej Kaczmarek <[email protected]>
AuthorDate: Tue Sep 27 21:39:00 2022 +0200
nimble/ll: Fix MIC failure during encryption start
This fixes unexpected MIC failure when retransmission happens during
encryption start procedure as follows:
- peripheral sends LL_START_ENC_REQ unencrypted, central acks
- central sends LL_START_ENC_RSP encrypted, peripheral acks
- central retransmits LL_START_ENC_RSP for whatever reason
The problem is that peripheral increments rx packet counter after 1st
LL_START_ENC_RSP is received, so retransmission is decrypted with
different rx packet counter and thus is not valid. We properly ignore
MIC failure for retransmission, but then code checks if received PDU is
valid in currect state, i.e. encryption start procedure. Since it was
not properly decrypted, the PDU type is likely garbage and thus
considered as not allowed so we terminate connection with MIC failure.
The "ultimate" fix for such issues is to simply ignore any retransmitted
PDU with MIC failure since basically contents of such PDUs are garbage
and not really useful for any checks.
---
nimble/controller/src/ble_ll_conn.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/nimble/controller/src/ble_ll_conn.c
b/nimble/controller/src/ble_ll_conn.c
index 9bfa1f8e..12b67069 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -3434,9 +3434,15 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct
ble_mbuf_hdr *hdr)
rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
- if (BLE_MBUF_HDR_MIC_FAILURE(hdr) && (rxd_sn != connsm->last_rxd_sn)) {
- STATS_INC(ble_ll_conn_stats, mic_failures);
- ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
+ if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) {
+ /* MIC failure is expected on retransmissions since packet counter does
+ * not match, so we simply ignore retransmitted PDU with MIC failure as
+ * they do not have proper decrypted contents.
+ */
+ if (rxd_sn != connsm->last_rxd_sn) {
+ STATS_INC(ble_ll_conn_stats, mic_failures);
+ ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
+ }
goto conn_rx_data_pdu_end;
}
#endif