All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP
@ 2011-11-23 16:28 Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 1/6] Bluetooth: Add User Passkey Response handling Brian Gix
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth


Mods made per Gustavo's request: Moved function Prototypes to Header
in the patch that they were created.

Also some mods to the blkcipher clean-up, and added a key NULL check
to handling of incoming SMP User Response.

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

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

* [PATCH-v5 1/6] Bluetooth: Add User Passkey Response handling
  2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
@ 2011-11-23 16:28 ` Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 2/6] Bluetooth: Add HCI User Passkey Req Evt handling Brian Gix
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

For some MITM protection pairing scenarios, the user is
required to enter or accept a 6 digit passkey.

Signed-off-by: Brian Gix <bgix@codeaurora.org>
---
 include/net/bluetooth/hci_core.h |    5 +++
 net/bluetooth/mgmt.c             |   74 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1795257..e7b2e25 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -933,6 +933,11 @@ int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
 								u8 status);
 int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
 						bdaddr_t *bdaddr, u8 status);
+int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+								u8 status);
+int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev,
+						bdaddr_t *bdaddr, u8 status);
 int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
 int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
 int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c06a05c..7a23f21 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1618,7 +1618,15 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
 	}
 
 	/* Continue with pairing via HCI */
-	err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
+	if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
+		struct hci_cp_user_passkey_reply cp;
+
+		bacpy(&cp.bdaddr, bdaddr);
+		cp.passkey = passkey;
+		err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
+	} else
+		err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
+
 	if (err < 0)
 		mgmt_pending_remove(cmd);
 
@@ -1660,6 +1668,37 @@ static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
 			HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
 }
 
+static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
+{
+	struct mgmt_cp_user_passkey_reply *cp = (void *) data;
+
+	BT_DBG("");
+
+	if (len != sizeof(*cp))
+		return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_REPLY,
+									EINVAL);
+
+	return user_pairing_resp(sk, index, &cp->bdaddr,
+			MGMT_OP_USER_PASSKEY_REPLY,
+			HCI_OP_USER_PASSKEY_REPLY, cp->passkey);
+}
+
+static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
+									u16 len)
+{
+	struct mgmt_cp_user_passkey_neg_reply *cp = (void *) data;
+
+	BT_DBG("");
+
+	if (len != sizeof(*cp))
+		return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_NEG_REPLY,
+									EINVAL);
+
+	return user_pairing_resp(sk, index, &cp->bdaddr,
+			MGMT_OP_USER_PASSKEY_NEG_REPLY,
+			HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
+}
+
 static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
 								u16 len)
 {
@@ -2117,6 +2156,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 		err = user_confirm_neg_reply(sk, index, buf + sizeof(*hdr),
 									len);
 		break;
+	case MGMT_OP_USER_PASSKEY_REPLY:
+		err = user_passkey_reply(sk, index, buf + sizeof(*hdr), len);
+		break;
+	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
+		err = user_passkey_neg_reply(sk, index, buf + sizeof(*hdr),
+									len);
+		break;
 	case MGMT_OP_SET_LOCAL_NAME:
 		err = set_local_name(sk, index, buf + sizeof(*hdr), len);
 		break;
@@ -2477,6 +2523,18 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
 									NULL);
 }
 
+int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct mgmt_ev_user_passkey_request ev;
+
+	BT_DBG("%s", hdev->name);
+
+	bacpy(&ev.bdaddr, bdaddr);
+
+	return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
+									NULL);
+}
+
 static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
 							u8 status, u8 opcode)
 {
@@ -2511,6 +2569,20 @@ int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
 					MGMT_OP_USER_CONFIRM_NEG_REPLY);
 }
 
+int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+								u8 status)
+{
+	return user_pairing_resp_complete(hdev, bdaddr, status,
+						MGMT_OP_USER_PASSKEY_REPLY);
+}
+
+int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev,
+						bdaddr_t *bdaddr, u8 status)
+{
+	return user_pairing_resp_complete(hdev, bdaddr, status,
+					MGMT_OP_USER_PASSKEY_NEG_REPLY);
+}
+
 int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
 {
 	struct mgmt_ev_auth_failed ev;
-- 
1.7.7.2

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum 

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

* [PATCH-v5 2/6] Bluetooth: Add HCI User Passkey Req Evt handling
  2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 1/6] Bluetooth: Add User Passkey Response handling Brian Gix
@ 2011-11-23 16:28 ` Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 3/6] Bluetooth: Cleanup blkcipher on SMP termination Brian Gix
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

