Merge branch 'bugfix/btdm_add_static_passkey_and_accept_specified_sec_aut' into 'release/v3.1'

component/bt:  add static passkey and accept specified sec auth (backport v3.1)

See merge request idf/esp-idf!3559
This commit is contained in:
Jiang Jiang Jian
2018-11-05 11:02:18 +08:00
26 changed files with 467 additions and 27 deletions

View File

@ -441,6 +441,23 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d
esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
void *value, uint8_t len)
{
if(param_type >= ESP_BLE_SM_MAX_PARAM) {
return ESP_ERR_INVALID_ARG;
}
if((param_type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY) && ( value == NULL || len < sizeof(uint8_t) || len > sizeof(uint32_t))) {
return ESP_ERR_INVALID_ARG;
}
if((param_type == ESP_BLE_SM_SET_STATIC_PASSKEY)) {
uint32_t passkey = 0;
for(uint8_t i = 0; i < len; i++)
{
passkey += (((uint8_t *)value)[i]<<(8*i));
}
if(passkey > 999999) {
return ESP_ERR_INVALID_ARG;
}
}
btc_msg_t msg;
btc_ble_gap_args_t arg;

View File

@ -54,12 +54,16 @@ typedef uint8_t esp_ble_key_type_t;
#define ESP_LE_AUTH_NO_BOND 0x00 /*!< 0*/ /* relate to BTM_LE_AUTH_NO_BOND in stack/btm_api.h */
#define ESP_LE_AUTH_BOND 0x01 /*!< 1 << 0 */ /* relate to BTM_LE_AUTH_BOND in stack/btm_api.h */
#define ESP_LE_AUTH_REQ_MITM (1 << 2) /*!< 1 << 2 */ /* relate to BTM_LE_AUTH_REQ_MITM in stack/btm_api.h */
#define ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)/*!< 0101*/
#define ESP_LE_AUTH_REQ_SC_ONLY (1 << 3) /*!< 1 << 3 */ /* relate to BTM_LE_AUTH_REQ_SC_ONLY in stack/btm_api.h */
#define ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1001 */ /* relate to BTM_LE_AUTH_REQ_SC_BOND in stack/btm_api.h */
#define ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1100 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM in stack/btm_api.h */
#define ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND) /*!< 1101 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM_BOND in stack/btm_api.h */
typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */
#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE 0
#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE 1
/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */
#define ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
#define ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
@ -264,6 +268,10 @@ typedef enum {
ESP_BLE_SM_SET_INIT_KEY,
ESP_BLE_SM_SET_RSP_KEY,
ESP_BLE_SM_MAX_KEY_SIZE,
ESP_BLE_SM_SET_STATIC_PASSKEY,
ESP_BLE_SM_CLEAR_STATIC_PASSKEY,
ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH,
ESP_BLE_SM_MAX_PARAM,
} esp_ble_sm_param_t;
/// Advertising parameters
@ -508,7 +516,8 @@ typedef struct
uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */
esp_ble_addr_type_t addr_type; /*!< Peer device address type */
esp_bt_dev_type_t dev_type; /*!< Device type */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */
esp_ble_auth_req_t auth_mode; /*!< authentication mode */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */
/**
* @brief union associated with ble security

View File

@ -4249,9 +4249,8 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
switch (event) {
case BTM_LE_IO_REQ_EVT:
// #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
case BTM_LE_IO_REQ_EVT: {
// #if (BT_SSP_INCLUDED == TRUE)
bta_dm_co_ble_io_req(bda,
&p_data->io_req.io_cap,
&p_data->io_req.oob_data,
@ -4266,6 +4265,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
APPL_TRACE_EVENT("io mitm: %d oob_data:%d\n", p_data->io_req.auth_req, p_data->io_req.oob_data);
break;
}
case BTM_LE_SEC_REQUEST_EVT:
bdcpy(sec_event.ble_req.bd_addr, bda);
@ -4341,7 +4341,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
}
}
sec_event.auth_cmpl.auth_mode = p_data->complt.auth_mode;
if (bta_dm_cb.p_sec_cback) {
//bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
@ -4459,6 +4459,10 @@ void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
}
void bta_dm_ble_set_static_passkey(tBTA_DM_MSG *p_data)
{
BTM_BleSetStaticPasskey(p_data->ble_set_static_passkey.add, p_data->ble_set_static_passkey.static_passkey);
}
/*******************************************************************************
**
** Function bta_dm_ble_confirm_reply

View File

@ -825,6 +825,21 @@ void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, BOOLEAN accept, UINT32 passkey)
bta_sys_sendmsg(p_msg);
}
}
void BTA_DmBleSetStaticPasskey(bool add, uint32_t passkey)
{
tBTA_DM_API_SET_DEFAULT_PASSKEY *p_msg;
if ((p_msg = (tBTA_DM_API_SET_DEFAULT_PASSKEY *) osi_malloc(sizeof(tBTA_DM_API_SET_DEFAULT_PASSKEY))) != NULL) {
memset(p_msg, 0, sizeof(tBTA_DM_API_SET_DEFAULT_PASSKEY));
p_msg->hdr.event = BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT;
p_msg->add = add;
p_msg->static_passkey = passkey;
bta_sys_sendmsg(p_msg);
}
}
/*******************************************************************************
**
** Function BTA_DmBleConfirmReply

View File

@ -31,6 +31,10 @@
#endif /* #if (defined(BTIF_INCLUDED) && BTIF_INCLUDED == TRUE) */
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
#include "common/bte_appl.h"
#define BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE 0
#define BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_ENABLE 1
tBTE_APPL_CFG bte_appl_cfg = {
#if SMP_INCLUDED == TRUE
BTA_LE_AUTH_REQ_SC_MITM_BOND, // Authentication requirements
@ -40,7 +44,8 @@ tBTE_APPL_CFG bte_appl_cfg = {
BTM_LOCAL_IO_CAPS_BLE,
BTM_BLE_INITIATOR_KEY_SIZE,
BTM_BLE_RESPONDER_KEY_SIZE,
BTM_BLE_MAX_KEY_SIZE
BTM_BLE_MAX_KEY_SIZE,
BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE
};
#endif
@ -363,5 +368,32 @@ void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size)
}
#endif ///SMP_INCLUDED == TRUE
}
void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable)
{
#if (SMP_INCLUDED == TRUE)
if (enable) {
enable = BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_ENABLE;
}
bte_appl_cfg.ble_accept_auth_enable = enable;
#endif ///SMP_INCLUDED == TRUE
}
UINT8 bta_dm_co_ble_get_accept_auth_enable(void)
{
#if (SMP_INCLUDED == TRUE)
return bte_appl_cfg.ble_accept_auth_enable;
#endif ///SMP_INCLUDED == TRUE
return 0;
}
UINT8 bta_dm_co_ble_get_auth_req(void)
{
#if (SMP_INCLUDED == TRUE)
return bte_appl_cfg.ble_auth_req;
#endif ///SMP_INCLUDED == TRUE
return 0;
}
#endif

View File

@ -89,6 +89,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */
bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */
bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */
bta_dm_ble_set_static_passkey, /* BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT */
bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */
bta_dm_security_grant,
#endif ///SMP_INCLUDED == TRUE

View File

@ -87,6 +87,7 @@ enum {
BTA_DM_API_ADD_BLEKEY_EVT,
BTA_DM_API_ADD_BLEDEVICE_EVT,
BTA_DM_API_BLE_PASSKEY_REPLY_EVT,
BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT,
BTA_DM_API_BLE_CONFIRM_REPLY_EVT,
BTA_DM_API_BLE_SEC_GRANT_EVT,
#endif ///SMP_INCLUDED == TRUE
@ -444,6 +445,12 @@ typedef struct {
UINT32 passkey;
} tBTA_DM_API_PASSKEY_REPLY;
typedef struct {
BT_HDR hdr;
BOOLEAN add;
UINT32 static_passkey;
} tBTA_DM_API_SET_DEFAULT_PASSKEY;
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
@ -787,6 +794,7 @@ typedef union {
tBTA_DM_API_ADD_BLEKEY add_ble_key;
tBTA_DM_API_ADD_BLE_DEVICE add_ble_device;
tBTA_DM_API_PASSKEY_REPLY ble_passkey_reply;
tBTA_DM_API_SET_DEFAULT_PASSKEY ble_set_static_passkey;
tBTA_DM_API_BLE_SEC_GRANT ble_sec_grant;
tBTA_DM_API_BLE_SET_BG_CONN_TYPE ble_set_bd_conn_type;
tBTA_DM_API_BLE_CONN_PARAMS ble_set_conn_params;
@ -1189,6 +1197,7 @@ extern void bta_dm_add_ampkey (tBTA_DM_MSG *p_data);
extern void bta_dm_add_blekey (tBTA_DM_MSG *p_data);
extern void bta_dm_add_ble_device (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_static_passkey(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data);
extern void bta_dm_security_grant (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data);

View File

@ -763,6 +763,7 @@ typedef struct {
UINT8 fail_reason; /* The HCI reason/error code for when success=FALSE */
tBLE_ADDR_TYPE addr_type; /* Peer device address type */
tBT_DEVICE_TYPE dev_type;
UINT8 auth_mode;
} tBTA_DM_AUTH_CMPL;
@ -1802,6 +1803,22 @@ extern void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_B
*******************************************************************************/
extern void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, BOOLEAN accept, UINT32 passkey);
/*******************************************************************************
**
** Function BTA_DmBleSetStaticPasskey
**
** Description Set BLE SMP static passkey.
**
** Parameters: add - add static passkey when add is true
** clear static passkey when add is false
** passkey - static passkey value
**
**
** Returns void
**
*******************************************************************************/
extern void BTA_DmBleSetStaticPasskey(bool add, uint32_t passkey);
/*******************************************************************************
**
** Function BTA_DmBleConfirmReply

View File

@ -190,4 +190,10 @@ extern void bta_dm_co_ble_set_init_key_req(UINT8 init_key);
extern void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key);
extern void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size);
extern void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable);
extern UINT8 bta_dm_co_ble_get_accept_auth_enable(void);
extern UINT8 bta_dm_co_ble_get_auth_req(void);
#endif

View File

@ -584,6 +584,7 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
param.ble_security.auth_cmpl.key_present = p_data->auth_cmpl.key_present;
memcpy(param.ble_security.auth_cmpl.bd_addr, p_data->auth_cmpl.bd_addr, sizeof(BD_ADDR));
memcpy(param.ble_security.auth_cmpl.key, p_data->auth_cmpl.key, sizeof(LINK_KEY));
param.ble_security.auth_cmpl.auth_mode = p_data->auth_cmpl.auth_mode;
btc_dm_ble_auth_cmpl_evt(&p_data->auth_cmpl);
break;
}

View File

@ -1116,6 +1116,25 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
bta_dm_co_ble_set_max_key_size(key_size);
break;
}
case ESP_BLE_SM_SET_STATIC_PASSKEY: {
uint32_t passkey = 0;
for(uint8_t i = 0; i < arg->set_security_param.len; i++)
{
passkey += (((uint8_t *)value)[i]<<(8*i));
}
BTA_DmBleSetStaticPasskey(true, passkey);
break;
}
case ESP_BLE_SM_CLEAR_STATIC_PASSKEY: {
BTA_DmBleSetStaticPasskey(false, 0);
break;
}
case ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH: {
uint8_t enable = 0;
STREAM_TO_UINT8(enable, value);
bta_dm_co_ble_set_accept_auth_enable(enable);
break;
}
default:
break;
}

View File

@ -31,6 +31,7 @@ typedef struct {
UINT8 ble_init_key;
UINT8 ble_resp_key;
UINT8 ble_max_key_size;
UINT8 ble_accept_auth_enable;
#endif
} tBTE_APPL_CFG;

View File

@ -423,6 +423,26 @@ void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
#endif
}
/*******************************************************************************
**
** Function BTM_BleSetStaticPasskey
**
** Description This function is called to set static passkey
**
**
** Parameters: add - set static passkey when add is TRUE
** clear static passkey when add is FALSE
** passkey - static passkey
**
**
*******************************************************************************/
void BTM_BleSetStaticPasskey(BOOLEAN add, UINT32 passkey)
{
#if SMP_INCLUDED == TRUE
SMP_SetStaticPasskey(add, passkey);
#endif
}
/*******************************************************************************
**
** Function BTM_BleConfirmReply

View File

@ -1642,6 +1642,7 @@ typedef struct {
UINT8 sec_level;
BOOLEAN is_pair_cancel;
BOOLEAN smp_over_br;
tSMP_AUTH_REQ auth_mode;
} tBTM_LE_COMPLT;
#endif

View File

@ -1315,6 +1315,21 @@ void BTM_SecurityGrant(BD_ADDR bd_addr, UINT8 res);
//extern
void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey);
/*******************************************************************************
**
** Function BTM_BleSetStaticPasskey
**
** Description This function is called to set static passkey
**
**
** Parameters: add - set static passkey when add is TRUE
** clear static passkey when add is FALSE
** passkey - static passkey
**
**
*******************************************************************************/
void BTM_BleSetStaticPasskey(BOOLEAN add, UINT32 passkey);
/*******************************************************************************
**
** Function BTM_BleConfirmReply

View File

@ -224,6 +224,7 @@ typedef struct {
tSMP_SEC_LEVEL sec_level;
BOOLEAN is_pair_cancel;
BOOLEAN smp_over_br;
tSMP_AUTH_REQ auth_mode;
} tSMP_CMPL;
typedef struct {
@ -401,6 +402,21 @@ extern void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res);
*******************************************************************************/
extern void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey);
/*******************************************************************************
**
** Function SMP_SetStaticPasskey
**
** Description This function is called to set static passkey
**
**
** Parameters: add - set static passkey when add is TRUE
** clear static passkey when add is FALSE
** passkey - static passkey
**
**
*******************************************************************************/
extern void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey);
/*******************************************************************************
**
** Function SMP_ConfirmReply

View File

@ -132,6 +132,8 @@ typedef UINT8 tSMP_EVENT;
/* Assumption it's only using the low 8 bits, if bigger than that, need to expand it to 16 bits */
#define SMP_SEC_KEY_MASK 0x00ff
#define SMP_PASSKEY_MASK 0xfff00000
/* SMP pairing state */
enum {
SMP_STATE_IDLE,
@ -299,6 +301,7 @@ typedef struct {
tSMP_OOB_FLAG loc_oob_flag;
tSMP_AUTH_REQ peer_auth_req;
tSMP_AUTH_REQ loc_auth_req;
tSMP_AUTH_REQ auth_mode;
BOOLEAN secure_connections_only_mode_required;/* TRUE if locally SM is required to operate */
/* either in Secure Connections mode or not at all */
tSMP_ASSO_MODEL selected_association_model;
@ -331,6 +334,10 @@ typedef struct {
UINT8 rcvd_cmd_len;
UINT16 total_tx_unacked;
BOOLEAN wait_for_authorization_complete;
BOOLEAN use_static_passkey;
UINT32 static_passkey;
BOOLEAN accept_specified_sec_auth;
tSMP_AUTH_REQ origin_loc_auth_req;
} tSMP_CB;
/* Server Action functions are of this type */

View File

@ -52,6 +52,9 @@ const tSMP_ACT smp_distribute_act [] = {
smp_set_derive_link_key
};
extern UINT8 bta_dm_co_ble_get_accept_auth_enable(void);
extern UINT8 bta_dm_co_ble_get_auth_req(void);
static bool lmp_version_below(BD_ADDR bda, uint8_t version)
{
tACL_CONN *acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE);
@ -498,6 +501,33 @@ void smp_proc_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
p_cb->status = *(UINT8 *)p_data;
}
/*******************************************************************************
** Function smp_get_auth_mode
** Description Get the SMP pairing auth mode
*******************************************************************************/
uint16_t smp_get_auth_mode (tSMP_ASSO_MODEL model)
{
SMP_TRACE_DEBUG("%s model %d", __func__, model);
uint16_t auth = 0;
if (model == SMP_MODEL_ENCRYPTION_ONLY || model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
//No MITM
if(model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
//SC SMP_SC_SUPPORT_BIT
auth |= SMP_SC_SUPPORT_BIT;
}
} else if (model <= SMP_MODEL_KEY_NOTIF) {
//NO SC, MITM
auth |= SMP_AUTH_YN_BIT;
} else if (model <= SMP_MODEL_SEC_CONN_OOB) {
//SC, MITM
auth |= SMP_SC_SUPPORT_BIT;
auth |= SMP_AUTH_YN_BIT;
} else {
auth = 0;
}
return auth;
}
/*******************************************************************************
** Function smp_proc_pair_cmd
** Description Process the SMP pairing request/response from peer device
@ -528,7 +558,8 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
p_cb->accept_specified_sec_auth = bta_dm_co_ble_get_accept_auth_enable();
p_cb->origin_loc_auth_req = bta_dm_co_ble_get_auth_req();
if (p_cb->role == HCI_ROLE_SLAVE) {
if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) {
/* peer (master) started pairing sending Pairing Request */
@ -551,6 +582,22 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
uint16_t auth = smp_get_auth_mode(p_cb->selected_association_model);
if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
auth |= SMP_AUTH_GEN_BOND;
}
p_cb->auth_mode = auth;
if (p_cb->accept_specified_sec_auth) {
if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
SMP_TRACE_ERROR("%s pairing failed - slave requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
__func__, p_cb->origin_loc_auth_req, p_cb->peer_auth_req, p_cb->loc_auth_req);
if (BTM_IsAclConnectionUp(p_cb->pairing_bda, BT_TRANSPORT_LE)) {
btm_remove_acl (p_cb->pairing_bda, BT_TRANSPORT_LE);
}
reason = SMP_PAIR_AUTH_FAIL;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
}
}
if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
if (smp_request_oob_data(p_cb)) {
@ -573,6 +620,23 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
return;
}
uint16_t auth = smp_get_auth_mode(p_cb->selected_association_model);
if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
auth |= SMP_AUTH_GEN_BOND;
}
p_cb->auth_mode = auth;
if (p_cb->accept_specified_sec_auth) {
if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
SMP_TRACE_ERROR("%s pairing failed - master requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
__func__, p_cb->origin_loc_auth_req, p_cb->peer_auth_req, p_cb->loc_auth_req);
if (BTM_IsAclConnectionUp(p_cb->pairing_bda, BT_TRANSPORT_LE)) {
btm_remove_acl (p_cb->pairing_bda, BT_TRANSPORT_LE);
}
reason = SMP_PAIR_AUTH_FAIL;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
}
}
if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
if (smp_request_oob_data(p_cb)) {
return;
@ -1317,6 +1381,22 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
uint16_t auth = smp_get_auth_mode(p_cb->selected_association_model);
if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
auth |= SMP_AUTH_GEN_BOND;
}
p_cb->auth_mode = auth;
if (p_cb->accept_specified_sec_auth) {
if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
SMP_TRACE_ERROR("pairing failed - slave requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
p_cb->origin_loc_auth_req, p_cb->peer_auth_req, p_cb->loc_auth_req);
if (BTM_IsAclConnectionUp(p_cb->pairing_bda, BT_TRANSPORT_LE)) {
btm_remove_acl (p_cb->pairing_bda, BT_TRANSPORT_LE);
}
reason = SMP_PAIR_AUTH_FAIL;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
}
}
if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
if (smp_request_oob_data(p_cb)) {

View File

@ -328,6 +328,32 @@ void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
return;
}
/*******************************************************************************
**
** Function SMP_SetStaticPasskey
**
** Description This function is called to set static passkey
**
**
** Parameters: add - set static passkey when add is TRUE
** clear static passkey when add is FALSE
** passkey - static passkey
**
**
*******************************************************************************/
void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey)
{
SMP_TRACE_DEBUG("static passkey %6d", passkey);
tSMP_CB *p_cb = & smp_cb;
if(add) {
p_cb->static_passkey = passkey;
p_cb->use_static_passkey = true;
} else {
p_cb->static_passkey = 0;
p_cb->use_static_passkey = false;
}
}
/*******************************************************************************
**
** Function SMP_ConfirmReply

View File

@ -71,8 +71,6 @@ static const tSMP_ACT smp_encrypt_action[] = {
smp_generate_rand_cont /* SMP_GEN_SRAND_MRAND_CONT */
};
#define SMP_PASSKEY_MASK 0xfff00000
void smp_debug_print_nbyte_little_endian(UINT8 *p, const UINT8 *key_name, UINT8 len)
{
#if SMP_DEBUG == TRUE
@ -186,6 +184,29 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len,
return TRUE;
}
void smp_use_static_passkey(void)
{
tSMP_CB *p_cb = &smp_cb;
UINT8 *tt = p_cb->tk;
tSMP_KEY key;
UINT32 passkey = p_cb->static_passkey;
/* save the TK */
memset(p_cb->tk, 0, BT_OCTET16_LEN);
UINT32_TO_STREAM(tt, passkey);
key.key_type = SMP_KEY_TYPE_TK;
key.p_data = p_cb->tk;
if (p_cb->p_callback) {
(*p_cb->p_callback)(SMP_PASSKEY_NOTIF_EVT, p_cb->pairing_bda, (tSMP_EVT_DATA *)&passkey);
}
if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_DISP) {
smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &passkey);
} else {
smp_sm_event(p_cb, SMP_KEY_READY_EVT, (tSMP_INT_DATA *)&key);
}
}
/*******************************************************************************
**
** Function smp_generate_passkey
@ -199,7 +220,12 @@ void smp_generate_passkey(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
UNUSED(p_data);
SMP_TRACE_DEBUG ("%s", __func__);
if(p_cb->use_static_passkey) {
SMP_TRACE_DEBUG ("%s use static passkey %6d", __func__, p_cb->static_passkey);
smp_use_static_passkey();
return;
}
SMP_TRACE_DEBUG ("%s generate rand passkey", __func__);
p_cb->rand_enc_proc_state = SMP_GEN_TK;
/* generate MRand or SRand */

