aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-07-08 17:31:44 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-07-08 17:38:23 -0400
commit5a0a8b49746771fba79866fb9185ffa051a6a183 (patch)
tree1bc2a46c2e8eebd14c262020365320314954bac9 /net/bluetooth
parent0eb08e339836989557ea3aa4c427377bd32ce19c (diff)
Bluetooth: Add support for communicating keys with userspace
As the key format has changed to something that has a dynamic size, the way that keys are received and sent must be changed. The structure fields order is changed to make the parsing of the information received from the Management Interface easier. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/mgmt.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 4fd11e5d1024..f424d6ab4c1e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -908,7 +908,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
908 struct hci_dev *hdev; 908 struct hci_dev *hdev;
909 struct mgmt_cp_load_keys *cp; 909 struct mgmt_cp_load_keys *cp;
910 u16 key_count, expected_len; 910 u16 key_count, expected_len;
911 int i; 911 int i, err;
912 912
913 cp = (void *) data; 913 cp = (void *) data;
914 914
@@ -918,9 +918,9 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
918 key_count = get_unaligned_le16(&cp->key_count); 918 key_count = get_unaligned_le16(&cp->key_count);
919 919
920 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); 920 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
921 if (expected_len != len) { 921 if (expected_len > len) {
922 BT_ERR("load_keys: expected %u bytes, got %u bytes", 922 BT_ERR("load_keys: expected at least %u bytes, got %u bytes",
923 len, expected_len); 923 expected_len, len);
924 return -EINVAL; 924 return -EINVAL;
925 } 925 }
926 926
@@ -942,17 +942,36 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
942 else 942 else
943 clear_bit(HCI_DEBUG_KEYS, &hdev->flags); 943 clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
944 944
945 for (i = 0; i < key_count; i++) { 945 len -= sizeof(*cp);
946 struct mgmt_key_info *key = &cp->keys[i]; 946 i = 0;
947
948 while (i < len) {
949 struct mgmt_key_info *key = (void *) cp->keys + i;
950
951 i += sizeof(*key) + key->dlen;
952
953 if (key->type == HCI_LK_SMP_LTK) {
954 struct key_master_id *id = (void *) key->data;
955
956 if (key->dlen != sizeof(struct key_master_id))
957 continue;
958
959 hci_add_ltk(hdev, 0, &key->bdaddr, id->ediv,
960 id->rand, key->val);
961
962 continue;
963 }
947 964
948 hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, 965 hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
949 key->pin_len); 966 key->pin_len);
950 } 967 }
951 968
969 err = cmd_complete(sk, index, MGMT_OP_LOAD_KEYS, NULL, 0);
970
952 hci_dev_unlock_bh(hdev); 971 hci_dev_unlock_bh(hdev);
953 hci_dev_put(hdev); 972 hci_dev_put(hdev);
954 973
955 return 0; 974 return err;
956} 975}
957 976
958static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) 977static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
@@ -1958,17 +1977,28 @@ int mgmt_connectable(u16 index, u8 connectable)
1958 1977
1959int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) 1978int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
1960{ 1979{
1961 struct mgmt_ev_new_key ev; 1980 struct mgmt_ev_new_key *ev;
1981 int err, total;
1962 1982
1963 memset(&ev, 0, sizeof(ev)); 1983 total = sizeof(struct mgmt_ev_new_key) + key->dlen;
1984 ev = kzalloc(total, GFP_ATOMIC);
1985 if (!ev)
1986 return -ENOMEM;
1987
1988 bacpy(&ev->key.bdaddr, &key->bdaddr);
1989 ev->key.type = key->type;
1990 memcpy(ev->key.val, key->val, 16);
1991 ev->key.pin_len = key->pin_len;
1992 ev->key.dlen = key->dlen;
1993 ev->store_hint = persistent;
1994
1995 memcpy(ev->key.data, key->data, key->dlen);
1964 1996
1965 ev.store_hint = persistent; 1997 err = mgmt_event(MGMT_EV_NEW_KEY, index, ev, total, NULL);
1966 bacpy(&ev.key.bdaddr, &key->bdaddr);
1967 ev.key.type = key->type;
1968 memcpy(ev.key.val, key->val, 16);
1969 ev.key.pin_len = key->pin_len;
1970 1998
1971 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); 1999 kfree(ev);
2000
2001 return err;
1972} 2002}
1973 2003
1974int mgmt_connected(u16 index, bdaddr_t *bdaddr) 2004int mgmt_connected(u16 index, bdaddr_t *bdaddr)