diff mbox series

[2/5] crypto: support rsa-pss encoding

Message ID 1617714686-25754-3-git-send-email-herbert.tencent@gmail.com (mailing list archive)
State New
Headers show
Series crypto: add rsa pss support for x509 | expand

Commit Message

Hongbo Li April 6, 2021, 1:11 p.m. UTC
From: Hongbo Li <herberthbli@tencent.com>

This patch add the support of rsa-pss encoding which is described
rfc8017.
Similar to rsa-pkcs1, we create a pss template.

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 crypto/Makefile               |   7 ++-
 crypto/rsa.c                  |  14 ++---
 crypto/rsa_helper.c           | 127 ++++++++++++++++++++++++++++++++++++++++++
 include/crypto/internal/rsa.h |  25 ++++++++-
 4 files changed, 164 insertions(+), 9 deletions(-)

Comments

kernel test robot April 6, 2021, 5:23 p.m. UTC | #1
Hi Hongbo,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on crypto/master]
[also build test ERROR on security/next-testing linus/master v5.12-rc6 next-20210406]
[cannot apply to cryptodev/master]
[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/Hongbo-Li/crypto-add-rsa-pss-support-for-x509/20210406-211503
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git master
config: m68k-defconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/951e694ffaeb62069494bc7bc94c296183f4ed49
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hongbo-Li/crypto-add-rsa-pss-support-for-x509/20210406-211503
        git checkout 951e694ffaeb62069494bc7bc94c296183f4ed49
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   make[2]: *** No rule to make target 'crypto//seqiv.o', needed by 'crypto//seqiv.mod'.
   make[2]: *** No rule to make target 'crypto//echainiv.o', needed by 'crypto//echainiv.mod'.
   make[2]: *** No rule to make target 'crypto//dh.o', needed by 'crypto//dh_generic.o'.
   make[2]: *** No rule to make target 'crypto//dh_helper.o', needed by 'crypto//dh_generic.o'.
   make[2]: *** No rule to make target 'crypto//rsapubkey.asn1.c', needed by 'crypto//rsapubkey.asn1.o'.
   make[2]: *** No rule to make target 'crypto//rsapubkey.asn1.h', needed by 'crypto//rsapubkey.asn1.o'.
   make[2]: *** No rule to make target 'crypto//rsaprivkey.asn1.c', needed by 'crypto//rsaprivkey.asn1.o'.
   make[2]: *** No rule to make target 'crypto//rsaprivkey.asn1.h', needed by 'crypto//rsaprivkey.asn1.o'.
   make[2]: *** No rule to make target 'crypto//rsapss_params.asn1.c', needed by 'crypto//rsapss_params.asn1.o'.
   make[2]: *** No rule to make target 'crypto//rsapss_params.asn1.h', needed by 'crypto//rsapss_params.asn1.o'.
   make[2]: *** No rule to make target 'crypto//rsa.o', needed by 'crypto//rsa_generic.o'.
   make[2]: *** No rule to make target 'crypto//rsa-pkcs1pad.o', needed by 'crypto//rsa_generic.o'.
>> make[2]: *** No rule to make target 'crypto//rsa-psspad.o', needed by 'crypto//rsa_generic.o'.
   make[2]: *** No rule to make target 'crypto//sm2signature.asn1.c', needed by 'crypto//sm2signature.asn1.o'.
   make[2]: *** No rule to make target 'crypto//sm2signature.asn1.h', needed by 'crypto//sm2signature.asn1.o'.
   make[2]: *** No rule to make target 'crypto//crypto_user_base.o', needed by 'crypto//crypto_user.o'.
   make[2]: *** No rule to make target 'crypto//cmac.o', needed by 'crypto//cmac.mod'.
   make[2]: *** No rule to make target 'crypto//hmac.o', needed by 'crypto//hmac.mod'.
   make[2]: *** No rule to make target 'crypto//vmac.o', needed by 'crypto//vmac.mod'.
   make[2]: *** No rule to make target 'crypto//md4.o', needed by 'crypto//md4.mod'.
   make[2]: *** No rule to make target 'crypto//md5.o', needed by 'crypto//md5.mod'.
   make[2]: *** No rule to make target 'crypto//rmd160.o', needed by 'crypto//rmd160.mod'.
   make[2]: *** No rule to make target 'crypto//sha1_generic.o', needed by 'crypto//sha1_generic.mod'.
   make[2]: *** No rule to make target 'crypto//sha256_generic.o', needed by 'crypto//sha256_generic.mod'.
   make[2]: *** No rule to make target 'crypto//sha512_generic.o', needed by 'crypto//sha512_generic.mod'.
   make[2]: *** No rule to make target 'crypto//sha3_generic.o', needed by 'crypto//sha3_generic.mod'.
   make[2]: *** No rule to make target 'crypto//sm3_generic.o', needed by 'crypto//sm3_generic.mod'.
   make[2]: *** No rule to make target 'crypto//streebog_generic.o', needed by 'crypto//streebog_generic.mod'.
   make[2]: *** No rule to make target 'crypto//wp512.o', needed by 'crypto//wp512.mod'.
   make[2]: *** No rule to make target 'crypto//blake2b_generic.o', needed by 'crypto//blake2b_generic.mod'.
   make[2]: *** No rule to make target 'crypto//blake2s_generic.o', needed by 'crypto//blake2s_generic.mod'.
   make[2]: *** No rule to make target 'crypto//gf128mul.o', needed by 'crypto//gf128mul.mod'.
   make[2]: *** No rule to make target 'crypto//ecb.o', needed by 'crypto//ecb.mod'.
   make[2]: *** No rule to make target 'crypto//cbc.o', needed by 'crypto//cbc.mod'.
   make[2]: *** No rule to make target 'crypto//cfb.o', needed by 'crypto//cfb.mod'.
   make[2]: *** No rule to make target 'crypto//cts.o', needed by 'crypto//cts.mod'.
   make[2]: *** No rule to make target 'crypto//lrw.o', needed by 'crypto//lrw.mod'.
   make[2]: *** No rule to make target 'crypto//xts.o', needed by 'crypto//xts.mod'.
   make[2]: *** No rule to make target 'crypto//ctr.o', needed by 'crypto//ctr.mod'.
   make[2]: *** No rule to make target 'crypto//keywrap.o', needed by 'crypto//keywrap.mod'.
   make[2]: *** No rule to make target 'crypto//adiantum.o', needed by 'crypto//adiantum.mod'.
   make[2]: *** No rule to make target 'crypto//nhpoly1305.o', needed by 'crypto//nhpoly1305.mod'.
   make[2]: *** No rule to make target 'crypto//gcm.o', needed by 'crypto//gcm.mod'.
   make[2]: *** No rule to make target 'crypto//ccm.o', needed by 'crypto//ccm.mod'.
   make[2]: *** No rule to make target 'crypto//chacha20poly1305.o', needed by 'crypto//chacha20poly1305.mod'.
   make[2]: *** No rule to make target 'crypto//aegis128-core.o', needed by 'crypto//aegis128.o'.
   make[2]: *** No rule to make target 'crypto//cryptd.o', needed by 'crypto//cryptd.mod'.
   make[2]: *** No rule to make target 'crypto//des_generic.o', needed by 'crypto//des_generic.mod'.
   make[2]: *** No rule to make target 'crypto//fcrypt.o', needed by 'crypto//fcrypt.mod'.
   make[2]: *** No rule to make target 'crypto//blowfish_generic.o', needed by 'crypto//blowfish_generic.mod'.
   make[2]: *** No rule to make target 'crypto//blowfish_common.o', needed by 'crypto//blowfish_common.mod'.
   make[2]: *** No rule to make target 'crypto//twofish_generic.o', needed by 'crypto//twofish_generic.mod'.
   make[2]: *** No rule to make target 'crypto//twofish_common.o', needed by 'crypto//twofish_common.mod'.
   make[2]: *** No rule to make target 'crypto//serpent_generic.o', needed by 'crypto//serpent_generic.mod'.
   make[2]: *** No rule to make target 'crypto//sm4_generic.o', needed by 'crypto//sm4_generic.mod'.
   make[2]: *** No rule to make target 'crypto//aes_ti.o', needed by 'crypto//aes_ti.mod'.
   make[2]: *** No rule to make target 'crypto//camellia_generic.o', needed by 'crypto//camellia_generic.mod'.
   make[2]: *** No rule to make target 'crypto//cast_common.o', needed by 'crypto//cast_common.mod'.
   make[2]: *** No rule to make target 'crypto//cast5_generic.o', needed by 'crypto//cast5_generic.mod'.
   make[2]: *** No rule to make target 'crypto//cast6_generic.o', needed by 'crypto//cast6_generic.mod'.
   make[2]: *** No rule to make target 'crypto//arc4.o', needed by 'crypto//arc4.mod'.
   make[2]: *** No rule to make target 'crypto//tea.o', needed by 'crypto//tea.mod'.
   make[2]: *** No rule to make target 'crypto//khazad.o', needed by 'crypto//khazad.mod'.
   make[2]: *** No rule to make target 'crypto//anubis.o', needed by 'crypto//anubis.mod'.
   make[2]: *** No rule to make target 'crypto//seed.o', needed by 'crypto//seed.mod'.
   make[2]: *** No rule to make target 'crypto//chacha_generic.o', needed by 'crypto//chacha_generic.mod'.
   make[2]: *** No rule to make target 'crypto//poly1305_generic.o', needed by 'crypto//poly1305_generic.mod'.
   make[2]: *** No rule to make target 'crypto//deflate.o', needed by 'crypto//deflate.mod'.
   make[2]: *** No rule to make target 'crypto//michael_mic.o', needed by 'crypto//michael_mic.mod'.
   make[2]: *** No rule to make target 'crypto//authenc.o', needed by 'crypto//authenc.mod'.
   make[2]: *** No rule to make target 'crypto//authencesn.o', needed by 'crypto//authencesn.mod'.
   make[2]: *** No rule to make target 'crypto//lzo.o', needed by 'crypto//lzo.mod'.
   make[2]: *** No rule to make target 'crypto//lzo-rle.o', needed by 'crypto//lzo-rle.mod'.
   make[2]: *** No rule to make target 'crypto//lz4.o', needed by 'crypto//lz4.mod'.
   make[2]: *** No rule to make target 'crypto//lz4hc.o', needed by 'crypto//lz4hc.mod'.
   make[2]: *** No rule to make target 'crypto//xxhash_generic.o', needed by 'crypto//xxhash_generic.mod'.
   make[2]: *** No rule to make target 'crypto//842.o', needed by 'crypto//842.mod'.
   make[2]: *** No rule to make target 'crypto//ansi_cprng.o', needed by 'crypto//ansi_cprng.mod'.
   make[2]: *** No rule to make target 'crypto//drbg.o', needed by 'crypto//drbg.mod'.
   make[2]: *** No rule to make target 'crypto//jitterentropy.o', needed by 'crypto//jitterentropy_rng.o'.
   make[2]: *** No rule to make target 'crypto//jitterentropy-kcapi.o', needed by 'crypto//jitterentropy_rng.o'.
   make[2]: *** No rule to make target 'crypto//tcrypt.o', needed by 'crypto//tcrypt.mod'.
   make[2]: *** No rule to make target 'crypto//ghash-generic.o', needed by 'crypto//ghash-generic.mod'.
   make[2]: *** No rule to make target 'crypto//af_alg.o', needed by 'crypto//af_alg.mod'.
   make[2]: *** No rule to make target 'crypto//algif_hash.o', needed by 'crypto//algif_hash.mod'.
   make[2]: *** No rule to make target 'crypto//algif_skcipher.o', needed by 'crypto//algif_skcipher.mod'.
   make[2]: *** No rule to make target 'crypto//algif_rng.o', needed by 'crypto//algif_rng.mod'.
   make[2]: *** No rule to make target 'crypto//algif_aead.o', needed by 'crypto//algif_aead.mod'.
   make[2]: *** No rule to make target 'crypto//zstd.o', needed by 'crypto//zstd.mod'.
   make[2]: *** No rule to make target 'crypto//ofb.o', needed by 'crypto//ofb.mod'.
   make[2]: *** No rule to make target 'crypto//ecc.o', needed by 'crypto//ecc.mod'.
   make[2]: *** No rule to make target 'crypto//essiv.o', needed by 'crypto//essiv.mod'.
   make[2]: *** No rule to make target 'crypto//curve25519-generic.o', needed by 'crypto//curve25519-generic.mod'.
   make[2]: *** No rule to make target 'crypto//ecdh.o', needed by 'crypto//ecdh_generic.o'.
   make[2]: *** No rule to make target 'crypto//ecdh_helper.o', needed by 'crypto//ecdh_generic.o'.
   make[2]: *** No rule to make target 'crypto//ecrdsa_params.asn1.h', needed by 'crypto//ecrdsa.o'.
   make[2]: *** No rule to make target 'crypto//ecrdsa_pub_key.asn1.h', needed by 'crypto//ecrdsa.o'.
   make[2]: *** No rule to make target 'crypto//ecrdsa_params.asn1.c', needed by 'crypto//ecrdsa_params.asn1.o'.
   make[2]: *** No rule to make target 'crypto//ecrdsa_pub_key.asn1.c', needed by 'crypto//ecrdsa_pub_key.asn1.o'.
   make[2]: *** No rule to make target 'crypto//xor.o', needed by 'crypto//xor.mod'.
   make[2]: Target '__build' not remade because of errors.

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

Patch

diff --git a/crypto/Makefile b/crypto/Makefile
index cf23aff..025a425 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,13 +33,18 @@  obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
 
 $(obj)/rsapubkey.asn1.o: $(obj)/rsapubkey.asn1.c $(obj)/rsapubkey.asn1.h
 $(obj)/rsaprivkey.asn1.o: $(obj)/rsaprivkey.asn1.c $(obj)/rsaprivkey.asn1.h
-$(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.h
+$(obj)/rsapss_params.asn1.o: $(obj)/rsapss_params.asn1.c \
+			     $(obj)/rsapss_params.asn1.h
+$(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.h \
+		     $(obj)/rsapss_params.asn1.h
 
 rsa_generic-y := rsapubkey.asn1.o
 rsa_generic-y += rsaprivkey.asn1.o
+rsa_generic-y += rsapss_params.asn1.o
 rsa_generic-y += rsa.o
 rsa_generic-y += rsa_helper.o
 rsa_generic-y += rsa-pkcs1pad.o
+rsa_generic-y += rsa-psspad.o
 obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
 
 $(obj)/sm2signature.asn1.o: $(obj)/sm2signature.asn1.c $(obj)/sm2signature.asn1.h
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4cdbec9..adc9b2d2 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -6,18 +6,11 @@ 
  */
 
 #include <linux/module.h>
-#include <linux/mpi.h>
 #include <crypto/internal/rsa.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/akcipher.h>
 #include <crypto/algapi.h>
 
-struct rsa_mpi_key {
-	MPI n;
-	MPI e;
-	MPI d;
-};
-
 /*
  * RSAEP function [RFC3447 sec 5.1.1]
  * c = m^e mod n;
@@ -269,12 +262,19 @@  static int rsa_init(void)
 		return err;
 	}
 
+	err = crypto_register_template(&rsa_psspad_tmpl);
+	if (err) {
+		crypto_unregister_akcipher(&rsa);
+		return err;
+	}
+
 	return 0;
 }
 
 static void rsa_exit(void)
 {
 	crypto_unregister_template(&rsa_pkcs1pad_tmpl);
+	crypto_unregister_template(&rsa_psspad_tmpl);
 	crypto_unregister_akcipher(&rsa);
 }
 
diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
index 94266f2..912d975 100644
--- a/crypto/rsa_helper.c
+++ b/crypto/rsa_helper.c
@@ -12,6 +12,7 @@ 
 #include <crypto/internal/rsa.h>
 #include "rsapubkey.asn1.h"
 #include "rsaprivkey.asn1.h"
+#include "rsapss_params.asn1.h"
 
 int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
 	      const void *value, size_t vlen)
@@ -148,6 +149,115 @@  int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag,
 	return 0;
 }
 
+int rsa_get_pss_hash(void *context, size_t hdrlen, unsigned char tag,
+		     const void *value, size_t vlen)
+{
+	struct rsa_pss_ctx *ctx = context;
+	enum OID oid;
+
+	if (!value || !vlen)
+		return -EINVAL;
+
+	oid = look_up_OID(value, vlen);
+	switch (oid) {
+	case OID_sha1:
+		ctx->hash_algo = "sha1";
+		break;
+	case OID_sha224:
+		ctx->hash_algo = "sha224";
+		break;
+	case OID_sha256:
+		ctx->hash_algo = "sha256";
+		break;
+	case OID_sha384:
+		ctx->hash_algo = "sha384";
+		break;
+	case OID_sha512:
+		ctx->hash_algo = "sha512";
+		break;
+	default:
+		return -ENOPKG;
+
+	}
+
+	return 0;
+}
+
+int rsa_get_pss_mgf(void *context, size_t hdrlen, unsigned char tag,
+		    const void *value, size_t vlen)
+{
+	struct rsa_pss_ctx *ctx = context;
+	enum OID oid;
+
+	if (!value || !vlen)
+		return -EINVAL;
+
+	oid = look_up_OID(value, vlen);
+	if (oid != OID_rsa_mgf1)
+		return -ENOPKG;
+	ctx->mgf_algo = "mgf1";
+
+	return 0;
+}
+
+int rsa_get_pss_mgf_hash(void *context, size_t hdrlen, unsigned char tag,
+			 const void *value, size_t vlen)
+{
+	struct rsa_pss_ctx *ctx = context;
+	enum OID oid;
+
+	if (!value || !vlen)
+		return -EINVAL;
+	/* todo, merge with get_pss_hash */
+	oid = look_up_OID(value, vlen);
+	switch (oid) {
+	case OID_sha1:
+		ctx->mgf_hash_algo = "sha1";
+		break;
+	case OID_sha224:
+		ctx->mgf_hash_algo = "sha224";
+		break;
+	case OID_sha256:
+		ctx->mgf_hash_algo = "sha256";
+		break;
+	case OID_sha384:
+		ctx->mgf_hash_algo = "sha384";
+		break;
+	case OID_sha512:
+		ctx->mgf_hash_algo = "sha512";
+		break;
+	default:
+		return -ENOPKG;
+	}
+
+	return 0;
+}
+
+int rsa_get_pss_saltlen(void *context, size_t hdrlen, unsigned char tag,
+			const void *value, size_t vlen)
+{
+	struct rsa_pss_ctx *ctx = context;
+
+	if (!value || vlen < 1 || vlen > 2)
+		return -EINVAL;
+
+	if (vlen == 1)
+		ctx->salt_len = *(u8 *)value;
+	else if (vlen == 2)
+		ctx->salt_len = ntohs(*(u16 *)value);
+
+	return 0;
+}
+
+int rsa_get_pss_trailerfield(void *context, size_t hdrlen, unsigned char tag,
+			     const void *value, size_t vlen)
+{
+	if (!value || !vlen || *(u8 *)value != 1)
+		return -EINVAL;
+
+	return 0;
+}
+
 /**
  * rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
  *                       provided struct rsa_key, pointers to the raw key as is,
@@ -184,3 +294,20 @@  int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
 	return asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
 }
 EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
+
+/**
+ * rsa_parse_pss_params() - decodes the BER encoded pss padding params
+ *
+ * @ctx:	struct rsa_pss_ctx, pss padding context
+ * @params:	params in BER format
+ * @params_len:	length of params
+ *
+ * Return:	0 on success or error code in case of error
+ */
+int rsa_parse_pss_params(struct rsa_pss_ctx *ctx, const void *params,
+			 unsigned int params_len)
+{
+	return asn1_ber_decoder(&rsapss_params_decoder, ctx, params,
+				params_len);
+}
+EXPORT_SYMBOL_GPL(rsa_parse_pss_params);
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index e870133..cfb0801 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -8,6 +8,12 @@ 
 #ifndef _RSA_HELPER_
 #define _RSA_HELPER_
 #include <linux/types.h>
+#include <linux/mpi.h>
+#include <linux/oid_registry.h>
+#include <crypto/sha2.h>
+
+#define RSA_MAX_DIGEST_SIZE		SHA512_DIGEST_SIZE
+#define RSA_PSS_DEFAULT_SALT_LEN	20
 
 /**
  * rsa_key - RSA key structure
@@ -47,11 +53,28 @@  struct rsa_key {
 	size_t qinv_sz;
 };
 
+struct rsa_mpi_key {
+	MPI n;
+	MPI e;
+	MPI d;
+};
+
+struct rsa_pss_ctx {
+	struct crypto_akcipher *child;
+	unsigned int key_size;
+	const char *hash_algo;
+	const char *mgf_algo;
+	const char *mgf_hash_algo;
+	u32 salt_len;
+};
+
 int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
 		      unsigned int key_len);
 
 int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
 		       unsigned int key_len);
-
+int rsa_parse_pss_params(struct rsa_pss_ctx *ctx, const void *params,
+			 unsigned int params_len);
 extern struct crypto_template rsa_pkcs1pad_tmpl;
+extern struct crypto_template rsa_psspad_tmpl;
 #endif