aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-03-16 04:10:19 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-16 04:31:05 -0400
commit88a479d9507eb7a510a612705aa686c52d24b2ab (patch)
treeb49bcb4e3f33138e4626eaacf4dc9871ad2d78ca /net/bluetooth/smp.c
parent276812ec3e945493443e399921a07e9d6aa4d5b2 (diff)
Bluetooth: Create SMP device structure for local crypto context
Every Bluetooth Low Energy controller requires a local crypto context to handle the resolvable private addresses. At the moment this is just a single crypto context, but for out-of-band data generation it will require an additional. To facility this, create a struct smp_dev that will hold all the extra information. This patch is just the refactoring in preparation for future changes. 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.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index a2be6fcc3c51..952ba6376e1c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -73,6 +73,10 @@ enum {
73 SMP_FLAG_OOB, 73 SMP_FLAG_OOB,
74}; 74};
75 75
76struct smp_dev {
77 struct crypto_blkcipher *tfm_aes;
78};
79
76struct smp_chan { 80struct smp_chan {
77 struct l2cap_conn *conn; 81 struct l2cap_conn *conn;
78 struct delayed_work security_timer; 82 struct delayed_work security_timer;
@@ -478,18 +482,18 @@ bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
478 const bdaddr_t *bdaddr) 482 const bdaddr_t *bdaddr)
479{ 483{
480 struct l2cap_chan *chan = hdev->smp_data; 484 struct l2cap_chan *chan = hdev->smp_data;
481 struct crypto_blkcipher *tfm; 485 struct smp_dev *smp;
482 u8 hash[3]; 486 u8 hash[3];
483 int err; 487 int err;
484 488
485 if (!chan || !chan->data) 489 if (!chan || !chan->data)
486 return false; 490 return false;
487 491
488 tfm = chan->data; 492 smp = chan->data;
489 493
490 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); 494 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
491 495
492 err = smp_ah(tfm, irk, &bdaddr->b[3], hash); 496 err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash);
493 if (err) 497 if (err)
494 return false; 498 return false;
495 499
@@ -499,20 +503,20 @@ bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
499int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) 503int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
500{ 504{
501 struct l2cap_chan *chan = hdev->smp_data; 505 struct l2cap_chan *chan = hdev->smp_data;
502 struct crypto_blkcipher *tfm; 506 struct smp_dev *smp;
503 int err; 507 int err;
504 508
505 if (!chan || !chan->data) 509 if (!chan || !chan->data)
506 return -EOPNOTSUPP; 510 return -EOPNOTSUPP;
507 511
508 tfm = chan->data; 512 smp = chan->data;
509 513
510 get_random_bytes(&rpa->b[3], 3); 514 get_random_bytes(&rpa->b[3], 3);
511 515
512 rpa->b[5] &= 0x3f; /* Clear two most significant bits */ 516 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
513 rpa->b[5] |= 0x40; /* Set second most significant bit */ 517 rpa->b[5] |= 0x40; /* Set second most significant bit */
514 518
515 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b); 519 err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b);
516 if (err < 0) 520 if (err < 0)
517 return err; 521 return err;
518 522
@@ -2930,27 +2934,36 @@ static const struct l2cap_ops smp_root_chan_ops = {
2930static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) 2934static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
2931{ 2935{
2932 struct l2cap_chan *chan; 2936 struct l2cap_chan *chan;
2933 struct crypto_blkcipher *tfm_aes; 2937 struct smp_dev *smp;
2938 struct crypto_blkcipher *tfm_aes;
2934 2939
2935 if (cid == L2CAP_CID_SMP_BREDR) { 2940 if (cid == L2CAP_CID_SMP_BREDR) {
2936 tfm_aes = NULL; 2941 smp = NULL;
2937 goto create_chan; 2942 goto create_chan;
2938 } 2943 }
2939 2944
2940 tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0); 2945 smp = kzalloc(sizeof(*smp), GFP_KERNEL);
2946 if (!smp)
2947 return ERR_PTR(-ENOMEM);
2948
2949 tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
2941 if (IS_ERR(tfm_aes)) { 2950 if (IS_ERR(tfm_aes)) {
2942 BT_ERR("Unable to create crypto context"); 2951 BT_ERR("Unable to create ECB crypto context");
2952 kzfree(smp);
2943 return ERR_CAST(tfm_aes); 2953 return ERR_CAST(tfm_aes);
2944 } 2954 }
2945 2955
2956 smp->tfm_aes = tfm_aes;
2957
2946create_chan: 2958create_chan:
2947 chan = l2cap_chan_create(); 2959 chan = l2cap_chan_create();
2948 if (!chan) { 2960 if (!chan) {
2949 crypto_free_blkcipher(tfm_aes); 2961 crypto_free_blkcipher(smp->tfm_aes);
2962 kzfree(smp);
2950 return ERR_PTR(-ENOMEM); 2963 return ERR_PTR(-ENOMEM);
2951 } 2964 }
2952 2965
2953 chan->data = tfm_aes; 2966 chan->data = smp;
2954 2967
2955 l2cap_add_scid(chan, cid); 2968 l2cap_add_scid(chan, cid);
2956 2969
@@ -2983,14 +2996,16 @@ create_chan:
2983 2996
2984static void smp_del_chan(struct l2cap_chan *chan) 2997static void smp_del_chan(struct l2cap_chan *chan)
2985{ 2998{
2986 struct crypto_blkcipher *tfm_aes; 2999 struct smp_dev *smp;
2987 3000
2988 BT_DBG("chan %p", chan); 3001 BT_DBG("chan %p", chan);
2989 3002
2990 tfm_aes = chan->data; 3003 smp = chan->data;
2991 if (tfm_aes) { 3004 if (smp) {
2992 chan->data = NULL; 3005 chan->data = NULL;
2993 crypto_free_blkcipher(tfm_aes); 3006 if (smp->tfm_aes)
3007 crypto_free_blkcipher(smp->tfm_aes);
3008 kzfree(smp);
2994 } 3009 }
2995 3010
2996 l2cap_chan_put(chan); 3011 l2cap_chan_put(chan);