aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r--net/bluetooth/hci_core.c54
1 files changed, 52 insertions, 2 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;