Bluetooth: SMP: Delay LE SC pairing until PublicKey is generated
If HCI based ECC is used we should delay sending local Public Key in LE SC pairing until it is generated by controller. Change-Id: Ic979fc8efa40a8089ac2b74cbcfac21bdca79bfe Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
This commit is contained in:
parent
b2db881468
commit
97fb4d2990
3 changed files with 91 additions and 37 deletions
|
@ -995,12 +995,8 @@ static void le_pkey_complete(struct net_buf *buf)
|
|||
return;
|
||||
}
|
||||
|
||||
/* TODO
|
||||
* init should be blocked until this is received or we need to notify
|
||||
* SMP code about Public Key being available.
|
||||
*/
|
||||
|
||||
memcpy(bt_dev.pkey, evt->key, sizeof(bt_dev.pkey));
|
||||
bt_smp_pkey_ready();
|
||||
}
|
||||
|
||||
static void le_dhkey_complete(struct net_buf *buf)
|
||||
|
|
|
@ -75,7 +75,7 @@ enum {
|
|||
SMP_FLAG_PAIRING, /* if pairing is in progress */
|
||||
SMP_FLAG_TIMEOUT, /* if SMP timeout occurred */
|
||||
SMP_FLAG_SC, /* if LE Secure Connections is used */
|
||||
SMP_FLAG_PKEY_PENDING, /* if waiting for P256 Public Key */
|
||||
SMP_FLAG_PKEY_SEND, /* if should send Public Key when available */
|
||||
SMP_FLAG_DHKEY_PENDING, /* if waiting for local DHKey */
|
||||
SMP_FLAG_DHKEY_SEND, /* if should generate and send DHKey Check */
|
||||
SMP_FLAG_USER /* if waiting for user input */
|
||||
|
@ -176,6 +176,7 @@ static struct bt_smp bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN];
|
|||
static const struct bt_auth_cb *auth_cb;
|
||||
static uint8_t bt_smp_io_capa = BT_SMP_IO_NO_INPUT_OUTPUT;
|
||||
static bool sc_supported;
|
||||
static bool sc_local_pkey_valid;
|
||||
|
||||
static uint8_t get_pair_method(struct bt_smp *smp, uint8_t remote_io)
|
||||
{
|
||||
|
@ -1290,6 +1291,11 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
|
|||
smp->local_dist &= SEND_KEYS_SC;
|
||||
smp->remote_dist &= RECV_KEYS_SC;
|
||||
|
||||
if (!sc_local_pkey_valid) {
|
||||
atomic_set_bit(&smp->flags, SMP_FLAG_PKEY_SEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY);
|
||||
return sc_send_public_key(smp);
|
||||
}
|
||||
|
@ -2193,6 +2199,47 @@ static uint8_t display_passkey(struct bt_smp *smp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_PERIPHERAL)
|
||||
static uint8_t smp_public_key_slave(struct bt_smp *smp)
|
||||
{
|
||||
uint8_t err;
|
||||
|
||||
err = sc_send_public_key(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
switch (smp->method) {
|
||||
case PASSKEY_CONFIRM:
|
||||
case JUST_WORKS:
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM);
|
||||
|
||||
err = smp_send_pairing_confirm(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case PASSKEY_DISPLAY:
|
||||
err = display_passkey(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM);
|
||||
break;
|
||||
case PASSKEY_INPUT:
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM);
|
||||
atomic_set_bit(&smp->flags, SMP_FLAG_USER);
|
||||
auth_cb->passkey_entry(smp->chan.conn);
|
||||
break;
|
||||
default:
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
return generate_dhkey(smp);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_PERIPHERAL */
|
||||
|
||||
static uint8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf)
|
||||
{
|
||||
struct bt_smp_public_key *req = (void *)buf->data;
|
||||
|
@ -2237,39 +2284,12 @@ static uint8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf)
|
|||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CENTRAL */
|
||||
#if defined(CONFIG_BLUETOOTH_PERIPHERAL)
|
||||
err = sc_send_public_key(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
if (!sc_local_pkey_valid) {
|
||||
atomic_set_bit(&smp->flags, SMP_FLAG_PKEY_SEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (smp->method) {
|
||||
case PASSKEY_CONFIRM:
|
||||
case JUST_WORKS:
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM);
|
||||
|
||||
err = smp_send_pairing_confirm(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case PASSKEY_DISPLAY:
|
||||
err = display_passkey(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM);
|
||||
break;
|
||||
case PASSKEY_INPUT:
|
||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM);
|
||||
atomic_set_bit(&smp->flags, SMP_FLAG_USER);
|
||||
auth_cb->passkey_entry(smp->chan.conn);
|
||||
break;
|
||||
default:
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
err = generate_dhkey(smp);
|
||||
err = smp_public_key_slave(smp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
@ -2415,6 +2435,43 @@ static void bt_smp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
|||
}
|
||||
}
|
||||
|
||||
void bt_smp_pkey_ready(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
sc_local_pkey_valid = true;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) {
|
||||
struct bt_smp *smp = &bt_smp_pool[i];
|
||||
uint8_t err;
|
||||
|
||||
if (!atomic_test_bit(&smp->flags, SMP_FLAG_PKEY_SEND)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CENTRAL)
|
||||
if (smp->chan.conn->role == BT_HCI_ROLE_MASTER) {
|
||||
err = sc_send_public_key(smp);
|
||||
if (err) {
|
||||
smp_error(smp, err);
|
||||
}
|
||||
|
||||
atomic_set_bit(&smp->allowed_cmds,
|
||||
BT_SMP_CMD_PUBLIC_KEY);
|
||||
continue;
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CENTRAL */
|
||||
#if defined(CONFIG_BLUETOOTH_PERIPHERAL)
|
||||
err = smp_public_key_slave(smp);
|
||||
if (err) {
|
||||
smp_error(smp, err);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_PERIPHERAL */
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_smp_connected(struct bt_l2cap_chan *chan)
|
||||
{
|
||||
struct bt_smp *smp = CONTAINER_OF(chan, struct bt_smp, chan);
|
||||
|
|
|
@ -137,6 +137,7 @@ void bt_smp_update_keys(struct bt_conn *conn);
|
|||
bool bt_smp_get_tk(struct bt_conn *conn, uint8_t *tk);
|
||||
|
||||
void bt_smp_dhkey_ready(const uint8_t *dhkey);
|
||||
void bt_smp_pkey_ready(void);
|
||||
|
||||
int bt_smp_init(void);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue