From f852eac860a89fb9aaa7dd6e6251a9d9fb5d0d92 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 17 May 2023 05:41:49 +0530 Subject: [PATCH] Bluetooth: Controller: Use NRF_CCM HEADERMASK for ISO PDU encryption Use NRF_CCM HEADERMASK register to use correct Additional Authentication Data (AAD) from ISO PDU header. Signed-off-by: Vinayak Kariappa Chettimada --- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 47 +++++++++++++++++-- .../ll_sw/nordic/hal/nrf5/radio/radio.h | 28 ++++++----- .../ll_sw/nordic/lll/lll_peripheral_iso.c | 38 ++++++++------- .../ll_sw/nordic/lll/lll_sync_iso.c | 9 ++-- 4 files changed, 84 insertions(+), 38 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index dd2c5aaacb2c7e7..4043afa1afac389 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -445,7 +445,9 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags) /* To use same Data Channel PDU structure with nRF5 specific overhead * byte, include the S1 field in radio packet configuration. */ - if (pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) { + if ((pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) || + (pdu_type == RADIO_PKT_CONF_PDU_TYPE_BIS) || + (pdu_type == RADIO_PKT_CONF_PDU_TYPE_CIS)) { extra |= (RADIO_PCNF0_S1INCL_Include << RADIO_PCNF0_S1INCL_Pos) & RADIO_PCNF0_S1INCL_Msk; #if defined(CONFIG_BT_CTLR_DF) @@ -1643,7 +1645,7 @@ void radio_gpio_pa_lna_disable(void) static uint8_t MALIGN(4) _ccm_scratch[(HAL_RADIO_PDU_LEN_MAX - 4) + 16]; -void *radio_ccm_rx_pkt_set(struct ccm *ccm, uint8_t phy, void *pkt) +static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt) { uint32_t mode; @@ -1726,8 +1728,23 @@ void *radio_ccm_rx_pkt_set(struct ccm *ccm, uint8_t phy, void *pkt) NRF_CCM->MAXPACKETSIZE = max_len - 4U; #endif +#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) + switch (pdu_type) { + case RADIO_PKT_CONF_PDU_TYPE_BIS: + NRF_CCM->HEADERMASK = 0xC3; /* mask CSSN and CSTF */ + break; + case RADIO_PKT_CONF_PDU_TYPE_CIS: + NRF_CCM->HEADERMASK = 0xA3; /* mask SN, NESN, CIE and NPI */ + break; + default: + /* Using default reset value of HEADERMASK */ + NRF_CCM->HEADERMASK = 0xE3; /* mask SN, NESN and MD */ + break; + } +#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ + NRF_CCM->MODE = mode; - NRF_CCM->CNFPTR = (uint32_t)ccm; + NRF_CCM->CNFPTR = (uint32_t)cnf; NRF_CCM->INPTR = (uint32_t)_pkt_scratch; NRF_CCM->OUTPTR = (uint32_t)pkt; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; @@ -1741,7 +1758,17 @@ void *radio_ccm_rx_pkt_set(struct ccm *ccm, uint8_t phy, void *pkt) return _pkt_scratch; } -void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt) +void *radio_ccm_rx_pkt_set(struct ccm *cnf, uint8_t phy, void *pkt) +{ + return radio_ccm_ext_rx_pkt_set(cnf, phy, RADIO_PKT_CONF_PDU_TYPE_DC, pkt); +} + +void *radio_ccm_iso_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt) +{ + return radio_ccm_ext_rx_pkt_set(cnf, phy, pdu_type, pkt); +} + +static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *pkt) { uint32_t mode; @@ -1773,7 +1800,7 @@ void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt) #endif NRF_CCM->MODE = mode; - NRF_CCM->CNFPTR = (uint32_t)ccm; + NRF_CCM->CNFPTR = (uint32_t)cnf; NRF_CCM->INPTR = (uint32_t)pkt; NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; @@ -1787,6 +1814,16 @@ void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt) return _pkt_scratch; } +void *radio_ccm_tx_pkt_set(struct ccm *cnf, void *pkt) +{ + return radio_ccm_ext_tx_pkt_set(cnf, RADIO_PKT_CONF_PDU_TYPE_DC, pkt); +} + +void *radio_ccm_iso_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *pkt) +{ + return radio_ccm_ext_tx_pkt_set(cnf, pdu_type, pkt); +} + uint32_t radio_ccm_is_done(void) { nrf_ccm_int_enable(NRF_CCM, CCM_INTENSET_ENDCRYPT_Msk); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h index 93ad9272d1ab468..600d7e95481c7d9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -6,25 +6,25 @@ */ /* Set of macros related with Radio packet configuration flags */ -/* PDU type, 1 bit field*/ +/* PDU type, 2 bit field*/ #define RADIO_PKT_CONF_PDU_TYPE_POS (0U) -#define RADIO_PKT_CONF_PDU_TYPE_MSK BIT(RADIO_PKT_CONF_PDU_TYPE_POS) +#define RADIO_PKT_CONF_PDU_TYPE_MSK (BIT_MASK(2U)) #define RADIO_PKT_CONF_PDU_TYPE_AC (0U) #define RADIO_PKT_CONF_PDU_TYPE_DC (1U) -#define RADIO_PKT_CONF_PDU_TYPE_BIS (1U) -#define RADIO_PKT_CONF_PDU_TYPE_CIS (1U) +#define RADIO_PKT_CONF_PDU_TYPE_BIS (2U) +#define RADIO_PKT_CONF_PDU_TYPE_CIS (3U) /* PHY type, three bit field */ -#define RADIO_PKT_CONF_PHY_POS (1U) -#define RADIO_PKT_CONF_PHY_MSK (BIT_MASK(3U)) -#define RADIO_PKT_CONF_PHY_LEGACY (0U) -#define RADIO_PKT_CONF_PHY_1M (BIT(0U)) -#define RADIO_PKT_CONF_PHY_2M (BIT(1U)) -#define RADIO_PKT_CONF_PHY_CODED (BIT(2U)) +#define RADIO_PKT_CONF_PHY_POS (2U) +#define RADIO_PKT_CONF_PHY_MSK (BIT_MASK(3U)) +#define RADIO_PKT_CONF_PHY_LEGACY (0U) +#define RADIO_PKT_CONF_PHY_1M (BIT(0U)) +#define RADIO_PKT_CONF_PHY_2M (BIT(1U)) +#define RADIO_PKT_CONF_PHY_CODED (BIT(2U)) /* CTE enabled, 1 bit field */ -#define RADIO_PKT_CONF_CTE_POS (4U) -#define RADIO_PKT_CONF_CTE_MSK BIT(0) +#define RADIO_PKT_CONF_CTE_POS (5U) +#define RADIO_PKT_CONF_CTE_MSK (BIT_MASK(1U)) #define RADIO_PKT_CONF_CTE_DISABLED (0U) -#define RADIO_PKT_CONF_CTE_ENABLED (1U) +#define RADIO_PKT_CONF_CTE_ENABLED (1U) /* Macro to define length of the BLE packet length field in bits */ #define RADIO_PKT_CONF_LENGTH_8BIT (8U) @@ -164,7 +164,9 @@ void radio_gpio_pa_lna_enable(uint32_t trx_us); void radio_gpio_pa_lna_disable(void); void *radio_ccm_rx_pkt_set(struct ccm *ccm, uint8_t phy, void *pkt); +void *radio_ccm_iso_rx_pkt_set(struct ccm *ccm, uint8_t phy, uint8_t pdu_type, void *pkt); void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt); +void *radio_ccm_iso_tx_pkt_set(struct ccm *ccm, uint8_t pdu_type, void *pkt); uint32_t radio_ccm_is_done(void); uint32_t radio_ccm_mic_is_valid(void); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 11eba66c0dc11dd..5f4ef8fc19e7e43 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -263,20 +263,21 @@ static int prepare_cb(struct lll_prepare_param *p) (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_count; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (cis_lll->rx.max_pdu + PDU_MIC_SIZE), pkt_flags); - radio_pkt_rx_set(radio_ccm_rx_pkt_set(&cis_lll->rx.ccm, phy, - node_rx->pdu)); + radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&cis_lll->rx.ccm, phy, + RADIO_PKT_CONF_PDU_TYPE_CIS, + node_rx->pdu)); #endif /* CONFIG_BT_CTLR_LE_ENC */ } else { uint8_t pkt_flags; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, @@ -730,20 +731,21 @@ static void isr_rx(void *param) cis_lll->tx.ccm.counter = payload_count; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, cis_lll->tx.phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (cis_lll->tx.max_pdu + PDU_MIC_SIZE), pkt_flags); - radio_pkt_tx_set(radio_ccm_tx_pkt_set(&cis_lll->tx.ccm, + radio_pkt_tx_set(radio_ccm_iso_tx_pkt_set(&cis_lll->tx.ccm, + RADIO_PKT_CONF_PDU_TYPE_CIS, pdu_tx)); #endif /* CONFIG_BT_CTLR_LE_ENC */ } else { uint8_t pkt_flags; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, cis_lll->tx.phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, @@ -874,21 +876,22 @@ static void isr_tx(void *param) (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_count; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, cis_lll->rx.phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (cis_lll->rx.max_pdu + PDU_MIC_SIZE), pkt_flags); - radio_pkt_rx_set(radio_ccm_rx_pkt_set(&cis_lll->rx.ccm, - cis_lll->rx.phy, - node_rx->pdu)); + radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&cis_lll->rx.ccm, + cis_lll->rx.phy, + RADIO_PKT_CONF_PDU_TYPE_CIS, + node_rx->pdu)); #endif /* CONFIG_BT_CTLR_LE_ENC */ } else { uint8_t pkt_flags; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, cis_lll->rx.phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, @@ -1087,21 +1090,22 @@ static void isr_prepare_subevent_common(void *param) (cis_lll->rx.bn_curr - 1U); cis_lll->rx.ccm.counter = payload_count; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, cis_lll->rx.phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (cis_lll->rx.max_pdu + PDU_MIC_SIZE), pkt_flags); - radio_pkt_rx_set(radio_ccm_rx_pkt_set(&cis_lll->rx.ccm, - cis_lll->rx.phy, - node_rx->pdu)); + radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&cis_lll->rx.ccm, + cis_lll->rx.phy, + RADIO_PKT_CONF_PDU_TYPE_CIS, + node_rx->pdu)); #endif /* CONFIG_BT_CTLR_LE_ENC */ } else { uint8_t pkt_flags; - pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, + pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_CIS, cis_lll->rx.phy, RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c index 22d4a6e7521113a..51d745c270400af 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c @@ -319,8 +319,9 @@ static int prepare_cb_common(struct lll_prepare_param *p) RADIO_PKT_CONF_CTE_DISABLED); radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (lll->max_pdu + PDU_MIC_SIZE), pkt_flags); - radio_pkt_rx_set(radio_ccm_rx_pkt_set(&lll->ccm_rx, phy, - node_rx->pdu)); + radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&lll->ccm_rx, phy, + RADIO_PKT_CONF_PDU_TYPE_BIS, + node_rx->pdu)); } else { uint8_t pkt_flags; @@ -903,7 +904,9 @@ static void isr_rx(void *param) (void)memcpy(lll->ccm_rx.iv, lll->giv, 4U); mem_xor_32(lll->ccm_rx.iv, lll->ccm_rx.iv, access_addr); - radio_pkt_rx_set(radio_ccm_rx_pkt_set(&lll->ccm_rx, lll->phy, pdu)); + radio_pkt_rx_set(radio_ccm_iso_rx_pkt_set(&lll->ccm_rx, lll->phy, + RADIO_PKT_CONF_PDU_TYPE_BIS, + pdu)); } else { struct pdu_bis *pdu;