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>
+struct smp_dev {
+ struct crypto_blkcipher *tfm_aes;
+};
+
struct smp_chan {
struct l2cap_conn *conn;
struct delayed_work security_timer;
struct smp_chan {
struct l2cap_conn *conn;
struct delayed_work security_timer;
const bdaddr_t *bdaddr)
{
struct l2cap_chan *chan = hdev->smp_data;
const 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;
u8 hash[3];
int err;
if (!chan || !chan->data)
return false;
BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
- err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
+ err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash);
int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
{
struct l2cap_chan *chan = hdev->smp_data;
int smp_generate_rpa(struct hci_dev *hdev, const 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;
int err;
if (!chan || !chan->data)
return -EOPNOTSUPP;
get_random_bytes(&rpa->b[3], 3);
rpa->b[5] &= 0x3f; /* Clear two most significant bits */
rpa->b[5] |= 0x40; /* Set second most significant bit */
get_random_bytes(&rpa->b[3], 3);
rpa->b[5] &= 0x3f; /* Clear two most significant bits */
rpa->b[5] |= 0x40; /* Set second most significant bit */
- err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
+ err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b);
static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
{
struct l2cap_chan *chan;
static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
{
struct l2cap_chan *chan;
- struct crypto_blkcipher *tfm_aes;
+ struct smp_dev *smp;
+ struct crypto_blkcipher *tfm_aes;
if (cid == L2CAP_CID_SMP_BREDR) {
if (cid == L2CAP_CID_SMP_BREDR) {
- tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0);
+ smp = kzalloc(sizeof(*smp), GFP_KERNEL);
+ if (!smp)
+ return ERR_PTR(-ENOMEM);
+
+ tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
- BT_ERR("Unable to create crypto context");
+ BT_ERR("Unable to create ECB crypto context");
+ kzfree(smp);
return ERR_CAST(tfm_aes);
}
return ERR_CAST(tfm_aes);
}
+ smp->tfm_aes = tfm_aes;
+
create_chan:
chan = l2cap_chan_create();
if (!chan) {
create_chan:
chan = l2cap_chan_create();
if (!chan) {
- crypto_free_blkcipher(tfm_aes);
+ crypto_free_blkcipher(smp->tfm_aes);
+ kzfree(smp);
return ERR_PTR(-ENOMEM);
}
return ERR_PTR(-ENOMEM);
}
l2cap_add_scid(chan, cid);
l2cap_add_scid(chan, cid);
static void smp_del_chan(struct l2cap_chan *chan)
{
static void smp_del_chan(struct l2cap_chan *chan)
{
- struct crypto_blkcipher *tfm_aes;
- tfm_aes = chan->data;
- if (tfm_aes) {
+ smp = chan->data;
+ if (smp) {
- crypto_free_blkcipher(tfm_aes);
+ if (smp->tfm_aes)
+ crypto_free_blkcipher(smp->tfm_aes);
+ kzfree(smp);