View File

@ -881,12 +881,17 @@ void smp_cb_cleanup(tSMP_CB *p_cb)
{
tSMP_CALLBACK *p_callback = p_cb->p_callback;
UINT8 trace_level = p_cb->trace_level;
UINT32 static_passkey = p_cb->static_passkey;
BOOLEAN use_static_passkey = p_cb->use_static_passkey;
SMP_TRACE_EVENT("smp_cb_cleanup\n");
memset(p_cb, 0, sizeof(tSMP_CB));
p_cb->p_callback = p_callback;
p_cb->trace_level = trace_level;
if(use_static_passkey) {
p_cb->use_static_passkey = use_static_passkey;
p_cb->static_passkey = static_passkey;
}
}
/*******************************************************************************
@ -957,9 +962,10 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
evt_data.cmplt.reason = p_cb->status;
evt_data.cmplt.smp_over_br = p_cb->smp_over_br;
evt_data.cmplt.auth_mode = 0;
if (p_cb->status == SMP_SUCCESS) {
evt_data.cmplt.sec_level = p_cb->sec_level;
evt_data.cmplt.auth_mode = p_cb->auth_mode;
}
evt_data.cmplt.is_pair_cancel = FALSE;

View File

@ -105,3 +105,31 @@ TEST_CASE("ble_smp_public_key_check", "[ble_smp]")
TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&public_key));
}
}
TEST_CASE("ble_smp_set_clear_static_passkey", "[ble_smp]")
{
/* We wait init finish 200ms here */
vTaskDelay(200 / portTICK_PERIOD_MS);
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND;
uint32_t passkey = 123456;
/* test len = 0 when type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, 0) == ESP_ERR_INVALID_ARG);
/* test function */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(esp_ble_auth_req_t)) != ESP_ERR_INVALID_ARG);
/* test type >= ESP_BLE_SM_MAX_PARAM */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_PARAM, &passkey, sizeof(uint32_t)) == ESP_ERR_INVALID_ARG);
/* test len < sizeof(uint32_t) when type is ESP_BLE_SM_SET_STATIC_PASSKEY */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint8_t)) != ESP_ERR_INVALID_ARG);
/* test value is NULL when type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, NULL, sizeof(uint8_t)) == ESP_ERR_INVALID_ARG);
/* test value is NULL and len is 0 when type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, NULL, 0) == ESP_ERR_INVALID_ARG);
/* test function */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t)) != ESP_ERR_INVALID_ARG);
/* test function */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_CLEAR_STATIC_PASSKEY, &passkey, sizeof(uint32_t)) != ESP_ERR_INVALID_ARG);
/* test function */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_CLEAR_STATIC_PASSKEY, NULL, sizeof(uint32_t)) != ESP_ERR_INVALID_ARG);
/* test function */
TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_CLEAR_STATIC_PASSKEY, NULL, 0) != ESP_ERR_INVALID_ARG);
}

