[bluetooth-next 00/13] SMP Key Exchange Support

18 messages, 3 authors, 2011-06-09 · open the first message on its own page

[bluetooth-next 00/13] SMP Key Exchange Support

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:01

Hi,

This will introduce support for Exchanging Keys with remote devices.

The keys will be generated by the kernel and will be notified to
userspace so they can be stored. The management interface will
be used for this communication.

The "new key" event and the "load keys" command had to be changed, so
more information could be added to each key, for example, the long term
key has a 16bit number and a 64bit random value associated with it. But,
userpace isn't aware of the format of those keys, it just knows that they
are present or not.

Another thing that should be noted is that the link_keys list (already
present) is used to store these keys, including the Short Term Key, as
it makes the handling of this type of key more transparent.

The related userspace changes should appear a little after this series.


Cheers,
--

Anderson Lizardo (1):
  Bluetooth: Add support for random destination address

Vinicius Costa Gomes (12):
  Bluetooth: Add support for SMP phase 3 (key distribution)
  Bluetooth: Fix sending wrong IO Capabilities value
  Bluetooth: Add new structures for supporting SM key distribution
  Bluetooth: Add functions to manipulate the link key list for SMP
  Bluetooth: Reject an encryption request when the key isn't found
  Bluetooth: Add support for providing parameters to LE Start
    Encryption
  Bluetooth: Fix SM pairing parameters negotiation
  Bluetooth: Add support for storing the LTK
  Bluetooth: Use the link key list to temporarily store the STK
  Bluetooth: Use the stored LTK for restabilishing security
  Bluetooth: Remove unused field in hci_conn
  Bluetooth: Add support for communicating keys with userspace

 include/net/bluetooth/hci.h      |    4 +
 include/net/bluetooth/hci_core.h |   25 ++++-
 include/net/bluetooth/mgmt.h     |    2 +
 include/net/bluetooth/smp.h      |    1 +
 net/bluetooth/hci_conn.c         |    5 +-
 net/bluetooth/hci_core.c         |   81 ++++++++++++++
 net/bluetooth/hci_event.c        |   18 +++-
 net/bluetooth/l2cap_core.c       |    1 +
 net/bluetooth/mgmt.c             |   60 ++++++++---
 net/bluetooth/smp.c              |  214 ++++++++++++++++++++++++++++++++++----
 10 files changed, 368 insertions(+), 43 deletions(-)

--
1.7.5.4

[bluetooth-next 01/13] Bluetooth: Add support for SMP phase 3 (key distribution)

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:02

This adds support for generating and distributing all the keys
specified in the third phase of SMP.

This will make possible to re-establish secure connections, resolve
private addresses and sign commands.

For now, the values generated are random.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 include/net/bluetooth/smp.h |    1 +
 net/bluetooth/l2cap_core.c  |    1 +
 net/bluetooth/smp.c         |  114 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 114 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 4fb7d19..46c4576 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -118,5 +118,6 @@ struct smp_cmd_security_req {
 /* SMP Commands */
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
+int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
 
 #endif /* __SMP_H */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9db461d..f202fa3 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4193,6 +4193,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 				chan->sec_level = hcon->sec_level;
 				del_timer(&conn->security_timer);
 				l2cap_chan_ready(sk);
+				smp_distribute_keys(conn, 0);
 			}
 
 			bh_unlock_sock(sk);
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 3822159..c9ae5d4 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -201,8 +201,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
 	cmd->io_capability = SMP_IO_NO_INPUT_OUTPUT;
 	cmd->oob_flag = SMP_OOB_NOT_PRESENT;
 	cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-	cmd->init_key_dist = 0x00;
-	cmd->resp_key_dist = 0x00;
+	cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
+	cmd->resp_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
 	cmd->auth_req = authreq;
 }
 
@@ -462,6 +462,26 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 	return 0;
 }
 
+static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	BT_DBG("conn %p", conn);
+	/* FIXME: store the ltk */
+	return 0;
+}
+
+static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_pairing *paircmd = (void *) &conn->prsp[1];
+	u8 keydist = paircmd->init_key_dist;
+
+	BT_DBG("keydist 0x%x", keydist);
+	/* FIXME: store ediv and rand */
+
+	smp_distribute_keys(conn, 1);
+
+	return 0;
+}
+
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	__u8 code = skb->data[0];
@@ -503,10 +523,20 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 		break;
 
 	case SMP_CMD_ENCRYPT_INFO:
