Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC 09/15] Bluetooth: Use the link key list to temporarily store the STK
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

With this we can use only one place to store all keys, without
need to use a field in the connection structure for this
purpose.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/smp.c |   26 ++++++++++++++++----------
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 1aa620f..4a314cc 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -393,35 +393,41 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	}
 
 	if (conn->hcon->out) {
+		u8 stk[16], rand[8];
 		__le16 ediv;
-		u8 rand[8];
+
+		memset(rand, 0, sizeof(rand));
+		ediv = 0;
 
 		smp_s1(tfm, conn->tk, random, conn->prnd, key);
-		swap128(key, hcon->ltk);
+		swap128(key, stk);
 
-		memset(hcon->ltk + conn->smp_key_size, 0,
+		memset(stk + conn->smp_key_size, 0,
 				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
 
-
-		memset(rand, 0, sizeof(rand));
-		ediv = 0;
-		hci_le_start_enc(hcon, ediv, rand, hcon->ltk);
+		hci_le_start_enc(hcon, ediv, rand, stk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
 							sizeof(buf), 0);
 		BT_DBG("key %s", buf);
 	} else {
-		u8 r[16];
+		u8 stk[16], r[16], rand[8];
+		__le16 ediv;
+
+		memset(rand, 0, sizeof(rand));
+		ediv = 0;
 
 		swap128(conn->prnd, r);
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
 
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
-		swap128(key, hcon->ltk);
+		swap128(key, stk);
 
-		memset(hcon->ltk + conn->smp_key_size, 0,
+		memset(stk + conn->smp_key_size, 0,
 				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
 
+		hci_add_ltk(conn->hcon->hdev, 0, conn->dst, ediv, rand, stk);
+
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
 							sizeof(buf), 0);
 		BT_DBG("key %s", buf);
-- 
1.7.4.1


^ permalink raw reply related

* [RFC 10/15] Bluetooth: Use the stored LTK for restabilishing security
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

Now that it's possible that the exchanged key is present in
the link key list, we may be able to estabilish security with
an already existing key, without need to perform any SMP
procedure.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/smp.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 4a314cc..3fd97db 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -487,6 +487,20 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 	authreq = seclevel_to_authreq(sec_level);
 
 	if (hcon->link_mode & HCI_LM_MASTER) {
+		struct link_key *key;
+
+		key = hci_find_link_key_type(hcon->hdev, conn->dst,
+							KEY_TYPE_LTK);
+		if (key) {
+			struct key_master_id *master = (void *) key->data;
+
+			hci_le_start_enc(hcon, master->ediv, master->rand,
+								key->val);
+			goto done;
+		}
+	}
+
+	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
 
 		build_pairing_cmd(conn, &cp, NULL, authreq);
@@ -503,6 +517,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
 	}
 
+done:
 	hcon->pending_sec_level = sec_level;
 	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
 
-- 
1.7.4.1


^ permalink raw reply related

* [RFC 11/15] Bluetooth: Remove unused field in hci_conn
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |    1 -
 net/bluetooth/smp.c              |    2 --
 2 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 79b84d7..b402acd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -266,7 +266,6 @@ struct hci_conn {
 	__u8		power_save;
 	__u16		disc_timeout;
 	unsigned long	pend;
-	__u8		ltk[16];
 
 	__u8		remote_cap;
 	__u8		remote_oob;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 3fd97db..ba90f2c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -372,8 +372,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	swap128(skb->data, random);
 	skb_pull(skb, sizeof(random));
 
-	memset(hcon->ltk, 0, sizeof(hcon->ltk));
-
 	if (conn->hcon->out)
 		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
 				conn->src, 0, conn->dst, res);
-- 
1.7.4.1


^ permalink raw reply related

* [RFC 12/15] Bluetooth: Add support for communicating keys with userspace
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

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>
---
 include/net/bluetooth/mgmt.h |    2 +-
 net/bluetooth/mgmt.c         |   60 +++++++++++++++++++++++++++++++----------
 2 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index d467fb8..f4ef131 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -228,8 +228,8 @@ struct mgmt_ev_controller_error {
 
 #define MGMT_EV_NEW_KEY			0x000A
 struct mgmt_ev_new_key {
-	struct mgmt_key_info key;
 	__u8 old_key_type;
+	struct mgmt_key_info key;
 } __packed;
 
 #define MGMT_EV_CONNECTED		0x000B
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c304688..9c25513 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)
 	struct hci_dev *hdev;
 	struct mgmt_cp_load_keys *cp;
 	u16 key_count, expected_len;
-	int i;
+	int i, err;
 
 	cp = (void *) data;
 
@@ -918,9 +918,9 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
 	key_count = get_unaligned_le16(&cp->key_count);
 
 	expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
-	if (expected_len != len) {
-		BT_ERR("load_keys: expected %u bytes, got %u bytes",
-							len, expected_len);
+	if (expected_len > len) {
+		BT_ERR("load_keys: expected at least %u bytes, got %u bytes",
+							expected_len, len);
 		return -EINVAL;
 	}
 
@@ -942,17 +942,36 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
 	else
 		clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
 
-	for (i = 0; i < key_count; i++) {
-		struct mgmt_key_info *key = &cp->keys[i];
+	len -= sizeof(*cp);
+	i = 0;
+
+	while (i < len) {
+		struct mgmt_key_info *key = (void *) cp->keys + i;
+
+		i += sizeof(*key) + key->dlen;
+
+		if (key->type == KEY_TYPE_LTK) {
+			struct key_master_id *id = (void *) key->data;
+
+			if (key->dlen != sizeof(struct key_master_id))
+				continue;
+
+			hci_add_ltk(hdev, 0, &key->bdaddr, id->ediv,
+							id->rand, key->val);
+
+			continue;
+		}
 
 		hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
 								key->pin_len);
 	}
 
+	err = cmd_complete(sk, index, MGMT_OP_LOAD_KEYS, NULL, 0);
+
 	hci_dev_unlock(hdev);
 	hci_dev_put(hdev);
 
-	return 0;
+	return err;
 }
 
 static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
@@ -1786,17 +1805,28 @@ int mgmt_connectable(u16 index, u8 connectable)
 
 int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
 {
-	struct mgmt_ev_new_key ev;
+	struct mgmt_ev_new_key *ev;
+	int err, total;
 
-	memset(&ev, 0, sizeof(ev));
+	total = sizeof(struct mgmt_ev_new_key) + key->dlen;
+	ev = kzalloc(total, GFP_ATOMIC);
+	if (!ev)
+		return -ENOMEM;
+
+	bacpy(&ev->key.bdaddr, &key->bdaddr);
+	ev->key.type = key->type;
+	memcpy(ev->key.val, key->val, 16);
+	ev->key.pin_len = key->pin_len;
+	ev->old_key_type = old_key_type;
+	ev->key.dlen = key->dlen;
+
+	memcpy(ev->key.data, key->data, key->dlen);
 
-	bacpy(&ev.key.bdaddr, &key->bdaddr);
-	ev.key.type = key->type;
-	memcpy(ev.key.val, key->val, 16);
-	ev.key.pin_len = key->pin_len;
-	ev.old_key_type = old_key_type;
+	err = mgmt_event(MGMT_EV_NEW_KEY, index, ev, total, NULL);
 
-	return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
+	kfree(ev);
+
+	return err;
 }
 
 int mgmt_connected(u16 index, bdaddr_t *bdaddr)
-- 
1.7.4.1


^ permalink raw reply related

* [RFC 13/15] Bluetooth: Fix style issues reported by checkpatch.pl
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/bluetooth.h |   33 ++++++++++++++++++---------------
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 4375043..acf186d 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -1,4 +1,4 @@
-/* 
+/*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
 
@@ -12,20 +12,20 @@
    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
    SOFTWARE IS DISCLAIMED.
 */
 
 #ifndef __BLUETOOTH_H
 #define __BLUETOOTH_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 #include <linux/list.h>
 #include <linux/poll.h>
@@ -91,8 +91,8 @@ typedef struct {
 	__u8 b[6];
 } __packed bdaddr_t;
 
-#define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
-#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
+#define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} })
+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} })
 
 /* Copy, swap, convert BD Address */
 static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
