diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 768975ba458..3249c16796b 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -99,6 +99,12 @@ comment "BLE Controller features" if BLUETOOTH_CONN +config BLUETOOTH_CONTROLLER_LE_ENC + bool + default y + # Enable support for Bluetooth v4.0 LE Encryption feature in the + # Controller. + config BLUETOOTH_CONTROLLER_LE_PING bool "LE Ping" default y @@ -252,6 +258,7 @@ if BLUETOOTH_CONN config BLUETOOTH_CONTROLLER_FAST_ENC bool "Fast Encryption Setup" + depends on BLUETOOTH_CONTROLLER_LE_ENC help Enable connection encryption setup in 3 connection intervals. Peripheral will respond to Encryption Request with Encryption Response diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 54c5aebbb5c..4efc6caae88 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -721,6 +721,7 @@ static void le_set_host_chan_classif(struct net_buf *buf, struct net_buf **evt) ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static void le_start_encryption(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_start_encryption *cmd = (void *)buf->data; @@ -735,9 +736,11 @@ static void le_start_encryption(struct net_buf *buf, struct net_buf **evt) *evt = cmd_status((!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED); } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #endif /* CONFIG_BLUETOOTH_CENTRAL */ #if defined(CONFIG_BLUETOOTH_PERIPHERAL) +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static void le_ltk_req_reply(struct net_buf *buf, struct net_buf **evt) { struct bt_hci_cp_le_ltk_req_reply *cmd = (void *)buf->data; @@ -768,6 +771,7 @@ static void le_ltk_req_neg_reply(struct net_buf *buf, struct net_buf **evt) rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED; rp->handle = sys_le16_to_cpu(handle); } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #endif /* CONFIG_BLUETOOTH_PERIPHERAL */ static void le_read_remote_features(struct net_buf *buf, struct net_buf **evt) @@ -1076,12 +1080,15 @@ static int controller_cmd_handle(u8_t ocf, struct net_buf *cmd, le_set_host_chan_classif(cmd, evt); break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case BT_OCF(BT_HCI_OP_LE_START_ENCRYPTION): le_start_encryption(cmd, evt); break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #endif /* CONFIG_BLUETOOTH_CENTRAL */ #if defined(CONFIG_BLUETOOTH_PERIPHERAL) +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case BT_OCF(BT_HCI_OP_LE_LTK_REQ_REPLY): le_ltk_req_reply(cmd, evt); break; @@ -1089,6 +1096,7 @@ static int controller_cmd_handle(u8_t ocf, struct net_buf *cmd, case BT_OCF(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY): le_ltk_req_neg_reply(cmd, evt); break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #endif /* CONFIG_BLUETOOTH_PERIPHERAL */ case BT_OCF(BT_HCI_OP_LE_READ_REMOTE_FEATURES): @@ -1450,6 +1458,7 @@ static void le_conn_update_complete(struct pdu_data *pdu_data, u16_t handle, sep->supv_timeout = sys_cpu_to_le16(radio_cu->timeout); } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static void enc_refresh_complete(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { @@ -1465,6 +1474,7 @@ static void enc_refresh_complete(struct pdu_data *pdu_data, u16_t handle, ep->status = 0x00; ep->handle = sys_cpu_to_le16(handle); } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) static void auth_payload_timeout_exp(struct pdu_data *pdu_data, u16_t handle, @@ -1562,9 +1572,11 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, le_conn_update_complete(pdu_data, handle, buf); break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case NODE_RX_TYPE_ENC_REFRESH: enc_refresh_complete(pdu_data, handle, buf); break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) case NODE_RX_TYPE_APTO: @@ -1616,6 +1628,7 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, } } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static void le_ltk_request(struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) { @@ -1651,6 +1664,7 @@ static void encrypt_change(u8_t err, u16_t handle, ep->handle = sys_cpu_to_le16(handle); ep->encrypt = !err ? 1 : 0; } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ static void le_remote_feat_complete(u8_t status, struct pdu_data *pdu_data, u16_t handle, struct net_buf *buf) @@ -1764,6 +1778,8 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx, u16_t handle = node_rx->hdr.handle; switch (pdu_data->payload.llctrl.opcode) { + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case PDU_DATA_LLCTRL_TYPE_ENC_REQ: le_ltk_request(pdu_data, handle, buf); break; @@ -1771,6 +1787,7 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx, case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP: encrypt_change(0x00, handle, buf); break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ case PDU_DATA_LLCTRL_TYPE_FEATURE_RSP: le_remote_feat_complete(0x00, pdu_data, handle, buf); @@ -1780,11 +1797,13 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx, remote_version_info(pdu_data, handle, buf); break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case PDU_DATA_LLCTRL_TYPE_REJECT_IND: encrypt_change(pdu_data->payload.llctrl.ctrldata.reject_ind. error_code, handle, buf); break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ: le_conn_param_req(pdu_data, handle, buf); @@ -1903,7 +1922,11 @@ s8_t hci_get_class(struct radio_pdu_node_rx *node_rx) return HCI_CLASS_EVT_REQUIRED; case NODE_RX_TYPE_TERMINATE: case NODE_RX_TYPE_CONN_UPDATE: + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case NODE_RX_TYPE_ENC_REFRESH: +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ + #if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI) case NODE_RX_TYPE_RSSI: #endif diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index 7af3600a783..908b5e9dba5 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -260,6 +260,7 @@ static void ctrl_tx_enqueue(struct connection *conn, static void pdu_node_tx_release(u16_t handle, struct radio_pdu_node_tx *node_tx); static void connection_release(struct connection *conn); +static void terminate_ind_rx_enqueue(struct connection *conn, u8_t reason); static u32_t conn_update(struct connection *conn, struct pdu_data *pdu_data_rx); static u32_t is_peer_compatible(struct connection *conn); static u32_t conn_update_req(struct connection *conn); @@ -271,15 +272,17 @@ static inline u32_t phy_upd_ind(struct radio_pdu_node_rx *radio_pdu_node_rx, u8_t *rx_enqueue); #endif /* CONFIG_BLUETOOTH_CONTROLLER_PHY */ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static void enc_req_reused_send(struct connection *conn, struct radio_pdu_node_tx *node_tx); -static void terminate_ind_rx_enqueue(struct connection *conn, u8_t reason); static void enc_rsp_send(struct connection *conn); static void start_enc_rsp_send(struct connection *conn, struct pdu_data *pdu_ctrl_tx); +static void pause_enc_rsp_send(struct connection *conn); +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ + static void unknown_rsp_send(struct connection *conn, u8_t type); static void feature_rsp_send(struct connection *conn); -static void pause_enc_rsp_send(struct connection *conn); static void version_ind_send(struct connection *conn); #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) @@ -1307,6 +1310,7 @@ static inline u8_t isr_rx_conn_pkt_ack(struct pdu_data *pdu_data_tx, terminate = 1; break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case PDU_DATA_LLCTRL_TYPE_ENC_REQ: /* things from master stored for session key calculation */ memcpy(&_radio.conn_curr->llcp.encryption.skd[0], @@ -1375,6 +1379,7 @@ static inline u8_t isr_rx_conn_pkt_ack(struct pdu_data *pdu_data_tx, /* Procedure complete */ _radio.conn_curr->procedure_expire = 0; break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ #if defined(CONFIG_BLUETOOTH_CONTROLLER_DATA_LENGTH) case PDU_DATA_LLCTRL_TYPE_LENGTH_REQ: @@ -1781,6 +1786,7 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx, pdu_data_rx->payload.llctrl.ctrldata.terminate_ind.error_code; break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case PDU_DATA_LLCTRL_TYPE_ENC_REQ: /* things from master stored for session key calculation */ memcpy(&_radio.conn_curr->llcp.encryption.skd[0], @@ -1882,6 +1888,7 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx, /* Procedure complete */ _radio.conn_curr->procedure_expire = 0; break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ case PDU_DATA_LLCTRL_TYPE_FEATURE_REQ: case PDU_DATA_LLCTRL_TYPE_SLAVE_FEATURE_REQ: @@ -1914,6 +1921,7 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx, } break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ: pause_enc_rsp_send(_radio.conn_curr); @@ -1942,6 +1950,7 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx, /* disable transmit encryption */ _radio.conn_curr->enc_tx = 0; break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ case PDU_DATA_LLCTRL_TYPE_VERSION_IND: _radio.conn_curr->llcp_version.version_number = @@ -1970,6 +1979,7 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx, } break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case PDU_DATA_LLCTRL_TYPE_REJECT_IND: /* resume data packet rx and tx */ _radio.conn_curr->pause_rx = 0; @@ -1981,6 +1991,7 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx, /* enqueue the reject ind */ *rx_enqueue = 1; break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ: /* connection update or params req in progress @@ -5561,6 +5572,7 @@ static inline void event_ch_map_prep(struct connection *conn, } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static inline void event_enc_prep(struct connection *conn) { struct radio_pdu_node_tx *node_tx; @@ -5695,6 +5707,7 @@ static inline void event_enc_prep(struct connection *conn) ctrl_tx_enqueue(conn, node_tx); } } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ static inline void event_fex_prep(struct connection *conn) { @@ -6298,9 +6311,11 @@ static void event_connection_prepare(u32_t ticks_at_expire, event_ch_map_prep(conn, event_counter); break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) case LLCP_ENCRYPTION: event_enc_prep(conn); break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ case LLCP_FEATURE_EXCHANGE: event_fex_prep(conn); @@ -7426,6 +7441,7 @@ static inline u32_t phy_upd_ind(struct radio_pdu_node_rx *radio_pdu_node_rx, } #endif /* CONFIG_BLUETOOTH_CONTROLLER_PHY */ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) static void enc_req_reused_send(struct connection *conn, struct radio_pdu_node_tx *node_tx) { @@ -7504,6 +7520,25 @@ static void start_enc_rsp_send(struct connection *conn, } } +static void pause_enc_rsp_send(struct connection *conn) +{ + struct radio_pdu_node_tx *node_tx; + struct pdu_data *pdu_ctrl_tx; + + /* acquire tx mem */ + node_tx = mem_acquire(&_radio.pkt_tx_ctrl_free); + LL_ASSERT(node_tx); + + pdu_ctrl_tx = (struct pdu_data *)node_tx->pdu_data; + pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL; + pdu_ctrl_tx->len = offsetof(struct pdu_data_llctrl, ctrldata); + pdu_ctrl_tx->payload.llctrl.opcode = + PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP; + + ctrl_tx_enqueue(conn, node_tx); +} +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ + static void unknown_rsp_send(struct connection *conn, u8_t type) { struct radio_pdu_node_tx *node_tx; @@ -7550,24 +7585,6 @@ static void feature_rsp_send(struct connection *conn) ctrl_tx_enqueue(conn, node_tx); } -static void pause_enc_rsp_send(struct connection *conn) -{ - struct radio_pdu_node_tx *node_tx; - struct pdu_data *pdu_ctrl_tx; - - /* acquire tx mem */ - node_tx = mem_acquire(&_radio.pkt_tx_ctrl_free); - LL_ASSERT(node_tx); - - pdu_ctrl_tx = (struct pdu_data *)node_tx->pdu_data; - pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL; - pdu_ctrl_tx->len = offsetof(struct pdu_data_llctrl, ctrldata); - pdu_ctrl_tx->payload.llctrl.opcode = - PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP; - - ctrl_tx_enqueue(conn, node_tx); -} - static void version_ind_send(struct connection *conn) { struct radio_pdu_node_tx *node_tx; @@ -8595,6 +8612,7 @@ u32_t ll_chm_get(u16_t handle, u8_t *chm) return 0; } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk) { struct connection *conn; @@ -8715,6 +8733,7 @@ u32_t ll_start_enc_req_send(u16_t handle, u8_t error_code, return 0; } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ u32_t ll_feature_req_send(u16_t handle) { diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.h b/subsys/bluetooth/controller/ll_sw/ctrl.h index 8a3b85c4b0c..9a18d220fd1 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl.h @@ -34,6 +34,12 @@ #define BIT64(n) (1ULL << (n)) +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) +#define RADIO_BLE_FEAT_BIT_ENC BIT64(BT_LE_FEAT_BIT_ENC) +#else /* !CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ +#define RADIO_BLE_FEAT_BIT_ENC 0 +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ + #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING) #define RADIO_BLE_FEAT_BIT_PING BIT64(BT_LE_FEAT_BIT_PING) #else /* !CONFIG_BLUETOOTH_CONTROLLER_LE_PING */ @@ -118,7 +124,7 @@ #define RADIO_BLE_FEAT_BIT_MASK 0x1FFFF #define RADIO_BLE_FEAT_BIT_MASK_VALID 0x1CF2F -#define RADIO_BLE_FEAT (BIT(BT_LE_FEAT_BIT_ENC) | \ +#define RADIO_BLE_FEAT (RADIO_BLE_FEAT_BIT_ENC | \ BIT(BT_LE_FEAT_BIT_CONN_PARAM_REQ) | \ BIT(BT_LE_FEAT_BIT_EXT_REJ_IND) | \ BIT(BT_LE_FEAT_BIT_SLAVE_FEAT_REQ) | \ diff --git a/subsys/bluetooth/controller/ll_sw/ctrl_internal.h b/subsys/bluetooth/controller/ll_sw/ctrl_internal.h index 148ae3d948f..3213f988179 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl_internal.h @@ -9,7 +9,11 @@ enum llcp { LLCP_NONE, LLCP_CONNECTION_UPDATE, LLCP_CHAN_MAP, + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_ENC) LLCP_ENCRYPTION, +#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_ENC */ + LLCP_FEATURE_EXCHANGE, LLCP_VERSION_EXCHANGE, /* LLCP_TERMINATE, */