diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 23 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 16 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 16 |
4 files changed, 40 insertions, 17 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4b14972c1694..f75028b33883 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -328,7 +328,7 @@ void hci_conn_check_pending(struct hci_dev *hdev); | |||
328 | 328 | ||
329 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); | 329 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); |
330 | int hci_conn_check_link_mode(struct hci_conn *conn); | 330 | int hci_conn_check_link_mode(struct hci_conn *conn); |
331 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level); | 331 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); |
332 | int hci_conn_change_link_key(struct hci_conn *conn); | 332 | int hci_conn_change_link_key(struct hci_conn *conn); |
333 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); | 333 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); |
334 | 334 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 2435e830ba60..7fc4c048b57b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -391,19 +391,14 @@ int hci_conn_check_link_mode(struct hci_conn *conn) | |||
391 | EXPORT_SYMBOL(hci_conn_check_link_mode); | 391 | EXPORT_SYMBOL(hci_conn_check_link_mode); |
392 | 392 | ||
393 | /* Authenticate remote device */ | 393 | /* Authenticate remote device */ |
394 | static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level) | 394 | static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) |
395 | { | 395 | { |
396 | BT_DBG("conn %p", conn); | 396 | BT_DBG("conn %p", conn); |
397 | 397 | ||
398 | if (sec_level > conn->sec_level) | 398 | if (sec_level > conn->sec_level) { |
399 | conn->link_mode &= ~HCI_LM_AUTH; | 399 | conn->sec_level = sec_level; |
400 | 400 | conn->auth_type = auth_type; | |
401 | conn->sec_level = sec_level; | 401 | } else if (conn->link_mode & HCI_LM_AUTH) |
402 | |||
403 | if (sec_level == BT_SECURITY_HIGH) | ||
404 | conn->auth_type |= 0x01; | ||
405 | |||
406 | if (conn->link_mode & HCI_LM_AUTH) | ||
407 | return 1; | 402 | return 1; |
408 | 403 | ||
409 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 404 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
@@ -417,7 +412,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level) | |||
417 | } | 412 | } |
418 | 413 | ||
419 | /* Enable security */ | 414 | /* Enable security */ |
420 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level) | 415 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) |
421 | { | 416 | { |
422 | BT_DBG("conn %p", conn); | 417 | BT_DBG("conn %p", conn); |
423 | 418 | ||
@@ -426,18 +421,18 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level) | |||
426 | 421 | ||
427 | if (sec_level == BT_SECURITY_LOW) { | 422 | if (sec_level == BT_SECURITY_LOW) { |
428 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) | 423 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) |
429 | return hci_conn_auth(conn, sec_level); | 424 | return hci_conn_auth(conn, sec_level, auth_type); |
430 | else | 425 | else |
431 | return 1; | 426 | return 1; |
432 | } | 427 | } |
433 | 428 | ||
434 | if (conn->link_mode & HCI_LM_ENCRYPT) | 429 | if (conn->link_mode & HCI_LM_ENCRYPT) |
435 | return hci_conn_auth(conn, sec_level); | 430 | return hci_conn_auth(conn, sec_level, auth_type); |
436 | 431 | ||
437 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 432 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
438 | return 0; | 433 | return 0; |
439 | 434 | ||
440 | if (hci_conn_auth(conn, sec_level)) { | 435 | if (hci_conn_auth(conn, sec_level, auth_type)) { |
441 | struct hci_cp_set_conn_encrypt cp; | 436 | struct hci_cp_set_conn_encrypt cp; |
442 | cp.handle = cpu_to_le16(conn->handle); | 437 | cp.handle = cpu_to_le16(conn->handle); |
443 | cp.encrypt = 1; | 438 | cp.encrypt = 1; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index b677af671f31..8a93dde4095b 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -263,8 +263,22 @@ static void l2cap_chan_del(struct sock *sk, int err) | |||
263 | static inline int l2cap_check_security(struct sock *sk) | 263 | static inline int l2cap_check_security(struct sock *sk) |
264 | { | 264 | { |
265 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 265 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
266 | __u8 auth_type; | ||
267 | |||
268 | switch (l2cap_pi(sk)->sec_level) { | ||
269 | case BT_SECURITY_HIGH: | ||
270 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
271 | break; | ||
272 | case BT_SECURITY_MEDIUM: | ||
273 | auth_type = HCI_AT_GENERAL_BONDING; | ||
274 | break; | ||
275 | default: | ||
276 | auth_type = HCI_AT_NO_BONDING; | ||
277 | break; | ||
278 | } | ||
266 | 279 | ||
267 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level); | 280 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, |
281 | auth_type); | ||
268 | } | 282 | } |
269 | 283 | ||
270 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) | 284 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 3717c25ba33a..1828ec06ad1c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -226,8 +226,22 @@ static int rfcomm_l2sock_create(struct socket **sock) | |||
226 | static inline int rfcomm_check_security(struct rfcomm_dlc *d) | 226 | static inline int rfcomm_check_security(struct rfcomm_dlc *d) |
227 | { | 227 | { |
228 | struct sock *sk = d->session->sock->sk; | 228 | struct sock *sk = d->session->sock->sk; |
229 | __u8 auth_type; | ||
229 | 230 | ||
230 | return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level); | 231 | switch (d->sec_level) { |
232 | case BT_SECURITY_HIGH: | ||
233 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
234 | break; | ||
235 | case BT_SECURITY_MEDIUM: | ||
236 | auth_type = HCI_AT_GENERAL_BONDING; | ||
237 | break; | ||
238 | default: | ||
239 | auth_type = HCI_AT_NO_BONDING; | ||
240 | break; | ||
241 | } | ||
242 | |||
243 | return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level, | ||
244 | auth_type); | ||
231 | } | 245 | } |
232 | 246 | ||
233 | /* ---- RFCOMM DLCs ---- */ | 247 | /* ---- RFCOMM DLCs ---- */ |