@@ -130,10 +130,11 @@ int  bt_sock_register(int proto, const struct net_proto_family *ops);
 int  bt_sock_unregister(int proto);
 void bt_sock_link(struct bt_sock_list *l, struct sock *s);
 void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
-int  bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
+int  bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+				struct msghdr *msg, size_t len, int flags);
 int  bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			struct msghdr *msg, size_t len, int flags);
-uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
+uint bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait);
 int  bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
 
@@ -157,20 +158,22 @@ static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
 {
 	struct sk_buff *skb;
 
-	if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) {
+	skb = alloc_skb(len + BT_SKB_RESERVE, how);
+	if (skb) {
 		skb_reserve(skb, BT_SKB_RESERVE);
 		bt_cb(skb)->incoming  = 0;
 	}
 	return skb;
 }
 
-static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len, 
-							int nb, int *err)
+static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk,
+					unsigned long len, int nb, int *err)
 {
 	struct sk_buff *skb;
 
 	release_sock(sk);
-	if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
+	skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err);
+	if (skb) {
 		skb_reserve(skb, BT_SKB_RESERVE);
 		bt_cb(skb)->incoming  = 0;
 	}
-- 
1.7.4.1


^ permalink raw reply related

* [RFC 14/15] Bluetooth: Add support for storing the key length
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

In some cases it will be useful having the key size used for
encrypting the link. For example, some profiles may restrict
some operations depending on the key length.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |    2 +-
 net/bluetooth/hci_core.c         |    3 ++-
 net/bluetooth/hci_event.c        |    1 +
 net/bluetooth/mgmt.c             |    4 ++--
 net/bluetooth/smp.c              |   16 ++++++++++------
 5 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b402acd..1f95f03 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -549,7 +549,7 @@ struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
 struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
 					bdaddr_t *bdaddr, u8 type);
 int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
-					__le16 ediv, u8 rand[8], u8 ltk[16]);
+			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
 int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ab8ee1e..a573837 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1103,7 +1103,7 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 }
 
 int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
-					__le16 ediv, u8 rand[8], u8 ltk[16])
+			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
 {
 	struct link_key *key, *old_key;
 	struct key_master_id *id;
@@ -1128,6 +1128,7 @@ int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 	bacpy(&key->bdaddr, bdaddr);
 	memcpy(key->val, ltk, sizeof(key->val));
 	key->type = KEY_TYPE_LTK;
+	key->pin_len = key_size;
 
 	id = (void *) &key->data;
 	id->ediv = ediv;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 7282c39..2b57b99 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2649,6 +2649,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
 
 	memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
 	cp.handle = cpu_to_le16(conn->handle);
+	conn->pin_length = ltk->pin_len;
 
 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9c25513..ffbcd6e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -956,8 +956,8 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
 			if (key->dlen != sizeof(struct key_master_id))
 				continue;
 
-			hci_add_ltk(hdev, 0, &key->bdaddr, id->ediv,
-							id->rand, key->val);
+			hci_add_ltk(hdev, 0, &key->bdaddr, key->pin_len,
+						id->ediv, id->rand, key->val);
 
 			continue;
 		}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index ba90f2c..990c89f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -404,6 +404,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
 
 		hci_le_start_enc(hcon, ediv, rand, stk);
+		hcon->pin_length = conn->smp_key_size;
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
 							sizeof(buf), 0);
@@ -424,7 +425,8 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		memset(stk + conn->smp_key_size, 0,
 				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
 
-		hci_add_ltk(conn->hcon->hdev, 0, conn->dst, ediv, rand, stk);
+		hci_add_ltk(conn->hcon->hdev, 0, conn->dst, conn->smp_key_size,
+							ediv, rand, stk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
 							sizeof(buf), 0);
@@ -494,6 +496,8 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 
 			hci_le_start_enc(hcon, master->ediv, master->rand,
 								key->val);
+			hcon->pin_length = key->pin_len;
+
 			goto done;
 		}
 	}
@@ -534,7 +538,7 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	memset(rand, 0, sizeof(rand));
 
-	err = hci_add_ltk(conn->hcon->hdev, 0, conn->dst, 0, rand, rp->ltk);
+	err = hci_add_ltk(conn->hcon->hdev, 0, conn->dst, 0, 0, rand, rp->ltk);
 	if (err)
 		return SMP_UNSPECIFIED;
 
@@ -561,8 +565,8 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 	id->ediv = rp->ediv;
 	memcpy(id->rand, rp->rand, sizeof(rp->rand));
 
-	hci_add_ltk(conn->hcon->hdev, 1, conn->src, rp->ediv,
-						rp->rand, key->val);
+	hci_add_ltk(conn->hcon->hdev, 1, conn->src, conn->smp_key_size,
+						rp->ediv, rp->rand, key->val);
 
 	smp_distribute_keys(conn, 1);
 
@@ -681,8 +685,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 
 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
 
-		hci_add_ltk(conn->hcon->hdev, 1, conn->dst, ediv,
-							ident.rand, enc.ltk);
+		hci_add_ltk(conn->hcon->hdev, 1, conn->dst, conn->smp_key_size,
+						ediv, ident.rand, enc.ltk);
 
 		ident.ediv = cpu_to_le16(ediv);
 
-- 
1.7.4.1


^ permalink raw reply related

* [RFC 15/15] Bluetooth: Add support for returning the encryption key size
From: Vinicius Costa Gomes @ 2011-04-06  2:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1302055888-28177-1-git-send-email-vinicius.gomes@openbossa.org>

This will be useful when userspace wants to restrict some kinds of
operations based on the length of the key size used to encrypt the
link.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/bluetooth.h |    1 +
 net/bluetooth/l2cap_sock.c        |    4 ++++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index acf186d..28ae91a 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -56,6 +56,7 @@
 #define BT_SECURITY	4
 struct bt_security {
 	__u8 level;
+	__u8 key_size;
 };
 #define BT_SECURITY_SDP		0
 #define BT_SECURITY_LOW		1
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 12dbbf2..dd79b6b 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -492,8 +492,12 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
 			break;
 		}
 
+		memset(&sec, 0, sizeof(sec));
 		sec.level = l2cap_pi(sk)->sec_level;
 
+		if (sk->sk_state == BT_CONNECTED)
+			sec.key_size = l2cap_pi(sk)->conn->hcon->pin_length;
+
 		len = min_t(unsigned int, len, sizeof(sec));
 		if (copy_to_user(optval, (char *) &sec, len))
 			err = -EFAULT;
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH 3/3] Support hardcoded Nintendo Wii Remote pins
From: Daniele Forsi @ 2011-04-06 10:04 UTC (permalink / raw)
  To: linux-bluetooth

David Herrmann wrote:

> The Nintendo Wii Remote requires the destination bluetooth address
> as pincode.

according to my my tests they require the source address, ie the host
adapter's address

> +		/* Nintendo Wii Remote uses destination address as PIN */

better to document in that comment if it works when pressing the red
button or the 1+2 buttons

