diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-03-16 04:10:22 -0400 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-16 04:31:27 -0400 |
commit | 60a27d653d972584e5e98ab3558c62c3d3bc547a (patch) | |
tree | 0f77d9476e41e867ea89c4011d0188db70a204a8 /net/bluetooth | |
parent | 6e2dc6d1133f5f8bfd028ba7d1c3fb0b3fa717e9 (diff) |
Bluetooth: Add function for generating LE SC out-of-band data
This patch adds a smp_generate_oob function that allows to create
local out-of-band data that can be used for pairing and also provides
the confirmation and random value.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/smp.c | 53 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 1 |
2 files changed, 54 insertions, 0 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 12e9c833885b..1669e7127e2e 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -74,6 +74,12 @@ enum { | |||
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct smp_dev { | 76 | struct smp_dev { |
77 | /* Secure Connections OOB data */ | ||
78 | u8 local_pk[64]; | ||
79 | u8 local_sk[32]; | ||
80 | u8 local_rr[16]; | ||
81 | bool debug_key; | ||
82 | |||
77 | struct crypto_blkcipher *tfm_aes; | 83 | struct crypto_blkcipher *tfm_aes; |
78 | struct crypto_hash *tfm_cmac; | 84 | struct crypto_hash *tfm_cmac; |
79 | }; | 85 | }; |
@@ -526,6 +532,53 @@ int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) | |||
526 | return 0; | 532 | return 0; |
527 | } | 533 | } |
528 | 534 | ||
535 | int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) | ||
536 | { | ||
537 | struct l2cap_chan *chan = hdev->smp_data; | ||
538 | struct smp_dev *smp; | ||
539 | int err; | ||
540 | |||
541 | if (!chan || !chan->data) | ||
542 | return -EOPNOTSUPP; | ||
543 | |||
544 | smp = chan->data; | ||
545 | |||
546 | if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { | ||
547 | BT_DBG("Using debug keys"); | ||
548 | memcpy(smp->local_pk, debug_pk, 64); | ||
549 | memcpy(smp->local_sk, debug_sk, 32); | ||
550 | smp->debug_key = true; | ||
551 | } else { | ||
552 | while (true) { | ||
553 | /* Generate local key pair for Secure Connections */ | ||
554 | if (!ecc_make_key(smp->local_pk, smp->local_sk)) | ||
555 | return -EIO; | ||
556 | |||
557 | /* This is unlikely, but we need to check that | ||
558 | * we didn't accidentially generate a debug key. | ||
559 | */ | ||
560 | if (memcmp(smp->local_sk, debug_sk, 32)) | ||
561 | break; | ||
562 | } | ||
563 | smp->debug_key = false; | ||
564 | } | ||
565 | |||
566 | SMP_DBG("OOB Public Key X: %32phN", smp->local_pk); | ||
567 | SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); | ||
568 | SMP_DBG("OOB Private Key: %32phN", smp->local_sk); | ||
569 | |||
570 | get_random_bytes(smp->local_rr, 16); | ||
571 | |||
572 | err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, | ||
573 | smp->local_rr, 0, hash); | ||
574 | if (err < 0) | ||
575 | return err; | ||
576 | |||
577 | memcpy(rand, smp->local_rr, 16); | ||
578 | |||
579 | return 0; | ||
580 | } | ||
581 | |||
529 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | 582 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) |
530 | { | 583 | { |
531 | struct l2cap_chan *chan = conn->smp; | 584 | struct l2cap_chan *chan = conn->smp; |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 60c5b73fcb4b..6cf872563ea7 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -188,6 +188,7 @@ int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); | |||
188 | bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], | 188 | bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], |
189 | const bdaddr_t *bdaddr); | 189 | const bdaddr_t *bdaddr); |
190 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa); | 190 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa); |
191 | int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]); | ||
191 | 192 | ||
192 | int smp_register(struct hci_dev *hdev); | 193 | int smp_register(struct hci_dev *hdev); |
193 | void smp_unregister(struct hci_dev *hdev); | 194 | void smp_unregister(struct hci_dev *hdev); |