diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-09-15 14:55:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-15 14:55:45 -0400 |
commit | 1186b623c2b04ae8c963c36f1dbcc159a6c99f60 (patch) | |
tree | abce5dc9cebd1bc7b9bf07bb74edb4696f5501d3 | |
parent | 6bd2bd27baf12fa0f2e6d611509fc0e1bffb0f97 (diff) | |
parent | 9a783a139c32a905825ee0aa9597f485ea461f76 (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
-rw-r--r-- | net/bluetooth/hci_core.c | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 11 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 53 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 57 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 8 |
5 files changed, 75 insertions, 55 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 0d3782ad9a5b..067526d9680d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -3872,6 +3872,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) | |||
3872 | if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || | 3872 | if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || |
3873 | hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { | 3873 | hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { |
3874 | BT_DBG("Deferring random address update"); | 3874 | BT_DBG("Deferring random address update"); |
3875 | set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); | ||
3875 | return; | 3876 | return; |
3876 | } | 3877 | } |
3877 | 3878 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3a8381ab992f..8b0a2a6de419 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2438,6 +2438,12 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2438 | } | 2438 | } |
2439 | } | 2439 | } |
2440 | 2440 | ||
2441 | /* We should disregard the current RPA and generate a new one | ||
2442 | * whenever the encryption procedure fails. | ||
2443 | */ | ||
2444 | if (ev->status && conn->type == LE_LINK) | ||
2445 | set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); | ||
2446 | |||
2441 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | 2447 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); |
2442 | 2448 | ||
2443 | if (ev->status && conn->state == BT_CONNECTED) { | 2449 | if (ev->status && conn->state == BT_CONNECTED) { |
@@ -4506,10 +4512,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4506 | memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); | 4512 | memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); |
4507 | cp.handle = cpu_to_le16(conn->handle); | 4513 | cp.handle = cpu_to_le16(conn->handle); |
4508 | 4514 | ||
4509 | if (ltk->authenticated) | 4515 | conn->pending_sec_level = smp_ltk_sec_level(ltk); |
4510 | conn->pending_sec_level = BT_SECURITY_HIGH; | ||
4511 | else | ||
4512 | conn->pending_sec_level = BT_SECURITY_MEDIUM; | ||
4513 | 4516 | ||
4514 | conn->enc_key_size = ltk->enc_size; | 4517 | conn->enc_key_size = ltk->enc_size; |
4515 | 4518 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b71430caab4a..8d53fc57faba 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1283,6 +1283,24 @@ static void l2cap_start_connection(struct l2cap_chan *chan) | |||
1283 | } | 1283 | } |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | static void l2cap_request_info(struct l2cap_conn *conn) | ||
1287 | { | ||
1288 | struct l2cap_info_req req; | ||
1289 | |||
1290 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | ||
1291 | return; | ||
1292 | |||
1293 | req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); | ||
1294 | |||
1295 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; | ||
1296 | conn->info_ident = l2cap_get_ident(conn); | ||
1297 | |||
1298 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); | ||
1299 | |||
1300 | l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, | ||
1301 | sizeof(req), &req); | ||
1302 | } | ||
1303 | |||
1286 | static void l2cap_do_start(struct l2cap_chan *chan) | 1304 | static void l2cap_do_start(struct l2cap_chan *chan) |
1287 | { | 1305 | { |
1288 | struct l2cap_conn *conn = chan->conn; | 1306 | struct l2cap_conn *conn = chan->conn; |
@@ -1292,26 +1310,17 @@ static void l2cap_do_start(struct l2cap_chan *chan) | |||
1292 | return; | 1310 | return; |
1293 | } | 1311 | } |
1294 | 1312 | ||
1295 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 1313 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) { |
1296 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) | 1314 | l2cap_request_info(conn); |
1297 | return; | 1315 | return; |
1298 | 1316 | } | |
1299 | if (l2cap_chan_check_security(chan, true) && | ||
1300 | __l2cap_no_conn_pending(chan)) { | ||
1301 | l2cap_start_connection(chan); | ||
1302 | } | ||
1303 | } else { | ||
1304 | struct l2cap_info_req req; | ||
1305 | req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); | ||
1306 | |||
1307 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; | ||
1308 | conn->info_ident = l2cap_get_ident(conn); | ||
1309 | 1317 | ||
1310 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); | 1318 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) |
1319 | return; | ||
1311 | 1320 | ||
1312 | l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, | 1321 | if (l2cap_chan_check_security(chan, true) && |
1313 | sizeof(req), &req); | 1322 | __l2cap_no_conn_pending(chan)) |
1314 | } | 1323 | l2cap_start_connection(chan); |
1315 | } | 1324 | } |
1316 | 1325 | ||
1317 | static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | 1326 | static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) |
@@ -1370,6 +1379,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
1370 | l2cap_chan_lock(chan); | 1379 | l2cap_chan_lock(chan); |
1371 | 1380 | ||
1372 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1381 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
1382 | l2cap_chan_ready(chan); | ||
1373 | l2cap_chan_unlock(chan); | 1383 | l2cap_chan_unlock(chan); |
1374 | continue; | 1384 | continue; |
1375 | } | 1385 | } |
@@ -1474,6 +1484,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1474 | 1484 | ||
1475 | BT_DBG("conn %p", conn); | 1485 | BT_DBG("conn %p", conn); |
1476 | 1486 | ||
1487 | if (hcon->type == ACL_LINK) | ||
1488 | l2cap_request_info(conn); | ||
1489 | |||
1477 | mutex_lock(&conn->chan_lock); | 1490 | mutex_lock(&conn->chan_lock); |
1478 | 1491 | ||
1479 | list_for_each_entry(chan, &conn->chan_l, list) { | 1492 | list_for_each_entry(chan, &conn->chan_l, list) { |
@@ -1488,8 +1501,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1488 | if (hcon->type == LE_LINK) { | 1501 | if (hcon->type == LE_LINK) { |
1489 | l2cap_le_start(chan); | 1502 | l2cap_le_start(chan); |
1490 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1503 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
1491 | l2cap_chan_ready(chan); | 1504 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) |
1492 | 1505 | l2cap_chan_ready(chan); | |
1493 | } else if (chan->state == BT_CONNECT) { | 1506 | } else if (chan->state == BT_CONNECT) { |
1494 | l2cap_do_start(chan); | 1507 | l2cap_do_start(chan); |
1495 | } | 1508 | } |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 25c9040e0b12..51fc7db2d84e 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include "smp.h" | 32 | #include "smp.h" |
33 | 33 | ||
34 | #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) | 34 | #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) |
35 | #define SMP_DISALLOW_CMD(smp, code) clear_bit(code, &smp->allow_cmd) | ||
36 | 35 | ||
37 | #define SMP_TIMEOUT msecs_to_jiffies(30000) | 36 | #define SMP_TIMEOUT msecs_to_jiffies(30000) |
38 | 37 | ||
@@ -949,20 +948,22 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
949 | if (!smp) | 948 | if (!smp) |
950 | return SMP_UNSPECIFIED; | 949 | return SMP_UNSPECIFIED; |
951 | 950 | ||
951 | /* We didn't start the pairing, so match remote */ | ||
952 | auth = req->auth_req & AUTH_REQ_MASK; | ||
953 | |||
952 | if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && | 954 | if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && |
953 | (req->auth_req & SMP_AUTH_BONDING)) | 955 | (auth & SMP_AUTH_BONDING)) |
954 | return SMP_PAIRING_NOTSUPP; | 956 | return SMP_PAIRING_NOTSUPP; |
955 | 957 | ||
956 | SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); | ||
957 | |||
958 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 958 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
959 | memcpy(&smp->preq[1], req, sizeof(*req)); | 959 | memcpy(&smp->preq[1], req, sizeof(*req)); |
960 | skb_pull(skb, sizeof(*req)); | 960 | skb_pull(skb, sizeof(*req)); |
961 | 961 | ||
962 | /* We didn't start the pairing, so match remote */ | 962 | if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) |
963 | auth = req->auth_req; | 963 | sec_level = BT_SECURITY_MEDIUM; |
964 | else | ||
965 | sec_level = authreq_to_seclevel(auth); | ||
964 | 966 | ||
965 | sec_level = authreq_to_seclevel(auth); | ||
966 | if (sec_level > conn->hcon->pending_sec_level) | 967 | if (sec_level > conn->hcon->pending_sec_level) |
967 | conn->hcon->pending_sec_level = sec_level; | 968 | conn->hcon->pending_sec_level = sec_level; |
968 | 969 | ||
@@ -1003,7 +1004,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1003 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; | 1004 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; |
1004 | struct l2cap_chan *chan = conn->smp; | 1005 | struct l2cap_chan *chan = conn->smp; |
1005 | struct smp_chan *smp = chan->data; | 1006 | struct smp_chan *smp = chan->data; |
1006 | u8 key_size, auth = SMP_AUTH_NONE; | 1007 | u8 key_size, auth; |
1007 | int ret; | 1008 | int ret; |
1008 | 1009 | ||
1009 | BT_DBG("conn %p", conn); | 1010 | BT_DBG("conn %p", conn); |
@@ -1014,8 +1015,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1014 | if (conn->hcon->role != HCI_ROLE_MASTER) | 1015 | if (conn->hcon->role != HCI_ROLE_MASTER) |
1015 | return SMP_CMD_NOTSUPP; | 1016 | return SMP_CMD_NOTSUPP; |
1016 | 1017 | ||
1017 | SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); | ||
1018 | |||
1019 | skb_pull(skb, sizeof(*rsp)); | 1018 | skb_pull(skb, sizeof(*rsp)); |
1020 | 1019 | ||
1021 | req = (void *) &smp->preq[1]; | 1020 | req = (void *) &smp->preq[1]; |
@@ -1024,6 +1023,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1024 | if (check_enc_key_size(conn, key_size)) | 1023 | if (check_enc_key_size(conn, key_size)) |
1025 | return SMP_ENC_KEY_SIZE; | 1024 | return SMP_ENC_KEY_SIZE; |
1026 | 1025 | ||
1026 | auth = rsp->auth_req & AUTH_REQ_MASK; | ||
1027 | |||
1027 | /* If we need MITM check that it can be acheived */ | 1028 | /* If we need MITM check that it can be acheived */ |
1028 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { | 1029 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { |
1029 | u8 method; | 1030 | u8 method; |
@@ -1044,11 +1045,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1044 | */ | 1045 | */ |
1045 | smp->remote_key_dist &= rsp->resp_key_dist; | 1046 | smp->remote_key_dist &= rsp->resp_key_dist; |
1046 | 1047 | ||
1047 | if ((req->auth_req & SMP_AUTH_BONDING) && | 1048 | auth |= req->auth_req; |
1048 | (rsp->auth_req & SMP_AUTH_BONDING)) | ||
1049 | auth = SMP_AUTH_BONDING; | ||
1050 | |||
1051 | auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; | ||
1052 | 1049 | ||
1053 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); | 1050 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); |
1054 | if (ret) | 1051 | if (ret) |
@@ -1073,8 +1070,6 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1073 | if (skb->len < sizeof(smp->pcnf)) | 1070 | if (skb->len < sizeof(smp->pcnf)) |
1074 | return SMP_INVALID_PARAMS; | 1071 | return SMP_INVALID_PARAMS; |
1075 | 1072 | ||
1076 | SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); | ||
1077 | |||
1078 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); | 1073 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); |
1079 | skb_pull(skb, sizeof(smp->pcnf)); | 1074 | skb_pull(skb, sizeof(smp->pcnf)); |
1080 | 1075 | ||
@@ -1103,8 +1098,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1103 | if (skb->len < sizeof(smp->rrnd)) | 1098 | if (skb->len < sizeof(smp->rrnd)) |
1104 | return SMP_INVALID_PARAMS; | 1099 | return SMP_INVALID_PARAMS; |
1105 | 1100 | ||
1106 | SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); | ||
1107 | |||
1108 | memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); | 1101 | memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); |
1109 | skb_pull(skb, sizeof(smp->rrnd)); | 1102 | skb_pull(skb, sizeof(smp->rrnd)); |
1110 | 1103 | ||
@@ -1121,7 +1114,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) | |||
1121 | if (!key) | 1114 | if (!key) |
1122 | return false; | 1115 | return false; |
1123 | 1116 | ||
1124 | if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) | 1117 | if (smp_ltk_sec_level(key) < sec_level) |
1125 | return false; | 1118 | return false; |
1126 | 1119 | ||
1127 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) | 1120 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) |
@@ -1164,7 +1157,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1164 | struct smp_cmd_pairing cp; | 1157 | struct smp_cmd_pairing cp; |
1165 | struct hci_conn *hcon = conn->hcon; | 1158 | struct hci_conn *hcon = conn->hcon; |
1166 | struct smp_chan *smp; | 1159 | struct smp_chan *smp; |
1167 | u8 sec_level; | 1160 | u8 sec_level, auth; |
1168 | 1161 | ||
1169 | BT_DBG("conn %p", conn); | 1162 | BT_DBG("conn %p", conn); |
1170 | 1163 | ||
@@ -1174,7 +1167,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1174 | if (hcon->role != HCI_ROLE_MASTER) | 1167 | if (hcon->role != HCI_ROLE_MASTER) |
1175 | return SMP_CMD_NOTSUPP; | 1168 | return SMP_CMD_NOTSUPP; |
1176 | 1169 | ||
1177 | sec_level = authreq_to_seclevel(rp->auth_req); | 1170 | auth = rp->auth_req & AUTH_REQ_MASK; |
1171 | |||
1172 | if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) | ||
1173 | sec_level = BT_SECURITY_MEDIUM; | ||
1174 | else | ||
1175 | sec_level = authreq_to_seclevel(auth); | ||
1176 | |||
1178 | if (smp_sufficient_security(hcon, sec_level)) | 1177 | if (smp_sufficient_security(hcon, sec_level)) |
1179 | return 0; | 1178 | return 0; |
1180 | 1179 | ||
@@ -1189,13 +1188,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1189 | return SMP_UNSPECIFIED; | 1188 | return SMP_UNSPECIFIED; |
1190 | 1189 | ||
1191 | if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && | 1190 | if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && |
1192 | (rp->auth_req & SMP_AUTH_BONDING)) | 1191 | (auth & SMP_AUTH_BONDING)) |
1193 | return SMP_PAIRING_NOTSUPP; | 1192 | return SMP_PAIRING_NOTSUPP; |
1194 | 1193 | ||
1195 | skb_pull(skb, sizeof(*rp)); | 1194 | skb_pull(skb, sizeof(*rp)); |
1196 | 1195 | ||
1197 | memset(&cp, 0, sizeof(cp)); | 1196 | memset(&cp, 0, sizeof(cp)); |
1198 | build_pairing_cmd(conn, &cp, NULL, rp->auth_req); | 1197 | build_pairing_cmd(conn, &cp, NULL, auth); |
1199 | 1198 | ||
1200 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 1199 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
1201 | memcpy(&smp->preq[1], &cp, sizeof(cp)); | 1200 | memcpy(&smp->preq[1], &cp, sizeof(cp)); |
@@ -1293,7 +1292,6 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1293 | if (skb->len < sizeof(*rp)) | 1292 | if (skb->len < sizeof(*rp)) |
1294 | return SMP_INVALID_PARAMS; | 1293 | return SMP_INVALID_PARAMS; |
1295 | 1294 | ||
1296 | SMP_DISALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); | ||
1297 | SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); | 1295 | SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); |
1298 | 1296 | ||
1299 | skb_pull(skb, sizeof(*rp)); | 1297 | skb_pull(skb, sizeof(*rp)); |
@@ -1321,9 +1319,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1321 | /* Mark the information as received */ | 1319 | /* Mark the information as received */ |
1322 | smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; | 1320 | smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; |
1323 | 1321 | ||
1324 | SMP_DISALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); | ||
1325 | if (smp->remote_key_dist & SMP_DIST_ID_KEY) | 1322 | if (smp->remote_key_dist & SMP_DIST_ID_KEY) |
1326 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); | 1323 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); |
1324 | else if (smp->remote_key_dist & SMP_DIST_SIGN) | ||
1325 | SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); | ||
1327 | 1326 | ||
1328 | skb_pull(skb, sizeof(*rp)); | 1327 | skb_pull(skb, sizeof(*rp)); |
1329 | 1328 | ||
@@ -1351,7 +1350,6 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1351 | if (skb->len < sizeof(*info)) | 1350 | if (skb->len < sizeof(*info)) |
1352 | return SMP_INVALID_PARAMS; | 1351 | return SMP_INVALID_PARAMS; |
1353 | 1352 | ||
1354 | SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_INFO); | ||
1355 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); | 1353 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); |
1356 | 1354 | ||
1357 | skb_pull(skb, sizeof(*info)); | 1355 | skb_pull(skb, sizeof(*info)); |
@@ -1378,7 +1376,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1378 | /* Mark the information as received */ | 1376 | /* Mark the information as received */ |
1379 | smp->remote_key_dist &= ~SMP_DIST_ID_KEY; | 1377 | smp->remote_key_dist &= ~SMP_DIST_ID_KEY; |
1380 | 1378 | ||
1381 | SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); | ||
1382 | if (smp->remote_key_dist & SMP_DIST_SIGN) | 1379 | if (smp->remote_key_dist & SMP_DIST_SIGN) |
1383 | SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); | 1380 | SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); |
1384 | 1381 | ||
@@ -1434,8 +1431,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1434 | /* Mark the information as received */ | 1431 | /* Mark the information as received */ |
1435 | smp->remote_key_dist &= ~SMP_DIST_SIGN; | 1432 | smp->remote_key_dist &= ~SMP_DIST_SIGN; |
1436 | 1433 | ||
1437 | SMP_DISALLOW_CMD(smp, SMP_CMD_SIGN_INFO); | ||
1438 | |||
1439 | skb_pull(skb, sizeof(*rp)); | 1434 | skb_pull(skb, sizeof(*rp)); |
1440 | 1435 | ||
1441 | hci_dev_lock(hdev); | 1436 | hci_dev_lock(hdev); |
@@ -1480,7 +1475,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1480 | if (code > SMP_CMD_MAX) | 1475 | if (code > SMP_CMD_MAX) |
1481 | goto drop; | 1476 | goto drop; |
1482 | 1477 | ||
1483 | if (smp && !test_bit(code, &smp->allow_cmd)) | 1478 | if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) |
1484 | goto drop; | 1479 | goto drop; |
1485 | 1480 | ||
1486 | /* If we don't have a context the only allowed commands are | 1481 | /* If we don't have a context the only allowed commands are |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 5240537efde3..86a683a8b491 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -125,6 +125,14 @@ enum { | |||
125 | SMP_LTK_SLAVE, | 125 | SMP_LTK_SLAVE, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static inline u8 smp_ltk_sec_level(struct smp_ltk *key) | ||
129 | { | ||
130 | if (key->authenticated) | ||
131 | return BT_SECURITY_HIGH; | ||
132 | |||
133 | return BT_SECURITY_MEDIUM; | ||
134 | } | ||
135 | |||
128 | /* SMP Commands */ | 136 | /* SMP Commands */ |
129 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); | 137 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); |
130 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); | 138 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |