diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-03-16 04:10:19 -0400 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-16 04:31:05 -0400 |
commit | 88a479d9507eb7a510a612705aa686c52d24b2ab (patch) | |
tree | b49bcb4e3f33138e4626eaacf4dc9871ad2d78ca /net/bluetooth/smp.c | |
parent | 276812ec3e945493443e399921a07e9d6aa4d5b2 (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.c | 47 |
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 | ||
76 | struct smp_dev { | ||
77 | struct crypto_blkcipher *tfm_aes; | ||
78 | }; | ||
79 | |||
76 | struct smp_chan { | 80 | struct 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], | |||
499 | int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) | 503 | int 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 = { | |||
2930 | static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) | 2934 | static 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 | |||
2946 | create_chan: | 2958 | create_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 | ||
2984 | static void smp_del_chan(struct l2cap_chan *chan) | 2997 | static 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); |