diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-18 12:11:14 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-18 12:11:14 -0700 | 
| commit | 8b53c76533aa4356602aea98f98a2f3b4051464c (patch) | |
| tree | ab10ba58e21501407f8108a6bb9003daa2176962 /net/bluetooth/smp.c | |
| parent | 6cfae0c26b21dce323fe8799b66cf4bc996e3565 (diff) | |
| parent | 9575d1a5c0780ea26ff8dd29c94a32be32ce3c85 (diff) | |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
 "API:
   - Add the ability to abort a skcipher walk.
  Algorithms:
   - Fix XTS to actually do the stealing.
   - Add library helpers for AES and DES for single-block users.
   - Add library helpers for SHA256.
   - Add new DES key verification helper.
   - Add surrounding bits for ESSIV generator.
   - Add accelerations for aegis128.
   - Add test vectors for lzo-rle.
  Drivers:
   - Add i.MX8MQ support to caam.
   - Add gcm/ccm/cfb/ofb aes support in inside-secure.
   - Add ofb/cfb aes support in media-tek.
   - Add HiSilicon ZIP accelerator support.
  Others:
   - Fix potential race condition in padata.
   - Use unbound workqueues in padata"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (311 commits)
  crypto: caam - Cast to long first before pointer conversion
  crypto: ccree - enable CTS support in AES-XTS
  crypto: inside-secure - Probe transform record cache RAM sizes
  crypto: inside-secure - Base RD fetchcount on actual RD FIFO size
  crypto: inside-secure - Base CD fetchcount on actual CD FIFO size
  crypto: inside-secure - Enable extended algorithms on newer HW
  crypto: inside-secure: Corrected configuration of EIP96_TOKEN_CTRL
  crypto: inside-secure - Add EIP97/EIP197 and endianness detection
  padata: remove cpu_index from the parallel_queue
  padata: unbind parallel jobs from specific CPUs
  padata: use separate workqueues for parallel and serial work
  padata, pcrypt: take CPU hotplug lock internally in padata_alloc_possible
  crypto: pcrypt - remove padata cpumask notifier
  padata: make padata_do_parallel find alternate callback CPU
  workqueue: require CPU hotplug read exclusion for apply_workqueue_attrs
  workqueue: unconfine alloc/apply/free_workqueue_attrs()
  padata: allocate workqueue internally
  arm64: dts: imx8mq: Add CAAM node
  random: Use wait_event_freezable() in add_hwgenerator_randomness()
  crypto: ux500 - Fix COMPILE_TEST warnings
  ...
