Commit 763d9a30 authored by Salvatore Benedetto's avatar Salvatore Benedetto Committed by Marcel Holtmann
Browse files

Bluetooth: allocate data for kpp on heap



Bluetooth would crash when computing ECDH keys with kpp
if VMAP_STACK is enabled. Fix by allocating data passed
to kpp on heap.

Fixes: 58771c1c ("Bluetooth: convert smp and selftest to crypto kpp
API")
Signed-off-by: default avatarSalvatore Benedetto <salvatore.benedetto@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 58771c1c
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -59,16 +59,19 @@ bool compute_ecdh_secret(const u8 public_key[64], const u8 private_key[32],
	struct ecdh p;
	struct ecdh_completion result;
	struct scatterlist src, dst;
	u8 tmp[64];
	u8 *buf;
	u8 *tmp, *buf;
	unsigned int buf_len;
	int err = -ENOMEM;

	tmp = kmalloc(64, GFP_KERNEL);
	if (!tmp)
		return false;

	tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
	if (IS_ERR(tfm)) {
		pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n",
		       PTR_ERR(tfm));
		return false;
		goto free_tmp;
	}

	req = kpp_request_alloc(tfm, GFP_KERNEL);
@@ -128,6 +131,8 @@ free_req:
	kpp_request_free(req);
free_kpp:
	crypto_free_kpp(tfm);
free_tmp:
	kfree(tmp);
	return (err == 0);
}

@@ -138,18 +143,21 @@ bool generate_ecdh_keys(u8 public_key[64], u8 private_key[32])
	struct ecdh p;
	struct ecdh_completion result;
	struct scatterlist dst;
	u8 tmp[64];
	u8 *buf;
	u8 *tmp, *buf;
	unsigned int buf_len;
	int err = -ENOMEM;
	const unsigned short max_tries = 16;
	unsigned short tries = 0;

	tmp = kmalloc(64, GFP_KERNEL);
	if (!tmp)
		return false;

	tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
	if (IS_ERR(tfm)) {
		pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n",
		       PTR_ERR(tfm));
		return false;
		goto free_tmp;
	}

	req = kpp_request_alloc(tfm, GFP_KERNEL);
@@ -219,5 +227,7 @@ free_req:
	kpp_request_free(req);
free_kpp:
	crypto_free_kpp(tfm);
free_tmp:
	kfree(tmp);
	return (err == 0);
}
+17 −5
Original line number Diff line number Diff line
@@ -142,18 +142,30 @@ static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32],
				   const u8 pub_a[64], const u8 pub_b[64],
				   const u8 dhkey[32])
{
	u8 dhkey_a[32], dhkey_b[32];
	u8 *tmp, *dhkey_a, *dhkey_b;
	int ret = 0;

	tmp = kmalloc(64, GFP_KERNEL);
	if (!tmp)
		return -EINVAL;

	dhkey_a = &tmp[0];
	dhkey_b = &tmp[32];

	compute_ecdh_secret(pub_b, priv_a, dhkey_a);
	compute_ecdh_secret(pub_a, priv_b, dhkey_b);

	if (memcmp(dhkey_a, dhkey, 32))
		return -EINVAL;
	if (memcmp(dhkey_a, dhkey, 32)) {
		ret = -EINVAL;
		goto out;
	}

	if (memcmp(dhkey_b, dhkey, 32))
		return -EINVAL;
		ret = -EINVAL;

	return 0;
out:
	kfree(dhkey_a);
	return ret;
}

static char test_ecdh_buffer[32];