Shows a consent dialog on the local device when pairing a bluetooth low
energy device if the local device has a display.
Tag: #security
Bug: 157038281
Test: Manual
Merged-In: I7de396230beb84bd0fa2b0cea346523b6824472a
Change-Id: I7de396230beb84bd0fa2b0cea346523b6824472a
(cherry picked from commit 03580fc44067b4289d1d77bd2f3ddf1e5974cf30)
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index f0da558..d1b260c 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -3804,6 +3804,16 @@
break;
+ case BTM_LE_CONSENT_REQ_EVT:
+ sec_event.ble_req.bd_addr = bda;
+ p_name = BTM_SecReadDevName(bda);
+ if (p_name != NULL)
+ strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
+ else
+ sec_event.ble_req.bd_name[0] = 0;
+ bta_dm_cb.p_sec_cback(BTA_DM_BLE_CONSENT_REQ_EVT, &sec_event);
+ break;
+
case BTM_LE_SEC_REQUEST_EVT:
sec_event.ble_req.bd_addr = bda;
p_name = BTM_SecReadDevName(bda);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 5079232..b7d7d30 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -380,6 +380,7 @@
*/
#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
#define BTA_DM_BLE_SC_OOB_REQ_EVT 29 /* SMP SC OOB request event */
+#define BTA_DM_BLE_CONSENT_REQ_EVT 30 /* SMP consent request event */
typedef uint8_t tBTA_DM_SEC_EVT;
/* Structure associated with BTA_DM_ENABLE_EVT */
diff --git a/btif/include/btif_dm.h b/btif/include/btif_dm.h
index 63ff0e7..fae8929 100644
--- a/btif/include/btif_dm.h
+++ b/btif/include/btif_dm.h
@@ -102,7 +102,7 @@
tBTA_BLE_LOCAL_ID_KEYS* p_id_keys);
void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr);
void btif_dm_remove_ble_bonding_keys(void);
-void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req);
+void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent);
void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr,
BD_NAME bd_name,
diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc
index f2fcee8..48d3290 100644
--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -1816,9 +1816,13 @@
break;
}
break;
+ case BTA_DM_BLE_CONSENT_REQ_EVT:
+ BTIF_TRACE_DEBUG("BTA_DM_BLE_CONSENT_REQ_EVT. ");
+ btif_dm_ble_sec_req_evt(&p_data->ble_req, true);
+ break;
case BTA_DM_BLE_SEC_REQ_EVT:
BTIF_TRACE_DEBUG("BTA_DM_BLE_SEC_REQ_EVT. ");
- btif_dm_ble_sec_req_evt(&p_data->ble_req);
+ btif_dm_ble_sec_req_evt(&p_data->ble_req, false);
break;
case BTA_DM_BLE_PASSKEY_NOTIF_EVT:
BTIF_TRACE_DEBUG("BTA_DM_BLE_PASSKEY_NOTIF_EVT. ");
@@ -3028,14 +3032,14 @@
* Returns void
*
******************************************************************************/
-void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req) {
+void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent) {
bt_bdname_t bd_name;
uint32_t cod;
int dev_type;
BTIF_TRACE_DEBUG("%s", __func__);
- if (pairing_cb.state == BT_BOND_STATE_BONDING) {
+ if (!is_consent && pairing_cb.state == BT_BOND_STATE_BONDING) {
BTIF_TRACE_DEBUG("%s Discard security request", __func__);
return;
}
diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc
index 1c4aa37..06a597a 100644
--- a/stack/btm/btm_ble.cc
+++ b/stack/btm/btm_ble.cc
@@ -2012,6 +2012,7 @@
p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
FALLTHROUGH_INTENDED; /* FALLTHROUGH */
+ case SMP_CONSENT_REQ_EVT:
case SMP_SEC_REQUEST_EVT:
if (event == SMP_SEC_REQUEST_EVT &&
btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) {
@@ -2019,7 +2020,9 @@
break;
}
btm_cb.pairing_bda = bd_addr;
- p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+ if (event != SMP_CONSENT_REQ_EVT) {
+ p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+ }
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
FALLTHROUGH_INTENDED; /* FALLTHROUGH */
diff --git a/stack/include/btm_api_types.h b/stack/include/btm_api_types.h
index b291ce5..05f12f0 100755
--- a/stack/include/btm_api_types.h
+++ b/stack/include/btm_api_types.h
@@ -1504,6 +1504,7 @@
#define BTM_LE_LAST_FROM_SMP BTM_LE_BR_KEYS_REQ_EVT
/* KEY update event */
#define BTM_LE_KEY_EVT (BTM_LE_LAST_FROM_SMP + 1)
+#define BTM_LE_CONSENT_REQ_EVT SMP_CONSENT_REQ_EVT
typedef uint8_t tBTM_LE_EVT;
#define BTM_LE_KEY_NONE 0
diff --git a/stack/include/smp_api_types.h b/stack/include/smp_api_types.h
index cee1204..96e7d9e 100644
--- a/stack/include/smp_api_types.h
+++ b/stack/include/smp_api_types.h
@@ -59,6 +59,7 @@
/* SC OOB local data set is created (as result of SMP_CrLocScOobData(...)) */
#define SMP_SC_LOC_OOB_DATA_UP_EVT 10
#define SMP_BR_KEYS_REQ_EVT 12 /* SMP over BR keys request event */
+#define SMP_CONSENT_REQ_EVT 14 /* Consent request event */
typedef uint8_t tSMP_EVT;
/* pairing failure reason code */
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index 21b960b..1239542 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -1301,18 +1301,27 @@
smp_int_data.status = SMP_PAIR_AUTH_FAIL;
int_evt = SMP_AUTH_CMPL_EVT;
} else {
- p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
- SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
- p_cb->sec_level);
+ if (p_cb->local_io_capability != SMP_IO_CAP_NONE &&
+ p_cb->local_io_capability != SMP_IO_CAP_IN) {
+ /* display consent dialog if this device has a display */
+ SMP_TRACE_DEBUG("ENCRYPTION_ONLY showing Consent Dialog");
+ p_cb->cb_evt = SMP_CONSENT_REQ_EVT;
+ smp_set_state(SMP_STATE_WAIT_NONCE);
+ smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL);
+ } else {
+ p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
+ SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
+ p_cb->sec_level);
- tSMP_KEY key;
- key.key_type = SMP_KEY_TYPE_TK;
- key.p_data = p_cb->tk.data();
- smp_int_data.key = key;
+ tSMP_KEY key;
+ key.key_type = SMP_KEY_TYPE_TK;
+ key.p_data = p_cb->tk.data();
+ smp_int_data.key = key;
- p_cb->tk = {0};
- /* TK, ready */
- int_evt = SMP_KEY_READY_EVT;
+ p_cb->tk = {0};
+ /* TK, ready */
+ int_evt = SMP_KEY_READY_EVT;
+ }
}
break;
@@ -1647,8 +1656,17 @@
}
if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
- /* go directly to phase 2 */
- smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
+ if (p_cb->local_io_capability != SMP_IO_CAP_NONE &&
+ p_cb->local_io_capability != SMP_IO_CAP_IN) {
+ /* display consent dialog */
+ SMP_TRACE_DEBUG("JUST WORKS showing Consent Dialog");
+ p_cb->cb_evt = SMP_CONSENT_REQ_EVT;
+ smp_set_state(SMP_STATE_WAIT_NONCE);
+ smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL);
+ } else {
+ /* go directly to phase 2 */
+ smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
+ }
} else /* numeric comparison */
{
smp_set_state(SMP_STATE_WAIT_NONCE);
diff --git a/stack/smp/smp_api.cc b/stack/smp/smp_api.cc
index e082356..ff8cdf5 100644
--- a/stack/smp/smp_api.cc
+++ b/stack/smp/smp_api.cc
@@ -249,6 +249,39 @@
void SMP_SecurityGrant(const RawAddress& bd_addr, uint8_t res) {
SMP_TRACE_EVENT("SMP_SecurityGrant ");
+ // If JUSTWORKS, this is used to display the consent dialog
+ if (smp_cb.selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
+ if (res == SMP_SUCCESS) {
+ smp_sm_event(&smp_cb, SMP_SC_NC_OK_EVT, NULL);
+ } else {
+ SMP_TRACE_WARNING("%s() - Consent dialog fails for JUSTWORKS", __func__);
+ /* send pairing failure */
+ tSMP_INT_DATA smp_int_data;
+ smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
+ smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+ }
+ } else if (smp_cb.selected_association_model == SMP_MODEL_ENCRYPTION_ONLY) {
+ if (res == SMP_SUCCESS) {
+ smp_cb.sec_level = SMP_SEC_UNAUTHENTICATE;
+
+ tSMP_KEY key;
+ tSMP_INT_DATA smp_int_data;
+ key.key_type = SMP_KEY_TYPE_TK;
+ key.p_data = smp_cb.tk.data();
+ smp_int_data.key = key;
+
+ smp_cb.tk = {0};
+ smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &smp_int_data);
+ } else {
+ SMP_TRACE_WARNING("%s() - Consent dialog fails for ENCRYPTION_ONLY",
+ __func__);
+ /* send pairing failure */
+ tSMP_INT_DATA smp_int_data;
+ smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
+ smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+ }
+ }
+
if (smp_cb.smp_over_br) {
if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr) {