2011-04-28 10:07:52

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 0/7] Handle link key type and security requirements

Johan,

I modified patch 6/7 according to your comment and have added a new patch 7/7 which is an
extension of mgmt api to require secure pin code.

Thanks,
Waldek

Waldemar Rymarkiewicz (7):
Bluetooth: Add definitions for link key types
Bluetooth: Don't modify sec_level if auth failed
Bluetooth: Map sec_level to link key requirements
Bluetooth: Ignore key unauthenticated for high security
Bluetooth: Double check sec req for pre 2.1 device
Bluetooth: Respect local MITM req in io_cap reply
Bluetooth: Add secure flag for mgmt_pin_code_req

include/net/bluetooth/hci.h | 9 +++++
include/net/bluetooth/hci_core.h | 3 +-
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_conn.c | 61 +++++++++++++++++++++++++++++++------
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/hci_event.c | 39 ++++++++++++++++++-----
net/bluetooth/mgmt.c | 3 +-
net/bluetooth/rfcomm/core.c | 17 ++++++++++-
8 files changed, 112 insertions(+), 23 deletions(-)



2011-04-29 08:30:56

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: RE: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

Johan,

>Never mind. d->sec_level is obviously the security requirement
>for the RFCOMM link which could be different from the current
>ACL security level. Nevertheless, I think instead of doing the
>complicated if-statement on the key_type & pin_length you can
>simply check the value of conn->sec_level.
>

I agree. Will update and send again.

Waldek

2011-04-29 08:23:50

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: RE: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

Hi Gustavo,

>> +static int rfcomm_accept_secure(struct hci_conn *conn, struct
>> +rfcomm_dlc *d) {
>> + BT_DBG("");
>> +
>> + if (d->sec_level != BT_SECURITY_HIGH)
>> + return 1; /* Accept */
>> +
>> + if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
>> + (conn->key_type == HCI_LK_COMBINATION &&
>> + conn->pin_length == 16))
>> + return 1;
>> +
>> + return 0; /* Reject */
>> +}
>
>I don't like the idea of mix HCI and RFCOMM code, I prefer
>that you create an hci_accept_secure(conn, d->sec_level) instead.

We could do like this

static int hci_accept_secure(hci_conn *conn, u8 required_sec_level)
{
if (required_sec_level != BT_SECURITY_HIGH)
return 1; /* Accept */

if (conn->sec_level == BT_SECURITY_HIGH)
return 1;

return 0;
}


Waldek

2011-04-29 08:10:57

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: RE: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

Hi Johan,

>> +static int rfcomm_accept_secure(struct hci_conn *conn, struct
>> +rfcomm_dlc *d) {
>> + BT_DBG("");
>> +
>> + if (d->sec_level != BT_SECURITY_HIGH)
>> + return 1; /* Accept */
>> +
>> + if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
>> + (conn->key_type == HCI_LK_COMBINATION &&
>> + conn->pin_length == 16))
>> + return 1;
>> +
>> + return 0; /* Reject */
>> +}
>
>If conn->key_type and conn->pin_length are like you want them
>to be in the second if-statement, shouldn't conn->sec_level
>already be BT_SECURITY_HIGH?

Yes, but if service requires BT_SECURITY_MEDIUM we should accept it as well. Thus, we need this first check.

>And if that's the case I guess
>you don't need a separate function at all: just check for
>conn->sec_level.

However, we could do like this

if (d->sec_level != BT_SECURITY_HIGH)
return 1; /* Accept */

If (conn->sec_level == BT_SECURITY_HIGH)
return 1; /* Accept */

return 0; /* Reject */

... and then perhaps we don't need a new function here.


> Btw, what purpose does d->sec_level serve
>when we already have conn->sec_level?

d->sec_level is required sec level for the service and conn->sec_level is the level that's already on the link.

/Waldek

2011-04-28 21:08:52

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

Hi,

On Thu, Apr 28, 2011, Johan Hedberg wrote:
> On Thu, Apr 28, 2011, Waldemar Rymarkiewicz wrote:
> > +static int rfcomm_accept_secure(struct hci_conn *conn, struct rfcomm_dlc *d)
> > +{
> > + BT_DBG("");
> > +
> > + if (d->sec_level != BT_SECURITY_HIGH)
> > + return 1; /* Accept */
> > +
> > + if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
> > + (conn->key_type == HCI_LK_COMBINATION &&
> > + conn->pin_length == 16))
> > + return 1;
> > +
> > + return 0; /* Reject */
> > +}
>
> If conn->key_type and conn->pin_length are like you want them to be in
> the second if-statement, shouldn't conn->sec_level already be
> BT_SECURITY_HIGH? And if that's the case I guess you don't need a
> separate function at all: just check for conn->sec_level. Btw, what
> purpose does d->sec_level serve when we already have conn->sec_level?

Never mind. d->sec_level is obviously the security requirement for the
RFCOMM link which could be different from the current ACL security
level. Nevertheless, I think instead of doing the complicated
if-statement on the key_type & pin_length you can simply check the value
of conn->sec_level.

Johan

2011-04-28 18:34:45

by Gustavo Padovan

[permalink] [raw]
Subject: Re: [PATCH v3 7/7] Bluetooth: Add secure flag for mgmt_pin_code_req

Hi Waldemar,

* Waldemar Rymarkiewicz <[email protected]> [2011-04-28 12:07:59 +0200]:

> Extend the mgmt_pin_code_request interface to require secure
> pin code (16 digit) for authentication.
>
> This is a kernel part of the secure pin code requirement notification
> to user space agent.
>
> Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
> ---
> include/net/bluetooth/hci_core.h | 2 +-
> include/net/bluetooth/mgmt.h | 1 +
> net/bluetooth/hci_event.c | 9 +++++++--
> net/bluetooth/mgmt.c | 3 ++-
> 4 files changed, 11 insertions(+), 4 deletions(-)

All patches but 5/7 were applied. thanks.

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

2011-04-28 18:11:17

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

Hi Waldek,

On Thu, Apr 28, 2011, Waldemar Rymarkiewicz wrote:
> +static int rfcomm_accept_secure(struct hci_conn *conn, struct rfcomm_dlc *d)
> +{
> + BT_DBG("");
> +
> + if (d->sec_level != BT_SECURITY_HIGH)
> + return 1; /* Accept */
> +
> + if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
> + (conn->key_type == HCI_LK_COMBINATION &&
> + conn->pin_length == 16))
> + return 1;
> +
> + return 0; /* Reject */
> +}

If conn->key_type and conn->pin_length are like you want them to be in
the second if-statement, shouldn't conn->sec_level already be
BT_SECURITY_HIGH? And if that's the case I guess you don't need a
separate function at all: just check for conn->sec_level. Btw, what
purpose does d->sec_level serve when we already have conn->sec_level?

Johan

2011-04-28 18:09:39

by Gustavo Padovan

[permalink] [raw]
Subject: Re: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

Hi Waldermar,

* Waldemar Rymarkiewicz <[email protected]> [2011-04-28 12:07:57 +0200]:

> In case of pre v2.1 devices authentication request will return
> success immediately if the link key already exists without any
> authentication process.
>
> That means, it's not possible to re-authenticate the link if you
> already have combination key and for instance want to re-authenticate
> to get the high security (use 16 digit pin).
>
> Therefore, it's necessary to check security requirements on auth
> complete event to prevent not enough secure connection.
>
> Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
> ---
> net/bluetooth/rfcomm/core.c | 17 ++++++++++++++++-
> 1 files changed, 16 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
> index 121a5c1..676fdec 100644
> --- a/net/bluetooth/rfcomm/core.c
> +++ b/net/bluetooth/rfcomm/core.c
> @@ -2057,6 +2057,21 @@ static int rfcomm_run(void *unused)
> return 0;
> }
>
> +static int rfcomm_accept_secure(struct hci_conn *conn, struct rfcomm_dlc *d)
> +{
> + BT_DBG("");
> +
> + if (d->sec_level != BT_SECURITY_HIGH)
> + return 1; /* Accept */
> +
> + if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
> + (conn->key_type == HCI_LK_COMBINATION &&
> + conn->pin_length == 16))
> + return 1;
> +
> + return 0; /* Reject */
> +}

I don't like the idea of mix HCI and RFCOMM code, I prefer that you create an
hci_accept_secure(conn, d->sec_level) instead.

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

2011-04-28 10:07:59

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 7/7] Bluetooth: Add secure flag for mgmt_pin_code_req

Extend the mgmt_pin_code_request interface to require secure
pin code (16 digit) for authentication.

