Skip to content
Permalink
Browse files

Bluetooth: smp: Add LE SC OOB support for central side

Add support for LE secure connections using OOB authentication for the
central role.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
  • Loading branch information...
joerchan authored and carlescufi committed May 28, 2019
1 parent 0ac8318 commit f8b7f2ab6a2b1d25cfff7c0c8c455ab2afa79f20
Showing with 67 additions and 13 deletions.
  1. +67 −13 subsys/bluetooth/host/smp.c
@@ -2765,6 +2765,11 @@ static u8_t compute_and_send_master_dhcheck(struct bt_smp *smp)
case PASSKEY_INPUT:
memcpy(r, &smp->passkey, sizeof(smp->passkey));
break;
case LE_SC_OOB:
if (smp->oobd_remote) {
memcpy(r, smp->oobd_remote->r, sizeof(r));
}
break;
default:
return BT_SMP_ERR_UNSPECIFIED;
}
@@ -2923,6 +2928,8 @@ static u8_t sc_smp_check_confirm(struct bt_smp *smp)
u8_t r;

switch (smp->method) {
case LE_SC_OOB:
return 0;
case PASSKEY_CONFIRM:
case JUST_WORKS:
r = 0U;
@@ -2970,15 +2977,24 @@ static bool le_sc_oob_data_rsp_check(struct bt_smp *smp)
return ((rsp->oob_flag & BT_SMP_OOB_DATA_MASK) == BT_SMP_OOB_PRESENT);
}

#if defined(CONFIG_BT_PERIPHERAL)
static void le_sc_oob_config_set(struct bt_smp *smp,
struct bt_conn_oob_info *info)
{
bool req_oob_present = le_sc_oob_data_req_check(smp);
bool rsp_oob_present = le_sc_oob_data_rsp_check(smp);
int oob_config = BT_CONN_OOB_NO_DATA;

if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) {
oob_config = req_oob_present ? BT_CONN_OOB_REMOTE_ONLY :
BT_CONN_OOB_NO_DATA;

if (rsp_oob_present) {
oob_config = (oob_config == BT_CONN_OOB_REMOTE_ONLY) ?
BT_CONN_OOB_BOTH_PEERS :
BT_CONN_OOB_LOCAL_ONLY;
}
} else if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
oob_config = req_oob_present ? BT_CONN_OOB_LOCAL_ONLY :
BT_CONN_OOB_NO_DATA;

@@ -2991,7 +3007,6 @@ static void le_sc_oob_config_set(struct bt_smp *smp,

info->lesc.oob_config = oob_config;
}
#endif

static u8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf)
{
@@ -3030,6 +3045,8 @@ static u8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf)
return 0;
case JUST_WORKS:
break;
case LE_SC_OOB:
break;
case PASSKEY_DISPLAY:
case PASSKEY_INPUT:
smp->passkey_round++;
@@ -3505,6 +3522,31 @@ static u8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf)
atomic_set_bit(smp->flags, SMP_FLAG_USER);
bt_auth->passkey_entry(smp->chan.chan.conn);
break;
case LE_SC_OOB:
/* Step 6: Select random N */
if (bt_rand(smp->prnd, 16)) {
return BT_SMP_ERR_UNSPECIFIED;
}

if (bt_auth->oob_data_request) {
struct bt_conn_oob_info info = {
.type = BT_CONN_OOB_LE_SC,
.lesc.oob_config = BT_CONN_OOB_NO_DATA,
};

le_sc_oob_config_set(smp, &info);

smp->oobd_local = NULL;
smp->oobd_remote = NULL;

atomic_set_bit(smp->flags,
SMP_FLAG_OOB_PENDING);
bt_auth->oob_data_request(smp->chan.chan.conn,
&info);
} else {
return BT_SMP_ERR_UNSPECIFIED;
}
break;
default:
return BT_SMP_ERR_UNSPECIFIED;
}
@@ -3548,6 +3590,11 @@ static u8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf)
case PASSKEY_INPUT:
memcpy(r, &smp->passkey, sizeof(smp->passkey));
break;
case LE_SC_OOB:
if (smp->oobd_local) {
memcpy(r, smp->oobd_local->r, sizeof(r));
}
break;
default:
return BT_SMP_ERR_UNSPECIFIED;
}
@@ -4491,7 +4538,13 @@ static bool le_sc_oob_data_check(struct bt_smp *smp, bool oobd_local_present,
bool req_oob_present = le_sc_oob_data_req_check(smp);
bool rsp_oob_present = le_sc_oob_data_rsp_check(smp);

if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) {
if ((req_oob_present != oobd_remote_present) &&
(rsp_oob_present != oobd_local_present)) {
return false;
}
} else if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
if ((req_oob_present != oobd_local_present) &&
(rsp_oob_present != oobd_remote_present)) {
return false;
@@ -4512,23 +4565,24 @@ static int le_sc_oob_pairing_continue(struct bt_smp *smp)
return err;
}

if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
bool match = (memcmp(c, smp->oobd_remote->c,
sizeof(c)) == 0);
bool match = (memcmp(c, smp->oobd_remote->c, sizeof(c)) == 0);

if (!match) {
smp_error(smp, BT_SMP_ERR_CONFIRM_FAILED);
return 0;
}
if (!match) {
smp_error(smp, BT_SMP_ERR_CONFIRM_FAILED);
return 0;
}
}

if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) {
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM);
} else if (IS_ENABLED(CONFIG_BT_PERIPHERAL)) {
atomic_set_bit(&smp->allowed_cmds, BT_SMP_DHKEY_CHECK);
atomic_set_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT);
smp_send_pairing_random(smp);
}

smp_send_pairing_random(smp);

return 0;
}

0 comments on commit f8b7f2a

Please sign in to comment.
You can’t perform that action at this time.