summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-08-08 09:37:17 +0300
committerMarcel Holtmann <marcel@holtmann.org>2014-08-14 08:49:19 +0200
commitdefce9e83666658d4420d65e45ab1ad190992f72 (patch)
treeaf8d06908ba1f5c1e568c3408b490ee5c6a70396 /net/bluetooth/smp.c
parent70db83c4bcdc1447bbcb318389561c90d7056b18 (diff)
downloadlinux-stable-defce9e83666658d4420d65e45ab1ad190992f72.tar.gz
linux-stable-defce9e83666658d4420d65e45ab1ad190992f72.tar.bz2
linux-stable-defce9e83666658d4420d65e45ab1ad190992f72.zip
Bluetooth: Make AES crypto context private to SMP
Now that we have per-adapter SMP data thanks to the root SMP L2CAP channel we can take advantage of it and attach the AES crypto context (only used for SMP) to it. This means that the smp_irk_matches() and smp_generate_rpa() function can be converted to internally handle the AES context. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 2362ae35a4d5..6925fc4caaee 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -139,12 +139,18 @@ static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
return 0;
}
-bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
- bdaddr_t *bdaddr)
+bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
{
+ struct l2cap_chan *chan = hdev->smp_data;
+ struct crypto_blkcipher *tfm;
u8 hash[3];
int err;
+ if (!chan || !chan->data)
+ return false;
+
+ tfm = chan->data;
+
BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
@@ -154,10 +160,17 @@ bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
return !memcmp(bdaddr->b, hash, 3);
}
-int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
+int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
{
+ struct l2cap_chan *chan = hdev->smp_data;
+ struct crypto_blkcipher *tfm;
int err;
+ if (!chan || !chan->data)
+ return -EOPNOTSUPP;
+
+ tfm = chan->data;
+
get_random_bytes(&rpa->b[3], 3);
rpa->b[5] &= 0x3f; /* Clear two most significant bits */
@@ -1555,25 +1568,25 @@ static const struct l2cap_ops smp_root_chan_ops = {
int smp_register(struct hci_dev *hdev)
{
struct l2cap_chan *chan;
+ struct crypto_blkcipher *tfm_aes;
BT_DBG("%s", hdev->name);
- hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(hdev->tfm_aes)) {
- int err = PTR_ERR(hdev->tfm_aes);
+ tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm_aes)) {
+ int err = PTR_ERR(tfm_aes);
BT_ERR("Unable to create crypto context");
- hdev->tfm_aes = NULL;
return err;
}
chan = l2cap_chan_create();
if (!chan) {
- crypto_free_blkcipher(hdev->tfm_aes);
- hdev->tfm_aes = NULL;
+ crypto_free_blkcipher(tfm_aes);
return -ENOMEM;
}
+ chan->data = tfm_aes;
+
/* FIXME: Using reserved 0x1f value for now - to be changed to
* L2CAP_CID_SMP once all functionality is in place.
*/
@@ -1596,15 +1609,17 @@ int smp_register(struct hci_dev *hdev)
void smp_unregister(struct hci_dev *hdev)
{
struct l2cap_chan *chan = hdev->smp_data;
+ struct crypto_blkcipher *tfm_aes;
if (!chan)
return;
BT_DBG("%s chan %p", hdev->name, chan);
- if (hdev->tfm_aes) {
- crypto_free_blkcipher(hdev->tfm_aes);
- hdev->tfm_aes = NULL;
+ tfm_aes = chan->data;
+ if (tfm_aes) {
+ chan->data = NULL;
+ crypto_free_blkcipher(tfm_aes);
}
hdev->smp_data = NULL;