Some MITM scenarios require handling of the User Passkey Request event,
by querying the user, and passing the response back.

Signed-off-by: Brian Gix <bgix@codeaurora.org>
---
 net/bluetooth/hci_event.c |   58 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index dfe6fbc..980da08 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -931,6 +931,37 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
+static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
+								rp->status);
+
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
+								rp->status);
+
+	hci_dev_unlock(hdev);
+}
+
 static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
 							struct sk_buff *skb)
 {
@@ -2015,6 +2046,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_user_confirm_neg_reply(hdev, skb);
 		break;
 
+	case HCI_OP_USER_PASSKEY_REPLY:
+		hci_cc_user_passkey_reply(hdev, skb);
+		break;
+
+	case HCI_OP_USER_PASSKEY_NEG_REPLY:
+		hci_cc_user_passkey_neg_reply(hdev, skb);
+		break;
+
 	case HCI_OP_LE_SET_SCAN_ENABLE:
 		hci_cc_le_set_scan_enable(hdev, skb);
 		break;
@@ -2774,6 +2813,21 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_ev_user_passkey_req *ev = (void *) skb->data;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_user_passkey_request(hdev, &ev->bdaddr);
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
@@ -3113,6 +3167,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_user_confirm_request_evt(hdev, skb);
 		break;
 
+	case HCI_EV_USER_PASSKEY_REQUEST:
+		hci_user_passkey_request_evt(hdev, skb);
+		break;
+
 	case HCI_EV_SIMPLE_PAIR_COMPLETE:
 		hci_simple_pair_complete_evt(hdev, skb);
 		break;
-- 
1.7.7.2

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum 

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

* [PATCH-v5 3/6] Bluetooth: Cleanup blkcipher on SMP termination
  2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 1/6] Bluetooth: Add User Passkey Response handling Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 2/6] Bluetooth: Add HCI User Passkey Req Evt handling Brian Gix
