lkml.org 
[lkml]   [2016]   [Jul]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 01/32] bluetooth: Switch SMP to crypto_cipher_encrypt_one()
    Date
    SMP does ECB crypto on stack buffers.  This is complicated and
    fragile, and it will not work if the stack is virtually allocated.

    Switch to the crypto_cipher interface, which is simpler and safer.

    Cc: Marcel Holtmann <marcel@holtmann.org>
    Cc: Gustavo Padovan <gustavo@padovan.org>
    Cc: Johan Hedberg <johan.hedberg@gmail.com>
    Cc: "David S. Miller" <davem@davemloft.net>
    Cc: linux-bluetooth@vger.kernel.org
    Cc: netdev@vger.kernel.org
    Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
    Acked-and-tested-by: Johan Hedberg <johan.hedberg@intel.com>
    Signed-off-by: Andy Lutomirski <luto@kernel.org>
    ---
    net/bluetooth/smp.c | 67 ++++++++++++++++++++++-------------------------------
    1 file changed, 28 insertions(+), 39 deletions(-)

    diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
    index 50976a6481f3..4c1a16a96ae5 100644
    --- a/net/bluetooth/smp.c
    +++ b/net/bluetooth/smp.c
    @@ -22,9 +22,9 @@

    #include <linux/debugfs.h>
    #include <linux/scatterlist.h>
    +#include <linux/crypto.h>
    #include <crypto/b128ops.h>
    #include <crypto/hash.h>
    -#include <crypto/skcipher.h>

    #include <net/bluetooth/bluetooth.h>
    #include <net/bluetooth/hci_core.h>
    @@ -88,7 +88,7 @@ struct smp_dev {
    u8 min_key_size;
    u8 max_key_size;

    - struct crypto_skcipher *tfm_aes;
    + struct crypto_cipher *tfm_aes;
    struct crypto_shash *tfm_cmac;
    };

    @@ -127,7 +127,7 @@ struct smp_chan {
    u8 dhkey[32];
    u8 mackey[16];

    - struct crypto_skcipher *tfm_aes;
    + struct crypto_cipher *tfm_aes;
    struct crypto_shash *tfm_cmac;
    };

    @@ -361,10 +361,8 @@ static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16],
    * s1 and ah.
    */

    -static int smp_e(struct crypto_skcipher *tfm, const u8 *k, u8 *r)
    +static int smp_e(struct crypto_cipher *tfm, const u8 *k, u8 *r)
    {
    - SKCIPHER_REQUEST_ON_STACK(req, tfm);
    - struct scatterlist sg;
    uint8_t tmp[16], data[16];
    int err;

    @@ -378,7 +376,7 @@ static int smp_e(struct crypto_skcipher *tfm, const u8 *k, u8 *r)
    /* The most significant octet of key corresponds to k[0] */
    swap_buf(k, tmp, 16);

    - err = crypto_skcipher_setkey(tfm, tmp, 16);
    + err = crypto_cipher_setkey(tfm, tmp, 16);
    if (err) {
    BT_ERR("cipher setkey failed: %d", err);
    return err;
    @@ -387,16 +385,7 @@ static int smp_e(struct crypto_skcipher *tfm, const u8 *k, u8 *r)
    /* Most significant octet of plaintextData corresponds to data[0] */
    swap_buf(r, data, 16);

    - sg_init_one(&sg, data, 16);
    -
    - skcipher_request_set_tfm(req, tfm);
    - skcipher_request_set_callback(req, 0, NULL, NULL);
    - skcipher_request_set_crypt(req, &sg, &sg, 16, NULL);
    -
    - err = crypto_skcipher_encrypt(req);
    - skcipher_request_zero(req);
    - if (err)
    - BT_ERR("Encrypt data error %d", err);
    + crypto_cipher_encrypt_one(tfm, data, data);

    /* Most significant octet of encryptedData corresponds to data[0] */
    swap_buf(data, r, 16);
    @@ -406,7 +395,7 @@ static int smp_e(struct crypto_skcipher *tfm, const u8 *k, u8 *r)
    return err;
    }

    -static int smp_c1(struct crypto_skcipher *tfm_aes, const u8 k[16],
    +static int smp_c1(struct crypto_cipher *tfm_aes, const u8 k[16],
    const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
    const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
    {
    @@ -455,7 +444,7 @@ static int smp_c1(struct crypto_skcipher *tfm_aes, const u8 k[16],
    return err;
    }

    -static int smp_s1(struct crypto_skcipher *tfm_aes, const u8 k[16],
    +static int smp_s1(struct crypto_cipher *tfm_aes, const u8 k[16],
    const u8 r1[16], const u8 r2[16], u8 _r[16])
    {
    int err;
    @@ -471,7 +460,7 @@ static int smp_s1(struct crypto_skcipher *tfm_aes, const u8 k[16],
    return err;
    }

    -static int smp_ah(struct crypto_skcipher *tfm, const u8 irk[16],
    +static int smp_ah(struct crypto_cipher *tfm, const u8 irk[16],
    const u8 r[3], u8 res[3])
    {
    u8 _res[16];
    @@ -759,7 +748,7 @@ static void smp_chan_destroy(struct l2cap_conn *conn)
    kzfree(smp->slave_csrk);
    kzfree(smp->link_key);

    - crypto_free_skcipher(smp->tfm_aes);
    + crypto_free_cipher(smp->tfm_aes);
    crypto_free_shash(smp->tfm_cmac);

    /* Ensure that we don't leave any debug key around if debug key
    @@ -1359,9 +1348,9 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
    if (!smp)
    return NULL;

    - smp->tfm_aes = crypto_alloc_skcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
    + smp->tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
    if (IS_ERR(smp->tfm_aes)) {
    - BT_ERR("Unable to create ECB crypto context");
    + BT_ERR("Unable to create AES crypto context");
    kzfree(smp);
    return NULL;
    }
    @@ -1369,7 +1358,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
    smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
    if (IS_ERR(smp->tfm_cmac)) {
    BT_ERR("Unable to create CMAC crypto context");
    - crypto_free_skcipher(smp->tfm_aes);
    + crypto_free_cipher(smp->tfm_aes);
    kzfree(smp);
    return NULL;
    }
    @@ -3120,7 +3109,7 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
    {
    struct l2cap_chan *chan;
    struct smp_dev *smp;
    - struct crypto_skcipher *tfm_aes;
    + struct crypto_cipher *tfm_aes;
    struct crypto_shash *tfm_cmac;

    if (cid == L2CAP_CID_SMP_BREDR) {
    @@ -3132,9 +3121,9 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
    if (!smp)
    return ERR_PTR(-ENOMEM);

    - tfm_aes = crypto_alloc_skcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
    + tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
    if (IS_ERR(tfm_aes)) {
    - BT_ERR("Unable to create ECB crypto context");
    + BT_ERR("Unable to create AES crypto context");
    kzfree(smp);
    return ERR_CAST(tfm_aes);
    }
    @@ -3142,7 +3131,7 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
    tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
    if (IS_ERR(tfm_cmac)) {
    BT_ERR("Unable to create CMAC crypto context");
    - crypto_free_skcipher(tfm_aes);
    + crypto_free_cipher(tfm_aes);
    kzfree(smp);
    return ERR_CAST(tfm_cmac);
    }
    @@ -3156,7 +3145,7 @@ create_chan:
    chan = l2cap_chan_create();
    if (!chan) {
    if (smp) {
    - crypto_free_skcipher(smp->tfm_aes);
    + crypto_free_cipher(smp->tfm_aes);
    crypto_free_shash(smp->tfm_cmac);
    kzfree(smp);
    }
    @@ -3203,7 +3192,7 @@ static void smp_del_chan(struct l2cap_chan *chan)
    smp = chan->data;
    if (smp) {
    chan->data = NULL;
    - crypto_free_skcipher(smp->tfm_aes);
    + crypto_free_cipher(smp->tfm_aes);
    crypto_free_shash(smp->tfm_cmac);
    kzfree(smp);
    }
    @@ -3440,7 +3429,7 @@ void smp_unregister(struct hci_dev *hdev)

    #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)

    -static int __init test_ah(struct crypto_skcipher *tfm_aes)
    +static int __init test_ah(struct crypto_cipher *tfm_aes)
    {
    const u8 irk[16] = {
    0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
    @@ -3460,7 +3449,7 @@ static int __init test_ah(struct crypto_skcipher *tfm_aes)
    return 0;
    }

    -static int __init test_c1(struct crypto_skcipher *tfm_aes)
    +static int __init test_c1(struct crypto_cipher *tfm_aes)
    {
    const u8 k[16] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    @@ -3490,7 +3479,7 @@ static int __init test_c1(struct crypto_skcipher *tfm_aes)
    return 0;
    }

    -static int __init test_s1(struct crypto_skcipher *tfm_aes)
    +static int __init test_s1(struct crypto_cipher *tfm_aes)
    {
    const u8 k[16] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    @@ -3686,7 +3675,7 @@ static const struct file_operations test_smp_fops = {
    .llseek = default_llseek,
    };

    -static int __init run_selftests(struct crypto_skcipher *tfm_aes,
    +static int __init run_selftests(struct crypto_cipher *tfm_aes,
    struct crypto_shash *tfm_cmac)
    {
    ktime_t calltime, delta, rettime;
    @@ -3764,27 +3753,27 @@ done:

    int __init bt_selftest_smp(void)
    {
    - struct crypto_skcipher *tfm_aes;
    + struct crypto_cipher *tfm_aes;
    struct crypto_shash *tfm_cmac;
    int err;

    - tfm_aes = crypto_alloc_skcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
    + tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
    if (IS_ERR(tfm_aes)) {
    - BT_ERR("Unable to create ECB crypto context");
    + BT_ERR("Unable to create AES crypto context");
    return PTR_ERR(tfm_aes);
    }

    tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
    if (IS_ERR(tfm_cmac)) {
    BT_ERR("Unable to create CMAC crypto context");
    - crypto_free_skcipher(tfm_aes);
    + crypto_free_cipher(tfm_aes);
    return PTR_ERR(tfm_cmac);
    }

    err = run_selftests(tfm_aes, tfm_cmac);

    crypto_free_shash(tfm_cmac);
    - crypto_free_skcipher(tfm_aes);
    + crypto_free_cipher(tfm_aes);

    return err;
    }
    --
    2.7.4
    \
     
     \ /
      Last update: 2016-07-11 23:41    [W:3.503 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site