+		reason = smp_cmd_encrypt_info(conn, skb);
+		break;
+
 	case SMP_CMD_MASTER_IDENT:
+		reason = smp_cmd_master_ident(conn, skb);
+		break;
+
 	case SMP_CMD_IDENT_INFO:
 	case SMP_CMD_IDENT_ADDR_INFO:
 	case SMP_CMD_SIGN_INFO:
+		/* Just ignored */
+		reason = 0;
+		break;
+
 	default:
 		BT_DBG("Unknown command code 0x%2.2x", code);
 
@@ -523,3 +553,83 @@ done:
 	kfree_skb(skb);
 	return err;
 }
+
+int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
+{
+	struct smp_cmd_pairing *req, *rsp;
+	__u8 *keydist;
+
+	BT_DBG("conn %p force %d", conn, force);
+
+	if (IS_ERR(conn->hcon->hdev->tfm))
+		return PTR_ERR(conn->hcon->hdev->tfm);
+
+	rsp = (void *) &conn->prsp[1];
+
+	/* The responder sends its keys first */
+	if (!force && conn->hcon->out && (rsp->resp_key_dist & 0x07))
+		return 0;
+
+	req = (void *) &conn->preq[1];
+
+	if (conn->hcon->out) {
+		keydist = &rsp->init_key_dist;
+		*keydist &= req->init_key_dist;
+	} else {
+		keydist = &rsp->resp_key_dist;
+		*keydist &= req->resp_key_dist;
+	}
+
+
+	BT_DBG("keydist 0x%x", *keydist);
+
+	if (*keydist & SMP_DIST_ENC_KEY) {
+		struct smp_cmd_encrypt_info enc;
+		struct smp_cmd_master_ident ident;
+		__le16 ediv;
+
+		get_random_bytes(enc.ltk, sizeof(enc.ltk));
+		get_random_bytes(&ediv, sizeof(ediv));
+		get_random_bytes(ident.rand, sizeof(ident.rand));
+
+		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
+
+		ident.ediv = cpu_to_le16(ediv);
+
+		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
+
+		*keydist &= ~SMP_DIST_ENC_KEY;
+	}
+
+	if (*keydist & SMP_DIST_ID_KEY) {
+		struct smp_cmd_ident_addr_info addrinfo;
+		struct smp_cmd_ident_info idinfo;
+
+		/* Send a dummy key */
+		get_random_bytes(idinfo.irk, sizeof(idinfo.irk));
+
+		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
+
+		/* Just public address */
+		memset(&addrinfo, 0, sizeof(addrinfo));
+		bacpy(&addrinfo.bdaddr, conn->src);
+
+		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
+								&addrinfo);
+
+		*keydist &= ~SMP_DIST_ID_KEY;
+	}
+
+	if (*keydist & SMP_DIST_SIGN) {
+		struct smp_cmd_sign_info sign;
+
+		/* Send a dummy key */
+		get_random_bytes(sign.csrk, sizeof(sign.csrk));
+
+		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
+
+		*keydist &= ~SMP_DIST_SIGN;
+	}
+
+	return 0;
+}
-- 
1.7.5.4

[bluetooth-next 02/13] Bluetooth: Fix sending wrong IO Capabilities value

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:03

We should send the IO Capabilities set by userspace, using the
management interface, instead of a fixed value.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 net/bluetooth/smp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index c9ae5d4..171a65c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -198,7 +198,7 @@ static __u8 seclevel_to_authreq(__u8 level)
 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->io_capability = conn->hcon->io_capability;
 	cmd->oob_flag = SMP_OOB_NOT_PRESENT;
 	cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
 	cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
-- 
1.7.5.4

Re: [bluetooth-next 02/13] Bluetooth: Fix sending wrong IO Capabilities value

From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Date: 2011-06-08 08:20:41

Hi Vinicius,