@ 2011-11-23 16:28 ` Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 4/6] Bluetooth: Centralize SMP pairing failure handling Brian Gix
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

The blkcipher must be freed to avoid memory leak.

Signed-off-by: Brian Gix <bgix@codeaurora.org>
---
 net/bluetooth/smp.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 94e94ca..b9af488 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -379,7 +379,15 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 
 void smp_chan_destroy(struct l2cap_conn *conn)
 {
-	kfree(conn->smp_chan);
+	struct smp_chan *smp = conn->smp_chan;
+
+	clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend);
+
+	if (smp->tfm)
+		crypto_free_blkcipher(smp->tfm);
+
+	kfree(smp);
+	conn->smp_chan = NULL;
 	hci_conn_put(conn->hcon);
 }
 
-- 
1.7.7.2

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum 

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

* [PATCH-v5 4/6] Bluetooth: Centralize SMP pairing failure handling
  2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
                   ` (2 preceding siblings ...)
  2011-11-23 16:28 ` [PATCH-v5 3/6] Bluetooth: Cleanup blkcipher on SMP termination Brian Gix
@ 2011-11-23 16:28 ` Brian Gix
  2011-12-01 14:13   ` Gustavo Padovan
  2011-11-23 16:28 ` [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP Brian Gix
  2011-11-23 16:28 ` [PATCH-v5 6/6] Bluetooth: Add SMP to User Passkey and Confirm Brian Gix
  5 siblings, 1 reply; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

Signed-off-by: Brian Gix <bgix@codeaurora.org>
---
 net/bluetooth/smp.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b9af488..0b96737 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -232,6 +232,18 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
 	return 0;
 }
 
+static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
+{
+	if (send)
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+
+	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend);
+	mgmt_auth_failed(conn->hcon->hdev, conn->dst, reason);
+	del_timer(&conn->security_timer);
+	smp_chan_destroy(conn);
+}
+
 static void confirm_work(struct work_struct *work)
 {
 	struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
@@ -270,8 +282,7 @@ static void confirm_work(struct work_struct *work)
 	return;
 
 error:
-	smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
-	smp_chan_destroy(conn);
+	smp_failure(conn, reason, 1);
 }
 
 static void random_work(struct work_struct *work)
@@ -354,8 +365,7 @@ static void random_work(struct work_struct *work)
 	return;
 
 error:
-	smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
-	smp_chan_destroy(conn);
+	smp_failure(conn, reason, 1);
 }
 
 static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
@@ -655,6 +665,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 		break;
 
 	case SMP_CMD_PAIRING_FAIL:
+		smp_failure(conn, skb->data[0], 0);
 		reason = 0;
 		err = -EPERM;
 		break;
@@ -700,8 +711,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 done:
 	if (reason)
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
-								&reason);
+		smp_failure(conn, reason, 1);
 
 	kfree_skb(skb);
 	return err;
-- 
1.7.7.2

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum 

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

* [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP
  2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
                   ` (3 preceding siblings ...)
  2011-11-23 16:28 ` [PATCH-v5 4/6] Bluetooth: Centralize SMP pairing failure handling Brian Gix
@ 2011-11-23 16:28 ` Brian Gix
  2011-12-01 14:11   ` Gustavo Padovan
  2011-11-23 16:28 ` [PATCH-v5 6/6] Bluetooth: Add SMP to User Passkey and Confirm Brian Gix
  5 siblings, 1 reply; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

To achive Man-In-The-Middle (MITM) level security with Low Energy,
we have to enable User Passkey Comparison.  This commit modifies the
hard-coded JUST-WORKS pairing mechanism to support query via the MGMT
interface of Passkey comparison and User Confirmation.

Signed-off-by: Brian Gix <bgix@codeaurora.org>
---
 include/net/bluetooth/hci_core.h |    1 +
 include/net/bluetooth/smp.h      |    3 +
 net/bluetooth/smp.c              |  228 ++++++++++++++++++++++++++++++++++----
 3 files changed, 210 insertions(+), 22 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e7b2e25..4aa417c 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -312,6 +312,7 @@ struct hci_conn {
 	struct hci_dev	*hdev;
 	void		*l2cap_data;
 	void		*sco_data;
+	void		*smp_conn;
 
 	struct hci_conn	*link;
 
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 15b97d5..43b6c49 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -124,6 +124,8 @@ struct smp_chan {
 	u8		pcnf[16]; /* SMP Pairing Confirm */
 	u8		tk[16]; /* SMP Temporary Key */
 	u8		smp_key_size;
+	u8		smp_tk_valid;
+	u8		smp_cfm_pending;
 	struct crypto_blkcipher	*tfm;
 	struct work_struct confirm;
 	struct work_struct random;
@@ -134,6 +136,7 @@ struct smp_chan {
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
 int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
+int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
 
 void smp_chan_destroy(struct l2cap_conn *conn);
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 0b96737..e1df0a2 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -23,6 +23,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/mgmt.h>
 #include <net/bluetooth/smp.h>
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
@@ -188,24 +189,46 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 					msecs_to_jiffies(SMP_TIMEOUT));
 }
 
+static __u8 authreq_to_seclevel(__u8 authreq)
+{
+	if (authreq & SMP_AUTH_MITM)
+		return BT_SECURITY_HIGH;
+	else
+		return BT_SECURITY_MEDIUM;
+}
+
+static __u8 seclevel_to_authreq(__u8 sec_level)
+{
+	switch (sec_level) {
+	case BT_SECURITY_HIGH:
+		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
+	case BT_SECURITY_MEDIUM:
+		return SMP_AUTH_BONDING;
+	default:
+		return SMP_AUTH_NONE;
+	}
+}
+
 static void build_pairing_cmd(struct l2cap_conn *conn,
 				struct smp_cmd_pairing *req,
 				struct smp_cmd_pairing *rsp,
 				__u8 authreq)
 {
-	u8 dist_keys;
+	u8 all_keys = 0;
+	u8 dist_keys = 0;
 
-	dist_keys = 0;
 	if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
 		dist_keys = SMP_DIST_ENC_KEY;
 		authreq |= SMP_AUTH_BONDING;
+	} else {
+		authreq &= ~SMP_AUTH_BONDING;
 	}
 
 	if (rsp == NULL) {
 		req->io_capability = conn->hcon->io_capability;
 		req->oob_flag = SMP_OOB_NOT_PRESENT;
 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-		req->init_key_dist = dist_keys;
+		req->init_key_dist = all_keys;
 		req->resp_key_dist = dist_keys;
 		req->auth_req = authreq;
 		return;
@@ -214,7 +237,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
 	rsp->io_capability = conn->hcon->io_capability;
 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-	rsp->init_key_dist = req->init_key_dist & dist_keys;
+	rsp->init_key_dist = req->init_key_dist & all_keys;
 	rsp->resp_key_dist = req->resp_key_dist & dist_keys;
 	rsp->auth_req = authreq;
 }
@@ -244,6 +267,93 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
 	smp_chan_destroy(conn);
 }
 
+#define JUST_WORKS	0x00
+#define JUST_CFM	0x01
+#define REQ_PASSKEY	0x02
+#define CFM_PASSKEY	0x03
+#define REQ_OOB		0x04
+#define OVERLAP		0xFF
+
+static const u8	gen_method[5][5] = {
+	{JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY},
+	{JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY},
+	{CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY},
+	{JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM},
+	{CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP}
+};
+
+static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
+						u8 local_io, u8 remote_io)
+{
+	struct hci_conn *hcon = conn->hcon;
+	struct smp_chan *smp = conn->smp_chan;
+	u8 method;
+	u32 passkey = 0;
+	int ret = 0;
+
+	/* Initialize key to JUST WORKS */
+	memset(smp->tk, 0, sizeof(smp->tk));
+	smp->smp_tk_valid = 0;
+
+	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
+
+	/* If neither side wants MITM, use JUST WORKS */
+	/* If either side has unknown io_caps, use JUST_WORKS */
+	if (!(auth & SMP_AUTH_MITM) ||
+			local_io > SMP_IO_KEYBOARD_DISPLAY ||
+			remote_io > SMP_IO_KEYBOARD_DISPLAY) {
+		auth &= ~SMP_AUTH_MITM;
+		smp->smp_tk_valid = 1;
+		return 0;
+	}
+
+	/* MITM is now officially requested, but not required */
+	/* Determine what we need (if anything) from the agent */
+	method = gen_method[local_io][remote_io];
+
+	if (method == JUST_WORKS || method == JUST_CFM)
+		auth &= ~SMP_AUTH_MITM;
+
+	/* Don't bother confirming unbonded JUST_WORKS */
+	if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM) {
+		smp->smp_tk_valid = 1;
+		return 0;
+	} else if (method == JUST_WORKS) {
+		smp->smp_tk_valid = 1;
+		return 0;
+	} else if (method == OVERLAP) {
+		if (hcon->link_mode & HCI_LM_MASTER)
+			method = CFM_PASSKEY;
+		else
+			method = REQ_PASSKEY;
+	}
+
+	if (method == CFM_PASSKEY) {
+		u8 key[16];
+		/* Generate a passkey for display. It is not valid until
+		 * confirmed.
+		 */
+		memset(key, 0, sizeof(key));
+		get_random_bytes(&passkey, sizeof(passkey));
+		passkey %= 1000000;
+		put_unaligned_le32(passkey, key);
+		swap128(key, smp->tk);
+		BT_DBG("PassKey: %d", passkey);
+	}
+
+	hci_dev_lock(hcon->hdev);
+
+	if (method == REQ_PASSKEY)
+		ret = mgmt_user_passkey_request(hcon->hdev, conn->dst);
+	else
+		ret = mgmt_user_confirm_request(hcon->hdev, conn->dst,
+						cpu_to_le32(passkey), 0);
+
+	hci_dev_unlock(hcon->hdev);
+
+	return ret;
+}
+
 static void confirm_work(struct work_struct *work)
 {
 	struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
@@ -276,6 +386,8 @@ static void confirm_work(struct work_struct *work)
 		goto error;
 	}
 
