Re: [PATCH 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm

2020-10-31 Thread kernel test robot
Hi Meng,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on cryptodev/master]
[also build test ERROR on crypto/master v5.10-rc1 next-20201030]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Meng-Yu/crypto-hisilicon-hpre-add-something-for-Kunpeng-930/20201031-143748
base:   
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
# 
https://github.com/0day-ci/linux/commit/5bfec963e8d2806a362f1f9da490543d939baf26
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Meng-Yu/crypto-hisilicon-hpre-add-something-for-Kunpeng-930/20201031-143748
git checkout 5bfec963e8d2806a362f1f9da490543d939baf26
# save the attached .config to linux build tree
make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> ld: drivers/crypto/hisilicon/hpre/hpre_crypto.o:(.rodata+0x1860): multiple 
>> definition of `curve25519_null_point'; 
>> lib/crypto/curve25519-generic.o:(.rodata+0x40): first defined here

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


[PATCH 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm

2020-10-31 Thread Meng Yu
Enable 'CURVE25519' algorithm in 'Kunpeng 930'.

Signed-off-by: Meng Yu 
Reviewed-by: Zaibo Xu 
---
 drivers/crypto/hisilicon/hpre/hpre.h|   2 +
 drivers/crypto/hisilicon/hpre/hpre_crypto.c | 390 +++-
 2 files changed, 384 insertions(+), 8 deletions(-)

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 b7814ce..fae99ed 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 
@@ -70,6 +71,28 @@ struct curve_param_desc {
const unsigned char *n;
 };
 
+/* curve25519 */
+const u8 curve25519_null_point[CURVE25519_KEY_SIZE] __aligned(32) = { 0 };
+
+/* curve25519 CURVE PARAMS, in big-endian order */
+/* p = (2 ^ 255 - 19) */
+static const unsigned char curve25519_p[] = {
+   0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
+};
+ /* a = (486662 - 2) / 4 = 121665 */
+static const unsigned char curve25519_a[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDB, 0x41
+};
+static const unsigned char curve25519_x[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09
+};
+
 /* ECC CURVE PARAMS */
 /* 128 bits */
 static const unsigned char ecdh_p128_p[] = {
@@ -417,6 +440,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;
@@ -429,6 +462,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;
@@ -443,6 +477,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;
@@ -1877,6 +1912,318 @@ static void hpre_ecdh_exit_tfm(struct crypto_kpp *tfm)
hpre_ecc_clear_ctx(ctx, true, true);
 }
 
+static void hpre_key_to_big_end(u8 *data, int len)
+{
+   int i, j;
+   u8 tmp;
+
+   for (i = 0; i < len / 2; i++) {
+   j = len - i - 1;
+   tmp = data[j];
+   data[j] = data[i];
+   data[i] = tmp;
+   }
+}
+
+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 */
+   memcpy(p, curve25519_p, len);
+   memcpy(p + sz, curve25519_a, len);
+   memcpy(p + shift, secret, len);
+   memcpy(p + shift + sz, curve25519_x, len);
+   memzero_explicit(secret, CURVE25519_KEY_SIZE);
+}
+
+static int hpre_curve25519_set_param(struct hpre_ctx *ctx, const void *buf,
+unsigned int len)
+{
+   struct device *dev = HPRE_DEV(ctx);
+   unsigned int sz = ctx->key_sz;
+   unsigned int shift = sz << 1;
+
+