Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code
@ 2010-08-27 11:44 Waldemar Rymarkiewicz
  2010-08-27 19:45 ` Antonio Ospite
  2010-08-27 19:55 ` Gustavo F. Padovan
  0 siblings, 2 replies; 4+ messages in thread
From: Waldemar Rymarkiewicz @ 2010-08-27 11:44 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: par-gunnar.p.hjalmdahl, joakim.xj.ceder, johan.hedberg,
	Waldemar Rymarkiewicz

The security level BT_SECURITY_HIGH expects secure connection
and a minimum 16 digit pin code used for bonding. It's requitred by the
Sim Access Profile.

Patch on behalf of ST-Ericsson SA.

Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
---
 include/net/bluetooth/hci.h      |   17 +++++++
 include/net/bluetooth/hci_core.h |    4 ++
 net/bluetooth/hci_conn.c         |   97 +++++++++++++++++++++++++++++++-------
 net/bluetooth/hci_event.c        |    4 ++
 net/bluetooth/hci_sock.c         |    3 +
 net/bluetooth/rfcomm/core.c      |   10 ++++-
 6 files changed, 116 insertions(+), 19 deletions(-)
 mode change 100644 => 100755 include/net/bluetooth/hci.h
 mode change 100644 => 100755 include/net/bluetooth/hci_core.h
 mode change 100644 => 100755 net/bluetooth/hci_conn.c
 mode change 100644 => 100755 net/bluetooth/hci_event.c
 mode change 100644 => 100755 net/bluetooth/rfcomm/core.c

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
old mode 100644
new mode 100755
index bcbdd6d..34a6fbf
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -99,6 +99,7 @@ enum {
 #define HCISETLINKMODE	_IOW('H', 226, int)
 #define HCISETACLMTU	_IOW('H', 227, int)
 #define HCISETSCOMTU	_IOW('H', 228, int)
+#define HCISETCONNINFO	_IOW('H', 229, int)
 
 #define HCIBLOCKADDR	_IOW('H', 230, int)
 #define HCIUNBLOCKADDR	_IOW('H', 231, int)
@@ -224,6 +225,15 @@ enum {
 #define HCI_AT_GENERAL_BONDING		0x04
 #define HCI_AT_GENERAL_BONDING_MITM	0x05
 
+/* Link Key types */
+#define HCI_LK_COMBINATION			0x00
+#define HCI_LK_LOCAL_UNIT			0x01
+#define HCI_LK_REMOTE_UNIT			0x02
+#define HCI_LK_DEBUG_COMBINATION 		0x03
+#define HCI_LK_UNAUTHENTICATED_COMBINATION 	0x04
+#define HCI_LK_AUTHENTICATED_COMBINATION 	0x05
+#define HCI_LK_CHANGEED_COMBINATION_KEY 	0x06
+
 /* -----  HCI Commands ---- */
 #define HCI_OP_INQUIRY			0x0401
 struct hci_cp_inquiry {
@@ -1022,9 +1032,16 @@ struct hci_conn_info_req {
 	struct   hci_conn_info conn_info[0];
 };
 
+struct hci_set_conn_info_req {
+	bdaddr_t bdaddr;
+	__u8     pin_len;
+	__u8	 key_type;
+};
+
 struct hci_auth_info_req {
 	bdaddr_t bdaddr;
 	__u8     type;
+	__u8     level;
 };
 
 struct hci_inquiry_req {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
old mode 100644
new mode 100755
index 4568b93..9eb2da3
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -183,6 +183,8 @@ struct hci_conn {
 	__u32		 link_mode;
 	__u8             auth_type;
 	__u8             sec_level;
+	__u8             key_type;
+	__u8             pin_len;
 	__u8             power_save;
 	__u16            disc_timeout;
 	unsigned long	 pend;
@@ -430,6 +432,8 @@ int hci_get_dev_info(void __user *arg);
 int hci_get_conn_list(void __user *arg);
 int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
+int hci_set_conn_info(struct hci_dev *hdev, void __user *arg);
+
 int hci_inquiry(void __user *arg);
 
 struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
old mode 100644
new mode 100755
index 0b1e460..ed7a007
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -233,6 +233,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 	conn->mode  = HCI_CM_ACTIVE;
 	conn->state = BT_OPEN;
 	conn->auth_type = HCI_AT_GENERAL_BONDING;
+	conn->key_type = 0xff;
+	conn->pin_len = 0;
 
 	conn->power_save = 1;
 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
@@ -433,15 +435,11 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
 EXPORT_SYMBOL(hci_conn_check_link_mode);
 
 /* Authenticate remote device */
-static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
+static void hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
 	BT_DBG("conn %p", conn);
 
-	if (sec_level > conn->sec_level)
-		conn->sec_level = sec_level;
-	else if (conn->link_mode & HCI_LM_AUTH)
-		return 1;
-
+	conn->sec_level = sec_level;
 	conn->auth_type = auth_type;
 
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
@@ -450,8 +448,20 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
 							sizeof(cp), &cp);
 	}
+}
 
-	return 0;
+/* Encrypt the the link */
+static void hci_conn_encrypt(struct hci_conn *conn)
+{
+	BT_DBG("conn %p", conn);
+
+	if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+		struct hci_cp_set_conn_encrypt cp;
+		cp.handle  = cpu_to_le16(conn->handle);
+		cp.encrypt = 1;
+		hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
+							sizeof(cp), &cp);
+	}
 }
 
 /* Enable security */
