aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-07-07 17:59:36 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-07-08 16:36:31 -0400
commit75d262c2ad927751bb5f096f3a6a37d81e7784f2 (patch)
treecf526c6ef818e8a308b29882db7479557ec5009e /net
parent34918cd71b953905e5f832537ead436bcd57e8f9 (diff)
Bluetooth: Add functions to manipulate the link key list for SMP
As the LTK (the new type of key being handled now) has more data associated with it, we need to store this extra data and retrieve the keys based on that data. Methods for searching for a key and for adding a new LTK are introduced here. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7ba1ca12c1d8..4885914449f6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1057,6 +1057,42 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1057 return 0; 1057 return 0;
1058} 1058}
1059 1059
1060struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
1061{
1062 struct link_key *k;
1063
1064 list_for_each_entry(k, &hdev->link_keys, list) {
1065 struct key_master_id *id;
1066
1067 if (k->type != HCI_LK_SMP_LTK)
1068 continue;
1069
1070 if (k->dlen != sizeof(*id))
1071 continue;
1072
1073 id = (void *) &k->data;
1074 if (id->ediv == ediv &&
1075 (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
1076 return k;
1077 }
1078
1079 return NULL;
1080}
1081EXPORT_SYMBOL(hci_find_ltk);
1082
1083struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
1084 bdaddr_t *bdaddr, u8 type)
1085{
1086 struct link_key *k;
1087
1088 list_for_each_entry(k, &hdev->link_keys, list)
1089 if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
1090 return k;
1091
1092 return NULL;
1093}
1094EXPORT_SYMBOL(hci_find_link_key_type);
1095
1060int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1096int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1061 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 1097 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
1062{ 1098{
@@ -1112,6 +1148,43 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1112 return 0; 1148 return 0;
1113} 1149}
1114 1150
1151int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1152 __le16 ediv, u8 rand[8], u8 ltk[16])
1153{
1154 struct link_key *key, *old_key;
1155 struct key_master_id *id;
1156 u8 old_key_type;
1157
1158 BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
1159
1160 old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
1161 if (old_key) {
1162 key = old_key;
1163 old_key_type = old_key->type;
1164 } else {
1165 key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
1166 if (!key)
1167 return -ENOMEM;
1168 list_add(&key->list, &hdev->link_keys);
1169 old_key_type = 0xff;
1170 }
1171
1172 key->dlen = sizeof(*id);
1173
1174 bacpy(&key->bdaddr, bdaddr);
1175 memcpy(key->val, ltk, sizeof(key->val));
1176 key->type = HCI_LK_SMP_LTK;
1177
1178 id = (void *) &key->data;
1179 id->ediv = ediv;
1180 memcpy(id->rand, rand, sizeof(id->rand));
1181
1182 if (new_key)
1183 mgmt_new_key(hdev->id, key, old_key_type);
1184
1185 return 0;
1186}
1187
1115int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 1188int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
1116{ 1189{
1117 struct link_key *key; 1190 struct link_key *key;