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

Reply via email to