1. Add 'CURVE25519' curve parameter definition to
'include/crypto/ecc_curve_defs.h';
2. Enable 'CURVE25519' algorithm in Kunpeng 930.
Signed-off-by: Meng Yu
Reviewed-by: Zaibo Xu
Reported-by: kernel test robot
---
drivers/crypto/hisilicon/Kconfig| 1 +
drivers/crypto/hisilicon/hpre/hpre.h| 2 +
drivers/crypto/hisilicon/hpre/hpre_crypto.c | 364 +++-
include/crypto/ecc_curve_defs.h | 17 ++
4 files changed, 375 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig
index 8431926..c45adb1 100644
--- a/drivers/crypto/hisilicon/Kconfig
+++ b/drivers/crypto/hisilicon/Kconfig
@@ -65,6 +65,7 @@ config CRYPTO_DEV_HISI_HPRE
depends on UACCE || UACCE=n
depends on ARM64 || (COMPILE_TEST && 64BIT)
depends on ACPI
+ select CRYPTO_LIB_CURVE25519_GENERIC
select CRYPTO_DEV_HISI_QM
select CRYPTO_DH
select CRYPTO_RSA
diff --git a/drivers/crypto/hisilicon/hpre/hpre.h
b/drivers/crypto/hisilicon/hpre/hpre.h
index 50e6b2e..92892e3 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -84,6 +84,8 @@ enum hpre_alg_type {
HPRE_ALG_DH_G2 = 0x4,
HPRE_ALG_DH = 0x5,
HPRE_ALG_ECC_MUL = 0xD,
+ /* shared by x25519 and x448, but x448 is not supported now */
+ HPRE_ALG_CURVE25519_MUL = 0x10,
};
struct hpre_sqe {
diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
index 58f847b..e135732 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 HiSilicon Limited. */
#include
+#include
#include
#include
#include
@@ -98,6 +99,16 @@ struct hpre_ecdh_ctx {
dma_addr_t dma_g;
};
+struct hpre_curve25519_ctx {
+ /* low address: p->a->k */
+ unsigned char *p;
+ dma_addr_t dma_p;
+
+ /* gx coordinate */
+ unsigned char *g;
+ dma_addr_t dma_g;
+};
+
struct hpre_ctx {
struct hisi_qp *qp;
struct hpre_asym_request **req_list;
@@ -110,6 +121,7 @@ struct hpre_ctx {
struct hpre_rsa_ctx rsa;
struct hpre_dh_ctx dh;
struct hpre_ecdh_ctx ecdh;
+ struct hpre_curve25519_ctx curve25519;
};
/* for ecc algorithms */
unsigned int curve_id;
@@ -124,6 +136,7 @@ struct hpre_asym_request {
struct akcipher_request *rsa;
struct kpp_request *dh;
struct kpp_request *ecdh;
+ struct kpp_request *curve25519;
} areq;
int err;
int req_id;
@@ -446,7 +459,6 @@ static void hpre_alg_cb(struct hisi_qp *qp, void *resp)
struct hpre_sqe *sqe = resp;
struct hpre_asym_request *req = ctx->req_list[le16_to_cpu(sqe->tag)];
-
if (unlikely(!req)) {
atomic64_inc(&dfx[HPRE_INVALID_REQ_CNT].value);
return;
@@ -1176,6 +1188,12 @@ static void hpre_ecc_clear_ctx(struct hpre_ctx *ctx,
bool is_clear_all,
memzero_explicit(ctx->ecdh.p + shift, sz);
dma_free_coherent(dev, sz << 3, ctx->ecdh.p, ctx->ecdh.dma_p);
ctx->ecdh.p = NULL;
+ } else if (!is_ecdh && ctx->curve25519.p) {
+ /* curve25519: p->a->k */
+ memzero_explicit(ctx->curve25519.p + shift, sz);
+ dma_free_coherent(dev, sz << 2, ctx->curve25519.p,
+ ctx->curve25519.dma_p);
+ ctx->curve25519.p = NULL;
}
ctx->curve_id = 0;
@@ -1585,6 +1603,307 @@ static void hpre_ecdh_exit_tfm(struct crypto_kpp *tfm)
hpre_ecc_clear_ctx(ctx, true, true);
}
+static void hpre_curve25519_fill_curve(struct hpre_ctx *ctx, const void *buf,
+ unsigned int len)
+{
+ u8 secret[CURVE25519_KEY_SIZE] = { 0 };
+ unsigned int sz = ctx->key_sz;
+ unsigned int shift = sz << 1;
+ void *p;
+
+ /**
+* The key from 'buf' is in little-endian, we should preprocess it as
+* the description in rfc7748: "k[0] &= 248, k[31] &= 127, k[31] |= 64",
+* then convert it to big endian. Only in this way, the result can be
+* the same as the software curve-25519 that exists in crypto.
+*/
+ memcpy(secret, buf, len);
+ curve25519_clamp_secret(secret);
+ hpre_key_to_big_end(secret, CURVE25519_KEY_SIZE);
+
+ p = ctx->curve25519.p + sz - len;
+
+ /* fill curve parameters */
+ fill_curve_param(p, ecc_25519.p, len, ecc_25519.g.ndigits);
+ fill_curve_param(p + sz, ecc_25519.a, len, ecc_25519.g.ndigits);
+ memcpy(p + shift, secret, len);
+ fill_curve_param(p + shift + sz, ecc_25519.g.x, len,
ecc_25519.g.ndigits);
+ memzero_explicit(secret, CURVE255