@@ -459,28 +469,54 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
 	BT_DBG("conn %p", conn);
 
+	/* For sdp we do not need the link key. */
 	if (sec_level == BT_SECURITY_SDP)
 		return 1;
 
+	/* For non 2.1 devices and low security level we do not need the
+	   link key. */
 	if (sec_level == BT_SECURITY_LOW &&
 				(!conn->ssp_mode || !conn->hdev->ssp_mode))
 		return 1;
 
-	if (conn->link_mode & HCI_LM_ENCRYPT)
-		return hci_conn_auth(conn, sec_level, auth_type);
-
+	/* For other security levels we need link key. */
+	if (!(conn->link_mode & HCI_LM_AUTH))
+		goto do_auth;
+
+	/* An authenticated combination key has sufficient security for any
+	   security level. */
+	if (conn->key_type == HCI_LK_AUTHENTICATED_COMBINATION)
+		goto do_encrypt;
+
+	/* An unauthenticated combination key has sufficient security for
+	   security level 1 and 2. */
+	if (conn->key_type == HCI_LK_UNAUTHENTICATED_COMBINATION 
+			&& (sec_level == BT_SECURITY_MEDIUM
+				|| sec_level == BT_SECURITY_LOW))
+		goto do_encrypt;
+
+	/* A combination key has always sufficient security for the security
+	   levels 1 or 2. High security level requires that the combination key
+	   was generated using the maximum PIN code length (16).
+	   For pre 2.1 units. */
+	if ((conn->key_type == HCI_LK_COMBINATION))
+		if ((sec_level != BT_SECURITY_HIGH) || (conn->pin_len >= 16))
+			goto do_encrypt;
+
+do_auth:
 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
 		return 0;
 
-	if (hci_conn_auth(conn, sec_level, auth_type)) {
-		struct hci_cp_set_conn_encrypt cp;
-		cp.handle  = cpu_to_le16(conn->handle);
-		cp.encrypt = 1;
-		hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
-							sizeof(cp), &cp);
-	}
-
+	hci_conn_auth(conn, sec_level, auth_type);
 	return 0;
+
+do_encrypt:
+	if (conn->link_mode & HCI_LM_ENCRYPT)
+		return 1;  /* sufficient link key */
+	else{
+		hci_conn_encrypt(conn);
+		return 0; /* auth pending */
+	}
 }
 EXPORT_SYMBOL(hci_conn_security);
 
@@ -713,6 +749,30 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
 	return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
 }
 
