Loading net/bluetooth/hci_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -3872,6 +3872,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { BT_DBG("Deferring random address update"); set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); return; } Loading net/bluetooth/hci_event.c +7 −4 Original line number Diff line number Diff line Loading @@ -2438,6 +2438,12 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) } } /* We should disregard the current RPA and generate a new one * whenever the encryption procedure fails. */ if (ev->status && conn->type == LE_LINK) set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); if (ev->status && conn->state == BT_CONNECTED) { Loading Loading @@ -4506,10 +4512,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); cp.handle = cpu_to_le16(conn->handle); if (ltk->authenticated) conn->pending_sec_level = BT_SECURITY_HIGH; else conn->pending_sec_level = BT_SECURITY_MEDIUM; conn->pending_sec_level = smp_ltk_sec_level(ltk); conn->enc_key_size = ltk->enc_size; Loading net/bluetooth/l2cap_core.c +33 −20 Original line number Diff line number Diff line Loading @@ -1283,25 +1283,13 @@ static void l2cap_start_connection(struct l2cap_chan *chan) } } static void l2cap_do_start(struct l2cap_chan *chan) static void l2cap_request_info(struct l2cap_conn *conn) { struct l2cap_conn *conn = chan->conn; if (conn->hcon->type == LE_LINK) { l2cap_le_start(chan); return; } struct l2cap_info_req req; if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) return; if (l2cap_chan_check_security(chan, true) && __l2cap_no_conn_pending(chan)) { l2cap_start_connection(chan); } } else { struct l2cap_info_req req; req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; Loading @@ -1312,6 +1300,27 @@ static void l2cap_do_start(struct l2cap_chan *chan) l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, sizeof(req), &req); } static void l2cap_do_start(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; if (conn->hcon->type == LE_LINK) { l2cap_le_start(chan); return; } if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) { l2cap_request_info(conn); return; } if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) return; if (l2cap_chan_check_security(chan, true) && __l2cap_no_conn_pending(chan)) l2cap_start_connection(chan); } static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) Loading Loading @@ -1370,6 +1379,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) l2cap_chan_lock(chan); if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { l2cap_chan_ready(chan); l2cap_chan_unlock(chan); continue; } Loading Loading @@ -1474,6 +1484,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) BT_DBG("conn %p", conn); if (hcon->type == ACL_LINK) l2cap_request_info(conn); mutex_lock(&conn->chan_lock); list_for_each_entry(chan, &conn->chan_l, list) { Loading @@ -1488,8 +1501,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) if (hcon->type == LE_LINK) { l2cap_le_start(chan); } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) l2cap_chan_ready(chan); } else if (chan->state == BT_CONNECT) { l2cap_do_start(chan); } Loading net/bluetooth/smp.c +26 −31 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ #include "smp.h" #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) #define SMP_DISALLOW_CMD(smp, code) clear_bit(code, &smp->allow_cmd) #define SMP_TIMEOUT msecs_to_jiffies(30000) Loading Loading @@ -949,20 +948,22 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) if (!smp) return SMP_UNSPECIFIED; /* We didn't start the pairing, so match remote */ auth = req->auth_req & AUTH_REQ_MASK; if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && (req->auth_req & SMP_AUTH_BONDING)) (auth & SMP_AUTH_BONDING)) return SMP_PAIRING_NOTSUPP; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); smp->preq[0] = SMP_CMD_PAIRING_REQ; memcpy(&smp->preq[1], req, sizeof(*req)); skb_pull(skb, sizeof(*req)); /* We didn't start the pairing, so match remote */ auth = req->auth_req; if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) sec_level = BT_SECURITY_MEDIUM; else sec_level = authreq_to_seclevel(auth); if (sec_level > conn->hcon->pending_sec_level) conn->hcon->pending_sec_level = sec_level; Loading Loading @@ -1003,7 +1004,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_cmd_pairing *req, *rsp = (void *) skb->data; struct l2cap_chan *chan = conn->smp; struct smp_chan *smp = chan->data; u8 key_size, auth = SMP_AUTH_NONE; u8 key_size, auth; int ret; BT_DBG("conn %p", conn); Loading @@ -1014,8 +1015,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) if (conn->hcon->role != HCI_ROLE_MASTER) return SMP_CMD_NOTSUPP; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); skb_pull(skb, sizeof(*rsp)); req = (void *) &smp->preq[1]; Loading @@ -1024,6 +1023,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) if (check_enc_key_size(conn, key_size)) return SMP_ENC_KEY_SIZE; auth = rsp->auth_req & AUTH_REQ_MASK; /* If we need MITM check that it can be acheived */ if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { u8 method; Loading @@ -1044,11 +1045,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) */ smp->remote_key_dist &= rsp->resp_key_dist; if ((req->auth_req & SMP_AUTH_BONDING) && (rsp->auth_req & SMP_AUTH_BONDING)) auth = SMP_AUTH_BONDING; auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; auth |= req->auth_req; ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); if (ret) Loading @@ -1073,8 +1070,6 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(smp->pcnf)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); skb_pull(skb, sizeof(smp->pcnf)); Loading Loading @@ -1103,8 +1098,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(smp->rrnd)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); skb_pull(skb, sizeof(smp->rrnd)); Loading @@ -1121,7 +1114,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) if (!key) return false; if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) if (smp_ltk_sec_level(key) < sec_level) return false; if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) Loading Loading @@ -1164,7 +1157,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_cmd_pairing cp; struct hci_conn *hcon = conn->hcon; struct smp_chan *smp; u8 sec_level; u8 sec_level, auth; BT_DBG("conn %p", conn); Loading @@ -1174,7 +1167,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) if (hcon->role != HCI_ROLE_MASTER) return SMP_CMD_NOTSUPP; sec_level = authreq_to_seclevel(rp->auth_req); auth = rp->auth_req & AUTH_REQ_MASK; if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) sec_level = BT_SECURITY_MEDIUM; else sec_level = authreq_to_seclevel(auth); if (smp_sufficient_security(hcon, sec_level)) return 0; Loading @@ -1189,13 +1188,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) return SMP_UNSPECIFIED; if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && (rp->auth_req & SMP_AUTH_BONDING)) (auth & SMP_AUTH_BONDING)) return SMP_PAIRING_NOTSUPP; skb_pull(skb, sizeof(*rp)); memset(&cp, 0, sizeof(cp)); build_pairing_cmd(conn, &cp, NULL, rp->auth_req); build_pairing_cmd(conn, &cp, NULL, auth); smp->preq[0] = SMP_CMD_PAIRING_REQ; memcpy(&smp->preq[1], &cp, sizeof(cp)); Loading Loading @@ -1293,7 +1292,6 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(*rp)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); skb_pull(skb, sizeof(*rp)); Loading Loading @@ -1321,9 +1319,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; SMP_DISALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); if (smp->remote_key_dist & SMP_DIST_ID_KEY) SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); else if (smp->remote_key_dist & SMP_DIST_SIGN) SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); skb_pull(skb, sizeof(*rp)); Loading Loading @@ -1351,7 +1350,6 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(*info)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_INFO); SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); skb_pull(skb, sizeof(*info)); Loading @@ -1378,7 +1376,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_ID_KEY; SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); if (smp->remote_key_dist & SMP_DIST_SIGN) SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); Loading Loading @@ -1434,8 +1431,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_SIGN; SMP_DISALLOW_CMD(smp, SMP_CMD_SIGN_INFO); skb_pull(skb, sizeof(*rp)); hci_dev_lock(hdev); Loading Loading @@ -1480,7 +1475,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) if (code > SMP_CMD_MAX) goto drop; if (smp && !test_bit(code, &smp->allow_cmd)) if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) goto drop; /* If we don't have a context the only allowed commands are Loading net/bluetooth/smp.h +8 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,14 @@ enum { SMP_LTK_SLAVE, }; static inline u8 smp_ltk_sec_level(struct smp_ltk *key) { if (key->authenticated) return BT_SECURITY_HIGH; return BT_SECURITY_MEDIUM; } /* SMP Commands */ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); Loading Loading
net/bluetooth/hci_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -3872,6 +3872,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { BT_DBG("Deferring random address update"); set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); return; } Loading
net/bluetooth/hci_event.c +7 −4 Original line number Diff line number Diff line Loading @@ -2438,6 +2438,12 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) } } /* We should disregard the current RPA and generate a new one * whenever the encryption procedure fails. */ if (ev->status && conn->type == LE_LINK) set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); if (ev->status && conn->state == BT_CONNECTED) { Loading Loading @@ -4506,10 +4512,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); cp.handle = cpu_to_le16(conn->handle); if (ltk->authenticated) conn->pending_sec_level = BT_SECURITY_HIGH; else conn->pending_sec_level = BT_SECURITY_MEDIUM; conn->pending_sec_level = smp_ltk_sec_level(ltk); conn->enc_key_size = ltk->enc_size; Loading
net/bluetooth/l2cap_core.c +33 −20 Original line number Diff line number Diff line Loading @@ -1283,25 +1283,13 @@ static void l2cap_start_connection(struct l2cap_chan *chan) } } static void l2cap_do_start(struct l2cap_chan *chan) static void l2cap_request_info(struct l2cap_conn *conn) { struct l2cap_conn *conn = chan->conn; if (conn->hcon->type == LE_LINK) { l2cap_le_start(chan); return; } struct l2cap_info_req req; if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) return; if (l2cap_chan_check_security(chan, true) && __l2cap_no_conn_pending(chan)) { l2cap_start_connection(chan); } } else { struct l2cap_info_req req; req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; Loading @@ -1312,6 +1300,27 @@ static void l2cap_do_start(struct l2cap_chan *chan) l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, sizeof(req), &req); } static void l2cap_do_start(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; if (conn->hcon->type == LE_LINK) { l2cap_le_start(chan); return; } if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) { l2cap_request_info(conn); return; } if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) return; if (l2cap_chan_check_security(chan, true) && __l2cap_no_conn_pending(chan)) l2cap_start_connection(chan); } static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) Loading Loading @@ -1370,6 +1379,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) l2cap_chan_lock(chan); if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { l2cap_chan_ready(chan); l2cap_chan_unlock(chan); continue; } Loading Loading @@ -1474,6 +1484,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) BT_DBG("conn %p", conn); if (hcon->type == ACL_LINK) l2cap_request_info(conn); mutex_lock(&conn->chan_lock); list_for_each_entry(chan, &conn->chan_l, list) { Loading @@ -1488,8 +1501,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) if (hcon->type == LE_LINK) { l2cap_le_start(chan); } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) l2cap_chan_ready(chan); } else if (chan->state == BT_CONNECT) { l2cap_do_start(chan); } Loading
net/bluetooth/smp.c +26 −31 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ #include "smp.h" #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) #define SMP_DISALLOW_CMD(smp, code) clear_bit(code, &smp->allow_cmd) #define SMP_TIMEOUT msecs_to_jiffies(30000) Loading Loading @@ -949,20 +948,22 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) if (!smp) return SMP_UNSPECIFIED; /* We didn't start the pairing, so match remote */ auth = req->auth_req & AUTH_REQ_MASK; if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && (req->auth_req & SMP_AUTH_BONDING)) (auth & SMP_AUTH_BONDING)) return SMP_PAIRING_NOTSUPP; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); smp->preq[0] = SMP_CMD_PAIRING_REQ; memcpy(&smp->preq[1], req, sizeof(*req)); skb_pull(skb, sizeof(*req)); /* We didn't start the pairing, so match remote */ auth = req->auth_req; if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) sec_level = BT_SECURITY_MEDIUM; else sec_level = authreq_to_seclevel(auth); if (sec_level > conn->hcon->pending_sec_level) conn->hcon->pending_sec_level = sec_level; Loading Loading @@ -1003,7 +1004,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_cmd_pairing *req, *rsp = (void *) skb->data; struct l2cap_chan *chan = conn->smp; struct smp_chan *smp = chan->data; u8 key_size, auth = SMP_AUTH_NONE; u8 key_size, auth; int ret; BT_DBG("conn %p", conn); Loading @@ -1014,8 +1015,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) if (conn->hcon->role != HCI_ROLE_MASTER) return SMP_CMD_NOTSUPP; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); skb_pull(skb, sizeof(*rsp)); req = (void *) &smp->preq[1]; Loading @@ -1024,6 +1023,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) if (check_enc_key_size(conn, key_size)) return SMP_ENC_KEY_SIZE; auth = rsp->auth_req & AUTH_REQ_MASK; /* If we need MITM check that it can be acheived */ if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { u8 method; Loading @@ -1044,11 +1045,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) */ smp->remote_key_dist &= rsp->resp_key_dist; if ((req->auth_req & SMP_AUTH_BONDING) && (rsp->auth_req & SMP_AUTH_BONDING)) auth = SMP_AUTH_BONDING; auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; auth |= req->auth_req; ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); if (ret) Loading @@ -1073,8 +1070,6 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(smp->pcnf)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); skb_pull(skb, sizeof(smp->pcnf)); Loading Loading @@ -1103,8 +1098,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(smp->rrnd)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); skb_pull(skb, sizeof(smp->rrnd)); Loading @@ -1121,7 +1114,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) if (!key) return false; if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) if (smp_ltk_sec_level(key) < sec_level) return false; if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) Loading Loading @@ -1164,7 +1157,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_cmd_pairing cp; struct hci_conn *hcon = conn->hcon; struct smp_chan *smp; u8 sec_level; u8 sec_level, auth; BT_DBG("conn %p", conn); Loading @@ -1174,7 +1167,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) if (hcon->role != HCI_ROLE_MASTER) return SMP_CMD_NOTSUPP; sec_level = authreq_to_seclevel(rp->auth_req); auth = rp->auth_req & AUTH_REQ_MASK; if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) sec_level = BT_SECURITY_MEDIUM; else sec_level = authreq_to_seclevel(auth); if (smp_sufficient_security(hcon, sec_level)) return 0; Loading @@ -1189,13 +1188,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) return SMP_UNSPECIFIED; if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && (rp->auth_req & SMP_AUTH_BONDING)) (auth & SMP_AUTH_BONDING)) return SMP_PAIRING_NOTSUPP; skb_pull(skb, sizeof(*rp)); memset(&cp, 0, sizeof(cp)); build_pairing_cmd(conn, &cp, NULL, rp->auth_req); build_pairing_cmd(conn, &cp, NULL, auth); smp->preq[0] = SMP_CMD_PAIRING_REQ; memcpy(&smp->preq[1], &cp, sizeof(cp)); Loading Loading @@ -1293,7 +1292,6 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(*rp)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); skb_pull(skb, sizeof(*rp)); Loading Loading @@ -1321,9 +1319,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; SMP_DISALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); if (smp->remote_key_dist & SMP_DIST_ID_KEY) SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); else if (smp->remote_key_dist & SMP_DIST_SIGN) SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); skb_pull(skb, sizeof(*rp)); Loading Loading @@ -1351,7 +1350,6 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(*info)) return SMP_INVALID_PARAMS; SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_INFO); SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); skb_pull(skb, sizeof(*info)); Loading @@ -1378,7 +1376,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_ID_KEY; SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); if (smp->remote_key_dist & SMP_DIST_SIGN) SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); Loading Loading @@ -1434,8 +1431,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_SIGN; SMP_DISALLOW_CMD(smp, SMP_CMD_SIGN_INFO); skb_pull(skb, sizeof(*rp)); hci_dev_lock(hdev); Loading Loading @@ -1480,7 +1475,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) if (code > SMP_CMD_MAX) goto drop; if (smp && !test_bit(code, &smp->allow_cmd)) if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) goto drop; /* If we don't have a context the only allowed commands are Loading
net/bluetooth/smp.h +8 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,14 @@ enum { SMP_LTK_SLAVE, }; static inline u8 smp_ltk_sec_level(struct smp_ltk *key) { if (key->authenticated) return BT_SECURITY_HIGH; return BT_SECURITY_MEDIUM; } /* SMP Commands */ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); Loading