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>
This commit is contained in:
parent
0ac83180fd
commit
f8b7f2ab6a
1 changed files with 67 additions and 13 deletions
|
@ -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,7 +2977,6 @@ 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)
|
||||
{
|
||||
|
@ -2978,7 +2984,17 @@ static void le_sc_oob_config_set(struct bt_smp *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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue