Bluetooth: Use the LTK after receiving a LE Security Request
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>
Thu, 25 Aug 2011 23:02:28 +0000 (20:02 -0300)
committerGustavo F. Padovan <padovan@profusion.mobi>
Wed, 21 Sep 2011 15:59:15 +0000 (12:59 -0300)
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>
net/bluetooth/smp.c

index 7e558465133f9782b10608e5783113ca4ec0eb2c..8a7eaaedd67a81786ce0e9f0d841f2567aaf5ed4 100644 (file)
@@ -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;