I tested your 3 patches against bluez git 4.91-32-gd7f412e and
gnome-bluetooth 2.32 but they didn't work for me for 2 reasons:
1) can't get vid/pid so when the remote is unknown the
read_device_id() call in your code fails to get vid/pid and the
specific pin is never tried; the same happens after a failed pairing
when the /var/lib/bluetooth/*/did file contains a line this:
00:1F:C5:25:36:87 FFFF 0000 0000 0000
2) the source vs destination address I mentioned above

It works for me if I manually edit that line with the values read from
another wiimote's line:
00:1F:C5:25:36:87 0002 057E 0306 0600
and if I change dba to sba here
>			memcpy(pinbuf, dba, 6);

how can I help you to debug these issues?

BTW pairing also works when I use the test code mentioned in
https://bugzilla.gnome.org/show_bug.cgi?id=603845#c6
-- 
Daniele Forsi

^ permalink raw reply

* Re: [PATCH 3/3] Support hardcoded Nintendo Wii Remote pins
From: David Herrmann @ 2011-04-06 10:55 UTC (permalink / raw)
  To: Daniele Forsi; +Cc: linux-bluetooth
In-Reply-To: <BANLkTikdXHstUxQ52RM6OMSnqfLWYJVMvg@mail.gmail.com>

On Wed, Apr 6, 2011 at 12:04 PM, Daniele Forsi <dforsi@gmail.com> wrote:
>> The Nintendo Wii Remote requires the destination bluetooth address
>> as pincode.
>
> according to my my tests they require the source address, ie the host
> adapter's address
>
>> +             /* Nintendo Wii Remote uses destination address as PIN */
>
> better to document in that comment if it works when pressing the red
> button or the 1+2 buttons
Pressing 1+2 buttons requires the destination address, pressing the sync
button requires the source address. Since the 1+2 buttons technique is the
more easy way I decided to implement this way first, however, the bluez
daemon needs input from the user-agent to decide which method to use finally.
The Wii decides which PIN to use depending whether the red-sync button on the
Wii (yes, on the wii, not the wiimote) or the "connection" button in
the Wii-menu is used.
The latter one uses destination address, the first one source address.

I couldn't figure out when autoreconnection is established, reliably. Pairing
the wiimote works sometimes, but not always and I didn't figure out how to
reset the internal cache of reconnection addresses. My wiimote also saves up
to 3 addresses which it can reconnect to in an unreliable way and so I sometimes
end up with my wiimote starting the Wii instead of reconnecing to my
PC. However,
this issue may be solved later.

>
> I tested your 3 patches against bluez git 4.91-32-gd7f412e and
> gnome-bluetooth 2.32 but they didn't work for me for 2 reasons:
> 1) can't get vid/pid so when the remote is unknown the
> read_device_id() call in your code fails to get vid/pid and the
> specific pin is never tried; the same happens after a failed pairing
> when the /var/lib/bluetooth/*/did file contains a line this:
> 00:1F:C5:25:36:87 FFFF 0000 0000 0000
All my Wiimotes have a PnP SDP record which is fetched by the SDP code
inside bluez so VID/PID should be available. Could you test using
sdptool whether there is a valid PnP record in your wiimote? If there is
no PnP record with VID/PID information it would be useful to know how
old your wiimote is. I have 3 different wiimotes, one about 2 years old,
one 1 year old and one new WiimotePlus which is about 1/2 year old and
all of them have the same PnP record so I assumed all wiimotes have this
PnP record.
If there is a valid PnP record maybe some bluez Dev could elaborate whether
VID/PID values are guaranteed to be available when pairing is started. All
my tests worked and there was always a valid VID/PID when pairing was done.

> 2) the source vs destination address I mentioned above
Please try both methods: sync button and 1+2 buttons and report which
method works
with which PIN. As I mentioned above all my Wiimotes work with source-addr plus
red-sync-button and dest-addr plus 1+2 buttons.

>
> It works for me if I manually edit that line with the values read from
> another wiimote's line:
> 00:1F:C5:25:36:87 0002 057E 0306 0600
> and if I change dba to sba here
>>                       memcpy(pinbuf, dba, 6);
>
> how can I help you to debug these issues?
>
> BTW pairing also works when I use the test code mentioned in
> https://bugzilla.gnome.org/show_bug.cgi?id=603845#c6
This patch simply forces the source address as PIN for every device. If this
works for you, could you run the example code at:
http://goo.gl/axeqd
on the new /dev/hidrawX device which is created for the wiimote? HIDRAW support
must be enabled in the kernel of course.
This should give you VID/PID information and the HID descriptor table.
Git-url for this is: http://goo.gl/odnwd

> --
> Daniele Forsi

Thanks for helping. I think if we could figure out how to reliably get
the VID/PID
values we can change the PIN to sda to support all devices. Patch 1
and 2 of my series
might be applied anyway to allow binary pins. This would also allow to
extend the
DBUS agent interface.
If you have ideas how to support both, sba and dba via some new DBUS
interface, I would
be glad to hear about it.

David

^ permalink raw reply

* [PATCH 0/5] [RFC] handling avdtp collisions
From: Luiz Augusto von Dentz @ 2011-04-06 11:00 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

This has been causing some problems with some devices, specially with
start and suspend commands which even when local endpoint handles it
nicelly (by accepting as a valid response) the remote stack may not
respond at all causing the resquest to timeout/abort.

The spec suggest the following about this:

"In case an INT receives a request for the same command that it is
expecting a response for, it may reject the command and may use a
random time offset for a retransmission to avoid deadlock."

But note that this is not possible for abort which cannot be rejected
and also may be too expensive in some cases e.g. switching a2dp to hfp
when a call is ringing.

So instead of doing this directly on avdtp levle as the spec suggest, I
suggest to let the local sep decide what to do with the command
indication and in case it accepts remove the pending request from the
queue so it doesn't timeout nor can be rejected.

Note that this doesn't change much the current implementation of local
sep, it was already accepting indication regardless of pending
requests, but with the proposed changes when a collision happen
callbacks are called and the indication is properly propagated to the
endpoints.

Luiz Augusto von Dentz (5):
  Add handling of avdtp command collision
  Fix handling of a2dp suspend indication
  Fix handling of a2dp open indication
  Fix handling of a2dp start indication
  Fix handling of a2dp abort indication

 audio/a2dp.c  |   62 ++++++++++++++++++++++++++++++++++++++++++---
 audio/avdtp.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 127 insertions(+), 13 deletions(-)


^ permalink raw reply

* [PATCH 1/5] Add handling of avdtp command collision
From: Luiz Augusto von Dentz @ 2011-04-06 11:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1302087637-30131-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

Check collision for avdtp open, close, start, suspend and abort
commands and if they collided remove the pending request if sep
has accepted the indication.
---
 audio/avdtp.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 69 insertions(+), 9 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index 23281ac..db82329 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -310,6 +310,7 @@ struct pending_req {
 	size_t data_size;
 	struct avdtp_stream *stream; /* Set if the request targeted a stream */
 	guint timeout;
