All of lore.kernel.org
 help / color / mirror / Atom feed
* [bluetooth-next v3 00/16] SMP Just Works implementation
@ 2011-06-07 21:46 Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 01/16] Bluetooth: Implement the first SMP commands Vinicius Costa Gomes
                   ` (15 more replies)
  0 siblings, 16 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Hi,

Changes from last version:
 - The issues reported by Luiz and Johan are fixed;
 - Changing to the same security level doesn't cause the LTK to be
   requested again;

--
Cheers,

Anderson Briglia (6):
  Bluetooth: Implement the first SMP commands
  Bluetooth: Start SMP procedure
  Bluetooth: Add simple SMP pairing negotiation
  Bluetooth: Add LE SMP Cryptoolbox functions
  Bluetooth: Add SMP confirmation structs
  Bluetooth: Add SMP confirmation checks methods

Vinicius Costa Gomes (10):
  Bluetooth: Add support for using the crypto subsystem
  Bluetooth: Add support for LE Start Encryption
  Bluetooth: Remove debug statements
  Bluetooth: Add support for resuming socket when SMP is finished
  Bluetooth: Fix initial security level of LE links
  Bluetooth: Update the security level when link is encrypted
  Bluetooth: Add support for building pairing commands
  Bluetooth: Add support for Pairing features exchange
  Bluetooth: Add support for SMP timeout
  Bluetooth: Add key size checks for SMP

 include/net/bluetooth/hci.h      |   34 +++
 include/net/bluetooth/hci_core.h |   10 +
 include/net/bluetooth/l2cap.h    |    9 +
 include/net/bluetooth/smp.h      |   46 ++++
 net/bluetooth/Kconfig            |    8 +
 net/bluetooth/Makefile           |    2 +-
 net/bluetooth/hci_conn.c         |   47 ++++
 net/bluetooth/hci_core.c         |   22 ++
 net/bluetooth/hci_event.c        |   69 +++++
 net/bluetooth/l2cap_core.c       |  141 ++++++-----
 net/bluetooth/l2cap_sock.c       |   16 ++
 net/bluetooth/smp.c              |  525 ++++++++++++++++++++++++++++++++++++++
 12 files changed, 869 insertions(+), 60 deletions(-)
 create mode 100644 net/bluetooth/smp.c

--
1.7.5.4


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 01/16] Bluetooth: Implement the first SMP commands
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 02/16] Bluetooth: Start SMP procedure Vinicius Costa Gomes
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes

From: Anderson Briglia <anderson.briglia@openbossa.org>

These simple commands will allow the SMP procedure to be started
and terminated with a not supported error. This is the first step
toward something useful.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/smp.h |   26 ++++++++
 net/bluetooth/Makefile      |    2 +-
 net/bluetooth/smp.c         |  146 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 173 insertions(+), 1 deletions(-)
 create mode 100644 net/bluetooth/smp.c

diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 8f2edbf..36bdd6e 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -1,3 +1,25 @@
+/*
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   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
+   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
+   SOFTWARE IS DISCLAIMED.
+*/
+
 #ifndef __SMP_H
 #define __SMP_H
 
@@ -73,4 +95,8 @@ struct smp_cmd_security_req {
 #define SMP_UNSPECIFIED		0x08
 #define SMP_REPEATED_ATTEMPTS		0x09
 
+/* 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);
+
 #endif /* __SMP_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index f04fe9a..9b67f3d 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -9,5 +9,5 @@ obj-$(CONFIG_BT_CMTP)	+= cmtp/
 obj-$(CONFIG_BT_HIDP)	+= hidp/
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
-bluetooth-$(CONFIG_BT_L2CAP)	+= l2cap_core.o l2cap_sock.o
+bluetooth-$(CONFIG_BT_L2CAP)	+= l2cap_core.o l2cap_sock.o smp.o
 bluetooth-$(CONFIG_BT_SCO)	+= sco.o
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
new file mode 100644
index 0000000..aa0434f
--- /dev/null
+++ b/net/bluetooth/smp.c
@@ -0,0 +1,146 @@
+/*
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   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
+   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
+   SOFTWARE IS DISCLAIMED.
+*/
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
+
+static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
+						u16 dlen, void *data)
+{
+	struct sk_buff *skb;
+	struct l2cap_hdr *lh;
+	int len;
+
+	len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
+
+	if (len > conn->mtu)
+		return NULL;
+
+	skb = bt_skb_alloc(len, GFP_ATOMIC);
+	if (!skb)
+		return NULL;
+
+	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = cpu_to_le16(sizeof(code) + dlen);
+	lh->cid = cpu_to_le16(L2CAP_CID_SMP);
+
+	memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
+
+	memcpy(skb_put(skb, dlen), data, dlen);
+
+	return skb;
+}
+
+static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
+{
+	struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
+
+	BT_DBG("code 0x%2.2x", code);
+
+	if (!skb)
+		return;
+
+	hci_send_acl(conn->hcon, skb, 0);
+}
+
+int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
+{
+	__u8 authreq;
+
+	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
+
+	switch (sec_level) {
+	case BT_SECURITY_MEDIUM:
+		/* Encrypted, no MITM protection */
+		authreq = HCI_AT_NO_BONDING_MITM;
+		break;
+
+	case BT_SECURITY_HIGH:
+		/* Bonding, MITM protection */
+		authreq = HCI_AT_GENERAL_BONDING_MITM;
+		break;
+
+	case BT_SECURITY_LOW:
+	default:
+		return 1;
+	}
+
+	if (conn->hcon->link_mode & HCI_LM_MASTER) {
+		struct smp_cmd_pairing cp;
+		cp.io_capability = 0x00;
+		cp.oob_flag = 0x00;
+		cp.max_key_size = 16;
+		cp.init_key_dist = 0x00;
+		cp.resp_key_dist = 0x00;
+		cp.auth_req = authreq;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+	} else {
+		struct smp_cmd_security_req cp;
+		cp.auth_req = authreq;
+		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
+	}
+
+	return 0;
+}
+
+int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	__u8 code = skb->data[0];
+	__u8 reason;
+	int err = 0;
+
+	skb_pull(skb, sizeof(code));
+
+	switch (code) {
+	case SMP_CMD_PAIRING_REQ:
+		reason = SMP_PAIRING_NOTSUPP;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+		err = -EOPNOTSUPP;
+		break;
+
+	case SMP_CMD_PAIRING_FAIL:
+		break;
+
+	case SMP_CMD_PAIRING_RSP:
+	case SMP_CMD_PAIRING_CONFIRM:
+	case SMP_CMD_PAIRING_RANDOM:
+	case SMP_CMD_ENCRYPT_INFO:
+	case SMP_CMD_MASTER_IDENT:
+	case SMP_CMD_IDENT_INFO:
+	case SMP_CMD_IDENT_ADDR_INFO:
+	case SMP_CMD_SIGN_INFO:
+	case SMP_CMD_SECURITY_REQ:
+	default:
+		BT_DBG("Unknown command code 0x%2.2x", code);
+
+		reason = SMP_CMD_NOTSUPP;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+		err = -EOPNOTSUPP;
+	}
+
+	kfree_skb(skb);
+	return err;
+}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 02/16] Bluetooth: Start SMP procedure
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 01/16] Bluetooth: Implement the first SMP commands Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 03/16] Bluetooth: Add simple SMP pairing negotiation Vinicius Costa Gomes
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes

From: Anderson Briglia <anderson.briglia@openbossa.org>

Start SMP procedure for LE connections. This modification intercepts
l2cap received frames and call proper SMP functions to start the SMP
procedure. By now, no keys are being used.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 net/bluetooth/l2cap_core.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index bb451f3..1dda9f7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -54,6 +54,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
 
 int disable_ertm;
 
@@ -898,6 +899,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 			l2cap_chan_clear_timer(chan);
 			sk->sk_state = BT_CONNECTED;
 			sk->sk_state_change(sk);
+			if (smp_conn_security(conn, chan->sec_level))
+				BT_DBG("Insufficient security");
 		}
 
 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
@@ -4057,6 +4060,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 		l2cap_att_channel(conn, cid, skb);
 		break;
 
+	case L2CAP_CID_SMP:
+		if (smp_sig_channel(conn, skb))
+			l2cap_conn_del(conn->hcon, EACCES);
+		break;
+
 	default:
 		l2cap_data_channel(conn, cid, skb);
 		break;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 03/16] Bluetooth: Add simple SMP pairing negotiation
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 01/16] Bluetooth: Implement the first SMP commands Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 02/16] Bluetooth: Start SMP procedure Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 04/16] Bluetooth: Add support for using the crypto subsystem Vinicius Costa Gomes
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes

From: Anderson Briglia <anderson.briglia@openbossa.org>

This implementation only exchanges SMP messages between the Host and the
Remote. No keys are being generated. TK and STK generation will be
provided in further patches.

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

diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 36bdd6e..111853a 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -38,6 +38,23 @@ struct smp_cmd_pairing {
 	__u8	resp_key_dist;
 } __packed;
 
+#define SMP_IO_DISPLAY_ONLY	0x00
+#define SMP_IO_DISPLAY_YESNO	0x01
+#define SMP_IO_KEYBOARD_ONLY	0x02
+#define SMP_IO_NO_INPUT_OUTPUT	0x03
+#define SMP_IO_KEYBOARD_DISPLAY	0x04
+
+#define SMP_OOB_NOT_PRESENT	0x00
+#define SMP_OOB_PRESENT		0x01
+
+#define SMP_DIST_ENC_KEY	0x01
+#define SMP_DIST_ID_KEY		0x02
+#define SMP_DIST_SIGN		0x04
+
+#define SMP_AUTH_NONE		0x00
+#define SMP_AUTH_BONDING	0x01
+#define SMP_AUTH_MITM		0x04
+
 #define SMP_CMD_PAIRING_CONFIRM	0x03
 struct smp_cmd_pairing_confirm {
 	__u8	confirm_val[16];
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index aa0434f..2240e96 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -64,6 +64,94 @@ 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)
+{
+	struct smp_cmd_pairing *rp = (void *) skb->data;
+
+	BT_DBG("conn %p", conn);
+
+	skb_pull(skb, sizeof(*rp));
+
+	rp->io_capability = 0x00;
+	rp->oob_flag = 0x00;
+	rp->max_key_size = 16;
+	rp->init_key_dist = 0x00;
+	rp->resp_key_dist = 0x00;
+	rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
+
+	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+}
+
+static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_pairing_confirm cp;
+
+	BT_DBG("conn %p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
+}
+
+static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
+							struct sk_buff *skb)
+{
+	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
+
+	if (conn->hcon->out) {
+		struct smp_cmd_pairing_random random;
+
+		memset(&random, 0, sizeof(random));
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
+								&random);
+	} else {
+		struct smp_cmd_pairing_confirm confirm;
+
+		memset(&confirm, 0, sizeof(confirm));
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
+								&confirm);
+	}
+}
+
+static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_pairing_random cp;
+
+	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
+
+	skb_pull(skb, sizeof(cp));
+
+	if (conn->hcon->out) {
+		/* FIXME: start encryption */
+	} else {
+		memset(&cp, 0, sizeof(cp));
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
+	}
+}
+
+static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_security_req *rp = (void *) skb->data;
+	struct smp_cmd_pairing cp;
+
+	BT_DBG("conn %p", conn);
+
+	skb_pull(skb, sizeof(*rp));
+	memset(&cp, 0, sizeof(cp));
+
+	cp.io_capability = 0x00;
+	cp.oob_flag = 0x00;
+	cp.max_key_size = 16;
+	cp.init_key_dist = 0x00;
+	cp.resp_key_dist = 0x00;
+	cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM);
+
+	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+}
+
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 {
 	__u8 authreq;
@@ -114,24 +202,33 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	switch (code) {
 	case SMP_CMD_PAIRING_REQ:
-		reason = SMP_PAIRING_NOTSUPP;
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
-								&reason);
-		err = -EOPNOTSUPP;
+		smp_cmd_pairing_req(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_FAIL:
 		break;
 
 	case SMP_CMD_PAIRING_RSP:
+		smp_cmd_pairing_rsp(conn, skb);
+		break;
+
+	case SMP_CMD_SECURITY_REQ:
+		smp_cmd_security_req(conn, skb);
+		break;
+
 	case SMP_CMD_PAIRING_CONFIRM:
+		smp_cmd_pairing_confirm(conn, skb);
+		break;
+
 	case SMP_CMD_PAIRING_RANDOM:
+		smp_cmd_pairing_random(conn, skb);
+		break;
+
 	case SMP_CMD_ENCRYPT_INFO:
 	case SMP_CMD_MASTER_IDENT:
 	case SMP_CMD_IDENT_INFO:
 	case SMP_CMD_IDENT_ADDR_INFO:
 	case SMP_CMD_SIGN_INFO:
-	case SMP_CMD_SECURITY_REQ:
 	default:
 		BT_DBG("Unknown command code 0x%2.2x", code);
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 04/16] Bluetooth: Add support for using the crypto subsystem
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (2 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 03/16] Bluetooth: Add simple SMP pairing negotiation Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 05/16] Bluetooth: Add LE SMP Cryptoolbox functions Vinicius Costa Gomes
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes, Anderson Briglia

This will allow using the crypto subsystem for encrypting data. As SMP
(Security Manager Protocol) is implemented almost entirely on the host
side and the crypto module already implements the needed methods
(AES-128), it makes sense to use it.

There's now a new module option to enable/disable SMP support.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/Kconfig            |    8 ++++++++
 net/bluetooth/hci_core.c         |   22 ++++++++++++++++++++++
 net/bluetooth/smp.c              |   22 ++++++++++++++++++----
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 818eadb..b749508 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -177,6 +177,8 @@ struct hci_dev {
 
 	__u16			init_last_cmd;
 
+	struct crypto_blkcipher	*tfm;
+
 	struct inquiry_cache	inq_cache;
 	struct hci_conn_hash	conn_hash;
 	struct list_head	blacklist;
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 6ae5ec5..f495dea 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -22,6 +22,7 @@ menuconfig BT
 	     BNEP Module (Bluetooth Network Encapsulation Protocol)
 	     CMTP Module (CAPI Message Transport Protocol)
 	     HIDP Module (Human Interface Device Protocol)
+	     SMP Module (Security Manager Protocol)
 
 	  Say Y here to compile Bluetooth support into the kernel or say M to
 	  compile it as module (bluetooth).
@@ -36,11 +37,18 @@ if BT != n
 config BT_L2CAP
 	bool "L2CAP protocol support"
 	select CRC16
+	select CRYPTO
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_AES
+	select CRYPTO_ECB
 	help
 	  L2CAP (Logical Link Control and Adaptation Protocol) provides
 	  connection oriented and connection-less data transport.  L2CAP
 	  support is required for most Bluetooth applications.
 
+	  Also included is support for SMP (Security Manager Protocol) which
+	  is the security layer on top of LE (Low Energy) links.
+
 config BT_SCO
 	bool "SCO links support"
 	help
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e14e8a1..f62ca19 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -42,6 +42,7 @@
 #include <linux/notifier.h>
 #include <linux/rfkill.h>
 #include <linux/timer.h>
+#include <linux/crypto.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -59,6 +60,8 @@ static void hci_tx_task(unsigned long arg);
 
 static DEFINE_RWLOCK(hci_task_lock);
 
+static int enable_smp;
+
 /* HCI device list */
 LIST_HEAD(hci_dev_list);
 DEFINE_RWLOCK(hci_dev_list_lock);
@@ -1274,6 +1277,14 @@ int hci_add_adv_entry(struct hci_dev *hdev,
 	return 0;
 }
 
+static struct crypto_blkcipher *alloc_cypher(void)
+{
+	if (enable_smp)
+		return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+
+	return ERR_PTR(-ENOTSUPP);
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
@@ -1358,6 +1369,11 @@ int hci_register_dev(struct hci_dev *hdev)
 	if (!hdev->workqueue)
 		goto nomem;
 
+	hdev->tfm = alloc_cypher();
+	if (IS_ERR(hdev->tfm))
+		BT_INFO("Failed to load transform for ecb(aes): %ld",
+							PTR_ERR(hdev->tfm));
+
 	hci_register_sysfs(hdev);
 
 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -1406,6 +1422,9 @@ int hci_unregister_dev(struct hci_dev *hdev)
 					!test_bit(HCI_SETUP, &hdev->flags))
 		mgmt_index_removed(hdev->id);
 
+	if (!IS_ERR(hdev->tfm))
+		crypto_free_blkcipher(hdev->tfm);
+
 	hci_notify(hdev, HCI_DEV_UNREG);
 
 	if (hdev->rfkill) {
@@ -2242,3 +2261,6 @@ static void hci_cmd_task(unsigned long arg)
 		}
 	}
 }
+
+module_param(enable_smp, bool, 0644);
+MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)");
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 2240e96..aa20bee 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -154,9 +154,13 @@ 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(hcon->hdev->tfm))
+		return 1;
 
 	switch (sec_level) {
 	case BT_SECURITY_MEDIUM:
@@ -174,7 +178,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) {
 		struct smp_cmd_pairing cp;
 		cp.io_capability = 0x00;
 		cp.oob_flag = 0x00;
@@ -198,6 +202,12 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 	__u8 reason;
 	int err = 0;
 
+	if (IS_ERR(conn->hcon->hdev->tfm)) {
+		err = PTR_ERR(conn->hcon->hdev->tfm);
+		reason = SMP_PAIRING_NOTSUPP;
+		goto done;
+	}
+
 	skb_pull(skb, sizeof(code));
 
 	switch (code) {
@@ -233,11 +243,15 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 		BT_DBG("Unknown command code 0x%2.2x", code);
 
 		reason = SMP_CMD_NOTSUPP;
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
-								&reason);
 		err = -EOPNOTSUPP;
+		goto done;
 	}
 
+done:
+	if (reason)
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+
 	kfree_skb(skb);
 	return err;
 }
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 05/16] Bluetooth: Add LE SMP Cryptoolbox functions
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (3 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 04/16] Bluetooth: Add support for using the crypto subsystem Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs Vinicius Costa Gomes
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: Anderson Briglia, Anderson Lizardo, Bruna Moreira, Vinicius Costa Gomes

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 |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index aa20bee..57fc7d0 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -24,6 +24,123 @@
 #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];
+	int err;
+
+	memset(p1, 0, 16);
+
+	/* p1 = pres || preq || _rat || _iat */
+	swap56(pres, p1);
+	swap56(preq, p1 + 7);
+	p1[14] = _rat;
+	p1[15] = _iat;
+
+	memset(p2, 0, 16);
+
+	/* p2 = padding || ia || ra */
+	baswap((bdaddr_t *) (p2 + 4), ia);
+	baswap((bdaddr_t *) (p2 + 10), ra);
+
+	/* 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)
+{
+	get_random_bytes(buf, 16);
+
+	return 0;
+}
 
 static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
 						u16 dlen, void *data)
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (4 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 05/16] Bluetooth: Add LE SMP Cryptoolbox functions Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-08 18:46   ` Gustavo F. Padovan
  2011-06-07 21:46 ` [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods Vinicius Costa Gomes
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes

From: Anderson Briglia <anderson.briglia@openbossa.org>

This patch adds initial support for verifying the confirmation value
that the remote side has sent.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    5 +++++
 net/bluetooth/smp.c           |   17 +++++++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 0529d27..36f5b0d 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -379,6 +379,11 @@ struct l2cap_conn {
 
 	__u8		disc_reason;
 
+	__u8		preq[7]; /* SMP Pairing Request */
+	__u8		prsp[7]; /* SMP Pairing Response */
+	__u8		prnd[16]; /* SMP Pairing Random */
+	__u8		pcnf[16]; /* SMP Pairing Confirm */
+
 	struct list_head chan_l;
 	rwlock_t	chan_lock;
 };
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 57fc7d0..fa22f4a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -187,6 +187,8 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("conn %p", conn);
 
+	conn->preq[0] = SMP_CMD_PAIRING_REQ;
+	memcpy(&conn->preq[1], rp, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
 	rp->io_capability = 0x00;
@@ -196,17 +198,25 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	rp->resp_key_dist = 0x00;
 	rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
 
+	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
+	memcpy(&conn->prsp[1], rp, sizeof(*rp));
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
 }
 
 static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
+	struct smp_cmd_pairing *rp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
 
 	BT_DBG("conn %p", conn);
 
 	memset(&cp, 0, sizeof(cp));
 
+	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
+	memcpy(&conn->prsp[1], rp, sizeof(*rp));
+	skb_pull(skb, sizeof(*rp));
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 }
 
@@ -266,6 +276,9 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	cp.resp_key_dist = 0x00;
 	cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM);
 
+	conn->preq[0] = SMP_CMD_PAIRING_REQ;
+	memcpy(&conn->preq[1], &cp, sizeof(cp));
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 }
 
@@ -303,6 +316,10 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		cp.init_key_dist = 0x00;
 		cp.resp_key_dist = 0x00;
 		cp.auth_req = authreq;
+
+		conn->preq[0] = SMP_CMD_PAIRING_REQ;
+		memcpy(&conn->preq[1], &cp, sizeof(cp));
+
 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 	} else {
 		struct smp_cmd_security_req cp;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (5 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-08  2:26   ` Johan Hedberg
  2011-06-07 21:46 ` [bluetooth-next v3 08/16] Bluetooth: Add support for LE Start Encryption Vinicius Costa Gomes
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes

From: Anderson Briglia <anderson.briglia@openbossa.org>

This patch includes support for generating and sending the random value
used to produce the confirmation value.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    1 +
 net/bluetooth/smp.c           |   94 ++++++++++++++++++++++++++++++++++------
 2 files changed, 81 insertions(+), 14 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 36f5b0d..12f6c19 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -383,6 +383,7 @@ struct l2cap_conn {
 	__u8		prsp[7]; /* SMP Pairing Response */
 	__u8		prnd[16]; /* SMP Pairing Random */
 	__u8		pcnf[16]; /* SMP Pairing Confirm */
+	__u8		tk[16]; /* SMP Temporary Key */
 
 	struct list_head chan_l;
 	rwlock_t	chan_lock;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index fa22f4a..dfb9b63 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -198,6 +198,9 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	rp->resp_key_dist = 0x00;
 	rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
 
+	/* Just works */
+	memset(conn->tk, 0, sizeof(conn->tk));
+
 	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&conn->prsp[1], rp, sizeof(*rp));
 
@@ -208,54 +211,117 @@ static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
+	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+	int ret;
+	u8 res[16];
 
 	BT_DBG("conn %p", conn);
 
-	memset(&cp, 0, sizeof(cp));
+	/* Just works */
+	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&conn->prsp[1], rp, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
+	ret = smp_rand(conn->prnd);
+	if (ret)
+		return;
+
+	ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
+			conn->src, 0, conn->dst, res);
+	if (ret)
+		return;
+
+	swap128(res, cp.confirm_val);
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 }
 
 static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
 							struct sk_buff *skb)
 {
+	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
-	if (conn->hcon->out) {
-		struct smp_cmd_pairing_random random;
+	memcpy(conn->pcnf, skb->data, sizeof(conn->pcnf));
+	skb_pull(skb, sizeof(conn->pcnf));
 
-		memset(&random, 0, sizeof(random));
+	if (conn->hcon->out) {
+		u8 random[16];
 
+		swap128(conn->prnd, random);
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
-								&random);
+								random);
 	} else {
-		struct smp_cmd_pairing_confirm confirm;
+		struct smp_cmd_pairing_confirm cp;
+		int ret;
+		u8 res[16];
 
-		memset(&confirm, 0, sizeof(confirm));
+		ret = smp_rand(conn->prnd);
+		if (ret)
+			return;
 
-		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
-								&confirm);
+		ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
+					0, conn->dst, 0, conn->src, res);
+		if (ret)
+			return;
+
+		swap128(res, cp.confirm_val);
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 	}
 }
 
 static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing_random cp;
+	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+	int ret;
+	u8 key[16], res[16], random[16], confirm[16], buf[128];
+
+	swap128(skb->data, random);
+	skb_pull(skb, sizeof(random));
+
+	if (conn->hcon->out)
+		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
+				conn->src, 0, conn->dst, res);
+	else
+		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
+				conn->dst, 0, conn->src, res);
+	if (ret)
+		return;
 
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
-	skb_pull(skb, sizeof(cp));
+	swap128(res, confirm);
+
+	if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
+		struct smp_cmd_pairing_fail cp;
+
+		BT_ERR("Pairing failed (confirmation values mismatch)");
+		cp.reason = SMP_CONFIRM_FAILED;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
+		return;
+	}
 
 	if (conn->hcon->out) {
-		/* FIXME: start encryption */
+		smp_s1(tfm, conn->tk, random, conn->prnd, key);
+
+		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
+							sizeof(buf), 0);
+		BT_DBG("key %s", buf);
 	} else {
-		memset(&cp, 0, sizeof(cp));
+		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);
 
-		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
+		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
+							sizeof(buf), 0);
+		BT_DBG("key %s", buf);
 	}
 }
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 08/16] Bluetooth: Add support for LE Start Encryption
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (6 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 09/16] Bluetooth: Remove debug statements Vinicius Costa Gomes
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

This adds support for starting SMP Phase 2 Encryption, when the initial
SMP negotiation is successful. This adds the LE Start Encryption and LE
Long Term Key Request commands and related events.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/hci.h      |   34 +++++++++++++++++++
 include/net/bluetooth/hci_core.h |    5 +++
 net/bluetooth/hci_conn.c         |   46 ++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   67 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/smp.c              |    9 ++++-
 5 files changed, 160 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index bd285c6..65345cd 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -745,6 +745,33 @@ struct hci_cp_le_conn_update {
 	__le16   max_ce_len;
 } __packed;
 
+#define HCI_OP_LE_START_ENC		0x2019
+struct hci_cp_le_start_enc {
+	__le16	handle;
+	__u8	rand[8];
+	__le16	ediv;
+	__u8	ltk[16];
+} __packed;
+
+#define HCI_OP_LE_LTK_REPLY		0x201a
+struct hci_cp_le_ltk_reply {
+	__le16	handle;
+	__u8	ltk[16];
+} __packed;
+struct hci_rp_le_ltk_reply {
+	__u8	status;
+	__le16	handle;
+} __packed;
+
+#define HCI_OP_LE_LTK_NEG_REPLY		0x201b
+struct hci_cp_le_ltk_neg_reply {
+	__le16	handle;
+} __packed;
+struct hci_rp_le_ltk_neg_reply {
+	__u8	status;
+	__le16	handle;
+} __packed;
+
 /* ---- HCI Events ---- */
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 
@@ -1035,6 +1062,13 @@ struct hci_ev_le_conn_complete {
 	__u8     clk_accurancy;
 } __packed;
 
+#define HCI_EV_LE_LTK_REQ		0x05
+struct hci_ev_le_ltk_req {
+	__le16	handle;
+	__u8	random[8];
+	__le16	ediv;
+} __packed;
+
 /* Advertising report event types */
 #define ADV_IND		0x00
 #define ADV_DIRECT_IND	0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b749508..2f1c91a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -249,6 +249,7 @@ struct hci_conn {
 	__u8		power_save;
 	__u16		disc_timeout;
 	unsigned long	pend;
+	__u8		ltk[16];
 
 	__u8		remote_cap;
 	__u8		remote_oob;
@@ -849,4 +850,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_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
+void hci_le_ltk_neg_reply(struct hci_conn *conn);
+
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 37f5a17..101160c 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -204,6 +204,52 @@ 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])
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_le_start_enc cp;
+
+	BT_DBG("%p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle = cpu_to_le16(conn->handle);
+	memcpy(cp.ltk, ltk, sizeof(cp.ltk));
+
+	hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_start_enc);
+
+void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16])
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_le_ltk_reply cp;
+
+	BT_DBG("%p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle = cpu_to_le16(conn->handle);
+	memcpy(cp.ltk, ltk, sizeof(ltk));
+
+	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_ltk_reply);
+
+void hci_le_ltk_neg_reply(struct hci_conn *conn)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_le_ltk_neg_reply cp;
+
+	BT_DBG("%p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle = cpu_to_le16(conn->handle);
+
+	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(cp), &cp);
+}
+
 /* Device _must_ be locked */
 void hci_sco_setup(struct hci_conn *conn, __u8 status)
 {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0f643f8..166fa11 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -868,6 +868,30 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
+static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
+}
+
+static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1248,6 +1272,11 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
 	hci_dev_unlock(hdev);
 }
 
+static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
+{
+	BT_DBG("%s status 0x%x", hdev->name, status);
+}
+
 static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
@@ -1856,6 +1885,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_le_set_scan_enable(hdev, skb);
 		break;
 
+	case HCI_OP_LE_LTK_REPLY:
+		hci_cc_le_ltk_reply(hdev, skb);
+		break;
+
+	case HCI_OP_LE_LTK_NEG_REPLY:
+		hci_cc_le_ltk_neg_reply(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
@@ -1934,6 +1971,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cs_le_create_conn(hdev, ev->status);
 		break;
 
+	case HCI_OP_LE_START_ENC:
+		hci_cs_le_start_enc(hdev, ev->status);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
@@ -2745,6 +2786,28 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
+						struct sk_buff *skb)
+{
+	struct hci_ev_le_ltk_req *ev = (void *) skb->data;
+	struct hci_cp_le_ltk_reply cp;
+	struct hci_conn *conn;
+
+	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));
+
+	memset(&cp, 0, sizeof(cp));
+	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);
+}
+
 static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
@@ -2760,6 +2823,10 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_adv_report_evt(hdev, skb);
 		break;
 
+	case HCI_EV_LE_LTK_REQ:
+		hci_le_ltk_request_evt(hdev, skb);
+		break;
+
 	default:
 		break;
 	}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index dfb9b63..22c362b 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -276,13 +276,16 @@ static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
 
 static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+	struct hci_conn *hcon = conn->hcon;
+	struct crypto_blkcipher *tfm = hcon->hdev->tfm;
 	int ret;
 	u8 key[16], res[16], random[16], confirm[16], buf[128];
 
 	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);
@@ -307,6 +310,9 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	if (conn->hcon->out) {
 		smp_s1(tfm, conn->tk, random, conn->prnd, key);
+		swap128(key, hcon->ltk);
+
+		hci_le_start_enc(hcon, hcon->ltk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
 							sizeof(buf), 0);
@@ -318,6 +324,7 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
 
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
+		swap128(key, hcon->ltk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
 							sizeof(buf), 0);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 09/16] Bluetooth: Remove debug statements
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (7 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 08/16] Bluetooth: Add support for LE Start Encryption Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 10/16] Bluetooth: Add support for resuming socket when SMP is finished Vinicius Costa Gomes
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Now that these commands are sent to the controller we can use hcidump
to verify that the correct values are produced.

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

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 22c362b..c1c4bc0 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -279,7 +279,7 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	struct hci_conn *hcon = conn->hcon;
 	struct crypto_blkcipher *tfm = hcon->hdev->tfm;
 	int ret;
-	u8 key[16], res[16], random[16], confirm[16], buf[128];
+	u8 key[16], res[16], random[16], confirm[16];
 
 	swap128(skb->data, random);
 	skb_pull(skb, sizeof(random));
@@ -313,10 +313,6 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		swap128(key, hcon->ltk);
 
 		hci_le_start_enc(hcon, hcon->ltk);
-
-		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
-							sizeof(buf), 0);
-		BT_DBG("key %s", buf);
 	} else {
 		u8 r[16];
 
@@ -325,10 +321,6 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
 		swap128(key, hcon->ltk);
-
-		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf,
-							sizeof(buf), 0);
-		BT_DBG("key %s", buf);
 	}
 }
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 10/16] Bluetooth: Add support for resuming socket when SMP is finished
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (8 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 09/16] Bluetooth: Remove debug statements Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 11/16] Bluetooth: Fix initial security level of LE links Vinicius Costa Gomes
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

This adds support for resuming the user space traffic when SMP
negotiation is complete.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/l2cap_core.c |   61 ++++++++++++++++++++++---------------------
 net/bluetooth/l2cap_sock.c |   16 +++++++++++
 net/bluetooth/smp.c        |   40 ++++++++++++++++++++--------
 3 files changed, 75 insertions(+), 42 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 1dda9f7..d6cf2ac 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -879,6 +879,23 @@ clean:
 	bh_unlock_sock(parent);
 }
 
+static void l2cap_chan_ready(struct sock *sk)
+{
+	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+	struct sock *parent = bt_sk(sk)->parent;
+
+	BT_DBG("sk %p, parent %p", sk, parent);
+
+	chan->conf_state = 0;
+	l2cap_chan_clear_timer(chan);
+
+	sk->sk_state = BT_CONNECTED;
+	sk->sk_state_change(sk);
+
+	if (parent)
+		parent->sk_data_ready(parent, 0);
+}
+
 static void l2cap_conn_ready(struct l2cap_conn *conn)
 {
 	struct l2cap_chan *chan;
@@ -895,13 +912,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 
 		bh_lock_sock(sk);
 
-		if (conn->hcon->type == LE_LINK) {
-			l2cap_chan_clear_timer(chan);
-			sk->sk_state = BT_CONNECTED;
-			sk->sk_state_change(sk);
+		if (conn->hcon->type == LE_LINK)
 			if (smp_conn_security(conn, chan->sec_level))
-				BT_DBG("Insufficient security");
-		}
+				l2cap_chan_ready(sk);
 
 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
 			l2cap_chan_clear_timer(chan);
@@ -1664,30 +1677,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 	return err;
 }
 
-static void l2cap_chan_ready(struct sock *sk)
-{
-	struct sock *parent = bt_sk(sk)->parent;
-	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
-
-	BT_DBG("sk %p, parent %p", sk, parent);
-
-	chan->conf_state = 0;
-	l2cap_chan_clear_timer(chan);
-
-	if (!parent) {
-		/* Outgoing channel.
-		 * Wake up socket sleeping on connect.
-		 */
-		sk->sk_state = BT_CONNECTED;
-		sk->sk_state_change(sk);
-	} else {
-		/* Incoming channel.
-		 * Wake up socket sleeping on accept.
-		 */
-		parent->sk_data_ready(parent, 0);
-	}
-}
-
 /* Copy frame to all raw sockets on that connection */
 static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
 {
@@ -4184,6 +4173,18 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
 		bh_lock_sock(sk);
 
+		BT_DBG("chan->scid %d", chan->scid);
+
+		if (chan->scid == L2CAP_CID_LE_DATA) {
+			if (!status && encrypt) {
+				chan->sec_level = hcon->sec_level;
+				l2cap_chan_ready(sk);
+			}
+
+			bh_unlock_sock(sk);
+			continue;
+		}
+
 		if (chan->conf_state & L2CAP_CONF_CONNECT_PEND) {
 			bh_unlock_sock(sk);
 			continue;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index ab81894..d6cc558 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -29,6 +29,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
 
 static const struct proto_ops l2cap_sock_ops;
 
@@ -556,6 +557,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
 	struct bt_security sec;
 	struct bt_power pwr;
+	struct l2cap_conn *conn;
 	int len, err = 0;
 	u32 opt;
 
@@ -592,6 +594,20 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
 		}
 
 		chan->sec_level = sec.level;
+
+		conn = chan->conn;
+		if (conn && chan->scid == L2CAP_CID_LE_DATA) {
+			if (!conn->hcon->out) {
+				err = -EINVAL;
+				break;
+			}
+
+			if (smp_conn_security(conn, sec.level))
+				break;
+
+			err = 0;
+			sk->sk_state = BT_CONFIG;
+		}
 		break;
 
 	case BT_DEFER_SETUP:
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index c1c4bc0..8d0f623 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -328,9 +328,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_security_req *rp = (void *) skb->data;
 	struct smp_cmd_pairing cp;
+	struct hci_conn *hcon = conn->hcon;
 
 	BT_DBG("conn %p", conn);
 
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+		return;
+
 	skb_pull(skb, sizeof(*rp));
 	memset(&cp, 0, sizeof(cp));
 
@@ -345,6 +349,20 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&conn->preq[1], &cp, sizeof(cp));
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+
+	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+}
+
+static __u8 seclevel_to_authreq(__u8 level)
+{
+	switch (level) {
+	case BT_SECURITY_HIGH:
+		/* For now we don't support bonding */
+		return SMP_AUTH_MITM;
+
+	default:
+		return SMP_AUTH_NONE;
+	}
 }
 
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -357,21 +375,16 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 	if (IS_ERR(hcon->hdev->tfm))
 		return 1;
 
-	switch (sec_level) {
-	case BT_SECURITY_MEDIUM:
-		/* Encrypted, no MITM protection */
-		authreq = HCI_AT_NO_BONDING_MITM;
-		break;
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+		return 0;
 
-	case BT_SECURITY_HIGH:
-		/* Bonding, MITM protection */
-		authreq = HCI_AT_GENERAL_BONDING_MITM;
-		break;
+	if (sec_level == BT_SECURITY_LOW)
+		return 1;
 
-	case BT_SECURITY_LOW:
-	default:
+	if (hcon->sec_level >= sec_level)
 		return 1;
-	}
+
+	authreq = seclevel_to_authreq(sec_level);
 
 	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
@@ -392,6 +405,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
 	}
 
+	hcon->pending_sec_level = sec_level;
+	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+
 	return 0;
 }
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 11/16] Bluetooth: Fix initial security level of LE links
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (9 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 10/16] Bluetooth: Add support for resuming socket when SMP is finished Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 12/16] Bluetooth: Update the security level when link is encrypted Vinicius Costa Gomes
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

As the default security level (BT_SECURITY_SDP) doesn't make sense for
LE links, initialize LE links with something that makes sense.

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

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 101160c..b4754a8 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -53,6 +53,7 @@ static void hci_le_connect(struct hci_conn *conn)
 	conn->state = BT_CONNECT;
 	conn->out = 1;
 	conn->link_mode |= HCI_LM_MASTER;
+	conn->sec_level = BT_SECURITY_LOW;
 
 	memset(&cp, 0, sizeof(cp));
 	cp.scan_interval = cpu_to_le16(0x0004);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 166fa11..21d6055 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2753,6 +2753,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
 
 	mgmt_connected(hdev->id, &ev->bdaddr);
 
+	conn->sec_level = BT_SECURITY_LOW;
 	conn->handle = __le16_to_cpu(ev->handle);
 	conn->state = BT_CONNECTED;
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 12/16] Bluetooth: Update the security level when link is encrypted
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (10 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 11/16] Bluetooth: Fix initial security level of LE links Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 13/16] Bluetooth: Add support for building pairing commands Vinicius Costa Gomes
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

If the pending security level is greater than the current security
level and the link is now encrypted, we should update the link
security level.

This is only useful for LE links, when the only event generated
when SMP is sucessful in the Encrypt Change event.

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

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2f1c91a..13e5b48 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -734,6 +734,9 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
 	if (conn->sec_level == BT_SECURITY_SDP)
 		conn->sec_level = BT_SECURITY_LOW;
 
+	if (conn->pending_sec_level > conn->sec_level)
+		conn->sec_level = conn->pending_sec_level;
+
 	hci_proto_encrypt_cfm(conn, status, encrypt);
 
 	read_lock_bh(&hci_cb_list_lock);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 13/16] Bluetooth: Add support for building pairing commands
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (11 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 12/16] Bluetooth: Update the security level when link is encrypted Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 14/16] Bluetooth: Add support for Pairing features exchange Vinicius Costa Gomes
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Before we are able to do a proper exchange of pairing parameters,
we need a unified way of building pairing requests and responses.

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

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 8d0f623..57d7181 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -181,6 +181,17 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 	hci_send_acl(conn->hcon, skb, 0);
 }
 
+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;
+}
+
 static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 14/16] Bluetooth: Add support for Pairing features exchange
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (12 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 13/16] Bluetooth: Add support for building pairing commands Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 15/16] Bluetooth: Add support for SMP timeout Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 16/16] Bluetooth: Add key size checks for SMP Vinicius Costa Gomes
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

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       |  106 ++++++++++++++++++++++----------------------
 2 files changed, 54 insertions(+), 53 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 21d6055..ac2c5e8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1622,6 +1622,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 57d7181..caac3d0 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -181,6 +181,18 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 	hci_send_acl(conn->hcon, skb, 0);
 }
 
+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)
 {
@@ -192,7 +204,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
 	cmd->auth_req = authreq;
 }
 
-static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
 
@@ -202,12 +214,11 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&conn->preq[1], rp, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
-	rp->io_capability = 0x00;
-	rp->oob_flag = 0x00;
-	rp->max_key_size = 16;
-	rp->init_key_dist = 0x00;
-	rp->resp_key_dist = 0x00;
-	rp->auth_req &= (SMP_AUTH_BONDING | SMP_AUTH_MITM);
+	if (rp->oob_flag)
+		return SMP_OOB_NOT_AVAIL;
+
+	/* We didn't start the pairing, so no requirements */
+	build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
 
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
@@ -216,9 +227,11 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&conn->prsp[1], rp, sizeof(*rp));
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+
+	return 0;
 }
 
-static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
@@ -228,29 +241,34 @@ static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("conn %p", conn);
 
+	skb_pull(skb, sizeof(*rp));
+
+	if (rp->oob_flag)
+		return SMP_OOB_NOT_AVAIL;
+
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&conn->prsp[1], rp, sizeof(*rp));
-	skb_pull(skb, sizeof(*rp));
 
 	ret = smp_rand(conn->prnd);
 	if (ret)
-		return;
+		return SMP_UNSPECIFIED;
 
 	ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
 			conn->src, 0, conn->dst, res);
 	if (ret)
-		return;
+		return SMP_UNSPECIFIED;
 
 	swap128(res, cp.confirm_val);
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
+
+	return 0;
 }
 
-static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
-							struct sk_buff *skb)
+static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
 
@@ -272,20 +290,22 @@ static void smp_cmd_pairing_confirm(struct l2cap_conn *conn,
 
 		ret = smp_rand(conn->prnd);
 		if (ret)
-			return;
+			return SMP_UNSPECIFIED;
 
 		ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
 					0, conn->dst, 0, conn->src, res);
 		if (ret)
-			return;
+			return SMP_CONFIRM_FAILED;
 
 		swap128(res, cp.confirm_val);
 
 		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 	}
+
+	return 0;
 }
 
-static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct hci_conn *hcon = conn->hcon;
 	struct crypto_blkcipher *tfm = hcon->hdev->tfm;
@@ -304,19 +324,15 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
 				conn->dst, 0, conn->src, res);
 	if (ret)
-		return;
+		return SMP_UNSPECIFIED;
 
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
 	swap128(res, confirm);
 
 	if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
-		struct smp_cmd_pairing_fail cp;
-
 		BT_ERR("Pairing failed (confirmation values mismatch)");
-		cp.reason = SMP_CONFIRM_FAILED;
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
-		return;
+		return SMP_CONFIRM_FAILED;
 	}
 
 	if (conn->hcon->out) {
@@ -333,9 +349,11 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
 		swap128(key, hcon->ltk);
 	}
+
+	return 0;
 }
 
-static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_security_req *rp = (void *) skb->data;
 	struct smp_cmd_pairing cp;
@@ -344,17 +362,12 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	BT_DBG("conn %p", conn);
 
 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
-		return;
+		return 0;
 
 	skb_pull(skb, sizeof(*rp));
-	memset(&cp, 0, sizeof(cp));
 
-	cp.io_capability = 0x00;
-	cp.oob_flag = 0x00;
-	cp.max_key_size = 16;
-	cp.init_key_dist = 0x00;
-	cp.resp_key_dist = 0x00;
-	cp.auth_req = rp->auth_req & (SMP_AUTH_BONDING | SMP_AUTH_MITM);
+	memset(&cp, 0, sizeof(cp));
+	build_pairing_cmd(conn, &cp, rp->auth_req);
 
 	conn->preq[0] = SMP_CMD_PAIRING_REQ;
 	memcpy(&conn->preq[1], &cp, sizeof(cp));
@@ -362,18 +375,8 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 
 	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
-}
 
-static __u8 seclevel_to_authreq(__u8 level)
-{
-	switch (level) {
-	case BT_SECURITY_HIGH:
-		/* For now we don't support bonding */
-		return SMP_AUTH_MITM;
-
-	default:
-		return SMP_AUTH_NONE;
-	}
+	return 0;
 }
 
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -399,13 +402,8 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 
 	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
-		cp.io_capability = 0x00;
-		cp.oob_flag = 0x00;
-		cp.max_key_size = 16;
-		cp.init_key_dist = 0x00;
-		cp.resp_key_dist = 0x00;
-		cp.auth_req = authreq;
 
+		build_pairing_cmd(conn, &cp, authreq);
 		conn->preq[0] = SMP_CMD_PAIRING_REQ;
 		memcpy(&conn->preq[1], &cp, sizeof(cp));
 
@@ -438,26 +436,28 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	switch (code) {
 	case SMP_CMD_PAIRING_REQ:
-		smp_cmd_pairing_req(conn, skb);
+		reason = smp_cmd_pairing_req(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_FAIL:
+		reason = 0;
+		err = -EPERM;
 		break;
 
 	case SMP_CMD_PAIRING_RSP:
-		smp_cmd_pairing_rsp(conn, skb);
+		reason = smp_cmd_pairing_rsp(conn, skb);
 		break;
 
 	case SMP_CMD_SECURITY_REQ:
-		smp_cmd_security_req(conn, skb);
+		reason = smp_cmd_security_req(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_CONFIRM:
-		smp_cmd_pairing_confirm(conn, skb);
+		reason = smp_cmd_pairing_confirm(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_RANDOM:
-		smp_cmd_pairing_random(conn, skb);
+		reason = smp_cmd_pairing_random(conn, skb);
 		break;
 
 	case SMP_CMD_ENCRYPT_INFO:
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 15/16] Bluetooth: Add support for SMP timeout
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (13 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 14/16] Bluetooth: Add support for Pairing features exchange Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  2011-06-07 21:46 ` [bluetooth-next v3 16/16] Bluetooth: Add key size checks for SMP Vinicius Costa Gomes
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