+	smp->smp_cfm_pending = 0;
+
 	swap128(res, cp.confirm_val);
 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 
@@ -381,6 +493,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 
 	smp->conn = conn;
 	conn->smp_chan = smp;
+	conn->hcon->smp_conn = conn;
 
 	hci_conn_hold(conn->hcon);
 
@@ -398,18 +511,67 @@ void smp_chan_destroy(struct l2cap_conn *conn)
 
 	kfree(smp);
 	conn->smp_chan = NULL;
+	conn->hcon->smp_conn = NULL;
 	hci_conn_put(conn->hcon);
 }
 
+int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
+{
+	struct l2cap_conn *conn = hcon->smp_conn;
+	struct smp_chan *smp;
+	u32 value;
+	u8 key[16];
+	u8 reason = 0;
+	int ret = 0;
+
+	BT_DBG("");
+
+	if (!conn)
+		return -ENOTCONN;
+
+	smp = conn->smp_chan;
+
+	switch (mgmt_op) {
+	case MGMT_OP_USER_PASSKEY_REPLY:
+		value = le32_to_cpu(passkey);
+		memset(key, 0, sizeof(key));
+		BT_DBG("PassKey: %d", value);
+		put_unaligned_le32(value, key);
+		swap128(key, smp->tk);
+		/* Fall Through */
+	case MGMT_OP_USER_CONFIRM_REPLY:
+		smp->smp_tk_valid = 1;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		/* Fall Through */
+	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
+	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
+		reason = SMP_PASSKEY_ENTRY_FAILED;
+		break;
+	}
+
+	if (reason)
+		smp_failure(conn, reason, 1);
+	else if (smp->smp_cfm_pending)
+		queue_work(hcon->hdev->workqueue, &smp->confirm);
+
+	return ret;
+}
+
 static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
 	struct smp_chan *smp;
 	u8 key_size;