+	gboolean collided;
 };
 
 struct avdtp_remote_sep {
@@ -1617,6 +1618,55 @@ static gboolean avdtp_reconf_cmd(struct avdtp *session, uint8_t transaction,
 	return avdtp_unknown_cmd(session, transaction, AVDTP_RECONFIGURE);
 }
 
+static void avdtp_check_collision(struct avdtp *session, uint8_t cmd,
+					struct avdtp_stream *stream)
+{
+	struct pending_req *req = session->req;
+
+	if (req == NULL || (req->signal_id != cmd && cmd != AVDTP_ABORT))
+		return;
+
+	if (cmd == AVDTP_ABORT)
+		cmd = req->signal_id;
+
+	if (cmd == AVDTP_OPEN || cmd == AVDTP_CLOSE) {
+		struct seid_req *seid = session->req->data;
+
+		if (seid->acp_seid == stream->rseid)
+			req->collided = TRUE;
+	} else if (cmd == AVDTP_START) {
+		struct start_req *start = session->req->data;
+		struct seid *seid = &start->first_seid;
+		int count = 1 + session->req->data_size -
+						sizeof(struct start_req);
+		int i;
+
+		req->collided = FALSE;
+
+		for (i = 0; i < count; i++, seid++) {
+			if (seid->seid == stream->rseid) {
+				req->collided = TRUE;
+				break;
+			}
+		}
+	} else if (cmd == AVDTP_SUSPEND) {
+		struct suspend_req *suspend = session->req->data;
+		struct seid *seid = &suspend->first_seid;
+		int count = 1 + session->req->data_size -
+						sizeof(struct suspend_req);
+		int i;
+
+		req->collided = FALSE;
+
+		for (i = 0; i < count; i++, seid++) {
+			if (seid->seid == stream->rseid) {
+				req->collided = TRUE;
+				break;
+			}
+		}
+	}
+}
+
 static gboolean avdtp_open_cmd(struct avdtp *session, uint8_t transaction,
 				struct seid_req *req, unsigned int size)
 {
@@ -1648,6 +1698,8 @@ static gboolean avdtp_open_cmd(struct avdtp *session, uint8_t transaction,
 			goto failed;
 	}
 
+	avdtp_check_collision(session, AVDTP_OPEN, stream);
+
 	if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
 						AVDTP_OPEN, NULL, 0))
 		return FALSE;
@@ -1707,6 +1759,8 @@ static gboolean avdtp_start_cmd(struct avdtp *session, uint8_t transaction,
 				goto failed;
 		}
 
+		avdtp_check_collision(session, AVDTP_START, stream);
+
 		avdtp_sep_set_state(session, sep, AVDTP_STATE_STREAMING);
 	}
 
@@ -1753,6 +1807,8 @@ static gboolean avdtp_close_cmd(struct avdtp *session, uint8_t transaction,
 			goto failed;
 	}
 
+	avdtp_check_collision(session, AVDTP_CLOSE, stream);
+
 	avdtp_sep_set_state(session, sep, AVDTP_STATE_CLOSING);
 
 	if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
@@ -1812,6 +1868,8 @@ static gboolean avdtp_suspend_cmd(struct avdtp *session, uint8_t transaction,
 				goto failed;
 		}
 
+		avdtp_check_collision(session, AVDTP_SUSPEND, stream);
+
 		avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN);
 	}
 
@@ -1839,27 +1897,23 @@ static gboolean avdtp_abort_cmd(struct avdtp *session, uint8_t transaction,
 	}
 
 	sep = find_local_sep_by_seid(session->server, req->acp_seid);
-	if (!sep || !sep->stream) {
-		err = AVDTP_BAD_ACP_SEID;
-		goto failed;
-	}
+	if (!sep || !sep->stream)
+		return FALSE;
 
 	if (sep->ind && sep->ind->abort) {
 		if (!sep->ind->abort(session, sep, sep->stream, &err,
 					sep->user_data))
-			goto failed;
+			return FALSE;
 	}
 
+	avdtp_check_collision(session, AVDTP_ABORT, sep->stream);
+
 	ret = avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
 						AVDTP_ABORT, NULL, 0);
 	if (ret)
 		avdtp_sep_set_state(session, sep, AVDTP_STATE_ABORTING);
 
 	return ret;
-
-failed:
-	return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
-					AVDTP_ABORT, &err, sizeof(err));
 }
 
 static gboolean avdtp_secctl_cmd(struct avdtp *session, uint8_t transaction,
@@ -2142,6 +2196,11 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 		if (session->streams && session->dc_timer)
 			remove_disconnect_timer(session);
 
+		if (session->req && session->req->collided) {
+			DBG("Collision detected");
+			goto next;
+		}
+
 		return TRUE;
 	}
 
@@ -2192,6 +2251,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 		break;
 	}
 
+next:
 	pending_req_free(session->req);
 	session->req = NULL;
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/5] Fix handling of a2dp suspend indication
From: Luiz Augusto von Dentz @ 2011-04-06 11:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1302087637-30131-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

When accepting the suspend indication all callbacks should be notified
that suspend completed.
---
 audio/a2dp.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/audio/a2dp.c b/audio/a2dp.c
index 1f3bc99..c7b6c6a 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -986,6 +986,9 @@ static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 				void *user_data)
 {
 	struct a2dp_sep *a2dp_sep = user_data;
+	struct a2dp_setup *setup;
+	gboolean start;
+	int perr;
 
 	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 		DBG("Sink %p: Suspend_Ind", sep);
@@ -999,6 +1002,29 @@ static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 		a2dp_sep->session = NULL;
 	}
 
+	if (!a2dp_sep->suspending)
+		return TRUE;
+
+	a2dp_sep->suspending = FALSE;
+
+	setup = find_setup_by_session(session);
+	if (!setup)
+		return TRUE;
+
+	start = setup->start;
+	setup->start = FALSE;
+
+	finalize_suspend(setup);
+
+	if (!start)
+		return TRUE;
+
+	perr = avdtp_start(session, a2dp_sep->stream);
+	if (perr < 0) {
+		error("Error on avdtp_start %s (%d)", strerror(-perr), -perr);
+		finalize_setup_errno(setup, -EIO, finalize_resume);
+	}
+
 	return TRUE;
 }
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/5] Fix handling of a2dp open indication
From: Luiz Augusto von Dentz @ 2011-04-06 11:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1302087637-30131-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

When accepting the open indication all config callbacks should be
notified that open completed.
---
 audio/a2dp.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/audio/a2dp.c b/audio/a2dp.c
index c7b6c6a..a607f06 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -883,11 +883,22 @@ static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 				void *user_data)
 {
 	struct a2dp_sep *a2dp_sep = user_data;
+	struct a2dp_setup *setup;
 
 	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 		DBG("Sink %p: Open_Ind", sep);
 	else
 		DBG("Source %p: Open_Ind", sep);
+
+	setup = find_setup_by_session(session);
+	if (!setup)
+		return TRUE;
+
+	if (setup->reconfigure)
+		setup->reconfigure = FALSE;
+
+	finalize_config(setup);
+
 	return TRUE;
 }
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 4/5] Fix handling of a2dp start indication
From: Luiz Augusto von Dentz @ 2011-04-06 11:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1302087637-30131-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

Only process callbacks if avdtp_start was sent, otherwise it may cancel
setup callbacks that were registered via g_idle_add.
---
 audio/a2dp.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/audio/a2dp.c b/audio/a2dp.c
index a607f06..e7234eb 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -954,10 +954,6 @@ static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 	else
 		DBG("Source %p: Start_Ind", sep);
 
-	setup = find_setup_by_session(session);
-	if (setup)
-		finalize_resume(setup);
-
 	if (!a2dp_sep->locked) {
 		a2dp_sep->session = avdtp_ref(session);
 		a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT,
@@ -965,6 +961,15 @@ static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 						a2dp_sep);
 	}
 
+	if (!a2dp_sep->starting)
+		return TRUE;
+
+	a2dp_sep->starting = FALSE;
+
+	setup = find_setup_by_session(session);
+	if (setup)
+		finalize_resume(setup);
+
 	return TRUE;
 }
 
@@ -980,6 +985,8 @@ static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	else
 		DBG("Source %p: Start_Cfm", sep);
 