View File

@ -126,6 +126,42 @@ static const char *esp_key_type_to_str(esp_ble_key_type_t key_type)
return key_str;
}
static char *esp_auth_req_to_str(esp_ble_auth_req_t auth_req)
{
char *auth_str = NULL;
switch(auth_req) {
case ESP_LE_AUTH_NO_BOND:
auth_str = "ESP_LE_AUTH_NO_BOND";
break;
case ESP_LE_AUTH_BOND:
auth_str = "ESP_LE_AUTH_BOND";
break;
case ESP_LE_AUTH_REQ_MITM:
auth_str = "ESP_LE_AUTH_REQ_MITM";
break;
case ESP_LE_AUTH_REQ_BOND_MITM:
auth_str = "ESP_LE_AUTH_REQ_BOND_MITM";
break;
case ESP_LE_AUTH_REQ_SC_ONLY:
auth_str = "ESP_LE_AUTH_REQ_SC_ONLY";
break;
case ESP_LE_AUTH_REQ_SC_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_BOND";
break;
case ESP_LE_AUTH_REQ_SC_MITM:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM";
break;
case ESP_LE_AUTH_REQ_SC_MITM_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM_BOND";
break;
default:
auth_str = "INVALID BLE AUTH REQ";
break;
}
return auth_str;
}
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param;
@ -302,7 +338,7 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
ESP_LOGI(GATTC_TAG, "Write char success ");
break;
case ESP_GATTC_DISCONNECT_EVT:
ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = %d", p_data->disconnect.reason);
ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = 0x%x", p_data->disconnect.reason);
connect = false;
get_service = false;
break;
@ -365,7 +401,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer deivce.
ESP_LOGI(GATTC_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey);
ESP_LOGI(GATTC_TAG, "The passkey Notify number:%06d", param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
@ -379,6 +415,11 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
(bd_addr[4] << 8) + bd_addr[5]);
ESP_LOGI(GATTC_TAG, "address type = %d", param->ble_security.auth_cmpl.addr_type);
ESP_LOGI(GATTC_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
if (!param->ble_security.auth_cmpl.success) {
ESP_LOGI(GATTC_TAG, "fail reason = 0x%x",param->ble_security.auth_cmpl.fail_reason);
} else {
ESP_LOGI(GATTC_TAG, "auth mode = %s",esp_auth_req_to_str(param->ble_security.auth_cmpl.auth_mode));
}
break;
}
case ESP_GAP_BLE_SCAN_RESULT_EVT: {

View File

@ -227,6 +227,42 @@ static char *esp_key_type_to_str(esp_ble_key_type_t key_type)
return key_str;
}
static char *esp_auth_req_to_str(esp_ble_auth_req_t auth_req)
{
char *auth_str = NULL;
switch(auth_req) {
case ESP_LE_AUTH_NO_BOND:
auth_str = "ESP_LE_AUTH_NO_BOND";
break;
case ESP_LE_AUTH_BOND:
auth_str = "ESP_LE_AUTH_BOND";
break;
case ESP_LE_AUTH_REQ_MITM:
auth_str = "ESP_LE_AUTH_REQ_MITM";
break;
case ESP_LE_AUTH_REQ_BOND_MITM:
auth_str = "ESP_LE_AUTH_REQ_BOND_MITM";
break;
case ESP_LE_AUTH_REQ_SC_ONLY:
auth_str = "ESP_LE_AUTH_REQ_SC_ONLY";
break;
case ESP_LE_AUTH_REQ_SC_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_BOND";
break;
case ESP_LE_AUTH_REQ_SC_MITM:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM";
break;
case ESP_LE_AUTH_REQ_SC_MITM_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM_BOND";
break;
default:
auth_str = "INVALID BLE AUTH REQ";
break;
}
return auth_str;
}
static void show_bonded_devices(void)
{
int dev_num = esp_ble_get_bond_device_num();
@ -306,7 +342,7 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer deivce.
ESP_LOGI(GATTS_TABLE_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey);
ESP_LOGI(GATTS_TABLE_TAG, "The passkey Notify number:%06d", param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
@ -322,6 +358,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
if(!param->ble_security.auth_cmpl.success) {
ESP_LOGI(GATTS_TABLE_TAG, "fail reason = 0x%x",param->ble_security.auth_cmpl.fail_reason);
} else {
ESP_LOGI(GATTS_TABLE_TAG, "auth mode = %s",esp_auth_req_to_str(param->ble_security.auth_cmpl.auth_mode));
}
show_bonded_devices();
break;
@ -398,7 +436,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
break;
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT");
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
/* start advertising again when missing the connect */
esp_ble_gap_start_advertising(&heart_rate_adv_params);
break;
@ -518,14 +556,19 @@ void app_main()
}
/* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication
esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE; //set the IO capability to No output No input
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; //bonding with peer device after authentication
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; //set the IO capability to No output No input
uint8_t key_size = 16; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
//set static passkey
uint32_t passkey = 123456;
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
/* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribut to you,
and the response key means which key you can distribut to the Master;
If your BLE device act as a master, the response key means you hope which types of key of the slave should distribut to you,

View File

@ -481,7 +481,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
}
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT");
ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
esp_ble_gap_start_advertising(&adv_params);
break;
case ESP_GATTS_CONF_EVT:

View File

@ -452,7 +452,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
esp_ble_gap_update_conn_params(&conn_params);
break;
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT, reason = %d", param->disconnect.reason);
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT, reason = 0x%x", param->disconnect.reason);
esp_ble_gap_start_advertising(&adv_params);
break;
case ESP_GATTS_CREAT_ATTR_TAB_EVT:{