Skip to content

Commit 19f7a6f

Browse files
cvinayakAnas Nashif
authored andcommitted
Bluetooth: controller: Fix MIC error due to parallel Enc Proc
Fix to disallow initiating LE Start Encryption while another procedure is in progress. Similarly, disallow initiating another procedure while Encryption procedure is in progress. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 4aaf544 commit 19f7a6f

File tree

2 files changed

+113
-96
lines changed

2 files changed

+113
-96
lines changed

subsys/bluetooth/controller/ll_sw/ctrl.c

Lines changed: 112 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,21 +2470,26 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx,
24702470
break;
24712471

24722472
case PDU_DATA_LLCTRL_TYPE_START_ENC_REQ:
2473-
LL_ASSERT(_radio.conn_curr->llcp_req ==
2474-
_radio.conn_curr->llcp_ack);
2473+
LL_ASSERT((_radio.conn_curr->llcp_req ==
2474+
_radio.conn_curr->llcp_ack) ||
2475+
(_radio.conn_curr->llcp_type == LLCP_ENCRYPTION));
24752476

24762477
/* start enc rsp to be scheduled in master prepare */
2478+
_radio.conn_curr->llcp.encryption.initiate = 0;
24772479
_radio.conn_curr->llcp_type = LLCP_ENCRYPTION;
24782480
_radio.conn_curr->llcp_ack--;
24792481
break;
24802482