This patch adds support for disconnecting the link when SMP procedure
takes more than 30 seconds.

SMP begins when either the Pairing Request command is sent or the
Pairing Response is received, and it ends when the link is encrypted
(or terminated). Vol 3, Part H Section 3.4.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    2 +
 net/bluetooth/l2cap_core.c    |   74 ++++++++++++++++++++++++----------------
 net/bluetooth/smp.c           |   14 ++++++++
 3 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 12f6c19..6e160d4 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -385,6 +385,8 @@ struct l2cap_conn {
 	__u8		pcnf[16]; /* SMP Pairing Confirm */
 	__u8		tk[16]; /* SMP Temporary Key */
 
+	struct timer_list security_timer;
+
 	struct list_head chan_l;
 	rwlock_t	chan_lock;
 };
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d6cf2ac..9db461d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -958,6 +958,45 @@ static void l2cap_info_timeout(unsigned long arg)
 	l2cap_conn_start(conn);
 }
 
+static void l2cap_conn_del(struct hci_conn *hcon, int err)
+{
+	struct l2cap_conn *conn = hcon->l2cap_data;
+	struct l2cap_chan *chan, *l;
+	struct sock *sk;
+
+	if (!conn)
+		return;
+
+	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+
+	kfree_skb(conn->rx_skb);
+
+	/* Kill channels */
+	list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+		sk = chan->sk;
+		bh_lock_sock(sk);
+		l2cap_chan_del(chan, err);
+		bh_unlock_sock(sk);
+		l2cap_sock_kill(sk);
+	}
+
+	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
+		del_timer_sync(&conn->info_timer);
+
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+		del_timer(&conn->security_timer);
+
+	hcon->l2cap_data = NULL;
+	kfree(conn);
+}
+
+static void security_timeout(unsigned long arg)
+{
+	struct l2cap_conn *conn = (void *) arg;
+
+	l2cap_conn_del(conn->hcon, ETIMEDOUT);
+}
+
 static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 {
 	struct l2cap_conn *conn = hcon->l2cap_data;
@@ -989,7 +1028,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 
 	INIT_LIST_HEAD(&conn->chan_l);
 
-	if (hcon->type != LE_LINK)
+	if (hcon->type == LE_LINK)
+		setup_timer(&conn->security_timer, security_timeout,
+						(unsigned long) conn);
+	else
 		setup_timer(&conn->info_timer, l2cap_info_timeout,
 						(unsigned long) conn);
 
@@ -998,35 +1040,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 	return conn;
 }
 