This is a kernel part of the secure pin code requirement notification
to user space agent.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
include/net/bluetooth/hci_core.h | 2 +-
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_event.c | 9 +++++++--
net/bluetooth/mgmt.c | 3 ++-
4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2da2eb9..2995e2e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -777,7 +777,7 @@ int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
+int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 7434406..0e7de63 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -253,6 +253,7 @@ struct mgmt_ev_connect_failed {
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request {
bdaddr_t bdaddr;
+ __u8 secure;
} __packed;

#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9d50e90..5350ad0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2006,6 +2006,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
{
struct hci_ev_pin_code_req *ev = (void *) skb->data;
struct hci_conn *conn;
+ u8 secure = 0;

BT_DBG("%s", hdev->name);

@@ -2022,8 +2023,12 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);

- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_pin_code_request(hdev->id, &ev->bdaddr);
+ if (test_bit(HCI_MGMT, &hdev->flags)) {
+ if (conn->pending_sec_level == BT_SECURITY_HIGH)
+ secure = 1;
+
+ mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure);
+ }

hci_dev_unlock(hdev);
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 4542396..a7b4937 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1942,11 +1942,12 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
}

-int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
+int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure)
{
struct mgmt_ev_pin_code_request ev;

bacpy(&ev.bdaddr, bdaddr);
+ ev.secure = secure;

return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
NULL);
--
1.7.1


2011-04-28 10:07:58

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 6/7] Bluetooth: Respect local MITM req in io_cap reply

If host requires MITM protection notify that to controller in
io capabilities reply even if the remote device requires no bonding.

If it is not respected, host can get an unauthenticated link key while
it expects authenticated one.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
net/bluetooth/hci_event.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 40e96cd..9d50e90 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2397,7 +2397,7 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn)

/* If remote requests no-bonding follow that lead */
if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
- return 0x00;
+ return conn->remote_auth | (conn->auth_type & 0x01);

return conn->auth_type;
}
--
1.7.1


2011-04-28 10:07:57

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device

In case of pre v2.1 devices authentication request will return
success immediately if the link key already exists without any
authentication process.

That means, it's not possible to re-authenticate the link if you
already have combination key and for instance want to re-authenticate
to get the high security (use 16 digit pin).

Therefore, it's necessary to check security requirements on auth
complete event to prevent not enough secure connection.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
net/bluetooth/rfcomm/core.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 121a5c1..676fdec 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2057,6 +2057,21 @@ static int rfcomm_run(void *unused)
return 0;
}

+static int rfcomm_accept_secure(struct hci_conn *conn, struct rfcomm_dlc *d)
+{
+ BT_DBG("");
+
+ if (d->sec_level != BT_SECURITY_HIGH)
+ return 1; /* Accept */
+
+ if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
+ (conn->key_type == HCI_LK_COMBINATION &&
+ conn->pin_length == 16))
+ return 1;
+
+ return 0; /* Reject */
+}
+
static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
{
struct rfcomm_session *s;
@@ -2096,7 +2111,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
continue;

- if (!status)
+ if (!status && rfcomm_accept_secure(conn, d))
set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
else
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
--
1.7.1


2011-04-28 10:07:56

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 4/7] Bluetooth: Ignore key unauthenticated for high security

High security level for pre v2.1 devices requires combination link key
authenticated by at least 16 digit PIN code.

It's also necessary to update key_type and pin_length when the key
exists and is sufficently secured for the connection as there will be
no link key notify event in that case.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
net/bluetooth/hci_event.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 655af8b..40e96cd 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2059,11 +2059,23 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
}

conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (conn) {
+ if (key->type == HCI_LK_UNAUTH_COMBINATION &&
+ conn->auth_type != 0xff &&
+ (conn->auth_type & 0x01)) {
+ BT_DBG("%s ignoring unauthenticated key", hdev->name);
+ goto not_found;
+ }

- if (key->type == HCI_LK_UNAUTH_COMBINATION && conn &&
- conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
- BT_DBG("%s ignoring unauthenticated key", hdev->name);
- goto not_found;
+ if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
+ conn->pending_sec_level == BT_SECURITY_HIGH) {
+ BT_DBG("%s ignoring key unauthenticated for high \
+ security", hdev->name);
+ goto not_found;
+ }
+
+ conn->key_type = key->type;
+ conn->pin_length = key->pin_len;
}

bacpy(&cp.bdaddr, &ev->bdaddr);
--
1.7.1


2011-04-28 10:07:55

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 3/7] Bluetooth: Map sec_level to link key requirements

