Bluetooth: smp: Adding Legacy OOB pairing support

Added support for Legacy pairing using OOB Temporary Key

Signed-off-by: Iván Morales <ivan98ams@gmail.com>
This commit is contained in:
Iván Morales 2020-01-14 13:32:51 +01:00 committed by Johan Hedberg
commit cc0d2447f1
4 changed files with 77 additions and 5 deletions

View file

@ -618,6 +618,20 @@ void bt_set_bondable(bool enable);
*/
void bt_set_oob_data_flag(bool enable);
/**
* @brief Set OOB Temporary Key to be used for pairing
*
* This function allows to set OOB data for the LE legacy pairing procedure. The
* function should only be called in response to the oob_data_request() callback
* provided that the legacy method is user pairing.
*
* @param conn Connection object
* @param tk Pointer to 16 byte long TK array
*
* @return Zero on success or -EINVAL if NULL
*/
int bt_le_oob_set_legacy_tk(struct bt_conn *conn, const u8_t *tk);
/**
* @brief Set OOB data during LE SC pairing procedure
*

View file

@ -6876,6 +6876,13 @@ int bt_le_oob_get_local(u8_t id, struct bt_le_oob *oob)
}
#if defined(CONFIG_BT_SMP)
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
int bt_le_oob_set_legacy_tk(struct bt_conn *conn, const u8_t *tk)
{
return bt_smp_le_oob_set_tk(conn, tk);
}
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
int bt_le_oob_set_sc_data(struct bt_conn *conn,
const struct bt_le_oob_sc_data *oobd_local,
const struct bt_le_oob_sc_data *oobd_remote)
@ -6897,4 +6904,4 @@ int bt_le_oob_get_sc_data(struct bt_conn *conn,
return bt_smp_le_oob_get_sc_data(conn, oobd_local, oobd_remote);
}
#endif
#endif /* defined(CONFIG_BT_SMP) */

View file

@ -95,6 +95,7 @@ enum pairing_method {
PASSKEY_CONFIRM, /* Passkey confirm */
PASSKEY_ROLE, /* Passkey Entry depends on role */
LE_SC_OOB, /* LESC Out of Band */
LEGACY_OOB, /* Legacy Out of Band */
};
enum {
@ -2194,6 +2195,11 @@ static u8_t legacy_get_pair_method(struct bt_smp *smp, u8_t remote_io)
req = (struct bt_smp_pairing *)&smp->preq[1];
rsp = (struct bt_smp_pairing *)&smp->prsp[1];
/* if both sides have OOB data use OOB */
if ((req->oob_flag & rsp->oob_flag) & BT_SMP_OOB_DATA_MASK) {
return LEGACY_OOB;
}
/* if none side requires MITM use JustWorks */
if (!((req->auth_req | rsp->auth_req) & BT_SMP_AUTH_MITM)) {
return JUST_WORKS;
@ -2234,6 +2240,19 @@ static u8_t legacy_request_tk(struct bt_smp *smp)
}
switch (smp->method) {
case LEGACY_OOB:
if (bt_auth && bt_auth->oob_data_request) {
struct bt_conn_oob_info info = {
.type = BT_CONN_OOB_LE_LEGACY,
};
atomic_set_bit(smp->flags, SMP_FLAG_USER);
bt_auth->oob_data_request(smp->chan.chan.conn, &info);
} else {
return BT_SMP_ERR_OOB_NOT_AVAIL;
}
break;
case PASSKEY_DISPLAY:
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) &&
fixed_passkey != BT_PASSKEY_INVALID) {
@ -2420,11 +2439,8 @@ static u8_t legacy_pairing_confirm(struct bt_smp *smp)
return 0;
}
static void legacy_passkey_entry(struct bt_smp *smp, unsigned int passkey)
static void legacy_user_tk_entry(struct bt_smp *smp)
{
passkey = sys_cpu_to_le32(passkey);
memcpy(smp->tk, &passkey, sizeof(passkey));
if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_CFM_DELAYED)) {
return;
}
@ -2446,6 +2462,14 @@ static void legacy_passkey_entry(struct bt_smp *smp, unsigned int passkey)
}
}
static void legacy_passkey_entry(struct bt_smp *smp, unsigned int passkey)
{
passkey = sys_cpu_to_le32(passkey);
memcpy(smp->tk, &passkey, sizeof(passkey));
legacy_user_tk_entry(smp);
}
static u8_t smp_encrypt_info(struct bt_smp *smp, struct net_buf *buf)
{
BT_DBG("");
@ -5016,6 +5040,30 @@ int bt_smp_auth_passkey_confirm(struct bt_conn *conn)
return 0;
}
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
int bt_smp_le_oob_set_tk(struct bt_conn *conn, const u8_t *tk)
{
struct bt_smp *smp;
smp = smp_chan_get(conn);
if (!smp || !tk) {
return -EINVAL;
}
BT_DBG("%s", bt_hex(tk, 16));
if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_USER)) {
return -EINVAL;
}
memcpy(smp->tk, tk, 16*sizeof(u8_t));
legacy_user_tk_entry(smp);
return 0;
}
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
int bt_smp_le_oob_generate_sc_data(struct bt_le_oob_sc_data *le_sc_oob)
{
int err;
@ -5174,6 +5222,7 @@ int bt_smp_auth_cancel(struct bt_conn *conn)
case PASSKEY_CONFIRM:
return smp_error(smp, BT_SMP_ERR_CONFIRM_FAILED);
case LE_SC_OOB:
case LEGACY_OOB:
return smp_error(smp, BT_SMP_ERR_OOB_NOT_AVAIL);
case JUST_WORKS:
return smp_error(smp, BT_SMP_ERR_UNSPECIFIED);
@ -5349,6 +5398,7 @@ void bt_smp_update_keys(struct bt_conn *conn)
case PASSKEY_INPUT:
case PASSKEY_CONFIRM:
case LE_SC_OOB:
case LEGACY_OOB:
conn->le.keys->flags |= BT_KEYS_AUTHENTICATED;
break;
case JUST_WORKS:

View file

@ -138,6 +138,7 @@ int bt_smp_auth_passkey_confirm(struct bt_conn *conn);
int bt_smp_auth_pairing_confirm(struct bt_conn *conn);
int bt_smp_auth_cancel(struct bt_conn *conn);
int bt_smp_le_oob_set_tk(struct bt_conn *conn, const u8_t *tk);
int bt_smp_le_oob_generate_sc_data(struct bt_le_oob_sc_data *le_sc_oob);
int bt_smp_le_oob_set_sc_data(struct bt_conn *conn,
const struct bt_le_oob_sc_data *oobd_local,