-static void l2cap_conn_del(struct hci_conn *hcon, int err)
-{
-	struct l2cap_conn *conn = hcon->l2cap_data;
-	struct l2cap_chan *chan, *l;
-	struct sock *sk;
-
-	if (!conn)
-		return;
-
-	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-
-	kfree_skb(conn->rx_skb);
-
-	/* Kill channels */
-	list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
-		sk = chan->sk;
-		bh_lock_sock(sk);
-		l2cap_chan_del(chan, err);
-		bh_unlock_sock(sk);
-		l2cap_sock_kill(sk);
-	}
-
-	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
-		del_timer_sync(&conn->info_timer);
-
-	hcon->l2cap_data = NULL;
-	kfree(conn);
-}
-
 static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 {
 	write_lock_bh(&conn->chan_lock);
@@ -4178,6 +4191,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 		if (chan->scid == L2CAP_CID_LE_DATA) {
 			if (!status && encrypt) {
 				chan->sec_level = hcon->sec_level;
+				del_timer(&conn->security_timer);
 				l2cap_chan_ready(sk);
 			}
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index caac3d0..91f9d3a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -27,6 +27,8 @@
 #include <linux/crypto.h>
 #include <crypto/b128ops.h>
 
+#define SMP_TIMEOUT 30000 /* 30 seconds */
+
 static inline void swap128(u8 src[16], u8 dst[16])
 {
 	int i;
@@ -228,6 +230,9 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
 
+	mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 	return 0;
 }
 
@@ -302,6 +307,9 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 	}
 
+	mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 	return 0;
 }
 
@@ -374,6 +382,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 
+	mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
 
 	return 0;
@@ -407,6 +418,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		conn->preq[0] = SMP_CMD_PAIRING_REQ;
 		memcpy(&conn->preq[1], &cp, sizeof(cp));
 
+		mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 	} else {
 		struct smp_cmd_security_req cp;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [bluetooth-next v3 16/16] Bluetooth: Add key size checks for SMP
  2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
                   ` (14 preceding siblings ...)
  2011-06-07 21:46 ` [bluetooth-next v3 15/16] Bluetooth: Add support for SMP timeout Vinicius Costa Gomes
@ 2011-06-07 21:46 ` Vinicius Costa Gomes
  15 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-07 21:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes, Anderson Briglia

This patch implements a check in smp cmd pairing request and pairing
response to verify if encryption key maximum size is compatible in both
slave and master when SMP Pairing is requested. Keys are also masked to
the correct negotiated size.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    1 +
 include/net/bluetooth/smp.h   |    3 ++
 net/bluetooth/smp.c           |   54 +++++++++++++++++++++++++++++++----------
 3 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6e160d4..5ac334b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -384,6 +384,7 @@ struct l2cap_conn {
 	__u8		prnd[16]; /* SMP Pairing Random */
 	__u8		pcnf[16]; /* SMP Pairing Confirm */
 	__u8		tk[16]; /* SMP Temporary Key */
+	__u8		smp_key_size;
 
 	struct timer_list security_timer;
 
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 111853a..4fb7d19 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -112,6 +112,9 @@ struct smp_cmd_security_req {
 #define SMP_UNSPECIFIED		0x08
 #define SMP_REPEATED_ATTEMPTS		0x09
 
+#define SMP_MIN_ENC_KEY_SIZE		7
+#define SMP_MAX_ENC_KEY_SIZE		16
+
 /* 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);
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 91f9d3a..3822159 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -200,35 +200,51 @@ 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 = 16;
+	cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
 	cmd->init_key_dist = 0x00;
 	cmd->resp_key_dist = 0x00;
 	cmd->auth_req = authreq;
 }
 
+static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
+{
+	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
+			(max_key_size < SMP_MIN_ENC_KEY_SIZE))
+		return SMP_ENC_KEY_SIZE;
+
+	conn->smp_key_size = max_key_size;
+
+	return 0;
+}
+
 static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing *rp = (void *) skb->data;
+	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
+	u8 key_size;
 
 	BT_DBG("conn %p", conn);
 
 	conn->preq[0] = SMP_CMD_PAIRING_REQ;
-	memcpy(&conn->preq[1], rp, sizeof(*rp));
-	skb_pull(skb, sizeof(*rp));
+	memcpy(&conn->preq[1], req, sizeof(*req));
+	skb_pull(skb, sizeof(*req));
 
-	if (rp->oob_flag)
+	if (req->oob_flag)
 		return SMP_OOB_NOT_AVAIL;
 
 	/* We didn't start the pairing, so no requirements */
-	build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
+	build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE);
+
+	key_size = min(req->max_key_size, rsp.max_key_size);
+	if (check_enc_key_size(conn, key_size))
+		return SMP_ENC_KEY_SIZE;
 
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
-	memcpy(&conn->prsp[1], rp, sizeof(*rp));
+	memcpy(&conn->prsp[1], &rsp, sizeof(rsp));
 
-	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
 
 	mod_timer(&conn->security_timer, jiffies +
 					msecs_to_jiffies(SMP_TIMEOUT));
@@ -238,24 +254,30 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing *rp = (void *) skb->data;
+	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
 	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
 	int ret;
-	u8 res[16];
+	u8 res[16], key_size;
 
 	BT_DBG("conn %p", conn);
 
-	skb_pull(skb, sizeof(*rp));
+	skb_pull(skb, sizeof(*rsp));
+
+	req = (void *) &conn->preq[1];
 
-	if (rp->oob_flag)
+	key_size = min(req->max_key_size, rsp->max_key_size);
+	if (check_enc_key_size(conn, key_size))
+		return SMP_ENC_KEY_SIZE;
+
+	if (rsp->oob_flag)
 		return SMP_OOB_NOT_AVAIL;
 
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->prsp[0] = SMP_CMD_PAIRING_RSP;
-	memcpy(&conn->prsp[1], rp, sizeof(*rp));
+	memcpy(&conn->prsp[1], rsp, sizeof(*rsp));
 
 	ret = smp_rand(conn->prnd);
 	if (ret)
@@ -347,6 +369,9 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		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);
 	} else {
 		u8 r[16];
@@ -356,6 +381,9 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
 		swap128(key, hcon->ltk);
+
+		memset(hcon->ltk + conn->smp_key_size, 0,
+				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
 	}
 
 	return 0;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods
  2011-06-07 21:46 ` [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods Vinicius Costa Gomes
@ 2011-06-08  2:26   ` Johan Hedberg
  2011-06-08  4:16     ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 22+ messages in thread
From: Johan Hedberg @ 2011-06-08  2:26 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Anderson Briglia

Hi Vinicius/Anderson,

On Tue, Jun 07, 2011, Vinicius Costa Gomes wrote:
> +	ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
> +			conn->src, 0, conn->dst, res);

The third last parameter is the remote address type and you're
hard-coding it to 0 (public) here. This means that we cannot pair with a
device with a random address. I suppose you should be passing
conn->hcon->dst_type instead.

> +		ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
> +					0, conn->dst, 0, conn->src, res);

Same here.

> +	if (conn->hcon->out)
> +		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
> +				conn->src, 0, conn->dst, res);
> +	else
> +		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
> +				conn->dst, 0, conn->src, res);

And here.

You're also hard-coding the local address type to public, but that's a
less severe issue (for now).

Johan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods
  2011-06-08  2:26   ` Johan Hedberg
@ 2011-06-08  4:16     ` Luiz Augusto von Dentz
  2011-06-08 14:38       ` Vinicius Costa Gomes
  0 siblings, 1 reply; 22+ messages in thread
From: Luiz Augusto von Dentz @ 2011-06-08  4:16 UTC (permalink / raw)
  To: Vinicius Costa Gomes, linux-bluetooth, Anderson Briglia

Hi Vinicius,

On Wed, Jun 8, 2011 at 11:26 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Vinicius/Anderson,
>
> On Tue, Jun 07, 2011, Vinicius Costa Gomes wrote:
>> +     ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
>> +                     conn->src, 0, conn->dst, res);
>
> The third last parameter is the remote address type and you're
> hard-coding it to 0 (public) here. This means that we cannot pair with a
> device with a random address. I suppose you should be passing
> conn->hcon->dst_type instead.

I notice that you guys have this fixed here:

http://git.infradead.org/users/vcgomes/linux-2.6.git/commitdiff/f345aa37d6d49104ef4b2b7e4466fb3186807199

So I wonder why this was not fix in place?

>> +             ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
>> +                                     0, conn->dst, 0, conn->src, res);
>
> Same here.
>
>> +     if (conn->hcon->out)
>> +             ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
>> +                             conn->src, 0, conn->dst, res);
>> +     else
>> +             ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
>> +                             conn->dst, 0, conn->src, res);
>
> And here.
>
> You're also hard-coding the local address type to public, but that's a
> less severe issue (for now).
>
> Johan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods
  2011-06-08  4:16     ` Luiz Augusto von Dentz
@ 2011-06-08 14:38       ` Vinicius Costa Gomes
  0 siblings, 0 replies; 22+ messages in thread