On Wed, Jun 8, 2011 at 7:50 AM, Vinicius Costa Gomes
[off-list ref] wrote:
quoted hunk
We should send the IO Capabilities set by userspace, using the
management interface, instead of a fixed value.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 net/bluetooth/smp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index c9ae5d4..171a65c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -198,7 +198,7 @@ static __u8 seclevel_to_authreq(__u8 level)
 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->io_capability = conn->hcon->io_capability;
       cmd->oob_flag = SMP_OOB_NOT_PRESENT;
       cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
       cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
--
Does this fix something that is not upstream yet? If not then we
should be fixing it in place whenever possible.

-- 
Luiz Augusto von Dentz
Computer Engineer

Re: [bluetooth-next 02/13] Bluetooth: Fix sending wrong IO Capabilities value

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-08 16:30:35

Hi Luiz,

On 17:20 Wed 08 Jun, Luiz Augusto von Dentz wrote:
Hi Vinicius,

On Wed, Jun 8, 2011 at 7:50 AM, Vinicius Costa Gomes
[off-list ref] wrote:
quoted
We should send the IO Capabilities set by userspace, using the
management interface, instead of a fixed value.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 net/bluetooth/smp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index c9ae5d4..171a65c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -198,7 +198,7 @@ static __u8 seclevel_to_authreq(__u8 level)
 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->io_capability = conn->hcon->io_capability;
       cmd->oob_flag = SMP_OOB_NOT_PRESENT;
       cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
       cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
--
Does this fix something that is not upstream yet? If not then we
should be fixing it in place whenever possible.
Done. Thanks.
-- 
Luiz Augusto von Dentz
Computer Engineer

Cheers,
-- 
Vinicius

[bluetooth-next 03/13] Bluetooth: Add new structures for supporting SM key distribution

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:04

We need these changes because SMP keys may have more information
associated with them, for example, in the LTK case, it has an
encrypted diversifier (ediv) and a random number (rand).

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 include/net/bluetooth/hci.h      |    4 ++++
 include/net/bluetooth/hci_core.h |   16 ++++++++++++++++
 include/net/bluetooth/mgmt.h     |    2 ++
 3 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 65345cd..3b6d057 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -254,6 +254,10 @@ enum {
 #define HCI_LK_UNAUTH_COMBINATION	0x04
 #define HCI_LK_AUTH_COMBINATION		0x05
 #define HCI_LK_CHANGED_COMBINATION	0x06
+/* The spec doesn't define types for SMP keys */
+#define HCI_LK_SMP_LTK			0x81
+#define HCI_LK_SMP_IRK			0x82
+#define HCI_LK_SMP_CSRK			0x83
 
 /* -----  HCI Commands ---- */
 #define HCI_OP_NOP			0x0000
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 13e5b48..0ba309e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -74,12 +74,28 @@ struct bt_uuid {
 	u8 svc_hint;
 };
 
+struct key_master_id {
+	__le16 ediv;
+	u8 rand[8];
+} __packed;
+
+struct link_key_data {
+	bdaddr_t bdaddr;
+	u8 type;
+	u8 val[16];
+	u8 pin_len;
+	u8 dlen;
+	u8 data[0];
+} __packed;
+
 struct link_key {
 	struct list_head list;
 	bdaddr_t bdaddr;
 	u8 type;
 	u8 val[16];
 	u8 pin_len;
+	u8 dlen;
+	u8 data[0];
 };
 
 struct oob_data {
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4899286..129d4b3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -101,6 +101,8 @@ struct mgmt_key_info {
 	u8 type;
 	u8 val[16];
 	u8 pin_len;
+	u8 dlen;
+	u8 data[0];
 } __packed;
 
 #define MGMT_OP_LOAD_KEYS		0x000D
-- 
1.7.5.4

[bluetooth-next 04/13] Bluetooth: Add functions to manipulate the link key list for SMP

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:05

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 <redacted>
---
 include/net/bluetooth/hci_core.h |    5 ++
 net/bluetooth/hci_core.c         |   81 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0ba309e..dbe6321 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -548,6 +548,11 @@ int hci_link_keys_clear(struct hci_dev *hdev);
 struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 			bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
+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]);
 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 f62ca19..02cad1f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1059,6 +1059,50 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
 	return 0;
 }
 
+struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->link_keys) {
+		struct link_key *k;
+		struct key_master_id *id;
+
+		k = list_entry(p, struct link_key, list);
+
+		if (k->type != HCI_LK_SMP_LTK)
+			continue;
+
+		if (k->dlen != sizeof(*id))
+			continue;
+
+		id = (void *) &k->data;
+		if (id->ediv == ediv &&
+				(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
+			return k;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(hci_find_ltk);
+
+struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
+					bdaddr_t *bdaddr, u8 type)
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->link_keys) {
+		struct link_key *k;
+
+		k = list_entry(p, struct link_key, list);
+
+		if ((k->type == type) && (bacmp(bdaddr, &k->bdaddr) == 0))
+			return k;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(hci_find_link_key_type);
+
 int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
 {
@@ -1114,6 +1158,43 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 	return 0;
 }
 
+int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
+					__le16 ediv, u8 rand[8], u8 ltk[16])
+{
+	struct link_key *key, *old_key;
+	struct key_master_id *id;
+	u8 old_key_type;
+
+	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
+
+	old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
+	if (old_key) {
+		key = old_key;
+		old_key_type = old_key->type;
+	} else {
+		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
+		if (!key)
+			return -ENOMEM;
+		list_add(&key->list, &hdev->link_keys);
+		old_key_type = 0xff;
+	}
+
+	key->dlen = sizeof(*id);
+
+	bacpy(&key->bdaddr, bdaddr);
+	memcpy(key->val, ltk, sizeof(key->val));
+	key->type = HCI_LK_SMP_LTK;
+
+	id = (void *) &key->data;
+	id->ediv = ediv;
+	memcpy(id->rand, rand, sizeof(id->rand));
+
+	if (new_key)
+		mgmt_new_key(hdev->id, key, old_key_type);
+
+	return 0;
+}
+
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
 	struct link_key *key;
-- 
1.7.5.4

[bluetooth-next 05/13] Bluetooth: Reject an encryption request when the key isn't found

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:06

Now that we have methods to finding keys by its parameters we can
reject an encryption request if the key isn't found.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 net/bluetooth/hci_event.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index ac2c5e8..9c7c370 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2793,21 +2793,35 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
 {
 	struct hci_ev_le_ltk_req *ev = (void *) skb->data;
 	struct hci_cp_le_ltk_reply cp;
+	struct hci_cp_le_ltk_neg_reply neg;
 	struct hci_conn *conn;
+	struct link_key *ltk;
 
 	BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
 
 	hci_dev_lock(hdev);
 
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (conn == NULL)
+		goto not_found;
+
+	ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
+	if (ltk == NULL)
+		goto not_found;
 
-	memset(&cp, 0, sizeof(cp));
+	memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
 	cp.handle = cpu_to_le16(conn->handle);
-	memcpy(cp.ltk, conn->ltk, sizeof(conn->ltk));
 
 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
 
 	hci_dev_unlock(hdev);
+
+	return;
+
+not_found:
+	neg.handle = ev->handle;
+	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
+	hci_dev_unlock(hdev);
 }
 
 static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
-- 
1.7.5.4

[bluetooth-next 06/13] Bluetooth: Add support for providing parameters to LE Start Encryption

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:07

With LTK support we need to be able to provide LE Start Encryption
with EDIV (Encrypted Diversifier) and Rand (just an 64 bit random
number).

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 include/net/bluetooth/hci_core.h |    3 ++-
 net/bluetooth/hci_conn.c         |    5 ++++-
 net/bluetooth/smp.c              |    7 ++++++-
 3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dbe6321..f80ea71 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -874,7 +874,8 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
 
 void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
 					u16 latency, u16 to_multiplier);
-void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16]);
+void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
+							__u8 ltk[16]);
 void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
 void hci_le_ltk_neg_reply(struct hci_conn *conn);
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b4754a8..2f5ae53 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -205,7 +205,8 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
 }
 EXPORT_SYMBOL(hci_le_conn_update);
 