+	u8 auth = SMP_AUTH_NONE;
 	int ret;
 
 	BT_DBG("conn %p", conn);
 
+	if (conn->hcon->link_mode & HCI_LM_MASTER)
+		return SMP_CMD_NOTSUPP;
+
 	if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend))
 		smp = smp_chan_create(conn);
 
@@ -419,19 +581,16 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&smp->preq[1], req, sizeof(*req));
 	skb_pull(skb, sizeof(*req));
 
-	if (req->oob_flag)
-		return SMP_OOB_NOT_AVAIL;
+	/* We didn't start the pairing, so match remote */
+	if (req->auth_req & SMP_AUTH_BONDING)
+		auth = req->auth_req;
 
-	/* We didn't start the pairing, so no requirements */
-	build_pairing_cmd(conn, req, &rsp, SMP_AUTH_NONE);
+	build_pairing_cmd(conn, req, &rsp, auth);
 
 	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(smp->tk, 0, sizeof(smp->tk));
-
 	ret = smp_rand(smp->prnd);
 	if (ret)
 		return SMP_UNSPECIFIED;
@@ -441,6 +600,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
 
+	/* Request setup of TK */
+	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
+	if (ret)
+		return SMP_UNSPECIFIED;
+
 	return 0;
 }
 
@@ -449,11 +613,14 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
 	struct smp_chan *smp = conn->smp_chan;
 	struct hci_dev *hdev = conn->hcon->hdev;
-	u8 key_size;
+	u8 key_size, auth = SMP_AUTH_NONE;
 	int ret;
 
 	BT_DBG("conn %p", conn);
 
+	if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+		return SMP_CMD_NOTSUPP;
+
 	skb_pull(skb, sizeof(*rsp));
 
 	req = (void *) &smp->preq[1];
@@ -462,12 +629,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	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(smp->tk, 0, sizeof(smp->tk));
-
 	ret = smp_rand(smp->prnd);
 	if (ret)
 		return SMP_UNSPECIFIED;
@@ -475,6 +636,22 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
 
+	if ((req->auth_req & SMP_AUTH_BONDING) &&
+			(rsp->auth_req & SMP_AUTH_BONDING))
+		auth = SMP_AUTH_BONDING;
+
+	auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
+
+	ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability);
+	if (ret)
+		return SMP_UNSPECIFIED;
+
+	smp->smp_cfm_pending = 1;
+
+	/* Can't compose response until we have been confirmed */
+	if (!smp->smp_tk_valid)
+		return 0;
+
 	queue_work(hdev->workqueue, &smp->confirm);
 
 	return 0;
@@ -496,8 +673,10 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 		swap128(smp->prnd, random);
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
 								random);
-	} else {
+	} else if (smp->smp_tk_valid) {
 		queue_work(hdev->workqueue, &smp->confirm);
+	} else {
+		smp->smp_cfm_pending = 1;
 	}
 
 	return 0;
@@ -550,7 +729,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("conn %p", conn);
 
-	hcon->pending_sec_level = BT_SECURITY_MEDIUM;
+	hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
 
 	if (smp_ltk_encrypt(conn))
 		return 0;
