diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 432abb43dd..6c3dba3c76 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -713,6 +713,38 @@ esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len) btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16]) +{ + if (!p_c || !p_r) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT; + memcpy(arg.sc_oob_req_reply.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.sc_oob_req_reply.p_c = p_c; + arg.sc_oob_req_reply.p_r = p_r; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_create_sc_oob_data(void) +{ + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SC_CR_OOB_DATA_EVT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} #endif /* #if (SMP_INCLUDED == TRUE) */ esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 57bd34e687..490c94dc6a 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -163,6 +163,8 @@ typedef enum { ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT, /*!< When update duplicate exceptional list complete, the event comes */ #endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) ESP_GAP_BLE_SET_CHANNELS_EVT = 29, /*!< When setting BLE channels complete, the event comes */ + ESP_GAP_BLE_SC_OOB_REQ_EVT, /*!< Secure Connection OOB request event */ + ESP_GAP_BLE_SC_CR_LOC_OOB_EVT, /*!< Secure Connection create OOB data complete event */ #if (BLE_50_FEATURE_SUPPORT == TRUE) ESP_GAP_BLE_READ_PHY_COMPLETE_EVT, /*!< when reading phy complete, this event comes */ ESP_GAP_BLE_SET_PREFERRED_DEFAULT_PHY_COMPLETE_EVT, /*!< when preferred default phy complete, this event comes */ @@ -583,6 +585,13 @@ typedef struct { esp_bt_octet16_t dhk; /*!< the 16 bits of the dh key value */ } esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/ +/** +* @brief structure type of the ble local oob data value +*/ +typedef struct { + esp_bt_octet16_t oob_c; /*!< the 128 bits of confirmation value */ + esp_bt_octet16_t oob_r; /*!< the 128 bits of randomizer value */ +} esp_ble_local_oob_data_t; /** * @brief Structure associated with ESP_AUTH_CMPL_EVT @@ -609,6 +618,7 @@ typedef union esp_ble_sec_req_t ble_req; /*!< BLE SMP related request */ esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */ esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */ + esp_ble_local_oob_data_t oob_data; /*!< BLE SMP secure connection OOB data */ esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */ } esp_ble_sec_t; /*!< BLE security type */ #if (BLE_42_FEATURE_SUPPORT == TRUE) @@ -1769,6 +1779,29 @@ esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_lis */ esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len); +/** +* @brief This function is called to provide the OOB data for +* SMP in response to ESP_GAP_BLE_SC_OOB_REQ_EVT +* +* @param[in] bd_addr: BD address of the peer device. +* @param[in] p_c: Confirmation value, it shall be a 128-bit random number +* @param[in] p_r: Randomizer value, it should be a 128-bit random number +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16]); + +/** +* @brief This function is called to create the OOB data for +* SMP when secure connection +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_create_sc_oob_data(void); #endif /* #if (SMP_INCLUDED == TRUE) */ /** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index be699baa45..754f4c35d7 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -1427,6 +1427,40 @@ void bta_dm_oob_reply(tBTA_DM_MSG *p_data) #endif } +/******************************************************************************* +** +** Function bta_dm_sc_oob_reply +** +** Description This function is called to provide the OOB data for +** SMP in response to BLE secure connection OOB request. +** +** Returns void +** +*******************************************************************************/ +void bta_dm_sc_oob_reply(tBTA_DM_MSG *p_data) +{ +#if (BLE_INCLUDED) + BTM_BleSecureConnectionOobDataReply(p_data->sc_oob_reply.bd_addr, p_data->sc_oob_reply.c, p_data->sc_oob_reply.r); +#endif +} + +/******************************************************************************* +** +** Function bta_dm_sc_create_oob_data +** +** Description This function is called to create the OOB data for +** SMP when secure connection. +** +** Returns void +** +*******************************************************************************/ +void bta_dm_sc_create_oob_data(tBTA_DM_MSG *p_data) +{ +#if (BLE_INCLUDED) + BTM_BleSecureConnectionCreateOobData(); +#endif +} + /******************************************************************************* ** ** Function bta_dm_ci_io_req_act @@ -4711,6 +4745,17 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event); break; + case BTM_LE_SC_OOB_REQ_EVT: + bdcpy(sec_event.ble_req.bd_addr, bda); + bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event); + break; + + case BTM_LE_SC_LOC_OOB_EVT: + memcpy(sec_event.local_oob_data.local_oob_c, p_data->local_oob_data.commitment, BT_OCTET16_LEN); + memcpy(sec_event.local_oob_data.local_oob_r, p_data->local_oob_data.randomizer, BT_OCTET16_LEN); + bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_CR_LOC_OOB_EVT, &sec_event); + break; + case BTM_LE_NC_REQ_EVT: bdcpy(sec_event.key_notif.bd_addr, bda); BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,bta_dm_get_remname(), BD_NAME_LEN); diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index da63ae4c98..edf30142ca 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -650,7 +650,7 @@ void BTA_DmLocalOob(void) ** Function BTA_DmOobReply ** ** This function is called to provide the OOB data for -** SMP in response to BTM_LE_OOB_REQ_EVT +** SMP in response to BTA_LE_OOB_REQ_EVT ** ** Parameters: bd_addr - Address of the peer device ** len - length of simple pairing Randomizer C @@ -675,6 +675,55 @@ void BTA_DmOobReply(BD_ADDR bd_addr, UINT8 len, UINT8 *p_value) bta_sys_sendmsg(p_msg); } } + +/******************************************************************************* +** +** Function BTA_DmSecureConnectionOobReply +** +** This function is called to provide the OOB data for +** SMP in response to BTA_LE_OOB_REQ_EVT +** +** Parameters: bd_addr - Address of the peer device +** p_c - Pointer to Confirmation +** p_r - Pointer to Randomizer +** +** Returns void +** +*******************************************************************************/ +void BTA_DmSecureConnectionOobReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r) +{ + tBTA_DM_API_SC_OOB_REPLY *p_msg; + + if ((p_msg = (tBTA_DM_API_SC_OOB_REPLY *) osi_malloc(sizeof(tBTA_DM_API_OOB_REPLY))) != NULL) { + p_msg->hdr.event = BTA_DM_API_SC_OOB_REPLY_EVT; + if((p_c == NULL) || (p_r == NULL)) { + return; + } + memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN); + memcpy(p_msg->c, p_c, BT_OCTET16_LEN); + memcpy(p_msg->r, p_r, BT_OCTET16_LEN); + bta_sys_sendmsg(p_msg); + } +} +/******************************************************************************* +** +** Function BTA_DmSecureConnectionCreateOobData +** +** This function is called to create the OOB data for +** SMP when secure connection +** +** Returns void +** +*******************************************************************************/ +void BTA_DmSecureConnectionCreateOobData(void) +{ + tBTA_DM_API_SC_CR_OOB_DATA *p_msg; + + if ((p_msg = (tBTA_DM_API_SC_CR_OOB_DATA *) osi_malloc(sizeof(tBTA_DM_API_SC_CR_OOB_DATA))) != NULL) { + p_msg->hdr.event = BTA_DM_API_SC_CR_OOB_DATA_EVT; + bta_sys_sendmsg(p_msg); + } +} #endif /* BTM_OOB_INCLUDED */ /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c index c28369769c..86185052d5 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -350,10 +350,6 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, *p_auth_req = bte_appl_cfg.ble_auth_req | (bte_appl_cfg.ble_auth_req & BTA_LE_AUTH_REQ_MITM) | ((*p_auth_req) & BTA_LE_AUTH_REQ_MITM); - if (*p_oob_data == BTM_BLE_OOB_ENABLE) { - *p_auth_req = (*p_auth_req)&(~BTA_LE_AUTH_REQ_SC_ONLY); - } - if (bte_appl_cfg.ble_io_cap <= 4) { *p_io_cap = bte_appl_cfg.ble_io_cap; } diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index fdc19fedce..37e2022bd5 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -96,6 +96,8 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE) bta_dm_loc_oob, /* BTA_DM_API_LOC_OOB_EVT */ bta_dm_oob_reply, /* BTA_DM_API_OOB_REPLY_EVT */ + bta_dm_sc_oob_reply, /* BTA_DM_API_SC_OOB_REPLY_EVT */ + bta_dm_sc_create_oob_data, /* BTA_DM_API_SC_CR_OOB_DATA_EVT */ bta_dm_ci_io_req_act, /* BTA_DM_CI_IO_REQ_EVT */ bta_dm_ci_rmt_oob_act, /* BTA_DM_CI_RMT_OOB_EVT */ #endif /* BTM_OOB_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index f6b93d0744..67aaf6313a 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -92,6 +92,8 @@ enum { #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE) BTA_DM_API_LOC_OOB_EVT, BTA_DM_API_OOB_REPLY_EVT, + BTA_DM_API_SC_OOB_REPLY_EVT, + BTA_DM_API_SC_CR_OOB_DATA_EVT, BTA_DM_CI_IO_REQ_EVT, BTA_DM_CI_RMT_OOB_EVT, #endif /* BTM_OOB_INCLUDED */ @@ -394,8 +396,23 @@ typedef struct { BD_ADDR bd_addr; UINT8 len; UINT8 value[BT_OCTET16_LEN]; + UINT8 c[BT_OCTET16_LEN]; + UINT8 r[BT_OCTET16_LEN]; } tBTA_DM_API_OOB_REPLY; +/* data type for BTA_DM_API_SC_OOB_REPLY_EVT */ +typedef struct { + BT_HDR hdr; + BD_ADDR bd_addr; + UINT8 c[BT_OCTET16_LEN]; + UINT8 r[BT_OCTET16_LEN]; +} tBTA_DM_API_SC_OOB_REPLY; + +/* data type for BTA_DM_API_SC_CR_OOB_DATA_EVT */ +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_SC_CR_OOB_DATA; + /* data type for BTA_DM_API_CONFIRM_EVT */ typedef struct { BT_HDR hdr; @@ -1047,6 +1064,7 @@ typedef union { tBTA_DM_API_LOC_OOB loc_oob; tBTA_DM_API_OOB_REPLY oob_reply; + tBTA_DM_API_SC_OOB_REPLY sc_oob_reply; tBTA_DM_API_CONFIRM confirm; tBTA_DM_API_KEY_REQ key_req; tBTA_DM_CI_IO_REQ ci_io_req; @@ -1605,6 +1623,8 @@ extern BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr); #if (BTM_OOB_INCLUDED == TRUE) extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data); extern void bta_dm_oob_reply(tBTA_DM_MSG *p_data); +extern void bta_dm_sc_oob_reply(tBTA_DM_MSG *p_data); +extern void bta_dm_sc_create_oob_data(tBTA_DM_MSG *p_data); extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data); extern void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data); #endif /* BTM_OOB_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 0a166100ea..7423d0fd2d 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -657,6 +657,8 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK; #define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */ #define BTA_DM_PM_MODE_CHG_EVT 31 /* Mode changed event */ #define BTA_DM_ACL_LINK_STAT_EVT 32 /* ACL connection status report event */ +#define BTA_DM_BLE_SC_OOB_REQ_EVT 33 /* BLE SMP SC OOB request event */ +#define BTA_DM_BLE_SC_CR_LOC_OOB_EVT 34 /* BLE SMP SC Create Local OOB request event */ typedef UINT8 tBTA_DM_SEC_EVT; @@ -976,6 +978,10 @@ typedef struct { tBTA_PM_MODE mode; /* the new connection role */ } tBTA_DM_MODE_CHG; +typedef struct { + BT_OCTET16 local_oob_c; /* Local OOB Data Confirmation/Commitment */ + BT_OCTET16 local_oob_r; /* Local OOB Data Randomizer */ +} tBTA_DM_LOC_OOB_DATA; /* Union of all security callback structures */ typedef union { @@ -1001,6 +1007,7 @@ typedef union { #if BTA_DM_PM_INCLUDED tBTA_DM_MODE_CHG mode_chg; /* mode change event */ #endif ///BTA_DM_PM_INCLUDED + tBTA_DM_LOC_OOB_DATA local_oob_data; /* Local OOB data generated by us */ } tBTA_DM_SEC; /* Security callback */ @@ -1919,7 +1926,7 @@ extern void BTA_DmLocalOob(void); ** Function BTA_DmOobReply ** ** This function is called to provide the OOB data for -** SMP in response to BTM_LE_OOB_REQ_EVT +** SMP in response to BTA_LE_OOB_REQ_EVT ** ** Parameters: bd_addr - Address of the peer device ** len - length of simple pairing Randomizer C @@ -1929,6 +1936,33 @@ extern void BTA_DmLocalOob(void); ** *******************************************************************************/ extern void BTA_DmOobReply(BD_ADDR bd_addr, UINT8 len, UINT8 *p_value); + +/******************************************************************************* +** +** Function BTA_DmSecureConnectionOobReply +** +** This function is called to provide the OOB data for +** SMP in response to BTA_LE_OOB_REQ_EVT when secure connection +** +** Parameters: bd_addr - Address of the peer device +** p_c - Pointer to Confirmation +** p_r - Pointer to Randomizer +** +** Returns void +** +*******************************************************************************/ +extern void BTA_DmSecureConnectionOobReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r); +/******************************************************************************* +** +** Function BTA_DmSecureConnectionCreateOobData +** +** This function is called to create the OOB data for +** SMP when secure connection +** +** Returns void +** +*******************************************************************************/ +extern void BTA_DmSecureConnectionCreateOobData(void); #endif /* BTM_OOB_INCLUDED */ /******************************************************************************* diff --git a/components/bt/host/bluedroid/btc/core/btc_dm.c b/components/bt/host/bluedroid/btc/core/btc_dm.c index 70b41efe7b..5fb684702b 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dm.c +++ b/components/bt/host/bluedroid/btc/core/btc_dm.c @@ -944,6 +944,19 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) memcpy(param.ble_security.ble_req.bd_addr, p_data->ble_req.bd_addr, BD_ADDR_LEN); break; } + case BTA_DM_BLE_SC_OOB_REQ_EVT: { + rsp_app = true; + ble_msg->act = ESP_GAP_BLE_SC_OOB_REQ_EVT; + memcpy(param.ble_security.ble_req.bd_addr, p_data->ble_req.bd_addr, BD_ADDR_LEN); + break; + } + case BTA_DM_BLE_SC_CR_LOC_OOB_EVT: { + rsp_app = true; + ble_msg->act = ESP_GAP_BLE_SC_CR_LOC_OOB_EVT; + memcpy(param.ble_security.oob_data.oob_c, p_data->local_oob_data.local_oob_c, BT_OCTET16_LEN); + memcpy(param.ble_security.oob_data.oob_r, p_data->local_oob_data.local_oob_r, BT_OCTET16_LEN); + break; + } case BTA_DM_BLE_LOCAL_IR_EVT: { rsp_app = true; ble_msg->act = ESP_GAP_BLE_LOCAL_IR_EVT; diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 9517dddd9d..091bbf1119 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1307,6 +1307,27 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } break; } + case BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT: { + btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src; + btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *)p_dest; + if (src->sc_oob_req_reply.p_c) { + dst->sc_oob_req_reply.p_c = osi_malloc(BT_OCTET16_LEN); + if (dst->sc_oob_req_reply.p_c) { + memcpy(dst->sc_oob_req_reply.p_c, src->sc_oob_req_reply.p_c, BT_OCTET16_LEN); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + if (src->sc_oob_req_reply.p_r) { + dst->sc_oob_req_reply.p_r = osi_malloc(BT_OCTET16_LEN); + if (dst->sc_oob_req_reply.p_r) { + memcpy(dst->sc_oob_req_reply.p_r, src->sc_oob_req_reply.p_r, BT_OCTET16_LEN); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + } #if (BLE_50_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW: case BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW: { @@ -1432,6 +1453,17 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg) } break; } + case BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT: { + uint8_t *value = ((btc_ble_gap_args_t *)msg->arg)->sc_oob_req_reply.p_c; + if (value) { + osi_free(value); + } + value = ((btc_ble_gap_args_t *)msg->arg)->sc_oob_req_reply.p_r; + if (value) { + osi_free(value); + } + break; + } #if (BLE_50_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW: case BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW: { @@ -1690,6 +1722,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) case BTC_GAP_BLE_OOB_REQ_REPLY_EVT: BTA_DmOobReply(arg->oob_req_reply.bd_addr, arg->oob_req_reply.len, arg->oob_req_reply.p_value); break; + case BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT: + BTA_DmSecureConnectionOobReply(arg->sc_oob_req_reply.bd_addr, arg->sc_oob_req_reply.p_c, arg->sc_oob_req_reply.p_r); + break; + case BTC_GAP_BLE_SC_CR_OOB_DATA_EVT: + BTA_DmSecureConnectionCreateOobData(); + break; #endif ///SMP_INCLUDED == TRUE case BTC_GAP_BLE_DISCONNECT_EVT: btc_ble_disconnect(arg->disconnect.remote_device); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 926976b3a6..15c70ceb45 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -54,6 +54,8 @@ typedef enum { BTC_GAP_BLE_DISCONNECT_EVT, BTC_GAP_BLE_REMOVE_BOND_DEV_EVT, BTC_GAP_BLE_OOB_REQ_REPLY_EVT, + BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT, + BTC_GAP_BLE_SC_CR_OOB_DATA_EVT, BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST, BTC_GAP_BLE_SET_AFH_CHANNELS, #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -200,6 +202,11 @@ typedef union { uint8_t len; uint8_t *p_value; } oob_req_reply; + struct sc_oob_req_reply_args { + esp_bd_addr_t bd_addr; + uint8_t *p_c; + uint8_t *p_r; + } sc_oob_req_reply; //BTC_GAP_BLE_DISCONNECT_EVT struct disconnect_args { esp_bd_addr_t remote_device; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 962a3ef961..0d357849ad 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -496,6 +496,62 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data) #endif } +/******************************************************************************* +** +** Function BTM_BleSecureConnectionOobDataReply +** +** Description This function is called to provide the OOB data for +** SMP in response to BTM_LE_SC_OOB_REQ_EVT when secure connection +** +** Parameters: bd_addr - Address of the peer device +** p_c - pointer to Confirmation +** p_r - pointer to Randomizer +** +*******************************************************************************/ +void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r) +{ +#if SMP_INCLUDED == TRUE + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr); + + BTM_TRACE_DEBUG ("%s", __func__); + + if (p_dev_rec == NULL) { + BTM_TRACE_ERROR("%s Unknown device", __func__); + return; + } + + p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + + tSMP_SC_OOB_DATA oob; + memset(&oob, 0, sizeof(tSMP_SC_OOB_DATA)); + + oob.peer_oob_data.present = true; + memcpy(&oob.peer_oob_data.commitment, p_c, BT_OCTET16_LEN); + memcpy(&oob.peer_oob_data.randomizer, p_r, BT_OCTET16_LEN); + oob.peer_oob_data.addr_rcvd_from.type = p_dev_rec->ble.ble_addr_type; + memcpy(oob.peer_oob_data.addr_rcvd_from.bda, bd_addr, BD_ADDR_LEN); + + SMP_SecureConnectionOobDataReply((UINT8 *)&oob); +#endif +} + +/******************************************************************************* +** +** Function BTM_BleSecureConnectionCreateOobData +** +** Description This function is called to create the OOB data for +** SMP when secure connection +** +*******************************************************************************/ +void BTM_BleSecureConnectionCreateOobData(void) +{ +#if SMP_INCLUDED == TRUE + BTM_TRACE_DEBUG ("%s", __func__); + + SMP_CreateLocalSecureConnectionsOobData(); +#endif +} + /****************************************************************************** ** ** Function BTM_BleSetConnScanParams @@ -2212,7 +2268,15 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) } } else { - BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device"); + if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { + tBTM_LE_EVT_DATA evt_data; + memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); + if (btm_cb.api.p_le_callback) { + (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data); + } + } else { + BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device"); + } } return 0; } diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index 495e9d41e7..cc74ba4ed8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -1765,6 +1765,7 @@ typedef union { #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE tBTM_LE_COMPLT complt; /* BTM_LE_COMPLT_EVT */ tSMP_OOB_DATA_TYPE req_oob_type; + tSMP_LOC_OOB_DATA local_oob_data; #endif tBTM_LE_KEY key; } tBTM_LE_EVT_DATA; diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 5e4504dd88..866eab7ea4 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1809,6 +1809,29 @@ void BTM_BleConfirmReply (BD_ADDR bd_addr, UINT8 res); //extern void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data); +/******************************************************************************* +** +** Function BTM_BleSecureConnectionOobDataReply +** +** Description This function is called to provide the OOB data for +** SMP in response to BTM_LE_SC_OOB_REQ_EVT when secure connection +** +** Parameters: bd_addr - Address of the peer device +** p_c - pointer to Confirmation +** p_r - pointer to Randomizer +** +*******************************************************************************/ +void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r); + +/******************************************************************************* +** +** Function BTM_BleSecureConnectionCreateOobData +** +** Description This function is called to create the OOB data for +** SMP when secure connection +** +*******************************************************************************/ +void BTM_BleSecureConnectionCreateOobData(void); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/include/stack/smp_api.h b/components/bt/host/bluedroid/stack/include/stack/smp_api.h index 1064237c8d..11d432e716 100644 --- a/components/bt/host/bluedroid/stack/include/stack/smp_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/smp_api.h @@ -498,13 +498,9 @@ extern void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value); ** Description This function is called to start creation of local SC OOB ** data set (tSMP_LOC_OOB_DATA). ** -** Parameters: bd_addr - Address of the device to send OOB data block -** to. -** ** Returns Boolean - TRUE: creation of local SC OOB data set started. *******************************************************************************/ -extern BOOLEAN SMP_CreateLocalSecureConnectionsOobData ( - tBLE_BD_ADDR *addr_to_send_to); +extern BOOLEAN SMP_CreateLocalSecureConnectionsOobData (void); #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/smp/include/smp_int.h b/components/bt/host/bluedroid/stack/smp/include/smp_int.h index d8fb55c381..f3ab7ad445 100644 --- a/components/bt/host/bluedroid/stack/smp/include/smp_int.h +++ b/components/bt/host/bluedroid/stack/smp/include/smp_int.h @@ -527,6 +527,9 @@ extern BOOLEAN smp_calculate_f5_key(UINT8 *w, UINT8 *t); extern BOOLEAN smp_calculate_f6(UINT8 *w, UINT8 *n1, UINT8 *n2, UINT8 *r, UINT8 *iocap, UINT8 *a1, UINT8 *a2, UINT8 *f3); extern BOOLEAN smp_calculate_h6(UINT8 *w, UINT8 *keyid, UINT8 *h2); +extern void smp_save_local_oob_data(tSMP_CB *p_cb); +extern void smp_clear_local_oob_data(void); +extern tSMP_LOC_OOB_DATA *smp_get_local_oob_data(void); #if SMP_DEBUG == TRUE extern void smp_debug_print_nbyte_little_endian (UINT8 *p, const UINT8 *key_name, UINT8 len); diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index 353ee9c9b6..0e7dcd5b3f 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -622,7 +622,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } - if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { if (smp_request_oob_data(p_cb)) { return; } @@ -661,7 +661,8 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } - if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + /* Only if peer oob data present, then should request peer oob data */ + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { if (smp_request_oob_data(p_cb)) { return; } @@ -1459,7 +1460,7 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } - if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { if (smp_request_oob_data(p_cb)) { return; } @@ -1947,6 +1948,7 @@ void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->sc_oob_data.loc_oob_data.randomizer, 0, p_cb->sc_oob_data.loc_oob_data.commitment); + p_cb->sc_oob_data.loc_oob_data.present = true; #if SMP_DEBUG == TRUE UINT8 *p_print = NULL; SMP_TRACE_DEBUG("local SC OOB data set:\n"); @@ -1975,6 +1977,9 @@ void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT; smp_send_app_cback(p_cb, NULL); + // Store the data for later use when we are paired with + smp_save_local_oob_data(p_cb); + smp_cb_cleanup(p_cb); } diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index 69d4520c29..df8f4cea21 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -471,6 +471,9 @@ void SMP_SecureConnectionOobDataReply(UINT8 *p_data) return; } + /* Set local oob data when req_oob_type = SMP_OOB_BOTH */ + memcpy(&p_oob->loc_oob_data, smp_get_local_oob_data(), sizeof(tSMP_LOC_OOB_DATA)); + SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, " "peer_oob_data.present: %d", __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present, @@ -504,6 +507,7 @@ void SMP_SecureConnectionOobDataReply(UINT8 *p_data) } if (data_missing) { + SMP_TRACE_ERROR("%s data missing", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); return; } @@ -589,32 +593,13 @@ void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value) ** Description This function is called to start creation of local SC OOB ** data set (tSMP_LOC_OOB_DATA). ** -** Parameters: bd_addr - Address of the device to send OOB data block to -** ** Returns Boolean - TRUE: creation of local SC OOB data set started. *******************************************************************************/ -BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to) +BOOLEAN SMP_CreateLocalSecureConnectionsOobData (void) { tSMP_CB *p_cb = &smp_cb; -#if (!CONFIG_BT_STACK_NO_LOG) - UINT8 *bd_addr; -#endif - if (addr_to_send_to == NULL) { - SMP_TRACE_ERROR ("%s addr_to_send_to is not provided", __FUNCTION__); - return FALSE; - } - -#if (!CONFIG_BT_STACK_NO_LOG) - bd_addr = addr_to_send_to->bda; -#endif - - SMP_TRACE_EVENT ("%s addr type: %u, BDA: %08x%04x, state: %u, br_state: %u", - __FUNCTION__, addr_to_send_to->type, - (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], - (bd_addr[4] << 8) + bd_addr[5], - p_cb->state, - p_cb->br_state); + SMP_TRACE_EVENT ("%s state: %u, br_state: %u", __FUNCTION__, p_cb->state, p_cb->br_state); if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br)) { SMP_TRACE_WARNING ("%s creation of local OOB data set "\ @@ -622,7 +607,6 @@ BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to) return FALSE; } - p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to; smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL); return TRUE; diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index e8337b1007..aec6f709c5 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -71,6 +71,32 @@ static const tSMP_ACT smp_encrypt_action[] = { smp_generate_rand_cont /* SMP_GEN_SRAND_MRAND_CONT */ }; +/* If there is data saved here, then use its info instead + * This needs to be cleared on a successful pairing using the oob data + */ +static tSMP_LOC_OOB_DATA saved_local_oob_data = {}; + +void smp_save_local_oob_data(tSMP_CB *p_cb) +{ + memcpy(&saved_local_oob_data, &p_cb->sc_oob_data.loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); +} + +void smp_clear_local_oob_data(void) +{ + memset(&saved_local_oob_data, 0, sizeof(tSMP_LOC_OOB_DATA)); +} + +static BOOLEAN oob_data_is_empty(tSMP_LOC_OOB_DATA *data) +{ + tSMP_LOC_OOB_DATA empty_data = {0}; + return (memcmp(data, &empty_data, sizeof(tSMP_LOC_OOB_DATA)) == 0); +} + +tSMP_LOC_OOB_DATA *smp_get_local_oob_data(void) +{ + return &saved_local_oob_data; +} + void smp_debug_print_nbyte_little_endian(UINT8 *p, const UINT8 *key_name, UINT8 len) { #if SMP_DEBUG == TRUE @@ -973,7 +999,19 @@ BOOLEAN smp_calculate_legacy_short_term_key(tSMP_CB *p_cb, tSMP_ENC *output) *******************************************************************************/ void smp_create_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG ("%s", __FUNCTION__); + SMP_TRACE_DEBUG("%s", __func__); + + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + SMP_TRACE_EVENT("OOB Association Model"); + if (!oob_data_is_empty(&saved_local_oob_data)) { + SMP_TRACE_EVENT("Found OOB data, loading keys"); + memcpy(&p_cb->sc_oob_data.loc_oob_data, &saved_local_oob_data, sizeof(tSMP_LOC_OOB_DATA)); + smp_process_private_key(p_cb); + return; + } + SMP_TRACE_EVENT("OOB Association Model with no saved data"); + } + p_cb->rand_enc_proc_state = SMP_GENERATE_PRIVATE_KEY_0_7; if (!btsnd_hcic_ble_rand((void *)smp_rand_back)) { smp_rand_back(NULL); @@ -1005,7 +1043,7 @@ void smp_use_oob_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) case SMP_OOB_BOTH: case SMP_OOB_LOCAL: SMP_TRACE_DEBUG("%s restore secret key\n", __func__); - memcpy(p_cb->private_key, p_cb->sc_oob_data.loc_oob_data.private_key_used, BT_OCTET32_LEN); + // copy private key in smp_process_private_key smp_process_private_key(p_cb); break; default: @@ -1082,13 +1120,22 @@ void smp_process_private_key(tSMP_CB *p_cb) { Point public_key; BT_OCTET32 private_key; + tSMP_LOC_OOB_DATA *p_loc_oob = &p_cb->sc_oob_data.loc_oob_data; SMP_TRACE_DEBUG ("%s", __FUNCTION__); - memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); - ECC_PointMult(&public_key, &(curve_p256.G), (DWORD *) private_key, KEY_LENGTH_DWORDS_P256); - memcpy(p_cb->loc_publ_key.x, public_key.x, BT_OCTET32_LEN); - memcpy(p_cb->loc_publ_key.y, public_key.y, BT_OCTET32_LEN); + /* if local oob data present, then restore oob private and public key */ + if (p_loc_oob->present) { + memcpy(p_cb->private_key, p_loc_oob->private_key_used, BT_OCTET32_LEN); + memcpy(p_cb->loc_publ_key.x, p_loc_oob->publ_key_used.x, BT_OCTET32_LEN); + memcpy(p_cb->loc_publ_key.y, p_loc_oob->publ_key_used.y, BT_OCTET32_LEN); + memcpy(p_cb->local_random, p_loc_oob->randomizer, BT_OCTET16_LEN); + } else { + memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); + ECC_PointMult(&public_key, &(curve_p256.G), (DWORD *) private_key, KEY_LENGTH_DWORDS_P256); + memcpy(p_cb->loc_publ_key.x, public_key.x, BT_OCTET32_LEN); + memcpy(p_cb->loc_publ_key.y, public_key.y, BT_OCTET32_LEN); + } smp_debug_print_nbyte_little_endian (p_cb->private_key, (const UINT8 *)"private", BT_OCTET32_LEN); diff --git a/components/bt/host/bluedroid/stack/smp/smp_utils.c b/components/bt/host/bluedroid/stack/smp/smp_utils.c index a9b4bf1a12..2e9fac77c9 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_utils.c +++ b/components/bt/host/bluedroid/stack/smp/smp_utils.c @@ -1031,6 +1031,8 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb) #endif ///BLE_INCLUDED == TRUE smp_reset_control_value(p_cb); + // TODO: clear local oob data when start advertising + smp_clear_local_oob_data(); if (p_callback) { (*p_callback) (SMP_COMPLT_EVT, pairing_bda, &evt_data);