aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-03-16 01:10:22 -0700
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-16 10:31:27 +0200
commit60a27d653d972584e5e98ab3558c62c3d3bc547a (patch)
tree0f77d9476e41e867ea89c4011d0188db70a204a8 /net/bluetooth/smp.c
parentBluetooth: Add support for AES-CMAC hash for security manager device (diff)
downloadlinux-dev-60a27d653d972584e5e98ab3558c62c3d3bc547a.tar.xz
linux-dev-60a27d653d972584e5e98ab3558c62c3d3bc547a.zip
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/smp.c')
-rw-r--r--net/bluetooth/smp.c53
1 files changed, 53 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 {
};
struct smp_dev {
+ /* Secure Connections OOB data */
+ u8 local_pk[64];
+ u8 local_sk[32];
+ u8 local_rr[16];
+ bool debug_key;
+
struct crypto_blkcipher *tfm_aes;
struct crypto_hash *tfm_cmac;
};
@@ -526,6 +532,53 @@ int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
return 0;
}
+int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
+{
+ struct l2cap_chan *chan = hdev->smp_data;
+ struct smp_dev *smp;
+ int err;
+
+ if (!chan || !chan->data)
+ return -EOPNOTSUPP;
+
+ smp = chan->data;
+
+ if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
+ BT_DBG("Using debug keys");
+ memcpy(smp->local_pk, debug_pk, 64);
+ memcpy(smp->local_sk, debug_sk, 32);
+ smp->debug_key = true;
+ } else {
+ while (true) {
+ /* Generate local key pair for Secure Connections */
+ if (!ecc_make_key(smp->local_pk, smp->local_sk))
+ return -EIO;
+
+ /* This is unlikely, but we need to check that
+ * we didn't accidentially generate a debug key.
+ */
+ if (memcmp(smp->local_sk, debug_sk, 32))
+ break;
+ }
+ smp->debug_key = false;
+ }
+
+ SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
+ SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
+ SMP_DBG("OOB Private Key: %32phN", smp->local_sk);
+
+ get_random_bytes(smp->local_rr, 16);
+
+ err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk,
+ smp->local_rr, 0, hash);
+ if (err < 0)
+ return err;
+
+ memcpy(rand, smp->local_rr, 16);
+
+ return 0;
+}
+
static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
{
struct l2cap_chan *chan = conn->smp;