Skip to content

Commit 82db759

Browse files
cvinayakcfriedt
authored andcommitted
Bluetooth: controller: Fix missing encryption procedure state check
Fix a missing encryption procedure state check which allowed out of order receive of START_ENC_RSP PDU, which made the controller to believe its already in an encryption procedure in progress state. Fixes #34392. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 5a430ee commit 82db759

File tree

2 files changed

+38
-28
lines changed

2 files changed

+38
-28
lines changed

subsys/bluetooth/controller/ll_sw/ull_conn.c

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,6 +2897,11 @@ static inline void event_enc_prep(struct ll_conn *conn)
28972897
event_enc_reject_prep(conn, pdu_ctrl_tx);
28982898

28992899
ctrl_tx_enqueue(conn, tx);
2900+
2901+
/* procedure request acked */
2902+
conn->llcp_ack = conn->llcp_req;
2903+
2904+
return;
29002905
}
29012906
/* place the start enc req packet as next in tx queue */
29022907
else {
@@ -2942,19 +2947,16 @@ static inline void event_enc_prep(struct ll_conn *conn)
29422947
}
29432948

29442949
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
2950+
/* Peripheral sends start enc rsp after reception of start enc rsp */
29452951
} else {
29462952
start_enc_rsp_send(conn, pdu_ctrl_tx);
29472953

29482954
ctrl_tx_enqueue(conn, tx);
2949-
2950-
/* resume data packet rx and tx */
2951-
conn->llcp_enc.pause_rx = 0U;
2952-
conn->llcp_enc.pause_tx = 0U;
29532955
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
29542956
}
29552957

2956-
/* procedure request acked */
2957-
conn->llcp_ack = conn->llcp_req;
2958+
/* Wait for encryption setup to complete */
2959+
conn->llcp.encryption.state = LLCP_ENC_STATE_ENC_WAIT;
29582960
}
29592961
#endif /* CONFIG_BT_CTLR_LE_ENC */
29602962

@@ -5403,13 +5405,29 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
54035405
break;
54045406

54055407
case PDU_DATA_LLCTRL_TYPE_START_ENC_REQ:
5406-
/* Nothing to do.
5407-
* Remember that we may have received encrypted START_ENC_RSP
5408+
/* Remember that we may have received encrypted START_ENC_RSP
54085409
* alongwith this tx ack at this point in time.
54095410
*/
5411+
conn->llcp.encryption.state = LLCP_ENC_STATE_ENC_WAIT;
54105412
break;
54115413
#endif /* CONFIG_BT_PERIPHERAL */
54125414

5415+
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
5416+
if (conn->lll.role) {
5417+
/* resume data packet rx and tx */
5418+
conn->llcp_enc.pause_rx = 0U;
5419+
conn->llcp_enc.pause_tx = 0U;
5420+
5421+
/* Procedure complete */
5422+
conn->procedure_expire = 0U;
5423+
5424+
/* procedure request acked */
5425+
conn->llcp_ack = conn->llcp_req;
5426+
} else {
5427+
conn->llcp.encryption.state = LLCP_ENC_STATE_ENC_WAIT;
5428+
}
5429+
break;
5430+
54135431
#if defined(CONFIG_BT_CENTRAL)
54145432
case PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ:
54155433
/* pause data packet tx */
@@ -5820,40 +5838,35 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
58205838
#endif /* CONFIG_BT_CENTRAL */
58215839

58225840
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
5823-
if (!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_START_ENC_RSP,
5824-
pdu_rx->len)) {
5841+
if ((conn->llcp_req == conn->llcp_ack) ||
5842+
(conn->llcp_type != LLCP_ENCRYPTION) ||
5843+
(!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_START_ENC_RSP,
5844+
pdu_rx->len))) {
58255845
goto ull_conn_rx_unknown_rsp_send;
58265846
}
58275847

58285848
if (conn->lll.role) {
58295849
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
5830-
if ((conn->llcp_req != conn->llcp_ack) &&
5831-
(conn->llcp_type != LLCP_ENCRYPTION)) {
5832-
goto ull_conn_rx_unknown_rsp_send;
5833-
}
5834-
5835-
/* start enc rsp to be scheduled in slave prepare */
5850+
/* start enc rsp to be scheduled in slave prepare */
58365851
conn->llcp.encryption.state = LLCP_ENC_STATE_INPROG;
5837-
if (conn->llcp_req == conn->llcp_ack) {
5838-
conn->llcp_type = LLCP_ENCRYPTION;
5839-
conn->llcp_ack -= 2U;
5840-
}
58415852

58425853
#else /* CONFIG_BT_CTLR_FAST_ENC */
58435854
nack = start_enc_rsp_send(conn, NULL);
58445855
if (nack) {
58455856
break;
58465857
}
5847-
5848-
/* resume data packet rx and tx */
5849-
conn->llcp_enc.pause_rx = 0U;
5850-
conn->llcp_enc.pause_tx = 0U;
58515858
#endif /* CONFIG_BT_CTLR_FAST_ENC */
58525859

58535860
} else {
58545861
/* resume data packet rx and tx */
58555862
conn->llcp_enc.pause_rx = 0U;
58565863
conn->llcp_enc.pause_tx = 0U;
5864+
5865+
/* Procedure complete */
5866+
conn->procedure_expire = 0U;
5867+
5868+
/* procedure request acked */
5869+
conn->llcp_ack = conn->llcp_req;
58575870
}
58585871

58595872
/* enqueue the start enc resp (encryption change/refresh) */
@@ -5863,10 +5876,6 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
58635876
/* key refresh event */
58645877
(*rx)->hdr.type = NODE_RX_TYPE_ENC_REFRESH;
58655878
}
5866-
5867-
/* Procedure complete */
5868-
conn->procedure_expire = 0U;
5869-
58705879
break;
58715880
#endif /* CONFIG_BT_CTLR_LE_ENC */
58725881

subsys/bluetooth/controller/ll_sw/ull_conn_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct ll_conn {
134134
LLCP_ENC_STATE_INPROG,
135135
LLCP_ENC_STATE_INIT,
136136
LLCP_ENC_STATE_LTK_WAIT,
137+
LLCP_ENC_STATE_ENC_WAIT,
137138
} state:2 __packed;
138139
uint8_t error_code;
139140
uint8_t skd[16];

0 commit comments

Comments
 (0)