Diffstat (limited to 'net/bluetooth/smp.c')
| -rw-r--r-- | net/bluetooth/smp.c | 103 | 
1 files changed, 31 insertions, 72 deletions
| diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6c2b4e6e87ba..26e8cfad22b8 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -23,6 +23,7 @@  #include <linux/debugfs.h>  #include <linux/scatterlist.h>  #include <linux/crypto.h> +#include <crypto/aes.h>  #include <crypto/algapi.h>  #include <crypto/b128ops.h>  #include <crypto/hash.h> @@ -88,7 +89,6 @@ struct smp_dev {  	u8			local_rand[16];  	bool			debug_key; -	struct crypto_cipher	*tfm_aes;  	struct crypto_shash	*tfm_cmac;  	struct crypto_kpp	*tfm_ecdh;  }; @@ -127,7 +127,6 @@ struct smp_chan {  	u8			dhkey[32];  	u8			mackey[16]; -	struct crypto_cipher	*tfm_aes;  	struct crypto_shash	*tfm_cmac;  	struct crypto_kpp	*tfm_ecdh;  }; @@ -377,22 +376,18 @@ static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],   * s1 and ah.   */ -static int smp_e(struct crypto_cipher *tfm, const u8 *k, u8 *r) +static int smp_e(const u8 *k, u8 *r)  { +	struct crypto_aes_ctx ctx;  	uint8_t tmp[16], data[16];  	int err;  	SMP_DBG("k %16phN r %16phN", k, r); -	if (!tfm) { -		BT_ERR("tfm %p", tfm); -		return -EINVAL; -	} -  	/* The most significant octet of key corresponds to k[0] */  	swap_buf(k, tmp, 16); -	err = crypto_cipher_setkey(tfm, tmp, 16); +	err = aes_expandkey(&ctx, tmp, 16);  	if (err) {  		BT_ERR("cipher setkey failed: %d", err);  		return err; @@ -401,17 +396,18 @@ static int smp_e(struct crypto_cipher *tfm, const u8 *k, u8 *r)  	/* Most significant octet of plaintextData corresponds to data[0] */  	swap_buf(r, data, 16); -	crypto_cipher_encrypt_one(tfm, data, data); +	aes_encrypt(&ctx, data, data);  	/* Most significant octet of encryptedData corresponds to data[0] */  	swap_buf(data, r, 16);  	SMP_DBG("r %16phN", r); +	memzero_explicit(&ctx, sizeof (ctx));  	return err;  } -static int smp_c1(struct crypto_cipher *tfm_aes, const u8 k[16], +static int smp_c1(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])  { @@ -436,7 +432,7 @@ static int smp_c1(struct crypto_cipher *tfm_aes, const u8 k[16],  	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);  	/* res = e(k, res) */ -	err = smp_e(tfm_aes, k, res); +	err = smp_e(k, res);  	if (err) {  		BT_ERR("Encrypt data error");  		return err; @@ -453,14 +449,14 @@ static int smp_c1(struct crypto_cipher *tfm_aes, const u8 k[16],  	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);  	/* res = e(k, res) */ -	err = smp_e(tfm_aes, k, res); +	err = smp_e(k, res);  	if (err)  		BT_ERR("Encrypt data error");  	return err;  } -static int smp_s1(struct crypto_cipher *tfm_aes, const u8 k[16], +static int smp_s1(const u8 k[16],  		  const u8 r1[16], const u8 r2[16], u8 _r[16])  {  	int err; @@ -469,15 +465,14 @@ static int smp_s1(struct crypto_cipher *tfm_aes, const u8 k[16],  	memcpy(_r, r2, 8);  	memcpy(_r + 8, r1, 8); -	err = smp_e(tfm_aes, k, _r); +	err = smp_e(k, _r);  	if (err)  		BT_ERR("Encrypt data error");  	return err;  } -static int smp_ah(struct crypto_cipher *tfm, const u8 irk[16], -		  const u8 r[3], u8 res[3]) +static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3])  {  	u8 _res[16];  	int err; @@ -486,7 +481,7 @@ static int smp_ah(struct crypto_cipher *tfm, const u8 irk[16],  	memcpy(_res, r, 3);  	memset(_res + 3, 0, 13); -	err = smp_e(tfm, irk, _res); +	err = smp_e(irk, _res);  	if (err) {  		BT_ERR("Encrypt error");  		return err; @@ -518,7 +513,7 @@ bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],  	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); -	err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash); +	err = smp_ah(irk, &bdaddr->b[3], hash);  	if (err)  		return false; @@ -541,7 +536,7 @@ int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)  	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */  	rpa->b[5] |= 0x40;	/* Set second most significant bit */ -	err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b); +	err = smp_ah(irk, &rpa->b[3], rpa->b);  	if (err < 0)  		return err; @@ -768,7 +763,6 @@ static void smp_chan_destroy(struct l2cap_conn *conn)  	kzfree(smp->slave_csrk);  	kzfree(smp->link_key); -	crypto_free_cipher(smp->tfm_aes);  	crypto_free_shash(smp->tfm_cmac);  	crypto_free_kpp(smp->tfm_ecdh); @@ -957,7 +951,7 @@ static u8 smp_confirm(struct smp_chan *smp)  	BT_DBG("conn %p", conn); -	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp, +	ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp,  		     conn->hcon->init_addr_type, &conn->hcon->init_addr,  		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,  		     cp.confirm_val); @@ -983,12 +977,9 @@ static u8 smp_random(struct smp_chan *smp)  	u8 confirm[16];  	int ret; -	if (IS_ERR_OR_NULL(smp->tfm_aes)) -		return SMP_UNSPECIFIED; -  	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); -	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp, +	ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp,  		     hcon->init_addr_type, &hcon->init_addr,  		     hcon->resp_addr_type, &hcon->resp_addr, confirm);  	if (ret) @@ -1005,7 +996,7 @@ static u8 smp_random(struct smp_chan *smp)  		__le64 rand = 0;  		__le16 ediv = 0; -		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk); +		smp_s1(smp->tk, smp->rrnd, smp->prnd, stk);  		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))  			return SMP_UNSPECIFIED; @@ -1021,7 +1012,7 @@ static u8 smp_random(struct smp_chan *smp)  		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),  			     smp->prnd); -		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk); +		smp_s1(smp->tk, smp->prnd, smp->rrnd, stk);  		if (hcon->pending_sec_level == BT_SECURITY_HIGH)  			auth = 1; @@ -1389,16 +1380,10 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)  	if (!smp)  		return NULL; -	smp->tfm_aes = crypto_alloc_cipher("aes", 0, 0); -	if (IS_ERR(smp->tfm_aes)) { -		BT_ERR("Unable to create AES crypto context"); -		goto zfree_smp; -	} -  	smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);  	if (IS_ERR(smp->tfm_cmac)) {  		BT_ERR("Unable to create CMAC crypto context"); -		goto free_cipher; +		goto zfree_smp;  	}  	smp->tfm_ecdh = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0); @@ -1420,8 +1405,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)  free_shash:  	crypto_free_shash(smp->tfm_cmac); -free_cipher: -	crypto_free_cipher(smp->tfm_aes);  zfree_smp:  	kzfree(smp);  	return NULL; @@ -3232,7 +3215,6 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)  {  	struct l2cap_chan *chan;  	struct smp_dev *smp; -	struct crypto_cipher *tfm_aes;  	struct crypto_shash *tfm_cmac;  	struct crypto_kpp *tfm_ecdh; @@ -3245,17 +3227,9 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)  	if (!smp)  		return ERR_PTR(-ENOMEM); -	tfm_aes = crypto_alloc_cipher("aes", 0, 0); -	if (IS_ERR(tfm_aes)) { -		BT_ERR("Unable to create AES crypto context"); -		kzfree(smp); -		return ERR_CAST(tfm_aes); -	} -  	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);  	if (IS_ERR(tfm_cmac)) {  		BT_ERR("Unable to create CMAC crypto context"); -		crypto_free_cipher(tfm_aes);  		kzfree(smp);  		return ERR_CAST(tfm_cmac);  	} @@ -3264,13 +3238,11 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)  	if (IS_ERR(tfm_ecdh)) {  		BT_ERR("Unable to create ECDH crypto context");  		crypto_free_shash(tfm_cmac); -		crypto_free_cipher(tfm_aes);  		kzfree(smp);  		return ERR_CAST(tfm_ecdh);  	}  	smp->local_oob = false; -	smp->tfm_aes = tfm_aes;  	smp->tfm_cmac = tfm_cmac;  	smp->tfm_ecdh = tfm_ecdh; @@ -3278,7 +3250,6 @@ create_chan:  	chan = l2cap_chan_create();  	if (!chan) {  		if (smp) { -			crypto_free_cipher(smp->tfm_aes);  			crypto_free_shash(smp->tfm_cmac);  			crypto_free_kpp(smp->tfm_ecdh);  			kzfree(smp); @@ -3326,7 +3297,6 @@ static void smp_del_chan(struct l2cap_chan *chan)  	smp = chan->data;  	if (smp) {  		chan->data = NULL; -		crypto_free_cipher(smp->tfm_aes);  		crypto_free_shash(smp->tfm_cmac);  		crypto_free_kpp(smp->tfm_ecdh);  		kzfree(smp); @@ -3582,7 +3552,7 @@ static int __init test_debug_key(struct crypto_kpp *tfm_ecdh)  	return 0;  } -static int __init test_ah(struct crypto_cipher *tfm_aes) +static int __init test_ah(void)  {  	const u8 irk[16] = {  			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, @@ -3592,7 +3562,7 @@ static int __init test_ah(struct crypto_cipher *tfm_aes)  	u8 res[3];  	int err; -	err = smp_ah(tfm_aes, irk, r, res); +	err = smp_ah(irk, r, res);  	if (err)  		return err; @@ -3602,7 +3572,7 @@ static int __init test_ah(struct crypto_cipher *tfm_aes)  	return 0;  } -static int __init test_c1(struct crypto_cipher *tfm_aes) +static int __init test_c1(void)  {  	const u8 k[16] = {  			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3622,7 +3592,7 @@ static int __init test_c1(struct crypto_cipher *tfm_aes)  	u8 res[16];  	int err; -	err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res); +	err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res);  	if (err)  		return err; @@ -3632,7 +3602,7 @@ static int __init test_c1(struct crypto_cipher *tfm_aes)  	return 0;  } -static int __init test_s1(struct crypto_cipher *tfm_aes) +static int __init test_s1(void)  {  	const u8 k[16] = {  			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3647,7 +3617,7 @@ static int __init test_s1(struct crypto_cipher *tfm_aes)  	u8 res[16];  	int err; -	err = smp_s1(tfm_aes, k, r1, r2, res); +	err = smp_s1(k, r1, r2, res);  	if (err)  		return err; @@ -3828,8 +3798,7 @@ static const struct file_operations test_smp_fops = {  	.llseek		= default_llseek,  }; -static int __init run_selftests(struct crypto_cipher *tfm_aes, -				struct crypto_shash *tfm_cmac, +static int __init run_selftests(struct crypto_shash *tfm_cmac,  				struct crypto_kpp *tfm_ecdh)  {  	ktime_t calltime, delta, rettime; @@ -3844,19 +3813,19 @@ static int __init run_selftests(struct crypto_cipher *tfm_aes,  		goto done;  	} -	err = test_ah(tfm_aes); +	err = test_ah();  	if (err) {  		BT_ERR("smp_ah test failed");  		goto done;  	} -	err = test_c1(tfm_aes); +	err = test_c1();  	if (err) {  		BT_ERR("smp_c1 test failed");  		goto done;  	} -	err = test_s1(tfm_aes); +	err = test_s1();  	if (err) {  		BT_ERR("smp_s1 test failed");  		goto done; @@ -3913,21 +3882,13 @@ done:  int __init bt_selftest_smp(void)  { -	struct crypto_cipher *tfm_aes;  	struct crypto_shash *tfm_cmac;  	struct crypto_kpp *tfm_ecdh;  	int err; -	tfm_aes = crypto_alloc_cipher("aes", 0, 0); -	if (IS_ERR(tfm_aes)) { -		BT_ERR("Unable to create AES crypto context"); -		return PTR_ERR(tfm_aes); -	} -  	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);  	if (IS_ERR(tfm_cmac)) {  		BT_ERR("Unable to create CMAC crypto context"); -		crypto_free_cipher(tfm_aes);  		return PTR_ERR(tfm_cmac);  	} @@ -3935,14 +3896,12 @@ int __init bt_selftest_smp(void)  	if (IS_ERR(tfm_ecdh)) {  		BT_ERR("Unable to create ECDH crypto context");  		crypto_free_shash(tfm_cmac); -		crypto_free_cipher(tfm_aes);  		return PTR_ERR(tfm_ecdh);  	} -	err = run_selftests(tfm_aes, tfm_cmac, tfm_ecdh); +	err = run_selftests(tfm_cmac, tfm_ecdh);  	crypto_free_shash(tfm_cmac); -	crypto_free_cipher(tfm_aes);  	crypto_free_kpp(tfm_ecdh);  	return err; | 