24812483
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
24822484
if (_radio.role == ROLE_SLAVE) {
24832485
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
2484-
LL_ASSERT(_radio.conn_curr->llcp_req ==
2485-
_radio.conn_curr->llcp_ack);
2486+
LL_ASSERT((_radio.conn_curr->llcp_req ==
2487+
_radio.conn_curr->llcp_ack) ||
2488+
(_radio.conn_curr->llcp_type ==
2489+
LLCP_ENCRYPTION));
24862490

24872491
/* start enc rsp to be scheduled in slave prepare */
2492+
_radio.conn_curr->llcp.encryption.initiate = 0;
24882493
_radio.conn_curr->llcp_type = LLCP_ENCRYPTION;
24892494
_radio.conn_curr->llcp_ack--;
24902495
#else /* CONFIG_BT_CTLR_FAST_ENC */
@@ -6675,130 +6680,134 @@ static inline void event_enc_reject_prep(struct connection *conn,
66756680
static inline void event_enc_prep(struct connection *conn)
66766681
{
66776682
struct radio_pdu_node_tx *node_tx;
6683+
struct pdu_data *pdu_ctrl_tx;
6684+
6685+
if (conn->llcp.encryption.initiate) {
6686+
return;
6687+
}
66786688

66796689
node_tx = mem_acquire(&_radio.pkt_tx_ctrl_free);
6680-
if (node_tx) {
6681-
struct pdu_data *pdu_ctrl_tx =
6682-
(struct pdu_data *)node_tx->pdu_data;
6690+
if (!node_tx) {
6691+
return;
6692+
}
66836693

6684-
/* master sends encrypted enc start rsp in control priority */
6685-
if (!conn->role) {
6686-
/* calc the Session Key */
6687-
ecb_encrypt(&conn->llcp.encryption.ltk[0],
6688-
&conn->llcp.encryption.skd[0],
6689-
NULL, &conn->ccm_rx.key[0]);
6694+
pdu_ctrl_tx = (void *)node_tx->pdu_data;
66906695

6691-
/* copy the Session Key */
6692-
memcpy(&conn->ccm_tx.key[0], &conn->ccm_rx.key[0],
6693-
sizeof(conn->ccm_tx.key));
6696+
/* master sends encrypted enc start rsp in control priority */
6697+
if (!conn->role) {
6698+
/* calc the Session Key */
6699+
ecb_encrypt(&conn->llcp.encryption.ltk[0],
6700+
&conn->llcp.encryption.skd[0],
6701+
NULL, &conn->ccm_rx.key[0]);
66946702

6695-
/* copy the IV */
6696-
memcpy(&conn->ccm_tx.iv[0], &conn->ccm_rx.iv[0],
6697-
sizeof(conn->ccm_tx.iv));
6703+
/* copy the Session Key */
6704+
memcpy(&conn->ccm_tx.key[0], &conn->ccm_rx.key[0],
6705+
sizeof(conn->ccm_tx.key));
66986706

6699-
/* initialise counter */
6700-
conn->ccm_rx.counter = 0;
6701-
conn->ccm_tx.counter = 0;
6707+
/* copy the IV */
6708+
memcpy(&conn->ccm_tx.iv[0], &conn->ccm_rx.iv[0],
6709+
sizeof(conn->ccm_tx.iv));
67026710

6703-
/* set direction: slave to master = 0,
6704-
* master to slave = 1
6705-
*/
6706-
conn->ccm_rx.direction = 0;
6707-
conn->ccm_tx.direction = 1;
6711+
/* initialise counter */
6712+
conn->ccm_rx.counter = 0;
6713+
conn->ccm_tx.counter = 0;
67086714

6709-
/* enable receive encryption */
6710-
conn->enc_rx = 1;
6715+
/* set direction: slave to master = 0,
6716+
* master to slave = 1
6717+
*/
6718+
conn->ccm_rx.direction = 0;
6719+
conn->ccm_tx.direction = 1;
67116720

6712-
/* send enc start resp */
6713-
start_enc_rsp_send(conn, pdu_ctrl_tx);
6714-
}
6721+
/* enable receive encryption */
6722+
conn->enc_rx = 1;
67156723

6716-
/* slave send reject ind or start enc req at control priority */
6724+
/* send enc start resp */
6725+
start_enc_rsp_send(conn, pdu_ctrl_tx);
6726+
}
6727+
6728+
/* slave send reject ind or start enc req at control priority */
67176729

67186730
#if defined(CONFIG_BT_CTLR_FAST_ENC)
6719-
else {
6731+
else {
67206732
#else /* !CONFIG_BT_CTLR_FAST_ENC */
6721-
else if (!conn->pause_tx || conn->refresh) {
6733+
else if (!conn->pause_tx || conn->refresh) {
67226734
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
67236735

6724-
/* place the reject ind packet as next in tx queue */
6725-
if (conn->llcp.encryption.error_code) {
6726-
event_enc_reject_prep(conn, pdu_ctrl_tx);
6727-
}
6728-
/* place the start enc req packet as next in tx queue */
6729-
else {
6736+
/* place the reject ind packet as next in tx queue */
6737+
if (conn->llcp.encryption.error_code) {
6738+
event_enc_reject_prep(conn, pdu_ctrl_tx);
6739+
}
6740+
/* place the start enc req packet as next in tx queue */
6741+
else {
67306742

67316743
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
6732-
u8_t err;
6744+
u8_t err;
67336745

6734-
/* TODO BT Spec. text: may finalize the sending
6735-
* of additional data channel PDUs queued in the
6736-
* controller.
6737-
*/
6738-
err = enc_rsp_send(conn);
6739-
if (err) {
6740-
mem_release(node_tx,
6741-
&_radio.pkt_tx_ctrl_free);
6746+
/* TODO BT Spec. text: may finalize the sending
6747+
* of additional data channel PDUs queued in the
6748+
* controller.
6749+
*/
6750+
err = enc_rsp_send(conn);
6751+
if (err) {
6752+
mem_release(node_tx, &_radio.pkt_tx_ctrl_free);
67426753

6743-
return;
6744-
}
6754+
return;
6755+
}
67456756
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
67466757

6747-
/* calc the Session Key */
6748-
ecb_encrypt(&conn->llcp.encryption.ltk[0],
6749-
&conn->llcp.encryption.skd[0], NULL,
6750-
&conn->ccm_rx.key[0]);
6758+
/* calc the Session Key */
6759+
ecb_encrypt(&conn->llcp.encryption.ltk[0],
6760+
&conn->llcp.encryption.skd[0], NULL,
6761+
&conn->ccm_rx.key[0]);
67516762

6752-
/* copy the Session Key */
6753-
memcpy(&conn->ccm_tx.key[0],
6754-
&conn->ccm_rx.key[0],
6755-
sizeof(conn->ccm_tx.key));
6763+
/* copy the Session Key */
6764+
memcpy(&conn->ccm_tx.key[0],
6765+
&conn->ccm_rx.key[0],
6766+
sizeof(conn->ccm_tx.key));
67566767

6757-
/* copy the IV */
6758-
memcpy(&conn->ccm_tx.iv[0], &conn->ccm_rx.iv[0],
6759-
sizeof(conn->ccm_tx.iv));
6768+
/* copy the IV */
6769+
memcpy(&conn->ccm_tx.iv[0], &conn->ccm_rx.iv[0],
6770+
sizeof(conn->ccm_tx.iv));
67606771

6761-
/* initialise counter */
6762-
conn->ccm_rx.counter = 0;
6763-
conn->ccm_tx.counter = 0;
6772+
/* initialise counter */
6773+
conn->ccm_rx.counter = 0;
6774+
conn->ccm_tx.counter = 0;
67646775

6765-
/* set direction: slave to master = 0,
6766-
* master to slave = 1
6767-
*/
6768-
conn->ccm_rx.direction = 1;
6769-
conn->ccm_tx.direction = 0;
6776+
/* set direction: slave to master = 0,
6777+
* master to slave = 1
6778+
*/
6779+
conn->ccm_rx.direction = 1;
6780+
conn->ccm_tx.direction = 0;
67706781

6771-
/* enable receive encryption (transmit turned
6772-
* on when start enc resp from master is
6773-
* received)
6774-
*/
6775-
conn->enc_rx = 1;
6776-
6777-
/* prepare the start enc req */
6778-
pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL;
6779-
pdu_ctrl_tx->len =
6780-
offsetof(struct pdu_data_llctrl,
6781-
ctrldata);
6782-
pdu_ctrl_tx->payload.llctrl.opcode =
6783-
PDU_DATA_LLCTRL_TYPE_START_ENC_REQ;
6784-
}
6782+
/* enable receive encryption (transmit turned
6783+
* on when start enc resp from master is
6784+
* received)
6785+
*/
6786+
conn->enc_rx = 1;
6787+
6788+
/* prepare the start enc req */
6789+
pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL;
6790+
pdu_ctrl_tx->len = offsetof(struct pdu_data_llctrl,
6791+
ctrldata);
6792+
pdu_ctrl_tx->payload.llctrl.opcode =
6793+
PDU_DATA_LLCTRL_TYPE_START_ENC_REQ;
6794+
}
67856795

67866796
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
6787-
} else {
6788-
start_enc_rsp_send(_radio.conn_curr, pdu_ctrl_tx);
6797+
} else {
6798+
start_enc_rsp_send(_radio.conn_curr, pdu_ctrl_tx);
67896799

6790-
/* resume data packet rx and tx */
6791-
_radio.conn_curr->pause_rx = 0;
6792-
_radio.conn_curr->pause_tx = 0;
6800+
/* resume data packet rx and tx */
6801+
_radio.conn_curr->pause_rx = 0;
6802+
_radio.conn_curr->pause_tx = 0;
67936803
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
67946804

6795-
}
6805+
}
67966806

6797-
ctrl_tx_enqueue(conn, node_tx);
6807+
ctrl_tx_enqueue(conn, node_tx);
67986808

6799-
/* procedure request acked */
6800-
conn->llcp_ack = conn->llcp_req;
6801-
}
6809+
/* procedure request acked */
6810+
conn->llcp_ack = conn->llcp_req;
68026811
}
68036812
#endif /* CONFIG_BT_CTLR_LE_ENC */
68046813

@@ -10481,7 +10490,7 @@ u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
1048110490
struct radio_pdu_node_tx *node_tx;
1048210491

1048310492
conn = connection_get(handle);
10484-
if (!conn) {
10493+
if (!conn || (conn->llcp_req != conn->llcp_ack)) {
1048510494
return 1;
1048610495
}
1048710496

@@ -10534,6 +10543,11 @@ u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
1053410543
return 1;
1053510544
}
1053610545

10546+
conn->llcp.encryption.initiate = 1;
10547+
10548+
conn->llcp_type = LLCP_ENCRYPTION;
10549+
conn->llcp_req++;
10550+
1053710551
return 0;
1053810552
}
1053910553

@@ -10557,6 +10571,7 @@ u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code,
1055710571
}
1055810572

1055910573
conn->llcp.encryption.error_code = error_code;
10574+
conn->llcp.encryption.initiate = 0;
1056010575

1056110576
conn->llcp_type = LLCP_ENCRYPTION;
1056210577
conn->llcp_req++;
@@ -10579,6 +10594,7 @@ u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code,
1057910594
}
1058010595

1058110596
conn->llcp.encryption.error_code = 0;
10597+
conn->llcp.encryption.initiate = 0;
1058210598

1058310599
conn->llcp_type = LLCP_ENCRYPTION;
1058410600
conn->llcp_req++;

subsys/bluetooth/controller/ll_sw/ctrl_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ struct connection {
165165
#endif /* CONFIG_BT_CTLR_PHY */
166166

167167
struct {
168+
u8_t initiate;
168169
u8_t error_code;
169170
u8_t rand[8];
170171
u8_t ediv[2];

0 commit comments

Comments
 (0)