diff options
author | Vinicius Costa Gomes <vinicius.gomes@openbossa.org> | 2011-08-25 20:02:28 -0300 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-09-21 12:59:15 -0300 |
commit | 988c5997d32052a58bd0127710bc8e2c8c5665b1 (patch) | |
tree | d00b021239f09cfbeb5135e7e065cf90baadfdbd /net/bluetooth/smp.c | |
parent | 0fb4eb6f630a22bf4c2f358ef2db91f28a3d18d4 (diff) |
Bluetooth: Use the LTK after receiving a LE Security Request
When receiving a security request from the remote device we should find
if there is already a LTK associated with the remote device, if found
we should use it to encrypt the link.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r-- | net/bluetooth/smp.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 7e558465133..8a7eaaedd67 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -499,6 +499,29 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) return 0; } +static u8 smp_ltk_encrypt(struct l2cap_conn *conn) +{ + struct link_key *key; + struct key_master_id *master; + struct hci_conn *hcon = conn->hcon; + + key = hci_find_link_key_type(hcon->hdev, conn->dst, + HCI_LK_SMP_LTK); + if (!key) + return 0; + + if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, + &hcon->pend)) + return 1; + + master = (void *) key->data; + hci_le_start_enc(hcon, master->ediv, master->rand, + key->val); + hcon->enc_key_size = key->pin_len; + + return 1; + +} static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_security_req *rp = (void *) skb->data; @@ -508,6 +531,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) BT_DBG("conn %p", conn); + if (smp_ltk_encrypt(conn)) + return 0; + if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) return 0; @@ -542,25 +568,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) if (hcon->sec_level >= sec_level) return 1; - if (hcon->link_mode & HCI_LM_MASTER) { - struct link_key *key; - - key = hci_find_link_key_type(hcon->hdev, conn->dst, - HCI_LK_SMP_LTK); - if (key) { - struct key_master_id *master = (void *) key->data; - - if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, - &hcon->pend)) - goto done; - - hci_le_start_enc(hcon, master->ediv, master->rand, - key->val); - hcon->enc_key_size = key->pin_len; - + if (hcon->link_mode & HCI_LM_MASTER) + if (smp_ltk_encrypt(conn)) goto done; - } - } if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) return 0; |