Commit 812b3407 authored by Hui Tang's avatar Hui Tang Committed by Zheng Zengkai
Browse files

crypto: hisilicon/hpre - fix ecdh self test issue

mainline inclusion
from mainline-master
commit 1e609f5f
category: bugfix
bugzilla: 173981
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e609f5fb73b6b17af369a031f3a4c2b9b405854



----------------------------------------------------------------------

When the key length is zero, use stdrng to generate private key
to pass the crypto ecdh-nist-p256 self test on vector 2.

Signed-off-by: default avatarHui Tang <tanghui20@huawei.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarMingqiang Ling <lingmingqiang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 5a1348bc
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <crypto/dh.h>
#include <crypto/ecc_curve.h>
#include <crypto/ecdh.h>
#include <crypto/rng.h>
#include <crypto/internal/akcipher.h>
#include <crypto/internal/kpp.h>
#include <crypto/internal/rsa.h>
@@ -38,6 +39,9 @@ struct hpre_ctx;
#define HPRE_DFX_SEC_TO_US	1000000
#define HPRE_DFX_US_TO_NS	1000

/* due to nist p521  */
#define HPRE_ECC_MAX_KSZ	66

/* size in bytes of the n prime */
#define HPRE_ECC_NIST_P192_N_SIZE	24
#define HPRE_ECC_NIST_P256_N_SIZE	32
@@ -1333,11 +1337,32 @@ static bool hpre_key_is_zero(char *key, unsigned short key_sz)
	return true;
}

static int ecdh_gen_privkey(struct hpre_ctx *ctx, struct ecdh *params)
{
	struct device *dev = ctx->dev;
	int ret;

	ret = crypto_get_default_rng();
	if (ret) {
		dev_err(dev, "failed to get default rng, ret = %d!\n", ret);
		return ret;
	}

	ret = crypto_rng_get_bytes(crypto_default_rng, (u8 *)params->key,
				   params->key_size);
	crypto_put_default_rng();
	if (ret)
		dev_err(dev, "failed to get rng, ret = %d!\n", ret);

	return ret;
}

static int hpre_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
				unsigned int len)
{
	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
	struct device *dev = ctx->dev;
	char key[HPRE_ECC_MAX_KSZ];
	unsigned int sz, sz_shift;
	struct ecdh params;
	int ret;
@@ -1347,6 +1372,15 @@ static int hpre_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
		return -EINVAL;
	}

	/* Use stdrng to generate private key */
	if (!params.key || !params.key_size) {
		params.key = key;
		params.key_size = hpre_ecdh_get_curvesz(ctx->curve_id);
		ret = ecdh_gen_privkey(ctx, &params);
		if (ret)
			return ret;
	}

	if (hpre_key_is_zero(params.key, params.key_size)) {
		dev_err(dev, "Invalid hpre key!\n");
		return -EINVAL;