-void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16])
+void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
+							__u8 ltk[16])
 {
 	struct hci_dev *hdev = conn->hdev;
 	struct hci_cp_le_start_enc cp;
@@ -216,6 +217,8 @@ void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16])
 
 	cp.handle = cpu_to_le16(conn->handle);
 	memcpy(cp.ltk, ltk, sizeof(cp.ltk));
+	cp.ediv = ediv;
+	memcpy(cp.rand, rand, sizeof(rand));
 
 	hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
 }
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 171a65c..01a6038 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -366,13 +366,18 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	}
 
 	if (conn->hcon->out) {
+		__le16 ediv;
+		u8 rand[8];
+
 		smp_s1(tfm, conn->tk, random, conn->prnd, key);
 		swap128(key, hcon->ltk);
 
 		memset(hcon->ltk + conn->smp_key_size, 0,
 				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
 
-		hci_le_start_enc(hcon, hcon->ltk);
+		memset(rand, 0, sizeof(rand));
+		ediv = 0;
+		hci_le_start_enc(hcon, ediv, rand, hcon->ltk);
 	} else {
 		u8 r[16];
 
-- 
1.7.5.4

[bluetooth-next 07/13] Bluetooth: Fix SM pairing parameters negotiation

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:08

Before implementing SM key distribution, the pairing features
exchange must be better negotiated, taking into account some
features of the host and connection requirements.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 net/bluetooth/smp.c |   42 ++++++++++++++++++++++++++++++++----------
 1 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 01a6038..b8f9910 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -196,14 +196,36 @@ static __u8 seclevel_to_authreq(__u8 level)
 }
 
 static void build_pairing_cmd(struct l2cap_conn *conn,
-				struct smp_cmd_pairing *cmd, __u8 authreq)
+				struct smp_cmd_pairing *req,
+				struct smp_cmd_pairing *rsp,
+				__u8 authreq)
 {
-	cmd->io_capability = conn->hcon->io_capability;
-	cmd->oob_flag = SMP_OOB_NOT_PRESENT;
-	cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-	cmd->init_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
-	cmd->resp_key_dist = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN;
-	cmd->auth_req = authreq;
+	u8 all_keys = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY |
+						SMP_DIST_SIGN;
+	u8 dist_keys;
+
+	dist_keys = 0;
+	if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
+		dist_keys = SMP_DIST_ENC_KEY;
+		authreq |= SMP_AUTH_BONDING;
+	}
+
+	if (rsp == NULL) {
+		req->io_capability = conn->hcon->io_capability;
+		req->oob_flag = SMP_OOB_NOT_PRESENT;
+		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
+		req->init_key_dist = dist_keys;
+		req->resp_key_dist = all_keys;
+		req->auth_req = authreq;
+		return;
+	}
+
+	rsp->io_capability = conn->hcon->io_capability;
+	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
+	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
+	rsp->init_key_dist = req->init_key_dist & all_keys;
+	rsp->resp_key_dist = req->resp_key_dist & dist_keys;
+	rsp->auth_req = authreq;
 }
 
 static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
@@ -232,7 +254,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 		return SMP_OOB_NOT_AVAIL;
 
 	/* We didn't start the pairing, so no requirements */
-	build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE);
+	build_pairing_cmd(conn, req, &rsp, SMP_AUTH_NONE);
 
 	key_size = min(req->max_key_size, rsp.max_key_size);
 	if (check_enc_key_size(conn, key_size))
@@ -408,7 +430,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	skb_pull(skb, sizeof(*rp));
 
 	memset(&cp, 0, sizeof(cp));
-	build_pairing_cmd(conn, &cp, rp->auth_req);
+	build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
 
 	conn->preq[0] = SMP_CMD_PAIRING_REQ;
 	memcpy(&conn->preq[1], &cp, sizeof(cp));
@@ -447,7 +469,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
 
-		build_pairing_cmd(conn, &cp, authreq);
+		build_pairing_cmd(conn, &cp, NULL, authreq);
 		conn->preq[0] = SMP_CMD_PAIRING_REQ;
 		memcpy(&conn->preq[1], &cp, sizeof(cp));
 
-- 
1.7.5.4

