aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-05-31 11:48:26 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-12-03 10:51:18 -0500
commit783e057462d514441fbd371bbb398cf886fe3376 (patch)
tree20f08adfd2078be6f11a0a8e90aa8aa436dd6d89 /net
parent6a77083af57f2dc515a01c8ec82610ab0e7baa59 (diff)
Bluetooth: Track authentication method in SMP context
For Secure Connections we'll select the authentication method as soon as we receive the public key, but only use it later (both when actually triggering the method as well as when determining the quality of the resulting LTK). Store the method therefore in the SMP context. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/smp.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 20fa07aa9364..45e527d3c741 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -79,6 +79,7 @@ struct smp_chan {
79 struct smp_irk *remote_irk; 79 struct smp_irk *remote_irk;
80 u8 *link_key; 80 u8 *link_key;
81 unsigned long flags; 81 unsigned long flags;
82 u8 method;
82 83
83 /* Secure Connections variables */ 84 /* Secure Connections variables */
84 u8 local_pk[64]; 85 u8 local_pk[64];
@@ -688,7 +689,6 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
688 struct hci_conn *hcon = conn->hcon; 689 struct hci_conn *hcon = conn->hcon;
689 struct l2cap_chan *chan = conn->smp; 690 struct l2cap_chan *chan = conn->smp;
690 struct smp_chan *smp = chan->data; 691 struct smp_chan *smp = chan->data;
691 u8 method;
692 u32 passkey = 0; 692 u32 passkey = 0;
693 int ret = 0; 693 int ret = 0;
694 694
@@ -705,26 +705,28 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
705 * table. 705 * table.
706 */ 706 */
707 if (!(auth & SMP_AUTH_MITM)) 707 if (!(auth & SMP_AUTH_MITM))
708 method = JUST_CFM; 708 smp->method = JUST_CFM;
709 else 709 else
710 method = get_auth_method(smp, local_io, remote_io); 710 smp->method = get_auth_method(smp, local_io, remote_io);
711 711
712 /* Don't confirm locally initiated pairing attempts */ 712 /* Don't confirm locally initiated pairing attempts */
713 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) 713 if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
714 method = JUST_WORKS; 714 &smp->flags))
715 smp->method = JUST_WORKS;
715 716
716 /* Don't bother user space with no IO capabilities */ 717 /* Don't bother user space with no IO capabilities */
717 if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 718 if (smp->method == JUST_CFM &&
718 method = JUST_WORKS; 719 hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
720 smp->method = JUST_WORKS;
719 721
720 /* If Just Works, Continue with Zero TK */ 722 /* If Just Works, Continue with Zero TK */
721 if (method == JUST_WORKS) { 723 if (smp->method == JUST_WORKS) {
722 set_bit(SMP_FLAG_TK_VALID, &smp->flags); 724 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
723 return 0; 725 return 0;
724 } 726 }
725 727
726 /* Not Just Works/Confirm results in MITM Authentication */ 728 /* Not Just Works/Confirm results in MITM Authentication */
727 if (method != JUST_CFM) { 729 if (smp->method != JUST_CFM) {
728 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); 730 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
729 if (hcon->pending_sec_level < BT_SECURITY_HIGH) 731 if (hcon->pending_sec_level < BT_SECURITY_HIGH)
730 hcon->pending_sec_level = BT_SECURITY_HIGH; 732 hcon->pending_sec_level = BT_SECURITY_HIGH;
@@ -733,15 +735,15 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
733 /* If both devices have Keyoard-Display I/O, the master 735 /* If both devices have Keyoard-Display I/O, the master
734 * Confirms and the slave Enters the passkey. 736 * Confirms and the slave Enters the passkey.
735 */ 737 */
736 if (method == OVERLAP) { 738 if (smp->method == OVERLAP) {
737 if (hcon->role == HCI_ROLE_MASTER) 739 if (hcon->role == HCI_ROLE_MASTER)
738 method = CFM_PASSKEY; 740 smp->method = CFM_PASSKEY;
739 else 741 else
740 method = REQ_PASSKEY; 742 smp->method = REQ_PASSKEY;
741 } 743 }
742 744
743 /* Generate random passkey. */ 745 /* Generate random passkey. */
744 if (method == CFM_PASSKEY) { 746 if (smp->method == CFM_PASSKEY) {
745 memset(smp->tk, 0, sizeof(smp->tk)); 747 memset(smp->tk, 0, sizeof(smp->tk));
746 get_random_bytes(&passkey, sizeof(passkey)); 748 get_random_bytes(&passkey, sizeof(passkey));
747 passkey %= 1000000; 749 passkey %= 1000000;
@@ -750,10 +752,10 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
750 set_bit(SMP_FLAG_TK_VALID, &smp->flags); 752 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
751 } 753 }
752 754
753 if (method == REQ_PASSKEY) 755 if (smp->method == REQ_PASSKEY)
754 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, 756 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
755 hcon->type, hcon->dst_type); 757 hcon->type, hcon->dst_type);
756 else if (method == JUST_CFM) 758 else if (smp->method == JUST_CFM)
757 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 759 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
758 hcon->type, hcon->dst_type, 760 hcon->type, hcon->dst_type,
759 passkey, 1); 761 passkey, 1);