* [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses
@ 2011-04-28 18:28 johan.hedberg
2011-04-28 18:28 ` [PATCH 02/12] Bluetooth: Add variable SSP auto-accept delay support johan.hedberg
` (10 more replies)
0 siblings, 11 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
This patch adds automated negative and positive (auto-accept) responses
for Secure Simple Pairing user confirmation requests. The responses are
only sent if the HCI_MGMT flag is set in order not to confuse older user
space versions (without management interface support).
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 37 +++++++++++++++++++++++++++++++++++--
1 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 577d638..514e10e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2483,14 +2483,47 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
+ int loc_mitm, rem_mitm;
+ struct hci_conn *conn;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+ if (!test_bit(HCI_MGMT, &hdev->flags))
+ goto unlock;
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (!conn)
+ goto unlock;
+
+ loc_mitm = (conn->auth_type & 0x01);
+ rem_mitm = (conn->remote_auth & 0x01);
+
+ /* If we require MITM but the remote device can't provide that
+ * (it has NoInputNoOutput) then reject the confirmation
+ * request. The only exception is when we're dedicated bonding
+ * initiators (connect_cfm_cb set) since then we always have the MITM
+ * bit set. */
+ if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
+ BT_DBG("Rejecting request: remote device can't provide MITM");
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
+ sizeof(ev->bdaddr), &ev->bdaddr);
+ goto unlock;
+ }
+
+ /* If no side requires MITM protection; auto-accept */
+ if ((!loc_mitm || conn->remote_cap == 0x03) &&
+ (!rem_mitm || conn->io_capability == 0x03)) {
+ BT_DBG("Auto-accept of user confirmation");
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
+ sizeof(ev->bdaddr), &ev->bdaddr);
+ goto unlock;
+ }
+
+ mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+
+unlock:
hci_dev_unlock(hdev);
}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/12] Bluetooth: Add variable SSP auto-accept delay support
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
@ 2011-04-28 18:28 ` johan.hedberg
2011-04-28 18:28 ` [PATCH 03/12] Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests johan.hedberg
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
Some test systems require an arbitrary delay to the auto-accept test
cases for Secure Simple Pairing in order for the tests to pass.
Previously when this was handled in user space it was worked around by
code modifications and recompilation, but now that it's on the kernel
side it's more convenient if there's a debugfs interface for it.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 3 +++
net/bluetooth/hci_conn.c | 17 +++++++++++++++++
net/bluetooth/hci_event.c | 10 +++++++++-
net/bluetooth/hci_sysfs.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 60 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2995e2e..09b9dd6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -126,6 +126,8 @@ struct hci_dev {
__u16 sniff_min_interval;
__u16 sniff_max_interval;
+ unsigned int auto_accept_delay;
+
unsigned long quirks;
atomic_t cmd_cnt;
@@ -246,6 +248,7 @@ struct hci_conn {
struct timer_list disc_timer;
struct timer_list idle_timer;
+ struct timer_list auto_accept_timer;
struct work_struct work_add;
struct work_struct work_del;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 74cd755..7f5ad8a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg)
hci_conn_enter_sniff_mode(conn);
}
+static void hci_conn_auto_accept(unsigned long arg)
+{
+ struct hci_conn *conn = (void *) arg;
+ struct hci_dev *hdev = conn->hdev;
+
+ hci_dev_lock(hdev);
+
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
+ &conn->dst);
+
+ hci_dev_unlock(hdev);
+}
+
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
@@ -312,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
+ setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
+ (unsigned long) conn);
atomic_set(&conn->refcnt, 0);
@@ -342,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn)
del_timer(&conn->disc_timer);
+ del_timer(&conn->auto_accept_timer);
+
if (conn->type == ACL_LINK) {
struct hci_conn *sco = conn->link;
if (sco)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 514e10e..a479389 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2515,7 +2515,15 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
/* If no side requires MITM protection; auto-accept */
if ((!loc_mitm || conn->remote_cap == 0x03) &&
(!rem_mitm || conn->io_capability == 0x03)) {
- BT_DBG("Auto-accept of user confirmation");
+ BT_DBG("Auto-accept of user confirmation with %ums delay",
+ hdev->auto_accept_delay);
+
+ if (hdev->auto_accept_delay > 0) {
+ int delay = msecs_to_jiffies(hdev->auto_accept_delay);
+ mod_timer(&conn->auto_accept_timer, jiffies + delay);
+ goto unlock;
+ }
+
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
goto unlock;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 8775933..a6c3aa8 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -511,6 +511,35 @@ static const struct file_operations uuids_fops = {
.release = single_release,
};
+static int auto_accept_delay_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock_bh(hdev);
+
+ hdev->auto_accept_delay = val;
+
+ hci_dev_unlock_bh(hdev);
+
+ return 0;
+}
+
+static int auto_accept_delay_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock_bh(hdev);
+
+ *val = hdev->auto_accept_delay;
+
+ hci_dev_unlock_bh(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
+ auto_accept_delay_set, "%llu\n");
+
int hci_register_sysfs(struct hci_dev *hdev)
{
struct device *dev = &hdev->dev;
@@ -545,6 +574,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
+ debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev,
+ &auto_accept_delay_fops);
return 0;
}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/12] Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
2011-04-28 18:28 ` [PATCH 02/12] Bluetooth: Add variable SSP auto-accept delay support johan.hedberg
@ 2011-04-28 18:28 ` johan.hedberg
2011-04-28 18:28 ` [PATCH 04/12] Bluetooth: Add confirm_hint parameter to user confirmation requests johan.hedberg
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
The HCI_CONN_AUTH_PEND flag should be set whenever requesting
authentication so that multiple pending requests can't occur.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 22 ++++++++++++++++++----
1 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a479389..94c1296 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1021,12 +1021,19 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
- if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ if (!conn)
+ goto unlock;
+
+ if (!hci_outgoing_auth_needed(hdev, conn))
+ goto unlock;
+
+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
- cp.handle = __cpu_to_le16(conn->handle);
+ cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
+unlock:
hci_dev_unlock(hdev);
}
@@ -1516,12 +1523,19 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
- if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ if (!conn)
+ goto unlock;
+
+ if (!hci_outgoing_auth_needed(hdev, conn))
+ goto unlock;
+
+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
- cp.handle = __cpu_to_le16(conn->handle);
+ cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
+unlock:
hci_dev_unlock(hdev);
}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/12] Bluetooth: Add confirm_hint parameter to user confirmation requests
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
2011-04-28 18:28 ` [PATCH 02/12] Bluetooth: Add variable SSP auto-accept delay support johan.hedberg
2011-04-28 18:28 ` [PATCH 03/12] Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests johan.hedberg
@ 2011-04-28 18:28 ` johan.hedberg
2011-04-28 18:28 ` [PATCH 05/12] Bluetooth: Fix reason code for pairing rejection johan.hedberg
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
When accepting a pairing request which fulfills the SSP auto-accept
criteria we need to push the request all the way to the user for
confirmation. This patch adds a new hint to the user_confirm_request
management event so user space can know when to show a numeric
comparison dialog and when to show a simple yes/no confirmation dialog.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 3 ++-
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_event.c | 16 ++++++++++++++--
net/bluetooth/mgmt.c | 4 +++-
4 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 09b9dd6..135dfac 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -783,7 +783,8 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
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);
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
+ u8 confirm_hint);
int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
u8 status);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 0e7de63..c444a2b 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -259,6 +259,7 @@ struct mgmt_ev_pin_code_request {
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
+ __u8 confirm_hint;
__le32 value;
} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 94c1296..470fab4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2497,7 +2497,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
- int loc_mitm, rem_mitm;
+ int loc_mitm, rem_mitm, confirm_hint = 0;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
@@ -2529,6 +2529,16 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
/* If no side requires MITM protection; auto-accept */
if ((!loc_mitm || conn->remote_cap == 0x03) &&
(!rem_mitm || conn->io_capability == 0x03)) {
+
+ /* If we're not the initiators request authorization to
+ * proceed from user space (mgmt_user_confirm with
+ * confirm_hint set to 1). */
+ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
+ BT_DBG("Confirming auto-accept as acceptor");
+ confirm_hint = 1;
+ goto confirm;
+ }
+
BT_DBG("Auto-accept of user confirmation with %ums delay",
hdev->auto_accept_delay);
@@ -2543,7 +2553,9 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
goto unlock;
}
- mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+confirm:
+ mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey,
+ confirm_hint);
unlock:
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a7b4937..a1b0ec4 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1995,13 +1995,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
return err;
}
-int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
+ u8 confirm_hint)
{
struct mgmt_ev_user_confirm_request ev;
BT_DBG("hci%u", index);
bacpy(&ev.bdaddr, bdaddr);
+ ev.confirm_hint = confirm_hint;
put_unaligned_le32(value, &ev.value);
return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 05/12] Bluetooth: Fix reason code for pairing rejection
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (2 preceding siblings ...)
2011-04-28 18:28 ` [PATCH 04/12] Bluetooth: Add confirm_hint parameter to user confirmation requests johan.hedberg
@ 2011-04-28 18:28 ` johan.hedberg
2011-04-28 18:28 ` [PATCH 06/12] Bluetooth: Fix logic in hci_pin_code_request_evt johan.hedberg
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
"Pairing not allowed" is 0x18 and not 0x16.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
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 470fab4..278a860 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2462,7 +2462,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
struct hci_cp_io_capability_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
- cp.reason = 0x16; /* Pairing not allowed */
+ cp.reason = 0x18; /* Pairing not allowed */
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
sizeof(cp), &cp);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/12] Bluetooth: Fix logic in hci_pin_code_request_evt
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (3 preceding siblings ...)
2011-04-28 18:28 ` [PATCH 05/12] Bluetooth: Fix reason code for pairing rejection johan.hedberg
@ 2011-04-28 18:28 ` johan.hedberg
2011-04-28 18:28 ` [PATCH 07/12] Bluetooth: Fix link key persistent storage criteria johan.hedberg
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
The mgmt_ev_pin_code_request event should not be sent to user space if
the request gets rejected by the kernel due to the pairable flag not
being set.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 278a860..8b72b8a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2035,8 +2035,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
if (!test_bit(HCI_PAIRABLE, &hdev->flags))
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
-
- if (test_bit(HCI_MGMT, &hdev->flags)) {
+ else if (test_bit(HCI_MGMT, &hdev->flags)) {
u8 secure;
if (conn->pending_sec_level == BT_SECURITY_HIGH)
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/12] Bluetooth: Fix link key persistent storage criteria
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (4 preceding siblings ...)
2011-04-28 18:28 ` [PATCH 06/12] Bluetooth: Fix logic in hci_pin_code_request_evt johan.hedberg
@ 2011-04-28 18:28 ` johan.hedberg
2011-04-28 18:29 ` [PATCH 08/12] Bluetooth: Fix old_key_type logic for non-persistent keys johan.hedberg
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
Link keys should only be stored if very specific criteria of the
authentication process are fulfilled. This patch essentially copies the
criteria that user space has so far been using to the kernel side so
that the management interface works properly.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 4 +-
net/bluetooth/hci_core.c | 54 ++++++++++++++++++++++++++++++++++++-
net/bluetooth/hci_event.c | 2 +-
net/bluetooth/mgmt.c | 2 +-
4 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 135dfac..3a3f7b4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -515,8 +515,8 @@ int hci_uuids_clear(struct hci_dev *hdev);
int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 *key, u8 type, u8 pin_len);
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+ bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 07d0ba3..85fae57 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1022,8 +1022,44 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return NULL;
}
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 *val, u8 type, u8 pin_len)
+int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
+ u8 key_type, u8 old_key_type)
+{
+ /* Legacy key */
+ if (key_type < 0x03)
+ return 1;
+
+ /* Debug keys are insecure so don't store them persistently */
+ if (key_type == HCI_LK_DEBUG_COMBINATION)
+ return 0;
+
+ /* Changed combination key and there's no previous one */
+ if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
+ return 0;
+
+ /* Security mode 3 case */
+ if (!conn)
+ return 1;
+
+ /* Neither local nor remote side had no-bonding as requirement */
+ if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
+ return 1;
+
+ /* Local side had dedicated bonding as requirement */
+ if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
+ return 1;
+
+ /* Remote side had dedicated bonding as requirement */
+ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
+ return 1;
+
+ /* If none of the above criteria match, then don't store the key
+ * persistently */
+ return 0;
+}
+
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+ bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
{
struct link_key *key, *old_key;
u8 old_key_type;
@@ -1042,6 +1078,20 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
+ /* Some buggy controller combinations generate a changed
+ * combination key for legacy pairing even when there's no
+ * previous key */
+ if (type == HCI_LK_CHANGED_COMBINATION &&
+ (!conn || conn->remote_auth == 0xff) &&
+ old_key_type == 0xff)
+ type = HCI_LK_COMBINATION;
+
+ if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
+ list_del(&key->list);
+ kfree(key);
+ return 0;
+ }
+
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
key->type = type;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8b72b8a..8dfd386 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2136,7 +2136,7 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
}
if (test_bit(HCI_LINK_KEYS, &hdev->flags))
- hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
+ hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len);
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a1b0ec4..e1384fc 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
for (i = 0; i < key_count; i++) {
struct mgmt_key_info *key = &cp->keys[i];
- hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
+ hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
key->pin_len);
}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/12] Bluetooth: Fix old_key_type logic for non-persistent keys
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (5 preceding siblings ...)
2011-04-28 18:28 ` [PATCH 07/12] Bluetooth: Fix link key persistent storage criteria johan.hedberg
@ 2011-04-28 18:29 ` johan.hedberg
2011-04-28 18:29 ` [PATCH 09/12] Bluetooth: Fix connection key type updating for buggy controllers johan.hedberg
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
Even if there's no previous key stored the connection might still be
secured with a non-persistent key and in that case the key type in the
hci_conn struct should be checked.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_core.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 85fae57..88ed4ff 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1069,7 +1069,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
old_key_type = old_key->type;
key = old_key;
} else {
- old_key_type = 0xff;
+ old_key_type = conn ? conn->key_type : 0xff;
key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 09/12] Bluetooth: Fix connection key type updating for buggy controllers
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (6 preceding siblings ...)
2011-04-28 18:29 ` [PATCH 08/12] Bluetooth: Fix old_key_type logic for non-persistent keys johan.hedberg
@ 2011-04-28 18:29 ` johan.hedberg
2011-04-28 18:29 ` [PATCH 10/12] Bluetooth: Remove old_key_type from mgmt_ev_new_key johan.hedberg
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
If a controller generates a changed combination key as its first key the
connection key type will not be correctly set. In these situations make
sure the update the connection key type when such a buggy controller is
detected.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_core.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 88ed4ff..1531dd7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1083,8 +1083,11 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
* previous key */
if (type == HCI_LK_CHANGED_COMBINATION &&
(!conn || conn->remote_auth == 0xff) &&
- old_key_type == 0xff)
+ old_key_type == 0xff) {
type = HCI_LK_COMBINATION;
+ if (conn)
+ conn->key_type = type;
+ }
if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
list_del(&key->list);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/12] Bluetooth: Remove old_key_type from mgmt_ev_new_key
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (7 preceding siblings ...)
2011-04-28 18:29 ` [PATCH 09/12] Bluetooth: Fix connection key type updating for buggy controllers johan.hedberg
@ 2011-04-28 18:29 ` johan.hedberg
2011-04-28 18:29 ` [PATCH 11/12] Bluetooth: Add store_hint parameter to mgmt_new_key johan.hedberg
2011-04-28 18:29 ` [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt johan.hedberg
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
User space shouldn't have any need for the old key type so remove it
from the corresponding Management interface event.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 2 +-
include/net/bluetooth/mgmt.h | 1 -
net/bluetooth/hci_core.c | 9 +++++----
net/bluetooth/mgmt.c | 3 +--
4 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3a3f7b4..88c2cd9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -775,7 +775,7 @@ int mgmt_index_removed(u16 index);
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
+int mgmt_new_key(u16 index, struct link_key *key);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index c444a2b..353a85d 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -231,7 +231,6 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
struct mgmt_key_info key;
- __u8 old_key_type;
} __packed;
#define MGMT_EV_CONNECTED 0x000B
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1531dd7..13ac796 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1097,14 +1097,15 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
- key->type = type;
key->pin_len = pin_len;
- if (new_key)
- mgmt_new_key(hdev->id, key, old_key_type);
-
if (type == HCI_LK_CHANGED_COMBINATION)
key->type = old_key_type;
+ else
+ key->type = type;
+
+ if (new_key)
+ mgmt_new_key(hdev->id, key);
return 0;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e1384fc..232ea8b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1858,7 +1858,7 @@ int mgmt_connectable(u16 index, u8 connectable)
return ret;
}
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
+int mgmt_new_key(u16 index, struct link_key *key)
{
struct mgmt_ev_new_key ev;
@@ -1868,7 +1868,6 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
ev.key.pin_len = key->pin_len;
- ev.old_key_type = old_key_type;
return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 11/12] Bluetooth: Add store_hint parameter to mgmt_new_key
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (8 preceding siblings ...)
2011-04-28 18:29 ` [PATCH 10/12] Bluetooth: Remove old_key_type from mgmt_ev_new_key johan.hedberg
@ 2011-04-28 18:29 ` johan.hedberg
2011-04-28 18:29 ` [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt johan.hedberg
10 siblings, 0 replies; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
Even for keys that shouldn't be stored some use cases require the
knowledge of a new key having been created so that the conclusion of a
successful pairing can be made. Therefore, always send the mgmt_new_key
event but add a store_hint parameter to it to indicate to user space
whether the key should be stored or not.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 2 +-
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_core.c | 21 ++++++++++++---------
net/bluetooth/mgmt.c | 3 ++-
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 88c2cd9..14cc324 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -775,7 +775,7 @@ int mgmt_index_removed(u16 index);
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key);
+int mgmt_new_key(u16 index, struct link_key *key, u8 persistent);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 353a85d..4899286 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -230,6 +230,7 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
+ __u8 store_hint;
struct mgmt_key_info key;
} __packed;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 13ac796..dfc600c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1062,7 +1062,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
{
struct link_key *key, *old_key;
- u8 old_key_type;
+ u8 old_key_type, persistent;
old_key = hci_find_link_key(hdev, bdaddr);
if (old_key) {
@@ -1089,12 +1089,6 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
conn->key_type = type;
}
- if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
- list_del(&key->list);
- kfree(key);
- return 0;
- }
-
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
key->pin_len = pin_len;
@@ -1104,8 +1098,17 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
else
key->type = type;
- if (new_key)
- mgmt_new_key(hdev->id, key);
+ if (!new_key)
+ return 0;
+
+ persistent = hci_persistent_key(hdev, conn, type, old_key_type);
+
+ mgmt_new_key(hdev->id, key, persistent);
+
+ if (!persistent) {
+ list_del(&key->list);
+ kfree(key);
+ }
return 0;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 232ea8b..2481d25 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1858,12 +1858,13 @@ int mgmt_connectable(u16 index, u8 connectable)
return ret;
}
-int mgmt_new_key(u16 index, struct link_key *key)
+int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
{
struct mgmt_ev_new_key ev;
memset(&ev, 0, sizeof(ev));
+ ev.store_hint = persistent;
bacpy(&ev.key.bdaddr, &key->bdaddr);
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
` (9 preceding siblings ...)
2011-04-28 18:29 ` [PATCH 11/12] Bluetooth: Add store_hint parameter to mgmt_new_key johan.hedberg
@ 2011-04-28 18:29 ` johan.hedberg
2011-04-28 19:18 ` Gustavo F. Padovan
10 siblings, 1 reply; 13+ messages in thread
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
In some circumstances hci_get_auth_req will return a value different
from the current conn->auth_type. In these cases update conn->auth_type
so that when a user confirm request comes it doesn't falsely trigger
auto-accept.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8dfd386..f6219e2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2447,7 +2447,8 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.capability = conn->io_capability;
- cp.authentication = hci_get_auth_req(conn);
+ conn->auth_type = hci_get_auth_req(conn);
+ cp.authentication = conn->auth_type;
if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
hci_find_remote_oob_data(hdev, &conn->dst))
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt
2011-04-28 18:29 ` [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt johan.hedberg
@ 2011-04-28 19:18 ` Gustavo F. Padovan
0 siblings, 0 replies; 13+ messages in thread
From: Gustavo F. Padovan @ 2011-04-28 19:18 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
* johan.hedberg@gmail.com <johan.hedberg@gmail.com> [2011-04-28 11:29:04 -0700]:
> From: Johan Hedberg <johan.hedberg@nokia.com>
>
> In some circumstances hci_get_auth_req will return a value different
> from the current conn->auth_type. In these cases update conn->auth_type
> so that when a user confirm request comes it doesn't falsely trigger
> auto-accept.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
> ---
> net/bluetooth/hci_event.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 8dfd386..f6219e2 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -2447,7 +2447,8 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
>
> bacpy(&cp.bdaddr, &ev->bdaddr);
> cp.capability = conn->io_capability;
> - cp.authentication = hci_get_auth_req(conn);
> + conn->auth_type = hci_get_auth_req(conn);
> + cp.authentication = conn->auth_type;
>
> if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
> hci_find_remote_oob_data(hdev, &conn->dst))
All applied, thanks for fixes.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-04-28 19:18 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-28 18:28 [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses johan.hedberg
2011-04-28 18:28 ` [PATCH 02/12] Bluetooth: Add variable SSP auto-accept delay support johan.hedberg
2011-04-28 18:28 ` [PATCH 03/12] Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests johan.hedberg
2011-04-28 18:28 ` [PATCH 04/12] Bluetooth: Add confirm_hint parameter to user confirmation requests johan.hedberg
2011-04-28 18:28 ` [PATCH 05/12] Bluetooth: Fix reason code for pairing rejection johan.hedberg
2011-04-28 18:28 ` [PATCH 06/12] Bluetooth: Fix logic in hci_pin_code_request_evt johan.hedberg
2011-04-28 18:28 ` [PATCH 07/12] Bluetooth: Fix link key persistent storage criteria johan.hedberg
2011-04-28 18:29 ` [PATCH 08/12] Bluetooth: Fix old_key_type logic for non-persistent keys johan.hedberg
2011-04-28 18:29 ` [PATCH 09/12] Bluetooth: Fix connection key type updating for buggy controllers johan.hedberg
2011-04-28 18:29 ` [PATCH 10/12] Bluetooth: Remove old_key_type from mgmt_ev_new_key johan.hedberg
2011-04-28 18:29 ` [PATCH 11/12] Bluetooth: Add store_hint parameter to mgmt_new_key johan.hedberg
2011-04-28 18:29 ` [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt johan.hedberg
2011-04-28 19:18 ` Gustavo F. Padovan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).