Keep the link key type together with connection and use it to
map security level to link key requirements. Authenticate and/or
encrypt connection if the link is insufficiently secure.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_conn.c | 61 +++++++++++++++++++++++++++++++------
net/bluetooth/hci_event.c | 4 ++
3 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 69967e5..2da2eb9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -226,6 +226,7 @@ struct hci_conn {
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
+ __u8 key_type;
__u8 auth_type;
__u8 sec_level;
__u8 pending_sec_level;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 7a6f56b..74cd755 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -287,6 +287,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->io_capability = hdev->io_capability;
conn->remote_auth = 0xff;
+ conn->key_type = 0xff;

conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
@@ -535,32 +536,72 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
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 = 0x01;
+ hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
+ &cp);
+ }
+}
+
/* Enable security */
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);

+ /* For sdp we don't need the link key. */
if (sec_level == BT_SECURITY_SDP)
return 1;

+ /* For non 2.1 devices and low security level we don't 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 the link key. */
+ if (!(conn->link_mode & HCI_LM_AUTH))
+ goto auth;
+
+ /* An authenticated combination key has sufficient security for any
+ security level. */
+ if (conn->key_type == HCI_LK_AUTH_COMBINATION)
+ goto encrypt;
+
+ /* An unauthenticated combination key has sufficient security for
+ security level 1 and 2. */
+ if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
+ (sec_level == BT_SECURITY_MEDIUM ||
+ sec_level == BT_SECURITY_LOW))
+ goto encrypt;
+
+ /* A combination key has always sufficient security for the security
+ levels 1 or 2. High security level requires the combination key
+ is generated using maximum PIN code length (16).
+ For pre 2.1 units. */
+ if (conn->key_type == HCI_LK_COMBINATION &&
+ (sec_level != BT_SECURITY_HIGH ||
+ conn->pin_length == 16))
+ goto encrypt;
+
+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;
+
+encrypt:
+ if (conn->link_mode & HCI_LM_ENCRYPT)
+ return 1;

+ hci_conn_encrypt(conn);
return 0;
}
EXPORT_SYMBOL(hci_conn_security);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 35f9898..655af8b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2095,6 +2095,10 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
pin_len = conn->pin_length;
+
+ if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
+ conn->key_type = ev->key_type;
+
hci_conn_put(conn);
}

--
1.7.1


2011-04-28 10:07:54

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 2/7] Bluetooth: Don't modify sec_level if auth failed

If authentication fails the security level should stay as it was set
before the process has started. Setting BT_SECURITY_LOW can hide real
security level on a link eg. having BT_SECURITY_MEDIUM on the link,
re-authenticate with failure to get BT_SECURITY_HIGH, as a result we
get BT_SECURITY_LOW on the link while the real security is still medium.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
net/bluetooth/hci_event.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index fbbb63f..35f9898 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1459,7 +1459,6 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn->sec_level = conn->pending_sec_level;
} else {
mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
- conn->sec_level = BT_SECURITY_LOW;
}

clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
--
1.7.1


2011-04-28 10:07:53

by Rymarkiewicz Waldemar

[permalink] [raw]
Subject: [PATCH v3 1/7] Bluetooth: Add definitions for link key types

Introduce the link key types defs and use them instead of magic numbers.

Signed-off-by: Waldemar Rymarkiewicz <[email protected]>
---
include/net/bluetooth/hci.h | 9 +++++++++
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/hci_event.c | 7 ++++---
3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 6138e31..e0a3cf1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -246,6 +246,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_UNAUTH_COMBINATION 0x04
+#define HCI_LK_AUTH_COMBINATION 0x05
+#define HCI_LK_CHANGED_COMBINATION 0x06
+
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 98aa24b..07d0ba3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1050,7 +1050,7 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
if (new_key)
mgmt_new_key(hdev->id, key, old_key_type);

- if (type == 0x06)
+ if (type == HCI_LK_CHANGED_COMBINATION)
key->type = old_key_type;

return 0;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e64a3de..fbbb63f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2053,15 +2053,16 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s found key type %u for %s", hdev->name, key->type,
batostr(&ev->bdaddr));

- if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
+ if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
+ key->type == HCI_LK_DEBUG_COMBINATION) {
BT_DBG("%s ignoring debug key", hdev->name);
goto not_found;
}

conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);

- if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
- (conn->auth_type & 0x01)) {
+ if (key->type == HCI_LK_UNAUTH_COMBINATION && conn &&
+ conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
BT_DBG("%s ignoring unauthenticated key", hdev->name);
goto not_found;
}
--
1.7.1