summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_event.c48
-rw-r--r--net/bluetooth/l2cap_core.c21
-rw-r--r--net/bluetooth/mgmt.c20
-rw-r--r--net/bluetooth/smp.c11
4 files changed, 88 insertions, 12 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4eefb7f65cf6..94ad124a4ea3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3043,6 +3043,50 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
3043 hci_dev_unlock(hdev); 3043 hci_dev_unlock(hdev);
3044} 3044}
3045 3045
3046static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3047 struct sk_buff *skb)
3048{
3049 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3050 struct hci_conn *conn;
3051
3052 BT_DBG("%s status %u handle %u", hdev->name, ev->status,
3053 __le16_to_cpu(ev->handle));
3054
3055 hci_dev_lock(hdev);
3056
3057 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3058 if (!conn)
3059 goto unlock;
3060
3061 if (!ev->status)
3062 conn->sec_level = conn->pending_sec_level;
3063
3064 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3065
3066 if (ev->status && conn->state == BT_CONNECTED) {
3067 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
3068 hci_conn_put(conn);
3069 goto unlock;
3070 }
3071
3072 if (conn->state == BT_CONFIG) {
3073 if (!ev->status)
3074 conn->state = BT_CONNECTED;
3075
3076 hci_proto_connect_cfm(conn, ev->status);
3077 hci_conn_put(conn);
3078 } else {
3079 hci_auth_cfm(conn, ev->status);
3080
3081 hci_conn_hold(conn);
3082 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3083 hci_conn_put(conn);
3084 }
3085
3086unlock:
3087 hci_dev_unlock(hdev);
3088}
3089
3046static inline u8 hci_get_auth_req(struct hci_conn *conn) 3090static inline u8 hci_get_auth_req(struct hci_conn *conn)
3047{ 3091{
3048 /* If remote requests dedicated bonding follow that lead */ 3092 /* If remote requests dedicated bonding follow that lead */
@@ -3559,6 +3603,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3559 hci_extended_inquiry_result_evt(hdev, skb); 3603 hci_extended_inquiry_result_evt(hdev, skb);
3560 break; 3604 break;
3561 3605
3606 case HCI_EV_KEY_REFRESH_COMPLETE:
3607 hci_key_refresh_complete_evt(hdev, skb);
3608 break;
3609
3562 case HCI_EV_IO_CAPA_REQUEST: 3610 case HCI_EV_IO_CAPA_REQUEST:
3563 hci_io_capa_request_evt(hdev, skb); 3611 hci_io_capa_request_evt(hdev, skb);
3564 break; 3612 break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 24f144b72a96..4554e80d16a3 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1295,7 +1295,12 @@ static void security_timeout(struct work_struct *work)
1295 struct l2cap_conn *conn = container_of(work, struct l2cap_conn, 1295 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1296 security_timer.work); 1296 security_timer.work);
1297 1297
1298 l2cap_conn_del(conn->hcon, ETIMEDOUT); 1298 BT_DBG("conn %p", conn);
1299
1300 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1301 smp_chan_destroy(conn);
1302 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1303 }
1299} 1304}
1300 1305
1301static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) 1306static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
@@ -2910,12 +2915,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
2910 while (len >= L2CAP_CONF_OPT_SIZE) { 2915 while (len >= L2CAP_CONF_OPT_SIZE) {
2911 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); 2916 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2912 2917
2913 switch (type) { 2918 if (type != L2CAP_CONF_RFC)
2914 case L2CAP_CONF_RFC: 2919 continue;
2915 if (olen == sizeof(rfc)) 2920
2916 memcpy(&rfc, (void *)val, olen); 2921 if (olen != sizeof(rfc))
2917 goto done; 2922 break;
2918 } 2923
2924 memcpy(&rfc, (void *)val, olen);
2925 goto done;
2919 } 2926 }
2920 2927
2921 /* Use sane default values in case a misbehaving remote device 2928 /* Use sane default values in case a misbehaving remote device
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 25d220776079..3e5e3362ea00 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1598,7 +1598,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1598 else 1598 else
1599 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); 1599 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
1600 1600
1601 if (!conn) { 1601 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) {
1602 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1602 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT,
1603 MGMT_STATUS_NOT_CONNECTED); 1603 MGMT_STATUS_NOT_CONNECTED);
1604 goto failed; 1604 goto failed;
@@ -1873,6 +1873,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1873 pairing_complete(cmd, mgmt_status(status)); 1873 pairing_complete(cmd, mgmt_status(status));
1874} 1874}
1875 1875
1876static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
1877{
1878 struct pending_cmd *cmd;
1879
1880 BT_DBG("status %u", status);
1881
1882 if (!status)
1883 return;
1884
1885 cmd = find_pairing(conn);
1886 if (!cmd)
1887 BT_DBG("Unable to find a pending command");
1888 else
1889 pairing_complete(cmd, mgmt_status(status));
1890}
1891
1876static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, 1892static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1877 u16 len) 1893 u16 len)
1878{ 1894{
@@ -1934,6 +1950,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1934 /* For LE, just connecting isn't a proof that the pairing finished */ 1950 /* For LE, just connecting isn't a proof that the pairing finished */
1935 if (cp->addr.type == BDADDR_BREDR) 1951 if (cp->addr.type == BDADDR_BREDR)
1936 conn->connect_cfm_cb = pairing_complete_cb; 1952 conn->connect_cfm_cb = pairing_complete_cb;
1953 else
1954 conn->connect_cfm_cb = le_connect_complete_cb;
1937 1955
1938 conn->security_cfm_cb = pairing_complete_cb; 1956 conn->security_cfm_cb = pairing_complete_cb;
1939 conn->disconn_cfm_cb = pairing_complete_cb; 1957 conn->disconn_cfm_cb = pairing_complete_cb;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 6fc7c4708f3e..37df4e9b3896 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -648,7 +648,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
648 648
649 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; 649 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
650 650
651 ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability); 651 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
652 if (ret) 652 if (ret)
653 return SMP_UNSPECIFIED; 653 return SMP_UNSPECIFIED;
654 654
@@ -703,7 +703,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
703 return 0; 703 return 0;
704} 704}
705 705
706static u8 smp_ltk_encrypt(struct l2cap_conn *conn) 706static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
707{ 707{
708 struct smp_ltk *key; 708 struct smp_ltk *key;
709 struct hci_conn *hcon = conn->hcon; 709 struct hci_conn *hcon = conn->hcon;
@@ -712,6 +712,9 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
712 if (!key) 712 if (!key)
713 return 0; 713 return 0;
714 714
715 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
716 return 0;
717
715 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 718 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
716 return 1; 719 return 1;
717 720
@@ -732,7 +735,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
732 735
733 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); 736 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
734 737
735 if (smp_ltk_encrypt(conn)) 738 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
736 return 0; 739 return 0;
737 740
738 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 741 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
@@ -771,7 +774,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
771 return 1; 774 return 1;
772 775
773 if (hcon->link_mode & HCI_LM_MASTER) 776 if (hcon->link_mode & HCI_LM_MASTER)
774 if (smp_ltk_encrypt(conn)) 777 if (smp_ltk_encrypt(conn, sec_level))
775 goto done; 778 goto done;
776 779
777 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 780 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))