+int hci_set_conn_info(struct hci_dev *hdev, void __user *arg)
+{
+	struct hci_set_conn_info_req req;
+	struct hci_conn *conn;
+
+	if (copy_from_user(&req, arg, sizeof(req))) {
+		BT_DBG("copy from user failed");
+		return -EFAULT;
+	}
+
+	hci_dev_lock_bh(hdev);
+	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
+	if (conn) {
+		conn->pin_len = req.pin_len;
+		conn->key_type = req.key_type;
+	}
+	hci_dev_unlock_bh(hdev);
+
+	if (!conn)
+		return -ENOENT;
+
+	return 0;
+}
+
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
 {
 	struct hci_auth_info_req req;
@@ -725,6 +785,7 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
 	if (conn)
 		req.type = conn->auth_type;
+		req.level = conn->sec_level;
 	hci_dev_unlock_bh(hdev);
 
 	if (!conn)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
old mode 100644
new mode 100755
index bfef5ba..6d6b04c
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1521,6 +1521,10 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (conn) {
 		hci_conn_hold(conn);
+		/* For Changed Combination Link Key the only link key has
+		 * been changed, not link key type. */
+		if (conn->key_type != HCI_LK_CHANGEED_COMBINATION_KEY)
+			conn->key_type = ev->key_type;
 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
 		hci_conn_put(conn);
 	}
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 83acd16..502a7b0 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -269,6 +269,9 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
 	case HCIGETCONNINFO:
 		return hci_get_conn_info(hdev, (void __user *) arg);
 
+	case HCISETCONNINFO:
+		return hci_set_conn_info(hdev, (void __user *) arg);
+
 	case HCIGETAUTHINFO:
 		return hci_get_auth_info(hdev, (void __user *) arg);
 
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
old mode 100644
new mode 100755
index 7dca91b..2e248d5
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2086,7 +2086,15 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
 			continue;
 
 		if (!status)
-			set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
+			if (d->sec_level != BT_SECURITY_HIGH)
+				set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
+			else
+				if ((conn->key_type == HCI_LK_AUTHENTICATED_COMBINATION)
+					|| (conn->key_type == HCI_LK_COMBINATION
+						&& conn->pin_len >= 16))
+					set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
+				else
+					set_bit(RFCOMM_AUTH_REJECT, &d->flags);
 		else
 			set_bit(RFCOMM_AUTH_REJECT, &d->flags);
 	}
-- 
1.7.0.4


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