From: Vinicius Costa Gomes @ 2011-06-08 14:38 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth, Anderson Briglia

Hi Luiz,

On 13:16 Wed 08 Jun, Luiz Augusto von Dentz wrote:
> Hi Vinicius,
> 
> On Wed, Jun 8, 2011 at 11:26 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> > Hi Vinicius/Anderson,
> >
> > On Tue, Jun 07, 2011, Vinicius Costa Gomes wrote:
> >> +     ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0,
> >> +                     conn->src, 0, conn->dst, res);
> >
> > The third last parameter is the remote address type and you're
> > hard-coding it to 0 (public) here. This means that we cannot pair with a
> > device with a random address. I suppose you should be passing
> > conn->hcon->dst_type instead.
> 
> I notice that you guys have this fixed here:
> 
> http://git.infradead.org/users/vcgomes/linux-2.6.git/commitdiff/f345aa37d6d49104ef4b2b7e4466fb3186807199
> 
> So I wonder why this was not fix in place?

No reason at all. It happened because this patch was written when the dst_type field
wasn't introduced yet. Will fix.

> 
> >> +             ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp,
> >> +                                     0, conn->dst, 0, conn->src, res);
> >
> > Same here.
> >
> >> +     if (conn->hcon->out)
> >> +             ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
> >> +                             conn->src, 0, conn->dst, res);
> >> +     else
> >> +             ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0,
> >> +                             conn->dst, 0, conn->src, res);
> >
> > And here.
> >
> > You're also hard-coding the local address type to public, but that's a
> > less severe issue (for now).
> >
> > Johan
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 
> 
> 
> -- 
> Luiz Augusto von Dentz
> Computer Engineer


