diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/smp.c | 100 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 2 |
2 files changed, 50 insertions, 52 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 312ea5ec2d7d..07ca4ce0943b 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -366,6 +366,56 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) | |||
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
368 | 368 | ||
369 | static void smp_chan_destroy(struct l2cap_conn *conn) | ||
370 | { | ||
371 | struct l2cap_chan *chan = conn->smp; | ||
372 | struct smp_chan *smp = chan->data; | ||
373 | bool complete; | ||
374 | |||
375 | BUG_ON(!smp); | ||
376 | |||
377 | cancel_delayed_work_sync(&smp->security_timer); | ||
378 | /* In case the timeout freed the SMP context */ | ||
379 | if (!chan->data) | ||
380 | return; | ||
381 | |||
382 | if (work_pending(&smp->distribute_work)) { | ||
383 | cancel_work_sync(&smp->distribute_work); | ||
384 | if (!chan->data) | ||
385 | return; | ||
386 | } | ||
387 | |||
388 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); | ||
389 | mgmt_smp_complete(conn->hcon, complete); | ||
390 | |||
391 | kfree(smp->csrk); | ||
392 | kfree(smp->slave_csrk); | ||
393 | |||
394 | crypto_free_blkcipher(smp->tfm_aes); | ||
395 | |||
396 | /* If pairing failed clean up any keys we might have */ | ||
397 | if (!complete) { | ||
398 | if (smp->ltk) { | ||
399 | list_del(&smp->ltk->list); | ||
400 | kfree(smp->ltk); | ||
401 | } | ||
402 | |||
403 | if (smp->slave_ltk) { | ||
404 | list_del(&smp->slave_ltk->list); | ||
405 | kfree(smp->slave_ltk); | ||
406 | } | ||
407 | |||
408 | if (smp->remote_irk) { | ||
409 | list_del(&smp->remote_irk->list); | ||
410 | kfree(smp->remote_irk); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | chan->data = NULL; | ||
415 | kfree(smp); | ||
416 | hci_conn_drop(conn->hcon); | ||
417 | } | ||
418 | |||
369 | static void smp_failure(struct l2cap_conn *conn, u8 reason) | 419 | static void smp_failure(struct l2cap_conn *conn, u8 reason) |
370 | { | 420 | { |
371 | struct hci_conn *hcon = conn->hcon; | 421 | struct hci_conn *hcon = conn->hcon; |
@@ -812,56 +862,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
812 | return smp; | 862 | return smp; |
813 | } | 863 | } |
814 | 864 | ||
815 | void smp_chan_destroy(struct l2cap_conn *conn) | ||
816 | { | ||
817 | struct l2cap_chan *chan = conn->smp; | ||
818 | struct smp_chan *smp = chan->data; | ||
819 | bool complete; | ||
820 | |||
821 | BUG_ON(!smp); | ||
822 | |||
823 | cancel_delayed_work_sync(&smp->security_timer); | ||
824 | /* In case the timeout freed the SMP context */ | ||
825 | if (!chan->data) | ||
826 | return; | ||
827 | |||
828 | if (work_pending(&smp->distribute_work)) { | ||
829 | cancel_work_sync(&smp->distribute_work); | ||
830 | if (!chan->data) | ||
831 | return; | ||
832 | } | ||
833 | |||
834 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); | ||
835 | mgmt_smp_complete(conn->hcon, complete); | ||
836 | |||
837 | kfree(smp->csrk); | ||
838 | kfree(smp->slave_csrk); | ||
839 | |||
840 | crypto_free_blkcipher(smp->tfm_aes); | ||
841 | |||
842 | /* If pairing failed clean up any keys we might have */ | ||
843 | if (!complete) { | ||
844 | if (smp->ltk) { | ||
845 | list_del(&smp->ltk->list); | ||
846 | kfree(smp->ltk); | ||
847 | } | ||
848 | |||
849 | if (smp->slave_ltk) { | ||
850 | list_del(&smp->slave_ltk->list); | ||
851 | kfree(smp->slave_ltk); | ||
852 | } | ||
853 | |||
854 | if (smp->remote_irk) { | ||
855 | list_del(&smp->remote_irk->list); | ||
856 | kfree(smp->remote_irk); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | chan->data = NULL; | ||
861 | kfree(smp); | ||
862 | hci_conn_drop(conn->hcon); | ||
863 | } | ||
864 | |||
865 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | 865 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) |
866 | { | 866 | { |
867 | struct l2cap_conn *conn = hcon->l2cap_data; | 867 | struct l2cap_conn *conn = hcon->l2cap_data; |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 59a594278a85..cf1094617c69 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -128,8 +128,6 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); | |||
128 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); | 128 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |
129 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); | 129 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); |
130 | 130 | ||
131 | void smp_chan_destroy(struct l2cap_conn *conn); | ||
132 | |||
133 | bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr); | 131 | bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr); |
134 | int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa); | 132 | int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa); |
135 | 133 | ||