+	a2dp_sep->starting = FALSE;
+
 	setup = find_setup_by_session(session);
 	if (!setup)
 		return;
@@ -2209,6 +2216,7 @@ unsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
 			error("avdtp_start failed");
 			goto failed;
 		}
+		sep->starting = TRUE;
 		break;
 	case AVDTP_STATE_STREAMING:
 		if (!sep->suspending && sep->suspend_timer) {
-- 
1.7.1


^ permalink raw reply related

* [PATCH 5/5] Fix handling of a2dp abort indication
From: Luiz Augusto von Dentz @ 2011-04-06 11:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1302087637-30131-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

When an abort indication is received reset all flags and finalize any
ongoing setup.
---
 audio/a2dp.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/audio/a2dp.c b/audio/a2dp.c
index e7234eb..719658b 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -1180,6 +1180,7 @@ static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 				void *user_data)
 {
 	struct a2dp_sep *a2dp_sep = user_data;
+	struct a2dp_setup *setup;
 
 	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 		DBG("Sink %p: Abort_Ind", sep);
@@ -1187,6 +1188,16 @@ static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 		DBG("Source %p: Abort_Ind", sep);
 
 	a2dp_sep->stream = NULL;
+	a2dp_sep->suspending = FALSE;
+	a2dp_sep->starting = FALSE;
+
+	setup = find_setup_by_session(session);
+	if (!setup)
+		return TRUE;
+
+	finalize_setup_errno(setup, -ECONNRESET, finalize_suspend,
+							finalize_resume,
+							finalize_config);
 
 	return TRUE;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH] Bluetooth: Fix Out Of Band pairing when mgmt interface is disabled
From: Szymon Janc @ 2011-04-06 11:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

Use kernel stored remote Out Of Band data only if management interface
is enabled. Otherwise HCI_OP_REMOTE_OOB_DATA_NEG_REPLY was sent to
controller even if remote Out Of Band data was present in bluetoothd.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/hci_event.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9062e1b..7a3103e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2498,6 +2498,9 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
 
 	hci_dev_lock(hdev);
 
+	if (!test_bit(HCI_MGMT, &hdev->flags))
+		goto unlock;
+
 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
 	if (data) {
 		struct hci_cp_remote_oob_data_reply cp;
@@ -2516,6 +2519,7 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
 									&cp);
 	}
 
+unlock:
 	hci_dev_unlock(hdev);
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] Bluetooth: Fix unconditional call to mgmt interface in hci_event.c
From: Szymon Janc @ 2011-04-06 11:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

hci_cc_read_local_oob_data_reply funtion should call
mgmt_read_local_oob_data_reply_complete only if management interface
is enabled.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/hci_event.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 7a3398d..9062e1b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -831,7 +831,8 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
 
 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
 						rp->randomizer, rp->status);
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH 3/3] Support hardcoded Nintendo Wii Remote pins
From: Daniele Forsi @ 2011-04-06 14:05 UTC (permalink / raw)
  To: David Herrmann; +Cc: linux-bluetooth
In-Reply-To: <BANLkTinQBr7Scuab_KAs_1L1UY-E9j87pw@mail.gmail.com>

2011/4/6 David Herrmann:

> Please try both methods: sync button and 1+2 buttons and report which
> method works
> with which PIN. As I mentioned above all my Wiimotes work with source-addr plus
> red-sync-button and dest-addr plus 1+2 buttons.

now I understand, you're right, such explaination would be useful as a
comment in the code even if only one method is implemented
I can confirm that your code works unmodified for me too if I press
1+2 (after I manually fix the issue I still have with vid/pid), and it
also works after modifying it to use source-addr and pressing the sync
button

> If there is a valid PnP record maybe some bluez Dev could elaborate whether
> VID/PID values are guaranteed to be available when pairing is started.

I have two original remotes from December 2008 and different one from
December 2010 and their SDP records are identical:

Service RecHandle: 0x0
Service Class ID List:
  "SDP Server" (0x1000)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 1
  "SDP" (0x0001)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "" (0x0100)
    Version: 0x0100

Service Name: Nintendo RVL-CNT-01
Service Description: Nintendo RVL-CNT-01
Service Provider: Nintendo
Service RecHandle: 0x10000
Service Class ID List:
  "Human Interface Device" (0x1124)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 17
  "HIDP" (0x0011)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Human Interface Device" (0x1124)
    Version: 0x0100

Service RecHandle: 0x10001
Service Class ID List:
  "PnP Information" (0x1200)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 1
  "SDP" (0x0001)
Profile Descriptor List:
  "PnP Information" (0x1200)
    Version: 0x0100

> I couldn't figure out when autoreconnection is established, reliably. Pairing
> the wiimote works sometimes, but not always and I didn't figure out how to
> reset the internal cache of reconnection addresses.

if you have dangerous ideas I'm willing to sacrifice for the good of
science :-) my remote that doesn't work well

> If this works for you, could you run the example code at:
> http://goo.gl/axeqd
> on the new /dev/hidrawX device which is created for the wiimote?

it kind of works, but it seems I'm running an older kernel
(2.6.35-28-generic #49-Ubuntu):
$ sudo ./hid-example /dev/hidraw0
Report Descriptor Size: 218
Report Descriptor:
5 1 9 5 a1 1 85 10 15 0 26 ff 0 75 8 95 1 6 0 ff 9 1 91 0 85 11 95 1 9
1 91 0 85 12 95 2 9 1 91 0 85 13 95 1 9 1 91 0 85 14 95 1 9 1 91 0 85
15 95 1 9 1 91 0 85 16 95 15 9 1 91 0 85 17 95 6 9 1 91 0 85 18 95 15
9 1 91 0 85 19 95 1 9 1 91 0 85 1a 95 1 9 1 91 0 85 20 95 6 9 1 81 0
85 21 95 15 9 1 81 0 85 22 95 4 9 1 81 0 85 30 95 2 9 1 81 0 85 31 95
5 9 1 81 0 85 32 95 a 9 1 81 0 85 33 95 11 9 1 81 0 85 34 95 15 9 1 81
0 85 35 95 15 9 1 81 0 85 36 95 15 9 1 81 0 85 37 95 15 9 1 81 0 85 3d
95 15 9 1 81 0 85 3e 95 15 9 1 81 0 85 3f 95 15 9 1 81 0 c0 0

Raw Name: Nintendo RVL-CNT-01
Raw Phys: 00:1F:81:00:01:00
Raw Info:
	bustype: 5 (Bluetooth)
	vendor: 0x057e
	product: 0x0306
HIDIOCSFEATURE: Invalid argument
HIDIOCGFEATURE: Invalid argument
write() wrote 2 bytes
read: Resource temporarily unavailable

> If you have ideas how to support both, sba and dba via some new DBUS
> interface, I would be glad to hear about it.

using a binary pin seems to solve this problem and the pin could be
constructed by the agent based on user choice (and the agent can use
the binary pin interface also for plain strings)
I understand that constructing the pin in bluez would make it
available to all agents but then how do we ask the user for which
method to use?

you know better than me, but supporting dba doesn't seem a strict
requirement to me because pairing with 1+2 already worked for me with
gnome-bluetooth 2.32 and bluez-4.69; the config file has this
explaination:
  The special NULL pin means that the devices will not be paired, but
  connected to and marked as trusted. This is for devices such as mice
  and joypads where there is no encryption
I don't understand the details but this means that CreateDevice is
used instead of CreatePairedDevice
-- 
Daniele Forsi

^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix unconditional call to mgmt interface in hci_event.c
From: Marcel Holtmann @ 2011-04-06 14:08 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1302087740-18244-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

> hci_cc_read_local_oob_data_reply funtion should call
> mgmt_read_local_oob_data_reply_complete only if management interface
> is enabled.
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/hci_event.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 7a3398d..9062e1b 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -831,7 +831,8 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
>  
>  	BT_DBG("%s status 0x%x", hdev->name, rp->status);
>  

please just exit the function if flag is not set:

	if (!test_bit(...))
		return

> -	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
> +	if (test_bit(HCI_MGMT, &hdev->flags))
> +		mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
>  						rp->randomizer, rp->status);
>  }
>  

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 3/3] Support hardcoded Nintendo Wii Remote pins
From: Bastien Nocera @ 2011-04-06 14:31 UTC (permalink / raw)
  To: Daniele Forsi; +Cc: David Herrmann, linux-bluetooth