@@ -577,6 +756,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 {
 	struct hci_conn *hcon = conn->hcon;
 	struct smp_chan *smp = conn->smp_chan;
+	__u8 authreq;
 
 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
 
@@ -597,18 +777,22 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		return 0;
 
 	smp = smp_chan_create(conn);
+	if (!smp)
+		return 1;
+
+	authreq = seclevel_to_authreq(sec_level);
 
 	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
 
-		build_pairing_cmd(conn, &cp, NULL, SMP_AUTH_NONE);
+		build_pairing_cmd(conn, &cp, NULL, authreq);
 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
 		memcpy(&smp->preq[1], &cp, sizeof(cp));
 
 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 	} else {
 		struct smp_cmd_security_req cp;
-		cp.auth_req = SMP_AUTH_NONE;
+		cp.auth_req = authreq;
 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
 	}
 
-- 
1.7.7.2

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum 

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

* [PATCH-v5 6/6] Bluetooth: Add SMP to User Passkey and Confirm
  2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
                   ` (4 preceding siblings ...)
  2011-11-23 16:28 ` [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP Brian Gix
@ 2011-11-23 16:28 ` Brian Gix
  5 siblings, 0 replies; 11+ messages in thread
From: Brian Gix @ 2011-11-23 16:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

Low Energy pairing is performed through the SMP (Security Manager Protocol)
mechanism rather than HCI.

Signed-off-by: Brian Gix <bgix@codeaurora.org>
---
 net/bluetooth/mgmt.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 7a23f21..4e05e24 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -29,6 +29,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/mgmt.h>
+#include <net/bluetooth/smp.h>
 
 #define MGMT_VERSION	0
 #define MGMT_REVISION	1
@@ -1606,8 +1607,15 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
 		}
 
 		/* Continue with pairing via SMP */
+		err = smp_user_confirm_reply(conn, mgmt_op, passkey);
+
+		if (!err)
+			err = cmd_status(sk, index, mgmt_op,
+							MGMT_STATUS_SUCCESS);
+		else
+			err = cmd_status(sk, index, mgmt_op,
+							MGMT_STATUS_FAILED);
 
-		err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_SUCCESS);
 		goto done;
 	}
 
-- 
1.7.7.2

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum 

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

* Re: [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP
  2011-11-23 16:28 ` [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP Brian Gix
@ 2011-12-01 14:11   ` Gustavo Padovan
  2011-12-01 18:35     ` Brian Gix
  0 siblings, 1 reply; 11+ messages in thread
From: Gustavo Padovan @ 2011-12-01 14:11 UTC (permalink / raw)
  To: Brian Gix; +Cc: linux-bluetooth

Hi Brian,

* Brian Gix <bgix@codeaurora.org> [2011-11-23 08:28:37 -0800]:

> To achive Man-In-The-Middle (MITM) level security with Low Energy,
> we have to enable User Passkey Comparison.  This commit modifies the
> hard-coded JUST-WORKS pairing mechanism to support query via the MGMT
> interface of Passkey comparison and User Confirmation.
> 
> Signed-off-by: Brian Gix <bgix@codeaurora.org>
> ---
>  include/net/bluetooth/hci_core.h |    1 +
>  include/net/bluetooth/smp.h      |    3 +
>  net/bluetooth/smp.c              |  228 ++++++++++++++++++++++++++++++++++----
>  3 files changed, 210 insertions(+), 22 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index e7b2e25..4aa417c 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -312,6 +312,7 @@ struct hci_conn {
>  	struct hci_dev	*hdev;
>  	void		*l2cap_data;
>  	void		*sco_data;
> +	void		*smp_conn;
>  
>  	struct hci_conn	*link;
>  
> diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
> index 15b97d5..43b6c49 100644
> --- a/include/net/bluetooth/smp.h
> +++ b/include/net/bluetooth/smp.h
> @@ -124,6 +124,8 @@ struct smp_chan {
>  	u8		pcnf[16]; /* SMP Pairing Confirm */
>  	u8		tk[16]; /* SMP Temporary Key */
>  	u8		smp_key_size;
> +	u8		smp_tk_valid;
> +	u8		smp_cfm_pending;

Those two could be converted in a bitfield, you are using them as boolean.

>  	struct crypto_blkcipher	*tfm;
>  	struct work_struct confirm;
>  	struct work_struct random;
> @@ -134,6 +136,7 @@ struct smp_chan {
>  int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
>  int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
>  int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
> +int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
>  
>  void smp_chan_destroy(struct l2cap_conn *conn);
>  
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index 0b96737..e1df0a2 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -23,6 +23,7 @@
>  #include <net/bluetooth/bluetooth.h>
>  #include <net/bluetooth/hci_core.h>
>  #include <net/bluetooth/l2cap.h>
> +#include <net/bluetooth/mgmt.h>
>  #include <net/bluetooth/smp.h>
>  #include <linux/crypto.h>
>  #include <linux/scatterlist.h>
> @@ -188,24 +189,46 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
>  					msecs_to_jiffies(SMP_TIMEOUT));
>  }
>  
> +static __u8 authreq_to_seclevel(__u8 authreq)
> +{
> +	if (authreq & SMP_AUTH_MITM)
> +		return BT_SECURITY_HIGH;
> +	else
> +		return BT_SECURITY_MEDIUM;
> +}
> +
> +static __u8 seclevel_to_authreq(__u8 sec_level)
> +{
> +	switch (sec_level) {
> +	case BT_SECURITY_HIGH:
> +		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
> +	case BT_SECURITY_MEDIUM:
> +		return SMP_AUTH_BONDING;
> +	default:
> +		return SMP_AUTH_NONE;
> +	}
> +}
> +
>  static void build_pairing_cmd(struct l2cap_conn *conn,
>  				struct smp_cmd_pairing *req,
>  				struct smp_cmd_pairing *rsp,
>  				__u8 authreq)
>  {
> -	u8 dist_keys;
> +	u8 all_keys = 0;
> +	u8 dist_keys = 0;
>  
> -	dist_keys = 0;
>  	if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
>  		dist_keys = SMP_DIST_ENC_KEY;
>  		authreq |= SMP_AUTH_BONDING;
> +	} else {
> +		authreq &= ~SMP_AUTH_BONDING;
>  	}
>  
>  	if (rsp == NULL) {
>  		req->io_capability = conn->hcon->io_capability;
>  		req->oob_flag = SMP_OOB_NOT_PRESENT;
>  		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
> -		req->init_key_dist = dist_keys;
> +		req->init_key_dist = all_keys;
>  		req->resp_key_dist = dist_keys;
>  		req->auth_req = authreq;
>  		return;
> @@ -214,7 +237,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
>  	rsp->io_capability = conn->hcon->io_capability;
>  	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
>  	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
> -	rsp->init_key_dist = req->init_key_dist & dist_keys;
> +	rsp->init_key_dist = req->init_key_dist & all_keys;

all_keys is always zero. What's the purpose of create it?

	Gustavo

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

* Re: [PATCH-v5 4/6] Bluetooth: Centralize SMP pairing failure handling
  2011-11-23 16:28 ` [PATCH-v5 4/6] Bluetooth: Centralize SMP pairing failure handling Brian Gix
@ 2011-12-01 14:13   ` Gustavo Padovan
  0 siblings, 0 replies; 11+ messages in thread
From: Gustavo Padovan @ 2011-12-01 14:13 UTC (permalink / raw)
  To: Brian Gix; +Cc: linux-bluetooth

Hi Brian,

* Brian Gix <bgix@codeaurora.org> [2011-11-23 08:28:36 -0800]:

> Signed-off-by: Brian Gix <bgix@codeaurora.org>
> ---
>  net/bluetooth/smp.c |   22 ++++++++++++++++------
>  1 files changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index b9af488..0b96737 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -232,6 +232,18 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
>  	return 0;
>  }
>  
> +static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
> +{
> +	if (send)
> +		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
> +								&reason);
> +
> +	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend);
> +	mgmt_auth_failed(conn->hcon->hdev, conn->dst, reason);
> +	del_timer(&conn->security_timer);
> +	smp_chan_destroy(conn);
> +}
> +
>  static void confirm_work(struct work_struct *work)
>  {
>  	struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
> @@ -270,8 +282,7 @@ static void confirm_work(struct work_struct *work)
>  	return;
>  
>  error:
> -	smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
> -	smp_chan_destroy(conn);
> +	smp_failure(conn, reason, 1);
>  }
>  
>  static void random_work(struct work_struct *work)
> @@ -354,8 +365,7 @@ static void random_work(struct work_struct *work)
>  	return;
>  
>  error:
> -	smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
> -	smp_chan_destroy(conn);
> +	smp_failure(conn, reason, 1);
>  }
>  
>  static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
> @@ -655,6 +665,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
>  		break;
>  
>  	case SMP_CMD_PAIRING_FAIL:
> +		smp_failure(conn, skb->data[0], 0);
>  		reason = 0;
>  		err = -EPERM;
>  		break;
> @@ -700,8 +711,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
>  
>  done:
>  	if (reason)
> -		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
> -								&reason);
> +		smp_failure(conn, reason, 1);
>  
>  	kfree_skb(skb);
>  	return err;