[bluetooth-next 08/13] Bluetooth: Add support for storing the LTK

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:09

Now when the LTK is received from the remote or generated it is stored,
so it can later be used.

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 net/bluetooth/smp.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b8f9910..bbc327b 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -491,18 +491,23 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 
 static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	BT_DBG("conn %p", conn);
-	/* FIXME: store the ltk */
+	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
+
+	skb_pull(skb, sizeof(*rp));
+
+	memcpy(conn->tk, rp->ltk, sizeof(conn->tk));
+
 	return 0;
 }
 
 static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing *paircmd = (void *) &conn->prsp[1];
-	u8 keydist = paircmd->init_key_dist;
+	struct smp_cmd_master_ident *rp = (void *) skb->data;
+
+	skb_pull(skb, sizeof(*rp));
 
-	BT_DBG("keydist 0x%x", keydist);
-	/* FIXME: store ediv and rand */
+	hci_add_ltk(conn->hcon->hdev, 1, conn->src, rp->ediv,
+						rp->rand, conn->tk);
 
 	smp_distribute_keys(conn, 1);
 
@@ -621,6 +626,9 @@ 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);
+
 		ident.ediv = cpu_to_le16(ediv);
 
 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
-- 
1.7.5.4

[bluetooth-next 09/13] Bluetooth: Use the link key list to temporarily store the STK

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:10

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 <redacted>
---
 net/bluetooth/smp.c |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index bbc327b..11f5f4f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -388,29 +388,36 @@ 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);
 
+		hci_le_start_enc(hcon, ediv, rand, stk);
+	} else {
+		u8 stk[16], r[16], rand[8];
+		__le16 ediv;
+
 		memset(rand, 0, sizeof(rand));
 		ediv = 0;
-		hci_le_start_enc(hcon, ediv, rand, hcon->ltk);
-	} else {
-		u8 r[16];
 
 		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);
 	}
 
 	return 0;
-- 
1.7.5.4

[bluetooth-next 10/13] Bluetooth: Use the stored LTK for restabilishing security

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:11

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 <redacted>
---
 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 11f5f4f..adf625a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -474,6 +474,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,
+							HCI_LK_SMP_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);
@@ -490,6 +504,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.5.4

[bluetooth-next 11/13] Bluetooth: Remove unused field in hci_conn

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:12

Signed-off-by: Vinicius Costa Gomes <redacted>
---
 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 f80ea71..c04e798 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -265,7 +265,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 adf625a..b8774a7 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -367,8 +367,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.5.4

[bluetooth-next 12/13] Bluetooth: Add support for communicating keys with userspace

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:13

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 <redacted>
---
 net/bluetooth/mgmt.c |   60 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index fcccf10..f229342 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 == HCI_LK_SMP_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, NULL, 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)
@@ -1888,17 +1907,28 @@ int mgmt_connectable(u16 index, u8 connectable)
 
 int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
 {
-	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->key.dlen = key->dlen;
+	ev->store_hint = persistent;
+
+	memcpy(ev->key.data, key->data, key->dlen);
 
-	ev.store_hint = persistent;
-	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;
+	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.5.4

[bluetooth-next 13/13] Bluetooth: Add support for random destination address

From: Vinicius Costa Gomes <hidden>
Date: 2011-06-07 22:50:14

From: Anderson Lizardo <redacted>

For source address, only public address type is supported for now.

Signed-off-by: Anderson Lizardo <redacted>
---
 net/bluetooth/smp.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b8774a7..9abcc6a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -306,7 +306,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 		return SMP_UNSPECIFIED;
 
 	ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
-			conn->src, 0, conn->dst, res);
+			conn->src, conn->hcon->dst_type, conn->dst, res);
 	if (ret)
 		return SMP_UNSPECIFIED;
 
@@ -342,7 +342,8 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 			return SMP_UNSPECIFIED;
 
 		ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
-					0, conn->dst, 0, conn->src, res);
+						conn->hcon->dst_type, conn->dst,
+						0, conn->src, res);
 		if (ret)
 			return SMP_CONFIRM_FAILED;
 
@@ -369,10 +370,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	if (conn->hcon->out)
 		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