In-Reply-To: <BANLkTikn99GO4JV4uV64KCuka0G1QYYHpQ@mail.gmail.com>

On Wed, 2011-04-06 at 16:05 +0200, Daniele Forsi wrote:
> 2011/4/6 David Herrmann:
> 
> > Please try both methods: sync button and 1+2 buttons and report which
> > method works
> > with which PIN. As I mentioned above all my Wiimotes work with source-addr plus
> > red-sync-button and dest-addr plus 1+2 buttons.
> 
> now I understand, you're right, such explaination would be useful as a
> comment in the code even if only one method is implemented
> I can confirm that your code works unmodified for me too if I press
> 1+2 (after I manually fix the issue I still have with vid/pid), and it
> also works after modifying it to use source-addr and pressing the sync
> button
> 
> > If there is a valid PnP record maybe some bluez Dev could elaborate whether
> > VID/PID values are guaranteed to be available when pairing is started.
> 
> I have two original remotes from December 2008 and different one from
> December 2010 and their SDP records are identical:
> 
> Service RecHandle: 0x0
> Service Class ID List:
>   "SDP Server" (0x1000)
> Protocol Descriptor List:
>   "L2CAP" (0x0100)
>     PSM: 1
>   "SDP" (0x0001)
> Language Base Attr List:
>   code_ISO639: 0x656e
>   encoding:    0x6a
>   base_offset: 0x100
> Profile Descriptor List:
>   "" (0x0100)
>     Version: 0x0100
> 
> Service Name: Nintendo RVL-CNT-01
> Service Description: Nintendo RVL-CNT-01
> Service Provider: Nintendo
> Service RecHandle: 0x10000
> Service Class ID List:
>   "Human Interface Device" (0x1124)
> Protocol Descriptor List:
>   "L2CAP" (0x0100)
>     PSM: 17
>   "HIDP" (0x0011)
> Language Base Attr List:
>   code_ISO639: 0x656e
>   encoding:    0x6a
>   base_offset: 0x100
> Profile Descriptor List:
>   "Human Interface Device" (0x1124)
>     Version: 0x0100
> 
> Service RecHandle: 0x10001
> Service Class ID List:
>   "PnP Information" (0x1200)
> Protocol Descriptor List:
>   "L2CAP" (0x0100)
>     PSM: 1
>   "SDP" (0x0001)
> Profile Descriptor List:
>   "PnP Information" (0x1200)
>     Version: 0x0100
> 
> > I couldn't figure out when autoreconnection is established, reliably. Pairing
> > the wiimote works sometimes, but not always and I didn't figure out how to
> > reset the internal cache of reconnection addresses.
> 
> if you have dangerous ideas I'm willing to sacrifice for the good of
> science :-) my remote that doesn't work well
> 
> > If this works for you, could you run the example code at:
> > http://goo.gl/axeqd
> > on the new /dev/hidrawX device which is created for the wiimote?
> 
> it kind of works, but it seems I'm running an older kernel
> (2.6.35-28-generic #49-Ubuntu):
> $ sudo ./hid-example /dev/hidraw0
> Report Descriptor Size: 218
> Report Descriptor:
> 5 1 9 5 a1 1 85 10 15 0 26 ff 0 75 8 95 1 6 0 ff 9 1 91 0 85 11 95 1 9
> 1 91 0 85 12 95 2 9 1 91 0 85 13 95 1 9 1 91 0 85 14 95 1 9 1 91 0 85
> 15 95 1 9 1 91 0 85 16 95 15 9 1 91 0 85 17 95 6 9 1 91 0 85 18 95 15
> 9 1 91 0 85 19 95 1 9 1 91 0 85 1a 95 1 9 1 91 0 85 20 95 6 9 1 81 0
> 85 21 95 15 9 1 81 0 85 22 95 4 9 1 81 0 85 30 95 2 9 1 81 0 85 31 95
> 5 9 1 81 0 85 32 95 a 9 1 81 0 85 33 95 11 9 1 81 0 85 34 95 15 9 1 81
> 0 85 35 95 15 9 1 81 0 85 36 95 15 9 1 81 0 85 37 95 15 9 1 81 0 85 3d
> 95 15 9 1 81 0 85 3e 95 15 9 1 81 0 85 3f 95 15 9 1 81 0 c0 0
> 
> Raw Name: Nintendo RVL-CNT-01
> Raw Phys: 00:1F:81:00:01:00
> Raw Info:
> 	bustype: 5 (Bluetooth)
> 	vendor: 0x057e
> 	product: 0x0306
> HIDIOCSFEATURE: Invalid argument
> HIDIOCGFEATURE: Invalid argument
> write() wrote 2 bytes
> read: Resource temporarily unavailable
> 
> > If you have ideas how to support both, sba and dba via some new DBUS
> > interface, I would be glad to hear about it.
> 
> using a binary pin seems to solve this problem and the pin could be
> constructed by the agent based on user choice (and the agent can use
> the binary pin interface also for plain strings)
> I understand that constructing the pin in bluez would make it
> available to all agents but then how do we ask the user for which
> method to use?
> 
> you know better than me, but supporting dba doesn't seem a strict
> requirement to me because pairing with 1+2 already worked for me with
> gnome-bluetooth 2.32 and bluez-4.69; the config file has this
> explaination:

The whole point of this is of actually pairing the Wiimote so that when
turned on, the Wiimote connects to the computer. If you need to press
any buttons other than the power one, then it's not working.

>   The special NULL pin means that the devices will not be paired, but
>   connected to and marked as trusted. This is for devices such as mice
>   and joypads where there is no encryption
> I don't understand the details but this means that CreateDevice is
> used instead of CreatePairedDevice

The special NULL means that you would have needed to make the Wiimote
discoverable (through pressing 1/2) before it was usable.


^ permalink raw reply

* Re: [PATCH 3/3] Support hardcoded Nintendo Wii Remote pins
From: David Herrmann @ 2011-04-06 17:55 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Daniele Forsi, linux-bluetooth
In-Reply-To: <1302100288.3227.51.camel@novo.hadess.net>

On Wed, Apr 6, 2011 at 4:31 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Wed, 2011-04-06 at 16:05 +0200, Daniele Forsi wrote:
>> 2011/4/6 David Herrmann:
>>
>> > Please try both methods: sync button and 1+2 buttons and report which
>> > method works
>> > with which PIN. As I mentioned above all my Wiimotes work with source-addr plus
>> > red-sync-button and dest-addr plus 1+2 buttons.
>>
>> now I understand, you're right, such explaination would be useful as a
>> comment in the code even if only one method is implemented
>> I can confirm that your code works unmodified for me too if I press
>> 1+2 (after I manually fix the issue I still have with vid/pid), and it
>> also works after modifying it to use source-addr and pressing the sync
>> button
>>
>> > If there is a valid PnP record maybe some bluez Dev could elaborate whether
>> > VID/PID values are guaranteed to be available when pairing is started.
>>
>> I have two original remotes from December 2008 and different one from
>> December 2010 and their SDP records are identical:
>>
>> Service RecHandle: 0x0
>> Service Class ID List:
>>   "SDP Server" (0x1000)
>> Protocol Descriptor List:
>>   "L2CAP" (0x0100)
>>     PSM: 1
>>   "SDP" (0x0001)
>> Language Base Attr List:
>>   code_ISO639: 0x656e
>>   encoding:    0x6a
>>   base_offset: 0x100
>> Profile Descriptor List:
>>   "" (0x0100)
>>     Version: 0x0100
>>
>> Service Name: Nintendo RVL-CNT-01
>> Service Description: Nintendo RVL-CNT-01
>> Service Provider: Nintendo
>> Service RecHandle: 0x10000
>> Service Class ID List:
>>   "Human Interface Device" (0x1124)
>> Protocol Descriptor List:
>>   "L2CAP" (0x0100)
>>     PSM: 17
>>   "HIDP" (0x0011)
>> Language Base Attr List:
>>   code_ISO639: 0x656e
>>   encoding:    0x6a
>>   base_offset: 0x100
>> Profile Descriptor List:
>>   "Human Interface Device" (0x1124)
>>     Version: 0x0100
>>
>> Service RecHandle: 0x10001
>> Service Class ID List:
>>   "PnP Information" (0x1200)
>> Protocol Descriptor List:
>>   "L2CAP" (0x0100)
>>     PSM: 1
>>   "SDP" (0x0001)
>> Profile Descriptor List:
>>   "PnP Information" (0x1200)
>>     Version: 0x0100
>>
>> > I couldn't figure out when autoreconnection is established, reliably. Pairing
>> > the wiimote works sometimes, but not always and I didn't figure out how to
>> > reset the internal cache of reconnection addresses.
>>
>> if you have dangerous ideas I'm willing to sacrifice for the good of
>> science :-) my remote that doesn't work well
>>
>> > If this works for you, could you run the example code at:
>> > http://goo.gl/axeqd
>> > on the new /dev/hidrawX device which is created for the wiimote?
>>
>> it kind of works, but it seems I'm running an older kernel
>> (2.6.35-28-generic #49-Ubuntu):
>> $ sudo ./hid-example /dev/hidraw0
>> Report Descriptor Size: 218
>> Report Descriptor:
>> 5 1 9 5 a1 1 85 10 15 0 26 ff 0 75 8 95 1 6 0 ff 9 1 91 0 85 11 95 1 9
>> 1 91 0 85 12 95 2 9 1 91 0 85 13 95 1 9 1 91 0 85 14 95 1 9 1 91 0 85
>> 15 95 1 9 1 91 0 85 16 95 15 9 1 91 0 85 17 95 6 9 1 91 0 85 18 95 15
>> 9 1 91 0 85 19 95 1 9 1 91 0 85 1a 95 1 9 1 91 0 85 20 95 6 9 1 81 0
>> 85 21 95 15 9 1 81 0 85 22 95 4 9 1 81 0 85 30 95 2 9 1 81 0 85 31 95
>> 5 9 1 81 0 85 32 95 a 9 1 81 0 85 33 95 11 9 1 81 0 85 34 95 15 9 1 81
>> 0 85 35 95 15 9 1 81 0 85 36 95 15 9 1 81 0 85 37 95 15 9 1 81 0 85 3d
>> 95 15 9 1 81 0 85 3e 95 15 9 1 81 0 85 3f 95 15 9 1 81 0 c0 0
>>
>> Raw Name: Nintendo RVL-CNT-01
>> Raw Phys: 00:1F:81:00:01:00
>> Raw Info:
>>       bustype: 5 (Bluetooth)
>>       vendor: 0x057e
>>       product: 0x0306
>> HIDIOCSFEATURE: Invalid argument
>> HIDIOCGFEATURE: Invalid argument
>> write() wrote 2 bytes
>> read: Resource temporarily unavailable
>>
>> > If you have ideas how to support both, sba and dba via some new DBUS
>> > interface, I would be glad to hear about it.
>>
>> using a binary pin seems to solve this problem and the pin could be
>> constructed by the agent based on user choice (and the agent can use
>> the binary pin interface also for plain strings)
>> I understand that constructing the pin in bluez would make it
>> available to all agents but then how do we ask the user for which
>> method to use?
>>
>> you know better than me, but supporting dba doesn't seem a strict
>> requirement to me because pairing with 1+2 already worked for me with
>> gnome-bluetooth 2.32 and bluez-4.69; the config file has this
>> explaination:
>
> The whole point of this is of actually pairing the Wiimote so that when
> turned on, the Wiimote connects to the computer. If you need to press
> any buttons other than the power one, then it's not working.

Exactly.

I prefer my solution with dba over sba because it allows to pair the wiimote
without opening the backside. The only issue left with the patches is the
VID/PID thing. It works perfectly for me when I delete the device with
gnome-bluetooth and add the wiimote as new device.

It would be interesting to know from a bluez dev or gnome-bluetooth dev whether
the SDP records are always retrieved before trying to connect to a remote
device or whether we need to do this manually.

^ permalink raw reply

* Re: [PATCH 3/3] Support hardcoded Nintendo Wii Remote pins
From: Bastien Nocera @ 2011-04-06 18:05 UTC (permalink / raw)
  To: David Herrmann; +Cc: Daniele Forsi, linux-bluetooth
In-Reply-To: <BANLkTi=gqh3fxYipPE9CqMgV=6Qr0MkTSA@mail.gmail.com>

On Wed, 2011-04-06 at 19:55 +0200, David Herrmann wrote:
<snip>
> Exactly.
> 
> I prefer my solution with dba over sba because it allows to pair the wiimote
> without opening the backside. The only issue left with the patches is the
> VID/PID thing. It works perfectly for me when I delete the device with
> gnome-bluetooth and add the wiimote as new device.

gnome-bluetooth just calls RemoveDevice() which won't remove cached SDP
records, resolved name, etc. for the device. Best open
up /var/lib/bluetooth files with a text editor, and remove everything
related to your Wiimote for testing.

(or you can just nuke the directory if you don't care about pairing your
other devices again).

> It would be interesting to know from a bluez dev or gnome-bluetooth dev whether
> the SDP records are always retrieved before trying to connect to a remote
> device or whether we need to do this manually.

The ordering of this is done by bluetoothd, and I'm pretty certain that
the SDP records are only updated *after* pairing, as some devices might
refuse to answer SDP requests from unpaired devices.

But at that point we should already have a name for it cached (at least
with gnome-bluetooth, which waits for the name to be resolved to allow
you to go through the next steps).




^ permalink raw reply

* Re: [bluetooth-next 08/15] Bluetooth: Minor fix in SMP methods
From: Gustavo F. Padovan @ 2011-04-06 19:09 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Anderson Briglia
In-Reply-To: <1302054716-24534-9-git-send-email-vinicius.gomes@openbossa.org>

Hi Vinicius,

* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-04-05 22:51:49 -0300]:

