Skip to content

Commit 4792158

Browse files
cvinayakaescolar
authored andcommitted
Bluetooth: Controller: Broadcast ISO encryption support
Implementation of Broadcast ISO encryption using crypto toolbox function h8. And support for encryption in lower link layer for nRF5x series. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 4d3f869 commit 4792158

File tree

14 files changed

+258
-40
lines changed

14 files changed

+258
-40
lines changed

subsys/bluetooth/controller/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ zephyr_library_sources_ifdef(
171171
zephyr_library_include_directories(
172172
.
173173
include
174+
../crypto
174175
)
175176

176177
zephyr_library_compile_options_ifdef(

subsys/bluetooth/controller/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ config BT_CTLR_SYNC_ISO
721721

722722
config BT_CTLR_BROADCAST_ISO
723723
bool
724+
select BT_CRYPTO if BT_LL_SW_SPLIT
724725
default BT_CTLR_ADV_ISO || BT_CTLR_SYNC_ISO
725726

726727
config BT_CTLR_ADV_ISO_SET

subsys/bluetooth/controller/ll_sw/ll_addr.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <zephyr/bluetooth/hci.h>
1313
#include <zephyr/bluetooth/controller.h>
1414

15+
#include "hal/ccm.h"
16+
1517
#include "util/util.h"
1618
#include "util/memq.h"
1719
#include "util/mem.h"

subsys/bluetooth/controller/ll_sw/lll_adv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ struct lll_adv_iso {
7676
uint8_t ctrl_expire;
7777
uint16_t ctrl_instant;
7878

79+
/* Encryption */
80+
uint8_t giv[8];
81+
struct ccm ccm_tx;
82+
7983
uint16_t stream_handle[BT_CTLR_ADV_ISO_STREAM_MAX];
8084
};
8185

subsys/bluetooth/controller/ll_sw/lll_sync_iso.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ struct lll_sync_iso {
5656

5757
uint8_t next_chan_use;
5858

59+
/* Encryption */
60+
uint8_t giv[8];
61+
struct ccm ccm_rx;
62+
5963
uint8_t chm_chan_map[PDU_CHANNEL_MAP_SIZE];
6064
uint8_t chm_chan_count:6;
6165

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
/* PDU type, 1 bit field*/
1010
#define RADIO_PKT_CONF_PDU_TYPE_POS (0U)
1111
#define RADIO_PKT_CONF_PDU_TYPE_MSK BIT(RADIO_PKT_CONF_PDU_TYPE_POS)
12-
#define RADIO_PKT_CONF_PDU_TYPE_AC (0U)
13-
#define RADIO_PKT_CONF_PDU_TYPE_DC (1U)
12+
#define RADIO_PKT_CONF_PDU_TYPE_AC (0U)
13+
#define RADIO_PKT_CONF_PDU_TYPE_DC (1U)
14+
#define RADIO_PKT_CONF_PDU_TYPE_BIS (1U)
15+
#define RADIO_PKT_CONF_PDU_TYPE_CIS (1U)
1416
/* PHY type, three bit field */
1517
#define RADIO_PKT_CONF_PHY_POS (1U)
1618
#define RADIO_PKT_CONF_PHY_MSK (BIT_MASK(3U))

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static int prepare_cb_common(struct lll_prepare_param *p)
179179
uint32_t ticks_at_start;
180180
uint16_t event_counter;
181181
uint8_t access_addr[4];
182+
uint64_t payload_count;
182183
uint16_t data_chan_id;
183184
uint8_t data_chan_use;
184185
uint8_t crc_init[3];
@@ -198,8 +199,9 @@ static int prepare_cb_common(struct lll_prepare_param *p)
198199
/* Calculate the current event counter value */
199200
event_counter = (lll->payload_count / lll->bn) + lll->latency_event;
200201

201-
/* Update BIS packet counter to next value */
202+
/* Update BIS payload counter to next value */
202203
lll->payload_count += (lll->latency_prepare * lll->bn);
204+
payload_count = lll->payload_count - lll->bn;
203205

204206
/* Reset accumulated latencies */
205207
lll->latency_prepare = 0U;
@@ -240,7 +242,6 @@ static int prepare_cb_common(struct lll_prepare_param *p)
240242

241243
phy = lll->phy;
242244
radio_phy_set(phy, lll->phy_flags);
243-
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu, RADIO_PKT_CONF_PHY(phy));
244245
radio_aa_set(access_addr);
245246
radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
246247
lll_chan_set(data_chan_use);
@@ -250,7 +251,6 @@ static int prepare_cb_common(struct lll_prepare_param *p)
250251
struct lll_adv_iso_stream *stream;
251252
memq_link_t *link = NULL;
252253
struct node_tx_iso *tx;
253-
uint64_t payload_count;
254254
uint16_t stream_handle;
255255
uint16_t handle;
256256
uint8_t bis_idx;
@@ -262,8 +262,6 @@ static int prepare_cb_common(struct lll_prepare_param *p)
262262
stream = ull_adv_iso_lll_stream_get(stream_handle);
263263
LL_ASSERT(stream);
264264

265-
payload_count = lll->payload_count - lll->bn;
266-
267265
do {
268266
link = memq_peek(stream->memq_tx.head,
269267
stream->memq_tx.tail, (void **)&tx);
@@ -312,11 +310,11 @@ static int prepare_cb_common(struct lll_prepare_param *p)
312310
pdu->payload[2] = lll->ptc_curr;
313311
pdu->payload[3] = lll->bis_curr;
314312

315-
pdu->payload[4] = lll->payload_count;
316-
pdu->payload[5] = lll->payload_count >> 8;
317-
pdu->payload[6] = lll->payload_count >> 16;
318-
pdu->payload[7] = lll->payload_count >> 24;
319-
pdu->payload[8] = lll->payload_count >> 32;
313+
pdu->payload[4] = payload_count;
314+
pdu->payload[5] = payload_count >> 8;
315+
pdu->payload[6] = payload_count >> 16;
316+
pdu->payload[7] = payload_count >> 24;
317+
pdu->payload[8] = payload_count >> 32;
320318
#endif /* TEST_WITH_DUMMY_PDU */
321319

322320
/* Initialize reserve bit */
@@ -347,8 +345,33 @@ static int prepare_cb_common(struct lll_prepare_param *p)
347345
}
348346
pdu->cssn = lll->cssn;
349347

350-
radio_pkt_tx_set(pdu);
348+
/* Encryption */
349+
if (pdu->len && lll->enc) {
350+
uint8_t pkt_flags;
351351

352+
lll->ccm_tx.counter = payload_count;
353+
354+
(void)memcpy(lll->ccm_tx.iv, lll->giv, 4U);
355+
mem_xor_32(lll->ccm_tx.iv, lll->ccm_tx.iv, access_addr);
356+
357+
pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
358+
phy,
359+
RADIO_PKT_CONF_CTE_DISABLED);
360+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
361+
(lll->max_pdu + PDU_MIC_SIZE), pkt_flags);
362+
radio_pkt_tx_set(radio_ccm_tx_pkt_set(&lll->ccm_tx, pdu));
363+
} else {
364+
uint8_t pkt_flags;
365+
366+
pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
367+
phy,
368+
RADIO_PKT_CONF_CTE_DISABLED);
369+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu,
370+
pkt_flags);
371+
radio_pkt_tx_set(pdu);
372+
}
373+
374+
/* Setup radio IFS switching */
352375
if ((lll->bn_curr == lll->bn) &&
353376
(lll->irc_curr == lll->irc) &&
354377
(lll->ptc_curr == lll->ptc) &&
@@ -358,9 +381,11 @@ static int prepare_cb_common(struct lll_prepare_param *p)
358381
} else {
359382
uint16_t iss_us;
360383

384+
/* Calculate next subevent start based on previous PDU length */
361385
iss_us = lll->sub_interval -
362-
PDU_BIS_US(pdu->len, lll->enc, lll->phy,
363-
lll->phy_flags);
386+
PDU_BIS_US(pdu->len, ((pdu->len) ? lll->enc : 0U),
387+
lll->phy, lll->phy_flags);
388+
364389
radio_tmr_tifs_set(iss_us);
365390
radio_switch_complete_and_b2b_tx(lll->phy, lll->phy_flags,
366391
lll->phy, lll->phy_flags);
@@ -427,6 +452,7 @@ static void isr_tx_common(void *param,
427452
struct pdu_bis *pdu = NULL;
428453
struct lll_adv_iso *lll;
429454
uint8_t access_addr[4];
455+
uint64_t payload_count;
430456
uint16_t data_chan_id;
431457
uint8_t data_chan_use;
432458
uint8_t crc_init[3];
@@ -442,9 +468,8 @@ static void isr_tx_common(void *param,
442468
bis = lll->bis_curr;
443469

444470
} else if (lll->irc_curr < lll->irc) {
445-
lll->bn_curr = 0U;
446471
/* transmit the (bn_curr)th Tx PDU of bis_curr */
447-
lll->bn_curr++; /* post increment */
472+
lll->bn_curr = 1U;
448473
lll->irc_curr++; /* post increment */
449474

450475
bis = lll->bis_curr;
@@ -459,9 +484,8 @@ static void isr_tx_common(void *param,
459484
lll->bis_curr++;
460485
lll->ptc_curr = 0U;
461486
lll->irc_curr = 1U;
462-
lll->bn_curr = 0U;
463487
/* transmit the (bn_curr)th PDU of bis_curr */
464-
lll->bn_curr++; /* post increment */
488+
lll->bn_curr = 1U;
465489

466490
bis = lll->bis_curr;
467491

@@ -486,6 +510,7 @@ static void isr_tx_common(void *param,
486510

487511
/* control subevent to use bis = 0 and se_n = 1 */
488512
bis = 0U;
513+
payload_count = lll->payload_count - lll->bn;
489514
data_chan_use = lll->ctrl_chan_use;
490515

491516
} else if (((lll->chm_req - lll->chm_ack) & CHM_STATE_MASK) ==
@@ -509,6 +534,7 @@ static void isr_tx_common(void *param,
509534

510535
/* control subevent to use bis = 0 and se_n = 1 */
511536
bis = 0U;
537+
payload_count = lll->payload_count - lll->bn;
512538
data_chan_use = lll->ctrl_chan_use;
513539

514540
} else {
@@ -571,22 +597,22 @@ static void isr_tx_common(void *param,
571597

572598
/* Get ISO data PDU, not control subevent */
573599
if (!pdu) {
600+
uint8_t payload_index;
601+
602+
payload_index = (lll->bn_curr - 1U) +
603+
(lll->ptc_curr * lll->pto);
604+
payload_count = lll->payload_count + payload_index - lll->bn;
605+
574606
#if !TEST_WITH_DUMMY_PDU
575607
struct lll_adv_iso_stream *stream;
576-
uint64_t payload_count;
577608
uint16_t stream_handle;
578609
struct node_tx_iso *tx;
579-
uint8_t payload_index;
580610
memq_link_t *link;
581611

582612
stream_handle = lll->stream_handle[lll->bis_curr - 1U];
583613
stream = ull_adv_iso_lll_stream_get(stream_handle);
584614
LL_ASSERT(stream);
585615

586-
payload_index = (lll->bn_curr - 1U) +
587-
(lll->ptc_curr * lll->pto);
588-
payload_count = lll->payload_count + payload_index - lll->bn;
589-
590616
link = memq_peek_n(stream->memq_tx.head, stream->memq_tx.tail,
591617
payload_index, (void **)&tx);
592618
if (!link || (tx->payload_count != payload_count)) {
@@ -624,6 +650,12 @@ static void isr_tx_common(void *param,
624650
pdu->payload[1] = lll->irc_curr;
625651
pdu->payload[2] = lll->ptc_curr;
626652
pdu->payload[3] = lll->bis_curr;
653+
654+
pdu->payload[4] = payload_count;
655+
pdu->payload[5] = payload_count >> 8;
656+
pdu->payload[6] = payload_count >> 16;
657+
pdu->payload[7] = payload_count >> 24;
658+
pdu->payload[8] = payload_count >> 32;
627659
#endif /* TEST_WITH_DUMMY_PDU */
628660

629661
data_chan_use = lll->next_chan_use;
@@ -632,7 +664,17 @@ static void isr_tx_common(void *param,
632664

633665
lll_chan_set(data_chan_use);
634666

635-
radio_pkt_tx_set(pdu);
667+
/* Encryption */
668+
if (pdu->len && lll->enc) {
669+
lll->ccm_tx.counter = payload_count;
670+
671+
(void)memcpy(lll->ccm_tx.iv, lll->giv, 4U);
672+
mem_xor_32(lll->ccm_tx.iv, lll->ccm_tx.iv, access_addr);
673+
674+
radio_pkt_tx_set(radio_ccm_tx_pkt_set(&lll->ccm_tx, pdu));
675+
} else {
676+
radio_pkt_tx_set(pdu);
677+
}
636678

637679
/* Control subevent, then complete subevent and close radio use */
638680
if (!bis) {
@@ -644,8 +686,8 @@ static void isr_tx_common(void *param,
644686

645687
/* Calculate next subevent start based on previous PDU length */
646688
iss_us = lll->sub_interval -
647-
PDU_BIS_US(pdu->len, lll->enc, lll->phy,
648-
lll->phy_flags);
689+
PDU_BIS_US(pdu->len, ((pdu->len) ? lll->enc : 0U),
690+
lll->phy, lll->phy_flags);
649691

650692
radio_tmr_tifs_set(iss_us);
651693
radio_switch_complete_and_b2b_tx(lll->phy, lll->phy_flags,

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "hal/ticker.h"
1717

1818
#include "util/util.h"
19+
#include "util/mem.h"
1920
#include "util/memq.h"
2021

2122
#include "pdu_df.h"
@@ -289,8 +290,6 @@ static int prepare_cb_common(struct lll_prepare_param *p)
289290

290291
phy = lll->phy;
291292
radio_phy_set(phy, PHY_FLAGS_S8);
292-
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu,
293-
RADIO_PKT_CONF_PHY(phy));
294293
radio_aa_set(access_addr);
295294
radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
296295
lll_chan_set(data_chan_use);
@@ -300,7 +299,35 @@ static int prepare_cb_common(struct lll_prepare_param *p)
300299
*/
301300
node_rx = ull_iso_pdu_rx_alloc_peek(1U);
302301
LL_ASSERT(node_rx);
303-
radio_pkt_rx_set(node_rx->pdu);
302+
303+
/* Encryption */
304+
if (lll->enc) {
305+
uint64_t payload_count;
306+
uint8_t pkt_flags;
307+
308+
payload_count = lll->payload_count - lll->bn;
309+
lll->ccm_rx.counter = payload_count;
310+
311+
(void)memcpy(lll->ccm_rx.iv, lll->giv, 4U);
312+
mem_xor_32(lll->ccm_rx.iv, lll->ccm_rx.iv, access_addr);
313+
314+
pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
315+
phy,
316+
RADIO_PKT_CONF_CTE_DISABLED);
317+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT,
318+
(lll->max_pdu + PDU_MIC_SIZE), pkt_flags);
319+
radio_pkt_rx_set(radio_ccm_rx_pkt_set(&lll->ccm_rx, phy,
320+
node_rx->pdu));
321+
} else {
322+
uint8_t pkt_flags;
323+
324+
pkt_flags = RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_BIS,
325+
phy,
326+
RADIO_PKT_CONF_CTE_DISABLED);
327+
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu,
328+
pkt_flags);
329+
radio_pkt_rx_set(node_rx->pdu);
330+
}
304331

305332
radio_switch_complete_and_disable();
306333

@@ -558,6 +585,17 @@ static void isr_rx(void *param)
558585
!lll->payload[bis_idx][payload_index] &&
559586
((payload_index >= lll->payload_tail) ||
560587
(payload_index < lll->payload_head))) {
588+
if (lll->enc) {
589+
uint32_t mic_failure;
590+
uint32_t done;
591+
592+
done = radio_ccm_is_done();
593+
LL_ASSERT(done);
594+
595+
mic_failure = !radio_ccm_mic_is_valid();
596+
LL_ASSERT(!mic_failure);
597+
}
598+
561599
ull_iso_pdu_rx_alloc();
562600
isr_rx_iso_data_valid(lll, handle, node_rx);
563601

@@ -919,7 +957,27 @@ static void isr_rx(void *param)
919957
*/
920958
node_rx = ull_iso_pdu_rx_alloc_peek(1U);
921959
LL_ASSERT(node_rx);
922-
radio_pkt_rx_set(node_rx->pdu);
960+
961+
/* Encryption */
962+
if (lll->enc) {
963+
uint64_t payload_count;
964+
965+
payload_count = lll->payload_count - lll->bn;
966+
if (bis) {
967+
payload_count += (lll->bn_curr - 1U) +
968+
(lll->ptc_curr * lll->pto);
969+
}
970+
971+
lll->ccm_rx.counter = payload_count;
972+
973+
(void)memcpy(lll->ccm_rx.iv, lll->giv, 4U);
974+
mem_xor_32(lll->ccm_rx.iv, lll->ccm_rx.iv, access_addr);
975+
976+
radio_pkt_rx_set(radio_ccm_rx_pkt_set(&lll->ccm_rx, lll->phy,
977+
node_rx->pdu));
978+
} else {
979+
radio_pkt_rx_set(node_rx->pdu);
980+
}
923981

924982
radio_switch_complete_and_disable();
925983

0 commit comments

Comments
 (0)