nimble/ll: Check MIC on every PDU
We should check for MIC failure before any other checks to detect
failures even on corrupted PDUs.
This fixes LL/SEC/PER/BI-04-C.
@@ -3161,6 +3161,15 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
acl_len = rxbuf[1];
llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
+
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+ if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) {
+ 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
+
/*
* Check that the LLID and payload length are reasonable.
* Empty payload is only allowed for LLID == 01b.
@@ -3232,18 +3241,6 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
goto conn_rx_data_pdu_end;
}
-#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
- /*
- * XXX: should we check to see if we are in a state where we
- * might expect to get an encrypted PDU?
- */
- if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) {
- 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
-
if (llid == BLE_LL_LLID_CTRL) {
/* Process control frame */
STATS_INC(ble_ll_conn_stats, rx_ctrl_pdus);