> From: Anderson Briglia <anderson.briglia@openbossa.org>
> 
> Minor fix in smp_conn_security function.
> 
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
>  net/bluetooth/smp.c |    7 ++++---
>  1 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index fd9c3ff..f03513d 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -355,11 +355,12 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
>  
>  int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
>  {
> +	struct hci_conn *hcon = conn->hcon;
>  	__u8 authreq;
>  
> -	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
> +	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
>  
> -	if (IS_ERR(conn->hcon->hdev->tfm))
> +	if (IS_ERR(hcon->hdev->tfm))

Merge these changes in the commits that add this code for the first time,
patch 01 and others.

>  		return 1;
>  
>  	switch (sec_level) {
> @@ -378,7 +379,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
>  		return 1;
>  	}
>  
> -	if (conn->hcon->link_mode & HCI_LM_MASTER) {
> +	if (hcon->link_mode & HCI_LM_MASTER) {

Same here.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [bluetooth-next 13/15] Bluetooth: Add support for Pairing features exchange
From: Gustavo F. Padovan @ 2011-04-06 19:18 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1302054716-24534-14-git-send-email-vinicius.gomes@openbossa.org>

Hi Vinícius,

* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-04-05 22:51:54 -0300]:

> This patch implements a simple version of the SMP Pairing Features
> exchange procedure (Vol. 3 Part H, Section 2.3.5.1).
> 
> For now, everything that would cause a Pairing Method different of
> Just Works to be chosen is rejected.
> 
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
>  net/bluetooth/hci_event.c |    1 +
>  net/bluetooth/smp.c       |  117 ++++++++++++++++++++++++--------------------
>  2 files changed, 65 insertions(+), 53 deletions(-)
> 
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index aa0d013..e40ce9a 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -1555,6 +1555,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
>  				/* Encryption implies authentication */
>  				conn->link_mode |= HCI_LM_AUTH;
>  				conn->link_mode |= HCI_LM_ENCRYPT;
> +				conn->sec_level = conn->pending_sec_level;
>  			} else
>  				conn->link_mode &= ~HCI_LM_ENCRYPT;
>  		}
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index 2724b70..b6f52ab 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -186,7 +186,30 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
>  	hci_send_acl(conn->hcon, skb, 0);
>  }
>  
> -static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
> +static __u8 seclevel_to_authreq(__u8 level)
> +{
> +	switch (level) {
> +	case BT_SECURITY_HIGH:
> +		/* Right now we don't support bonding */
> +		return SMP_AUTH_MITM;
> +
> +	default:
> +		return SMP_AUTH_NONE;
> +	}
> +}
> +
> +static void build_pairing_cmd(struct l2cap_conn *conn,
> +				struct smp_cmd_pairing *cmd, __u8 authreq)
> +{
> +	cmd->io_capability = SMP_IO_NO_INPUT_OUTPUT;
> +	cmd->oob_flag = SMP_OOB_NOT_PRESENT;
> +	cmd->max_key_size = 16;
> +	cmd->init_key_dist = 0x00;
> +	cmd->resp_key_dist = 0x00;
> +	cmd->auth_req = authreq;
> +}
> +