Cheers,
-- 
Vinicius

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs
  2011-06-07 21:46 ` [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs Vinicius Costa Gomes
@ 2011-06-08 18:46   ` Gustavo F. Padovan
  2011-06-09 19:36     ` Gustavo F. Padovan
  0 siblings, 1 reply; 22+ messages in thread
From: Gustavo F. Padovan @ 2011-06-08 18:46 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Anderson Briglia

* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-06-07 18:46:35 -0300]:

> From: Anderson Briglia <anderson.briglia@openbossa.org>
> 
> This patch adds initial support for verifying the confirmation value
> that the remote side has sent.
> 
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
>  include/net/bluetooth/l2cap.h |    5 +++++
>  net/bluetooth/smp.c           |   17 +++++++++++++++++
>  2 files changed, 22 insertions(+), 0 deletions(-)

Patch up to 6/16 are applied. Thanks.

	Gustavo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs
  2011-06-08 18:46   ` Gustavo F. Padovan
@ 2011-06-09 19:36     ` Gustavo F. Padovan
  0 siblings, 0 replies; 22+ messages in thread
From: Gustavo F. Padovan @ 2011-06-09 19:36 UTC (permalink / raw)
  To: Vinicius Costa Gomes, linux-bluetooth, Anderson Briglia

* Gustavo F. Padovan <padovan@profusion.mobi> [2011-06-08 15:46:49 -0300]:

> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-06-07 18:46:35 -0300]:
> 
> > From: Anderson Briglia <anderson.briglia@openbossa.org>
> > 
> > This patch adds initial support for verifying the confirmation value
> > that the remote side has sent.
> > 
> > Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > ---
> >  include/net/bluetooth/l2cap.h |    5 +++++
> >  net/bluetooth/smp.c           |   17 +++++++++++++++++
> >  2 files changed, 22 insertions(+), 0 deletions(-)
> 
> Patch up to 6/16 are applied. Thanks.

I dropped all six patches:

  CC [M]  net/bluetooth/l2cap_sock.o
  CC [M]  net/bluetooth/smp.o
  CC [M]  net/bluetooth/sco.o
net/bluetooth/smp.c:80:12: warning: ‘smp_c1’ defined but not used [-Wunused-function]
net/bluetooth/smp.c:122:12: warning: ‘smp_s1’ defined but not used [-Wunused-function]
net/bluetooth/smp.c:138:12: warning: ‘smp_rand’ defined but not used [-Wunused-function]
  CC [M]  net/bluetooth/bnep/core.o
  CC [M]  net/bluetooth/bnep/sock.o

I pick them again with the whole patchset next time to avoid warnings like these.

	Gustavo

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2011-06-09 19:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-07 21:46 [bluetooth-next v3 00/16] SMP Just Works implementation Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 01/16] Bluetooth: Implement the first SMP commands Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 02/16] Bluetooth: Start SMP procedure Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 03/16] Bluetooth: Add simple SMP pairing negotiation Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 04/16] Bluetooth: Add support for using the crypto subsystem Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 05/16] Bluetooth: Add LE SMP Cryptoolbox functions Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 06/16] Bluetooth: Add SMP confirmation structs Vinicius Costa Gomes
2011-06-08 18:46   ` Gustavo F. Padovan
2011-06-09 19:36     ` Gustavo F. Padovan
2011-06-07 21:46 ` [bluetooth-next v3 07/16] Bluetooth: Add SMP confirmation checks methods Vinicius Costa Gomes
2011-06-08  2:26   ` Johan Hedberg
2011-06-08  4:16     ` Luiz Augusto von Dentz
2011-06-08 14:38       ` Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 08/16] Bluetooth: Add support for LE Start Encryption Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 09/16] Bluetooth: Remove debug statements Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 10/16] Bluetooth: Add support for resuming socket when SMP is finished Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 11/16] Bluetooth: Fix initial security level of LE links Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 12/16] Bluetooth: Update the security level when link is encrypted Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 13/16] Bluetooth: Add support for building pairing commands Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 14/16] Bluetooth: Add support for Pairing features exchange Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 15/16] Bluetooth: Add support for SMP timeout Vinicius Costa Gomes
2011-06-07 21:46 ` [bluetooth-next v3 16/16] Bluetooth: Add key size checks for SMP Vinicius Costa Gomes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.