|
@@ -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_security_req *rp = (void *) skb->data;
|
|
struct smp_cmd_pairing cp;
|
|
struct smp_cmd_pairing cp;
|
|
|
|
+ struct hci_conn *hcon = conn->hcon;
|
|
|
|
|
|
BT_DBG("conn %p", conn);
|
|
BT_DBG("conn %p", conn);
|
|
|
|
|
|
|
|
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
|
|
|
|
+ return;
|
|
|
|
+
|
|
skb_pull(skb, sizeof(*rp));
|
|
skb_pull(skb, sizeof(*rp));
|
|
memset(&cp, 0, sizeof(cp));
|
|
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));
|
|
memcpy(&conn->preq[1], &cp, sizeof(cp));
|
|
|
|
|
|
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &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)
|
|
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))
|
|
if (IS_ERR(hcon->hdev->tfm))
|
|
return 1;
|
|
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;
|
|
return 1;
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ authreq = seclevel_to_authreq(sec_level);
|
|
|
|
|
|
if (hcon->link_mode & HCI_LM_MASTER) {
|
|
if (hcon->link_mode & HCI_LM_MASTER) {
|
|
struct smp_cmd_pairing cp;
|
|
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);
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|