-				conn->src, 0, conn->dst, res);
+				conn->src, conn->hcon->dst_type, conn->dst,
+				res);
 	else
-		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
-				conn->dst, 0, conn->src, res);
+		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp,
+				conn->hcon->dst_type, conn->dst, 0, conn->src,
+				res);
 	if (ret)
 		return SMP_UNSPECIFIED;
 
-- 
1.7.5.4

Re: [bluetooth-next 00/13] SMP Key Exchange Support

From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Date: 2011-06-09 13:02:36

Hi Vinicius,

On Wed, Jun 8, 2011 at 7:50 AM, Vinicius Costa Gomes
[off-list ref] wrote:
Hi,

This will introduce support for Exchanging Keys with remote devices.

The keys will be generated by the kernel and will be notified to
userspace so they can be stored. The management interface will
be used for this communication.

The "new key" event and the "load keys" command had to be changed, so
more information could be added to each key, for example, the long term
key has a 16bit number and a 64bit random value associated with it. But,
userpace isn't aware of the format of those keys, it just knows that they
are present or not.

Another thing that should be noted is that the link_keys list (already
present) is used to store these keys, including the Short Term Key, as
it makes the handling of this type of key more transparent.

The related userspace changes should appear a little after this series.


Cheers,
--

Anderson Lizardo (1):
 Bluetooth: Add support for random destination address

Vinicius Costa Gomes (12):
 Bluetooth: Add support for SMP phase 3 (key distribution)
 Bluetooth: Fix sending wrong IO Capabilities value
 Bluetooth: Add new structures for supporting SM key distribution
 Bluetooth: Add functions to manipulate the link key list for SMP
 Bluetooth: Reject an encryption request when the key isn't found
 Bluetooth: Add support for providing parameters to LE Start
   Encryption
 Bluetooth: Fix SM pairing parameters negotiation
 Bluetooth: Add support for storing the LTK
 Bluetooth: Use the link key list to temporarily store the STK
 Bluetooth: Use the stored LTK for restabilishing security
 Bluetooth: Remove unused field in hci_conn
 Bluetooth: Add support for communicating keys with userspace

 include/net/bluetooth/hci.h      |    4 +
 include/net/bluetooth/hci_core.h |   25 ++++-
 include/net/bluetooth/mgmt.h     |    2 +
 include/net/bluetooth/smp.h      |    1 +
 net/bluetooth/hci_conn.c         |    5 +-
 net/bluetooth/hci_core.c         |   81 ++++++++++++++
 net/bluetooth/hci_event.c        |   18 +++-
 net/bluetooth/l2cap_core.c       |    1 +
 net/bluetooth/mgmt.c             |   60 ++++++++---
 net/bluetooth/smp.c              |  214 ++++++++++++++++++++++++++++++++++----
 10 files changed, 368 insertions(+), 43 deletions(-)
This patches seems to be working fine, tried with pts and some other
stacks without problem, the only inconvenients for testing are the
hardcoded io capabilitity, hardcoded distribution keys (it seems we
distribute only LTK) and not being able to remove keys other than
remove the adapter (didn't try reset).

-- 
Luiz Augusto von Dentz
Computer Engineer

Re: [bluetooth-next 00/13] SMP Key Exchange Support

From: Anderson Lizardo <hidden>
Date: 2011-06-09 13:09:49

Hi Luiz,

On Thu, Jun 9, 2011 at 9:02 AM, Luiz Augusto von Dentz
[off-list ref] wrote:
This patches seems to be working fine, tried with pts and some other
stacks without problem, the only inconvenients for testing are the
hardcoded io capabilitity, hardcoded distribution keys (it seems we
distribute only LTK) and not being able to remove keys other than
remove the adapter (didn't try reset).
About the "not being able to remove keys" part, there is some proposal
(original code is from Johan) to a "mgmt tool" that could be used to
remove keys. Also note that if the remote reports pairing error due to
"missing key or PIN", the bluez side will forget the keys and issue a
fresh pairing.

Not sure what you meant about "hardcoded distribution keys". IIRC I've
seen at least master and identity information distributed as well (but
Vinicius can definitely confirm or deny that).

HTH,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help