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
commit f5c918d1b598052af2d61bf4a837d1033e11a200 Author: Andrzej Kaczmarek <[email protected]> AuthorDate: Tue Jan 31 00:30:43 2023 +0100 nimble/phy/nrf5x: Add workaround to allow encrypted ISO on nRF52840 nRF52840 does not allow to change mask for PDU header for keystream generation, but we can workaround this by masking bits out manually and then restoring original header byte after keystream is generated. This only works for TX (e.g. ISO Broadcaster) but it may still be useful. --- nimble/drivers/nrf5x/src/ble_phy.c | 43 +++++++++++++++++++++++++++++++++++++ nimble/drivers/nrf5x/src/phy_priv.h | 5 +++++ nimble/drivers/nrf5x/syscfg.yml | 9 ++++++++ 3 files changed, 57 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3e095329..c1e2df72 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -140,6 +140,10 @@ struct ble_phy_obj uint8_t phy_transition_late; uint8_t phy_rx_started; uint8_t phy_encrypted; +#if PHY_USE_HEADERMASK_WORKAROUND + uint8_t phy_headermask; + uint8_t phy_headerbyte; +#endif uint8_t phy_privacy; uint8_t phy_tx_pyld_len; uint8_t phy_cur_phy_mode; @@ -1517,6 +1521,20 @@ ble_phy_isr(void) os_trace_isr_exit(); } +#if PHY_USE_HEADERMASK_WORKAROUND +static void +ble_phy_ccm_isr(void) +{ + volatile uint8_t *tx_buf = (uint8_t *)g_ble_phy_tx_buf; + + if (NRF_CCM->EVENTS_ENDKSGEN) { + while (tx_buf[0] == 0xff); + tx_buf[0] = g_ble_phy_data.phy_headerbyte; + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; + } +} +#endif + /** * ble phy init * @@ -1599,6 +1617,12 @@ ble_phy_init(void) NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; NRF_CCM->EVENTS_ERROR = 0; memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad)); + +#if PHY_USE_HEADERMASK_WORKAROUND + NVIC_SetVector(CCM_AAR_IRQn, (uint32_t)ble_phy_ccm_isr); + NVIC_EnableIRQ(CCM_AAR_IRQn); + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk;; +#endif #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) @@ -1703,6 +1727,9 @@ ble_phy_encrypt_enable(const uint8_t *key) #ifdef NRF5340_XXAA NRF_CCM->HEADERMASK = BLE_LL_PDU_HEADERMASK_DATA; #endif +#if PHY_USE_HEADERMASK_WORKAROUND + g_ble_phy_data.phy_headermask = BLE_LL_PDU_HEADERMASK_DATA; +#endif } void @@ -1711,6 +1738,9 @@ ble_phy_encrypt_header_mask_set(uint8_t mask) #ifdef NRF5340_XXAA NRF_CCM->HEADERMASK = mask; #endif +#if PHY_USE_HEADERMASK_WORKAROUND + g_ble_phy_data.phy_headermask = mask; +#endif } void @@ -1914,6 +1944,15 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* Start key-stream generation and encryption (via short) */ if (g_ble_phy_data.phy_encrypted) { +#if PHY_USE_HEADERMASK_WORKAROUND + if (g_ble_phy_data.phy_headermask != BLE_LL_PDU_HEADERMASK_DATA) { + g_ble_phy_data.phy_headerbyte = dptr[0]; + dptr[0] &= g_ble_phy_data.phy_headermask; + g_ble_phy_tx_buf[0] = 0xffffffff; + NRF_CCM->EVENTS_ENDKSGEN = 0; + NRF_CCM->INTENSET = CCM_INTENSET_ENDKSGEN_Msk; + } +#endif nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); } #endif @@ -2134,6 +2173,10 @@ ble_phy_disable(void) { ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); +#if PHY_USE_HEADERMASK_WORKAROUND + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; +#endif + ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index 664d625c..c7323520 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -24,6 +24,11 @@ #include <nrf_gpio.h> #include <nrf_gpiote.h> + +#if defined(NRF52840_XXAA) && MYNEWT_VAL(BLE_PHY_NRF52_HEADERMASK_WORKAROUND) +#define PHY_USE_HEADERMASK_WORKAROUND 1 +#endif + #define PHY_USE_DEBUG_1 (MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0) #define PHY_USE_DEBUG_2 (MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0) #define PHY_USE_DEBUG_3 (MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0) diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index 3c8339c0..e483e844 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -55,6 +55,15 @@ syscfg.defs: This can be used to check if wfr is calculated properly. value: -1 + BLE_PHY_NRF52_HEADERMASK_WORKAROUND: + description: > + This enables workaround for lack of HEADERMASK register on some + nRF52 family MCUs (notably nRF52840) which is required for enabling + encryption for ISO PDUs. + Note: this requires exclusive access to CCM_AAR interrupt and only + works for TX (i.e. ISO Broadcaster). + value: 0 + BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: description: > Ublox BMD-345 modules come with public address preprogrammed
