summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 69839797b7dc..da46d76fc13d 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -336,9 +336,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_security_req *rp = (void *) skb->data;
struct smp_cmd_pairing cp;
+ struct hci_conn *hcon = conn->hcon;
BT_DBG("conn %p", conn);
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+ return;
+
skb_pull(skb, sizeof(*rp));
memset(&cp, 0, sizeof(cp));
@@ -353,6 +357,20 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
memcpy(&conn->preq[1], &cp, sizeof(cp));
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+
+ set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+}
+
+static __u8 seclevel_to_authreq(__u8 level)
+{
+ switch (level) {
+ case BT_SECURITY_HIGH:
+ /* For now we don't support bonding */
+ return SMP_AUTH_MITM;
+
+ default:
+ return SMP_AUTH_NONE;
+ }
}
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -365,21 +383,16 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
if (IS_ERR(hcon->hdev->tfm))
return 1;
- switch (sec_level) {
- case BT_SECURITY_MEDIUM:
- /* Encrypted, no MITM protection */
- authreq = HCI_AT_NO_BONDING_MITM;
- break;
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+ return 0;
- case BT_SECURITY_HIGH:
- /* Bonding, MITM protection */
- authreq = HCI_AT_GENERAL_BONDING_MITM;
- break;
+ if (sec_level == BT_SECURITY_LOW)
+ return 1;
- case BT_SECURITY_LOW:
- default:
+ if (hcon->sec_level >= sec_level)
return 1;
- }
+
+ authreq = seclevel_to_authreq(sec_level);
if (hcon->link_mode & HCI_LM_MASTER) {
struct smp_cmd_pairing cp;
@@ -400,6 +413,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
}
+ hcon->pending_sec_level = sec_level;
+ set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+
return 0;
}
OpenPOWER on IntegriCloud