bluedroid: support oob pairing for smp secure connection

This commit is contained in:
chenjianhua 2022-12-07 12:15:25 +08:00
parent 7d7a710b60
commit 2048322429
20 changed files with 437 additions and 43 deletions

View File

@ -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)

View File

@ -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) */
/**

View File

@ -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);

View File

@ -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 */
/*******************************************************************************
**

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */
/*******************************************************************************

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
/*******************************************************************************
**

View File

@ -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
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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);