Bluetooth: SMP: Fix using identity address while re-pairing

When remote device initiate pairing but its IRK is already known
identity address was used to calculate confirmation value. This
resulted in 'Confirm Value Failed' error and pairing failure.

To avoid any confusion simply track initiator and responder addresses
used for connection.

This fix re-enabling security with iPhone if device was unpaired
only on iPhone side.

Change-Id: I07d9589bee5fea7f6b028472b1709090a5755e31
Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
This commit is contained in:
Szymon Janc 2015-09-01 17:30:58 +02:00 committed by Anas Nashif
commit 4bf5573055
3 changed files with 15 additions and 21 deletions

View file

@ -61,6 +61,9 @@ struct bt_conn {
bt_addr_le_t src;
bt_addr_le_t dst;
bt_addr_le_t init_addr;
bt_addr_le_t resp_addr;
uint8_t encrypt;
bt_security_t sec_level;
bt_security_t required_sec_level;

View file

@ -804,6 +804,14 @@ static void le_conn_complete(struct bt_buf *buf)
copy_id_addr(conn, &evt->peer_addr);
conn->le_conn_interval = sys_le16_to_cpu(evt->interval);
if (conn->role == BT_HCI_ROLE_MASTER) {
bt_addr_le_copy(&conn->init_addr, &conn->src);
bt_addr_le_copy(&conn->resp_addr, &evt->peer_addr);
} else {
bt_addr_le_copy(&conn->init_addr, &evt->peer_addr);
bt_addr_le_copy(&conn->resp_addr, &conn->src);
}
bt_conn_set_state(conn, BT_CONN_CONNECTED);
if ((evt->role == BT_HCI_ROLE_MASTER) ||

View file

@ -598,7 +598,6 @@ static uint8_t smp_send_pairing_confirm(struct bt_conn *conn)
{
struct bt_smp_pairing_confirm *req;
struct bt_smp *smp = conn->smp;
const bt_addr_le_t *ra, *ia;
struct bt_buf *rsp_buf;
int err;
@ -610,16 +609,8 @@ static uint8_t smp_send_pairing_confirm(struct bt_conn *conn)
req = bt_buf_add(rsp_buf, sizeof(*req));
if (conn->role == BT_HCI_ROLE_MASTER) {
ra = &conn->dst;
ia = &conn->src;
} else {
ra = &conn->src;
ia = &conn->dst;
}
err = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, ia, ra,
req->val);
err = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, &conn->init_addr,
&conn->resp_addr, req->val);
if (err) {
bt_buf_put(rsp_buf);
return BT_SMP_ERR_UNSPECIFIED;
@ -726,7 +717,6 @@ static uint8_t get_keys_type(uint8_t method)
static uint8_t smp_pairing_random(struct bt_conn *conn, struct bt_buf *buf)
{
struct bt_smp_pairing_random *req = (void *)buf->data;
const bt_addr_le_t *ra, *ia;
struct bt_smp *smp = conn->smp;
struct bt_keys *keys;
uint8_t cfm[16];
@ -736,15 +726,8 @@ static uint8_t smp_pairing_random(struct bt_conn *conn, struct bt_buf *buf)
memcpy(smp->rrnd, req->val, sizeof(smp->rrnd));
if (conn->role == BT_HCI_ROLE_MASTER) {
ra = &conn->dst;
ia = &conn->src;
} else {
ra = &conn->src;
ia = &conn->dst;
}
err = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, ia, ra, cfm);
err = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, &conn->init_addr,
&conn->resp_addr, cfm);
if (err) {
return BT_SMP_ERR_UNSPECIFIED;
}