crypto: hisilicon/hpre - fix ecdh self test issue
authorHui Tang <tanghui20@huawei.com>
Sat, 29 May 2021 08:57:37 +0000 (16:57 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 3 Jun 2021 12:24:06 +0000 (20:24 +0800)
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: Hui Tang <tanghui20@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/hisilicon/hpre/hpre_crypto.c

index 294c3688aabb07cac4ea1421cb95bb462bcff2e2..6ba5d8af3875503679fff551de0cd8b70e984e1e 100644 (file)
@@ -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;