* Re: [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code
  2010-08-27 11:44 [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code Waldemar Rymarkiewicz
@ 2010-08-27 19:45 ` Antonio Ospite
  2010-08-27 19:55 ` Gustavo F. Padovan
  1 sibling, 0 replies; 4+ messages in thread
From: Antonio Ospite @ 2010-08-27 19:45 UTC (permalink / raw)
  To: Waldemar Rymarkiewicz
  Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, joakim.xj.ceder,
	johan.hedberg

[-- Attachment #1: Type: text/plain, Size: 662 bytes --]

On Fri, 27 Aug 2010 13:44:20 +0200
Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> wrote:

> The security level BT_SECURITY_HIGH expects secure connection
> and a minimum 16 digit pin code used for bonding. It's requitred by the

typo:
s/requitred/required/

> Sim Access Profile.
> 
> Patch on behalf of ST-Ericsson SA.
> 
> Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
[...]

-- 
Antonio Ospite
http://ao2.it

PGP public key ID: 0x4553B001

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code
  2010-08-27 11:44 [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code Waldemar Rymarkiewicz
  2010-08-27 19:45 ` Antonio Ospite
@ 2010-08-27 19:55 ` Gustavo F. Padovan
  2010-08-30  6:58   ` Waldemar.Rymarkiewicz
  1 sibling, 1 reply; 4+ messages in thread
From: Gustavo F. Padovan @ 2010-08-27 19:55 UTC (permalink / raw)
  To: Waldemar Rymarkiewicz
  Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, joakim.xj.ceder,
	johan.hedberg

Hi Waldemar,

* Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> [2010-08-27 13:44:20 +0200]:

> The security level BT_SECURITY_HIGH expects secure connection
> and a minimum 16 digit pin code used for bonding. It's requitred by the
> Sim Access Profile.
> 
> Patch on behalf of ST-Ericsson SA.
> 
> Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
> ---
>  include/net/bluetooth/hci.h      |   17 +++++++
>  include/net/bluetooth/hci_core.h |    4 ++
>  net/bluetooth/hci_conn.c         |   97 +++++++++++++++++++++++++++++++-------
>  net/bluetooth/hci_event.c        |    4 ++
>  net/bluetooth/hci_sock.c         |    3 +
>  net/bluetooth/rfcomm/core.c      |   10 ++++-
>  6 files changed, 116 insertions(+), 19 deletions(-)
>  mode change 100644 => 100755 include/net/bluetooth/hci.h
>  mode change 100644 => 100755 include/net/bluetooth/hci_core.h
>  mode change 100644 => 100755 net/bluetooth/hci_conn.c
>  mode change 100644 => 100755 net/bluetooth/hci_event.c
>  mode change 100644 => 100755 net/bluetooth/rfcomm/core.c

You are changing the files modes. Don't do that.

-- 
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi

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

* RE: [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code
  2010-08-27 19:55 ` Gustavo F. Padovan
@ 2010-08-30  6:58   ` Waldemar.Rymarkiewicz
  0 siblings, 0 replies; 4+ messages in thread
From: Waldemar.Rymarkiewicz @ 2010-08-30  6:58 UTC (permalink / raw)
  To: padovan; +Cc: linux-bluetooth

Oops, I missed that. It was done automatically somehow. It wasn't my intention of doing this.
Will fix it.

Thanks,

/Waldek 

>-----Original Message-----
>From: Gustavo F. Padovan [mailto:pao@profusion.mobi] On Behalf 
>Of Gustavo F. Padovan
>Sent: Friday, August 27, 2010 9:56 PM
>To: Rymarkiewicz Waldemar
>Cc: linux-bluetooth@vger.kernel.org; 
>par-gunnar.p.hjalmdahl@stericsson.com; 
>joakim.xj.ceder@stericsson.com; johan.hedberg@gmail.com
>Subject: Re: [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 
>digit pin code
>
>Hi Waldemar,
>
>* Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> 
>[2010-08-27 13:44:20 +0200]:
>
>> The security level BT_SECURITY_HIGH expects secure connection and a 
>> minimum 16 digit pin code used for bonding. It's requitred 
>by the Sim 
>> Access Profile.
>> 
>> Patch on behalf of ST-Ericsson SA.
>> 
>> Signed-off-by: Waldemar Rymarkiewicz 
><waldemar.rymarkiewicz@tieto.com>
>> ---
>>  include/net/bluetooth/hci.h      |   17 +++++++
>>  include/net/bluetooth/hci_core.h |    4 ++
>>  net/bluetooth/hci_conn.c         |   97 
>+++++++++++++++++++++++++++++++-------
>>  net/bluetooth/hci_event.c        |    4 ++
>>  net/bluetooth/hci_sock.c         |    3 +
>>  net/bluetooth/rfcomm/core.c      |   10 ++++-
>>  6 files changed, 116 insertions(+), 19 deletions(-)  mode change 
>> 100644 => 100755 include/net/bluetooth/hci.h  mode change 100644 => 
>> 100755 include/net/bluetooth/hci_core.h  mode change 100644 
>=> 100755 
>> net/bluetooth/hci_conn.c  mode change 100644 => 100755 
>> net/bluetooth/hci_event.c  mode change 100644 => 100755 
>> net/bluetooth/rfcomm/core.c
>
>You are changing the files modes. Don't do that.
>
>--
>Gustavo F. Padovan
>ProFUSION embedded systems - http://profusion.mobi
>

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

end of thread, other threads:[~2010-08-30  6:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-27 11:44 [PATCH] Bluetooth: BT_SECURITY_HIGH requires 16 digit pin code Waldemar Rymarkiewicz
2010-08-27 19:45 ` Antonio Ospite
2010-08-27 19:55 ` Gustavo F. Padovan
2010-08-30  6:58   ` Waldemar.Rymarkiewicz

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