diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 95 |
1 files changed, 85 insertions, 10 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 7a6f56b2f49d..3163330cd4f1 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg) | |||
269 | hci_conn_enter_sniff_mode(conn); | 269 | hci_conn_enter_sniff_mode(conn); |
270 | } | 270 | } |
271 | 271 | ||
272 | static void hci_conn_auto_accept(unsigned long arg) | ||
273 | { | ||
274 | struct hci_conn *conn = (void *) arg; | ||
275 | struct hci_dev *hdev = conn->hdev; | ||
276 | |||
277 | hci_dev_lock(hdev); | ||
278 | |||
279 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), | ||
280 | &conn->dst); | ||
281 | |||
282 | hci_dev_unlock(hdev); | ||
283 | } | ||
284 | |||
272 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 285 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) |
273 | { | 286 | { |
274 | struct hci_conn *conn; | 287 | struct hci_conn *conn; |
@@ -287,6 +300,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
287 | conn->auth_type = HCI_AT_GENERAL_BONDING; | 300 | conn->auth_type = HCI_AT_GENERAL_BONDING; |
288 | conn->io_capability = hdev->io_capability; | 301 | conn->io_capability = hdev->io_capability; |
289 | conn->remote_auth = 0xff; | 302 | conn->remote_auth = 0xff; |
303 | conn->key_type = 0xff; | ||
290 | 304 | ||
291 | conn->power_save = 1; | 305 | conn->power_save = 1; |
292 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 306 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
@@ -311,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
311 | 325 | ||
312 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); | 326 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); |
313 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); | 327 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); |
328 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, | ||
329 | (unsigned long) conn); | ||
314 | 330 | ||
315 | atomic_set(&conn->refcnt, 0); | 331 | atomic_set(&conn->refcnt, 0); |
316 | 332 | ||
@@ -341,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn) | |||
341 | 357 | ||
342 | del_timer(&conn->disc_timer); | 358 | del_timer(&conn->disc_timer); |
343 | 359 | ||
360 | del_timer(&conn->auto_accept_timer); | ||
361 | |||
344 | if (conn->type == ACL_LINK) { | 362 | if (conn->type == ACL_LINK) { |
345 | struct hci_conn *sco = conn->link; | 363 | struct hci_conn *sco = conn->link; |
346 | if (sco) | 364 | if (sco) |
@@ -535,36 +553,93 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
535 | return 0; | 553 | return 0; |
536 | } | 554 | } |
537 | 555 | ||
556 | /* Encrypt the the link */ | ||
557 | static void hci_conn_encrypt(struct hci_conn *conn) | ||
558 | { | ||
559 | BT_DBG("conn %p", conn); | ||
560 | |||
561 | if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { | ||
562 | struct hci_cp_set_conn_encrypt cp; | ||
563 | cp.handle = cpu_to_le16(conn->handle); | ||
564 | cp.encrypt = 0x01; | ||
565 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), | ||
566 | &cp); | ||
567 | } | ||
568 | } | ||
569 | |||
538 | /* Enable security */ | 570 | /* Enable security */ |
539 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | 571 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) |
540 | { | 572 | { |
541 | BT_DBG("conn %p", conn); | 573 | BT_DBG("conn %p", conn); |
542 | 574 | ||
575 | /* For sdp we don't need the link key. */ | ||
543 | if (sec_level == BT_SECURITY_SDP) | 576 | if (sec_level == BT_SECURITY_SDP) |
544 | return 1; | 577 | return 1; |
545 | 578 | ||
579 | /* For non 2.1 devices and low security level we don't need the link | ||
580 | key. */ | ||
546 | if (sec_level == BT_SECURITY_LOW && | 581 | if (sec_level == BT_SECURITY_LOW && |
547 | (!conn->ssp_mode || !conn->hdev->ssp_mode)) | 582 | (!conn->ssp_mode || !conn->hdev->ssp_mode)) |
548 | return 1; | 583 | return 1; |
549 | 584 | ||
550 | if (conn->link_mode & HCI_LM_ENCRYPT) | 585 | /* For other security levels we need the link key. */ |
551 | return hci_conn_auth(conn, sec_level, auth_type); | 586 | if (!(conn->link_mode & HCI_LM_AUTH)) |
552 | 587 | goto auth; | |
588 | |||
589 | /* An authenticated combination key has sufficient security for any | ||
590 | security level. */ | ||
591 | if (conn->key_type == HCI_LK_AUTH_COMBINATION) | ||
592 | goto encrypt; | ||
593 | |||
594 | /* An unauthenticated combination key has sufficient security for | ||
595 | security level 1 and 2. */ | ||
596 | if (conn->key_type == HCI_LK_UNAUTH_COMBINATION && | ||
597 | (sec_level == BT_SECURITY_MEDIUM || | ||
598 | sec_level == BT_SECURITY_LOW)) | ||
599 | goto encrypt; | ||
600 | |||
601 | /* A combination key has always sufficient security for the security | ||
602 | levels 1 or 2. High security level requires the combination key | ||
603 | is generated using maximum PIN code length (16). | ||
604 | For pre 2.1 units. */ | ||
605 | if (conn->key_type == HCI_LK_COMBINATION && | ||
606 | (sec_level != BT_SECURITY_HIGH || | ||
607 | conn->pin_length == 16)) | ||
608 | goto encrypt; | ||
609 | |||
610 | auth: | ||
553 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 611 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
554 | return 0; | 612 | return 0; |
555 | 613 | ||
556 | if (hci_conn_auth(conn, sec_level, auth_type)) { | 614 | hci_conn_auth(conn, sec_level, auth_type); |
557 | struct hci_cp_set_conn_encrypt cp; | 615 | return 0; |
558 | cp.handle = cpu_to_le16(conn->handle); | 616 | |
559 | cp.encrypt = 1; | 617 | encrypt: |
560 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, | 618 | if (conn->link_mode & HCI_LM_ENCRYPT) |
561 | sizeof(cp), &cp); | 619 | return 1; |
562 | } | ||
563 | 620 | ||
621 | hci_conn_encrypt(conn); | ||
564 | return 0; | 622 | return 0; |
565 | } | 623 | } |
566 | EXPORT_SYMBOL(hci_conn_security); | 624 | EXPORT_SYMBOL(hci_conn_security); |
567 | 625 | ||
626 | /* Check secure link requirement */ | ||
627 | int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) | ||
628 | { | ||
629 | BT_DBG("conn %p", conn); | ||
630 | |||
631 | if (sec_level != BT_SECURITY_HIGH) | ||
632 | return 1; /* Accept if non-secure is required */ | ||
633 | |||
634 | if (conn->key_type == HCI_LK_AUTH_COMBINATION || | ||
635 | (conn->key_type == HCI_LK_COMBINATION && | ||
636 | conn->pin_length == 16)) | ||
637 | return 1; | ||
638 | |||
639 | return 0; /* Reject not secure link */ | ||
640 | } | ||
641 | EXPORT_SYMBOL(hci_conn_check_secure); | ||
642 | |||
568 | /* Change link key */ | 643 | /* Change link key */ |
569 | int hci_conn_change_link_key(struct hci_conn *conn) | 644 | int hci_conn_change_link_key(struct hci_conn *conn) |
570 | { | 645 | { |