Bluetooth: Fix BR/EDR Link Key type when derived through LE SC
authorJohan Hedberg <johan.hedberg@intel.com>
Sun, 1 Jun 2014 13:33:39 +0000 (16:33 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 3 Dec 2014 15:51:19 +0000 (16:51 +0100)
We need to set the correct Link Key type based on the properties of the
LE SC pairing that it was derived from. If debug keys were used the type
should be a debug key, and the authenticated vs unauthenticated
information should be set on what kind of security level was reached.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/hci_core.c
net/bluetooth/smp.c

index 6c3220e9484fdcb5868cbe6e4fe8939ce9e229b1..2fa9f2b2bee3d06e099550cb40551e410ae18b2b 100644 (file)
@@ -3160,6 +3160,10 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
        if (!conn)
                return true;
 
+       /* BR/EDR key derived using SC from an LE link */
+       if (conn->type == LE_LINK)
+               return true;
+
        /* Neither local nor remote side had no-bonding as requirement */
        if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
                return true;
index b6cdb553ccd3429676472b236a9eb633273e088f..a322019610eb6657aaf58d32cfd33556fb231757 100644 (file)
@@ -965,9 +965,30 @@ static void smp_notify_keys(struct l2cap_conn *conn)
        }
 
        if (smp->link_key) {
-               hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
-                                smp->link_key, HCI_LK_AUTH_COMBINATION_P256,
-                                0, NULL);
+               struct link_key *key;
+               u8 type;
+
+               if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
+                       type = HCI_LK_DEBUG_COMBINATION;
+               else if (hcon->sec_level == BT_SECURITY_FIPS)
+                       type = HCI_LK_AUTH_COMBINATION_P256;
+               else
+                       type = HCI_LK_UNAUTH_COMBINATION_P256;
+
+               key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
+                                      smp->link_key, type, 0, &persistent);
+               if (key) {
+                       mgmt_new_link_key(hdev, key, persistent);
+
+                       /* Don't keep debug keys around if the relevant
+                        * flag is not set.
+                        */
+                       if (!test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags) &&
+                           key->type == HCI_LK_DEBUG_COMBINATION) {
+                               list_del_rcu(&key->list);
+                               kfree_rcu(key, rcu);
+                       }
+               }
        }
 }