Patch 1 to 4 were applied. Thanks.

	Gustavo

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

* Re: [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP
  2011-12-01 14:11   ` Gustavo Padovan
@ 2011-12-01 18:35     ` Brian Gix
  2011-12-01 23:38       ` Gustavo Padovan
  0 siblings, 1 reply; 11+ messages in thread
From: Brian Gix @ 2011-12-01 18:35 UTC (permalink / raw)
  To: linux-bluetooth

On 12/1/2011 6:11 AM, Gustavo Padovan wrote:
> Hi Brian,

>> diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
>> index 15b97d5..43b6c49 100644
>> --- a/include/net/bluetooth/smp.h
>> +++ b/include/net/bluetooth/smp.h
>> @@ -124,6 +124,8 @@ struct smp_chan {
>>   	u8		pcnf[16]; /* SMP Pairing Confirm */
>>   	u8		tk[16]; /* SMP Temporary Key */
>>   	u8		smp_key_size;
>> +	u8		smp_tk_valid;
>> +	u8		smp_cfm_pending;
>
> Those two could be converted in a bitfield, you are using them as boolean.
>

Is there a mandate that bitfields must be manipulated/checked with the 
clear_bit/set_bit/test_bit prototypes?  Or can I just use a single u8 to 
represent both boolean values (as opposed to an unsigned long), and use 
standard &=, |= and & to set/clear/check?


-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

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

* Re: [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP
  2011-12-01 18:35     ` Brian Gix
@ 2011-12-01 23:38       ` Gustavo Padovan
  0 siblings, 0 replies; 11+ messages in thread
From: Gustavo Padovan @ 2011-12-01 23:38 UTC (permalink / raw)
  To: Brian Gix; +Cc: linux-bluetooth

Hi Brian,

* Brian Gix <bgix@codeaurora.org> [2011-12-01 10:35:30 -0800]:

> On 12/1/2011 6:11 AM, Gustavo Padovan wrote:
> >Hi Brian,
> 
> >>diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
> >>index 15b97d5..43b6c49 100644
> >>--- a/include/net/bluetooth/smp.h
> >>+++ b/include/net/bluetooth/smp.h
> >>@@ -124,6 +124,8 @@ struct smp_chan {
> >>  	u8		pcnf[16]; /* SMP Pairing Confirm */
> >>  	u8		tk[16]; /* SMP Temporary Key */
> >>  	u8		smp_key_size;
> >>+	u8		smp_tk_valid;
> >>+	u8		smp_cfm_pending;
> >
> >Those two could be converted in a bitfield, you are using them as boolean.
> >
> 
> Is there a mandate that bitfields must be manipulated/checked with
> the clear_bit/set_bit/test_bit prototypes?  Or can I just use a
> single u8 to represent both boolean values (as opposed to an
> unsigned long), and use standard &=, |= and & to set/clear/check?

Please use clear/set/test_bit, it is the right way.

	Gustavo

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

end of thread, other threads:[~2011-12-01 23:38 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-23 16:28 [PATCH-v5 0/6] Bluetooth: Add MITM protection to LE-SMP Brian Gix
2011-11-23 16:28 ` [PATCH-v5 1/6] Bluetooth: Add User Passkey Response handling Brian Gix
2011-11-23 16:28 ` [PATCH-v5 2/6] Bluetooth: Add HCI User Passkey Req Evt handling Brian Gix
2011-11-23 16:28 ` [PATCH-v5 3/6] Bluetooth: Cleanup blkcipher on SMP termination Brian Gix
2011-11-23 16:28 ` [PATCH-v5 4/6] Bluetooth: Centralize SMP pairing failure handling Brian Gix
2011-12-01 14:13   ` Gustavo Padovan
2011-11-23 16:28 ` [PATCH-v5 5/6] Bluetooth: Add MITM mechanism to LE-SMP Brian Gix
2011-12-01 14:11   ` Gustavo Padovan
2011-12-01 18:35     ` Brian Gix
2011-12-01 23:38       ` Gustavo Padovan
2011-11-23 16:28 ` [PATCH-v5 6/6] Bluetooth: Add SMP to User Passkey and Confirm Brian Gix

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.