Message ID | 264af59a3060c2bc2a725cfc66a8fa68219d1c4a.1466974736.git.luto@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Andy, > 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(-) patch has been applied to bluetooth-next tree. Regards Marcel
* Marcel Holtmann <marcel@holtmann.org> wrote: > Hi Andy, > > > 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(-) > > patch has been applied to bluetooth-next tree. Sadly carrying this separately will delay the virtual kernel stacks feature by a kernel cycle, because it's a must-have prerequisite. Thanks, Ingo
Hi Ingo, >>> 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(-) >> >> patch has been applied to bluetooth-next tree. > > Sadly carrying this separately will delay the virtual kernel stacks feature by a > kernel cycle, because it's a must-have prerequisite. I can take it back out, but then I have the fear the the ECDH change to use KPP for SMP might be the one that has to wait a kernel cycle. Either way is fine with me, but I want to avoid nasty merge conflicts in the Bluetooth SMP code. Regards Marcel
On Mon, Jun 27, 2016 at 3:30 PM, Marcel Holtmann <marcel@holtmann.org> wrote: > Hi Ingo, > >>>> 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(-) >>> >>> patch has been applied to bluetooth-next tree. >> >> Sadly carrying this separately will delay the virtual kernel stacks feature by a >> kernel cycle, because it's a must-have prerequisite. > > I can take it back out, but then I have the fear the the ECDH change to use KPP for SMP might be the one that has to wait a kernel cycle. Either way is fine with me, but I want to avoid nasty merge conflicts in the Bluetooth SMP code. Nothing goes wrong if an identical patch is queued in both places, right? Or, if you prefer not to duplicate it, could one of you commit it and the other one pull it? Ingo, given that this is patch 1 in the series and unlikely to change, if you want to make this whole thing have a separate branch in -tip, this could live there for starters. (But, if you do so, please make sure you base off a very new copy of Linus' tree -- the series is heavily dependent on the thread_info change he applied a few days ago.) --Andy
Hi Andy, >>>>> 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(-) >>>> >>>> patch has been applied to bluetooth-next tree. >>> >>> Sadly carrying this separately will delay the virtual kernel stacks feature by a >>> kernel cycle, because it's a must-have prerequisite. >> >> I can take it back out, but then I have the fear the the ECDH change to use KPP for SMP might be the one that has to wait a kernel cycle. Either way is fine with me, but I want to avoid nasty merge conflicts in the Bluetooth SMP code. > > Nothing goes wrong if an identical patch is queued in both places, > right? Or, if you prefer not to duplicate it, could one of you commit > it and the other one pull it? Ingo, given that this is patch 1 in the > series and unlikely to change, if you want to make this whole thing > have a separate branch in -tip, this could live there for starters. > (But, if you do so, please make sure you base off a very new copy of > Linus' tree -- the series is heavily dependent on the thread_info > change he applied a few days ago.) so what are doing now? I take this back out or we keep it in and let git deal with it when merging the trees? Regards Marcel
On Mon, Jul 4, 2016 at 10:56 AM, Marcel Holtmann <marcel@holtmann.org> wrote: > Hi Andy, > >>>>>> 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(-) >>>>> >>>>> patch has been applied to bluetooth-next tree. >>>> >>>> Sadly carrying this separately will delay the virtual kernel stacks feature by a >>>> kernel cycle, because it's a must-have prerequisite. >>> >>> I can take it back out, but then I have the fear the the ECDH change to use KPP for SMP might be the one that has to wait a kernel cycle. Either way is fine with me, but I want to avoid nasty merge conflicts in the Bluetooth SMP code. >> >> Nothing goes wrong if an identical patch is queued in both places, >> right? Or, if you prefer not to duplicate it, could one of you commit >> it and the other one pull it? Ingo, given that this is patch 1 in the >> series and unlikely to change, if you want to make this whole thing >> have a separate branch in -tip, this could live there for starters. >> (But, if you do so, please make sure you base off a very new copy of >> Linus' tree -- the series is heavily dependent on the thread_info >> change he applied a few days ago.) > > so what are doing now? I take this back out or we keep it in and let git deal with it when merging the trees? > Unless Ingo says otherwise, let's let git deal with it.
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; }