aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-04-28 14:28:59 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-04-28 15:14:40 -0400
commitd25e28abe58d2bcedf6025a6ccc532c29a19046f (patch)
treed56b5d6b7443814f354db364db2f5717bde147e3 /net/bluetooth
parent582fbe9ef9d6fc089ff20956595f046d4899e74e (diff)
Bluetooth: Fix link key persistent storage criteria
Link keys should only be stored if very specific criteria of the authentication process are fulfilled. This patch essentially copies the criteria that user space has so far been using to the kernel side so that the management interface works properly. Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c54
-rw-r--r--net/bluetooth/hci_event.c2
-rw-r--r--net/bluetooth/mgmt.c2
3 files changed, 54 insertions, 4 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 07d0ba35b9a..5f55aef63e2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1022,8 +1022,44 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
1022 return NULL; 1022 return NULL;
1023} 1023}
1024 1024
1025int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, 1025static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1026 u8 *val, u8 type, u8 pin_len) 1026 u8 key_type, u8 old_key_type)
1027{
1028 /* Legacy key */
1029 if (key_type < 0x03)
1030 return 1;
1031
1032 /* Debug keys are insecure so don't store them persistently */
1033 if (key_type == HCI_LK_DEBUG_COMBINATION)
1034 return 0;
1035
1036 /* Changed combination key and there's no previous one */
1037 if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1038 return 0;
1039
1040 /* Security mode 3 case */
1041 if (!conn)
1042 return 1;
1043
1044 /* Neither local nor remote side had no-bonding as requirement */
1045 if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1046 return 1;
1047
1048 /* Local side had dedicated bonding as requirement */
1049 if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1050 return 1;
1051
1052 /* Remote side had dedicated bonding as requirement */
1053 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1054 return 1;
1055
1056 /* If none of the above criteria match, then don't store the key
1057 * persistently */
1058 return 0;
1059}
1060
1061int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1062 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
1027{ 1063{
1028 struct link_key *key, *old_key; 1064 struct link_key *key, *old_key;
1029 u8 old_key_type; 1065 u8 old_key_type;
@@ -1042,6 +1078,20 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1042 1078
1043 BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 1079 BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
1044 1080
1081 /* Some buggy controller combinations generate a changed
1082 * combination key for legacy pairing even when there's no
1083 * previous key */
1084 if (type == HCI_LK_CHANGED_COMBINATION &&
1085 (!conn || conn->remote_auth == 0xff) &&
1086 old_key_type == 0xff)
1087 type = HCI_LK_COMBINATION;
1088
1089 if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
1090 list_del(&key->list);
1091 kfree(key);
1092 return 0;
1093 }
1094
1045 bacpy(&key->bdaddr, bdaddr); 1095 bacpy(&key->bdaddr, bdaddr);
1046 memcpy(key->val, val, 16); 1096 memcpy(key->val, val, 16);
1047 key->type = type; 1097 key->type = type;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index ebbaa6c8d01..8a63d3a463f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2136,7 +2136,7 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
2136 } 2136 }
2137 2137
2138 if (test_bit(HCI_LINK_KEYS, &hdev->flags)) 2138 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
2139 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key, 2139 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
2140 ev->key_type, pin_len); 2140 ev->key_type, pin_len);
2141 2141
2142 hci_dev_unlock(hdev); 2142 hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a1b0ec4e517..e1384fc6016 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
945 for (i = 0; i < key_count; i++) { 945 for (i = 0; i < key_count; i++) {
946 struct mgmt_key_info *key = &cp->keys[i]; 946 struct mgmt_key_info *key = &cp->keys[i];
947 947
948 hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type, 948 hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
949 key->pin_len); 949 key->pin_len);
950 } 950 }
951 951