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 <andrzej.kaczma...@codecoup.pl> 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