Separate the creation of build_pairing_cmd() in a new commit.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [bluetooth-next 05/15] Bluetooth: LE SMP Cryptoolbox functions
From: Gustavo F. Padovan @ 2011-04-06 23:26 UTC (permalink / raw)
  To: Vinicius Costa Gomes
  Cc: linux-bluetooth, Anderson Briglia, Anderson Lizardo,
	Bruna Moreira
In-Reply-To: <1302054716-24534-6-git-send-email-vinicius.gomes@openbossa.org>

Hi Vinicius,

* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-04-05 22:51:46 -0300]:

> From: Anderson Briglia <anderson.briglia@openbossa.org>
> 
> This patch implements SMP crypto functions called ah, c1, s1 and e.
> It also implements auxiliary functions. All These functions are needed
> for SMP keys generation.
> 
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> Signed-off-by: Anderson Lizardo <anderson.lizardo@openbossa.org>
> Signed-off-by: Bruna Moreira <bruna.moreira@openbossa.org>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
>  net/bluetooth/smp.c |  122 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 122 insertions(+), 0 deletions(-)
> 
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index 42aed82..58047e8 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -24,6 +24,128 @@
>  #include <net/bluetooth/hci_core.h>
>  #include <net/bluetooth/l2cap.h>
>  #include <net/bluetooth/smp.h>
> +#include <linux/crypto.h>
> +#include <crypto/b128ops.h>
> +
> +static inline void swap128(u8 src[16], u8 dst[16])
> +{
> +	int i;
> +	for (i = 0; i < 16; i++)
> +		dst[15 - i] = src[i];
> +}
> +
> +static inline void swap56(u8 src[7], u8 dst[7])
> +{
> +	int i;
> +	for (i = 0; i < 7; i++)
> +		dst[6 - i] = src[i];
> +}
> +
> +static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
> +{
> +	struct blkcipher_desc desc;
> +	struct scatterlist sg;
> +	int err, iv_len;
> +	unsigned char iv[128];
> +
> +	if (tfm == NULL) {
> +		BT_ERR("tfm %p", tfm);
> +		return -EINVAL;
> +	}
> +
> +	desc.tfm = tfm;
> +	desc.flags = 0;
> +
> +	err = crypto_blkcipher_setkey(tfm, k, 16);
> +	if (err) {
> +		BT_ERR("cipher setkey failed: %d", err);
> +		return err;
> +	}
> +
> +	sg_init_one(&sg, r, 16);
> +
> +	iv_len = crypto_blkcipher_ivsize(tfm);
> +	if (iv_len) {
> +		memset(&iv, 0xff, iv_len);
> +		crypto_blkcipher_set_iv(tfm, iv, iv_len);
> +	}
> +
> +	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
> +	if (err)
> +		BT_ERR("Encrypt data error %d", err);
> +
> +	return err;
> +}
> +
> +static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
> +		u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
> +		u8 _rat, bdaddr_t *ra, u8 res[16])
> +{
> +	u8 p1[16], p2[16], pair[7];
> +	bdaddr_t addr;
> +	int err;
> +
> +	/* p1 = pres || preq || _rat || _iat */
> +	memset(p1, 0, 16);
> +	swap56(pres, pair);
> +
> +	memcpy(p1, pair, 7);
> +	swap56(preq, pair);
> +
> +	memcpy(p1 + 7, pair, 7);

	swap56(pres, p1)
	swap56(preq, pi + 7)

> +	*(p1 + 14) = _rat;
> +	*(p1 + 15) = _iat;

Isn't p1[14] = _rat better?

btw, if fill all 16 bytes here, there is no need for a memset(p1)

> +
> +	/* p2 = padding || ia || ra */
> +	memset(p2, 0, 16);
> +	baswap(&addr, ia);
> +	memcpy(p2 + 4, &addr, 6);
> +	baswap(&addr, ra);
> +	memcpy(p2 + 10, &addr, 6);

baswap(p2 + 4, ia) should have the same effect.

> +	/* res = r XOR p1 */
> +	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
> +
> +	/* res = e(k, res) */
> +	err = smp_e(tfm, k, res);
> +	if (err) {
> +		BT_ERR("Encrypt data error");
> +		return err;
> +	}
> +
> +	/* res = res XOR p2 */
> +	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
> +
> +	/* res = e(k, res) */
> +	err = smp_e(tfm, k, res);
> +	if (err)
> +		BT_ERR("Encrypt data error");
> +
> +	return err;
> +}
> +
> +static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
> +			u8 r1[16], u8 r2[16], u8 _r[16])
> +{
> +	int err;
> +
> +	/* Just least significant octets from r1 and r2 are considered */
> +	memcpy(_r, r1 + 8, 8);
> +	memcpy(_r + 8, r2 + 8, 8);
> +
> +	err = smp_e(tfm, k, _r);
> +	if (err)
> +		BT_ERR("Encrypt data error");
> +
> +	return err;
> +}
> +
> +static int smp_rand(u8 *buf)

This can be void.

> +{
> +	get_random_bytes(buf, 16);
> +
> +	return 0;
> +}
>  

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox