linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] crypto: add rsa pss support for x509
@ 2021-04-07  3:49 Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 1/4] x509: add support for rsa-pss Hongbo Li
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Hongbo Li @ 2021-04-07  3:49 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, zohar, jarkko, herberthbli
  Cc: linux-kernel, linux-integrity, Hongbo Li

From: Hongbo Li <herberthbli@tencent.com>

This series of patches adds support for x509 cert signed by RSA
with PSS encoding method. RSA PSS is described in rfc8017.

Patch1 make x509 support rsa pss encoding and parse hash parameter.

Patch2 add rsa pss template.

Patch3 add test vector for rsa pss.

Patch4 is the rsa-pss's ima patch.

Test by the following script, it tests different saltlen, hash, mgfhash.

keyctl newring test @u

while :; do
    for modbits in 1024 2048 4096; do
        if [ $modbits -eq 1024 ]; then
            saltlen=(-1 -2 0 20 32 48 64 94)
        elif [ $modbits -eq 2048 ]; then
            saltlen=(-1 -2 0 20 32 48 64 222)
        else
            saltlen=(-1 -2 0 20 32 48 64 478)
        fi

        for slen in ${saltlen[@]}; do
            for hash in sha1 sha224 sha256 sha384 sha512; do
                for mgfhash in sha1 sha224 sha256 sha384 sha512; do
                    certfile="cert.der"
                    echo slen $slen
                    openssl req \
                            -x509 \
                            -${hash} \
                            -newkey rsa:$modbits \
                            -keyout key.pem \
                            -days 365 \
                            -subj '/CN=test' \
                            -nodes \
                            -sigopt rsa_padding_mode:pss \
                            -sigopt rsa_mgf1_md:$mgfhash \
                            -sigopt rsa_pss_saltlen:${slen} \
                            -outform der \
                            -out ${certfile} 2>/dev/null

                    exp=0
                    id=$(keyctl padd asymmetric testkey %keyring:test < "${certfile}")
                    rc=$?
                    if [ $rc -ne $exp ]; then
                        case "$exp" in
                            0) echo "Error: Could not load rsa-pss certificate!";;
                        esac
                        echo "modbits $modbits sha: $hash mgfhash $mgfhash saltlen: $slen"
                        exit 1
                    else
                        case "$rc" in
                            0) echo "load cert: keyid: $id modbits $modbits hash: $hash mgfhash $mgfhash saltlen $slen"
                        esac
                    fi
                done
            done
        done
    done
done

Best Regards

Hongbo

v2-v3:
  -add the crypto/rsa-psspad.c which is missed in previous patch

v1->v2:
  -rebase patches to cryptodev/master to fix the issues that
   reported-by: kernel test robot <lkp@intel.com>

Hongbo Li (4):
  x509: add support for rsa-pss
  crypto: support rsa-pss encoding
  crypto: add rsa pss test vector
  ima: add support for rsa pss verification

 crypto/Makefile                                |   7 +-
 crypto/asymmetric_keys/Makefile                |   7 +-
 crypto/asymmetric_keys/public_key.c            |   5 +
 crypto/asymmetric_keys/x509_cert_parser.c      |  71 ++++-
 crypto/asymmetric_keys/x509_rsapss_params.asn1 |  19 ++
 crypto/rsa-psspad.c                            | 398 +++++++++++++++++++++++++
 crypto/rsa.c                                   |  14 +-
 crypto/rsa_helper.c                            | 127 ++++++++
 crypto/testmgr.c                               |   7 +
 crypto/testmgr.h                               |  90 ++++++
 include/crypto/internal/rsa.h                  |  25 +-
 include/linux/oid_registry.h                   |   2 +
 security/integrity/digsig_asymmetric.c         |  18 +-
 13 files changed, 770 insertions(+), 20 deletions(-)
 create mode 100644 crypto/asymmetric_keys/x509_rsapss_params.asn1
 create mode 100644 crypto/rsa-psspad.c

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/4] x509: add support for rsa-pss
  2021-04-07  3:49 [PATCH v3 0/4] crypto: add rsa pss support for x509 Hongbo Li
@ 2021-04-07  3:49 ` Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 2/4] crypto: support rsa-pss encoding Hongbo Li
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Hongbo Li @ 2021-04-07  3:49 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, zohar, jarkko, herberthbli
  Cc: linux-kernel, linux-integrity, Hongbo Li

This patch make x509 support rsa-pss, because the sha algo is
in paramters, so we need to parse the sha parameter, and skip
other params.

Signed-off-by: Hongbo Li <herbert.tencent@gmail.com>
---
 crypto/asymmetric_keys/Makefile                |  7 ++-
 crypto/asymmetric_keys/public_key.c            |  5 ++
 crypto/asymmetric_keys/x509_cert_parser.c      | 71 ++++++++++++++++++++++++--
 crypto/asymmetric_keys/x509_rsapss_params.asn1 | 19 +++++++
 include/linux/oid_registry.h                   |  2 +
 5 files changed, 99 insertions(+), 5 deletions(-)
 create mode 100644 crypto/asymmetric_keys/x509_rsapss_params.asn1

diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 28b91ad..9092de7 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -20,15 +20,20 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
 x509_key_parser-y := \
 	x509.asn1.o \
 	x509_akid.asn1.o \
+	x509_rsapss_params.asn1.o \
 	x509_cert_parser.o \
 	x509_public_key.o
 
 $(obj)/x509_cert_parser.o: \
 	$(obj)/x509.asn1.h \
-	$(obj)/x509_akid.asn1.h
+	$(obj)/x509_akid.asn1.h \
+	$(obj)/x509_rsapss_params.asn1.h
+
 
 $(obj)/x509.asn1.o: $(obj)/x509.asn1.c $(obj)/x509.asn1.h
 $(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h
+$(obj)/x509_rsapss_params.asn1.o: \
+	$(obj)/x509_rsapss_params.asn1.c $(obj)/x509_rsapss_params.asn1.h
 
 #
 # PKCS#8 private key handling
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 4fefb21..8f16d4d 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -84,6 +84,11 @@ int software_key_determine_akcipher(const char *encoding,
 				     "pkcs1pad(%s,%s)",
 				     pkey->pkey_algo, hash_algo);
 		return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+	} else if (strcmp(encoding, "pss") == 0) {
+		n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+			     "psspad(%s)",
+			     pkey->pkey_algo);
+		return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
 	}
 
 	if (strcmp(encoding, "raw") == 0 ||
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 6d00309..c2e5437 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -15,6 +15,7 @@
 #include "x509_parser.h"
 #include "x509.asn1.h"
 #include "x509_akid.asn1.h"
+#include "x509_rsapss_params.asn1.h"
 
 struct x509_parse_context {
 	struct x509_certificate	*cert;		/* Certificate being constructed */
@@ -115,6 +116,17 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
 	cert->pub->paramlen = ctx->params_size;
 	cert->pub->algo = ctx->key_algo;
 
+	if (!strcmp(cert->sig->pkey_algo, "rsa") &&
+	    !strcmp(cert->sig->encoding, "pss") &&
+	    cert->pub->paramlen) {
+		ret = asn1_ber_decoder(&x509_rsapss_params_decoder, ctx,
+				       cert->pub->params, cert->pub->paramlen);
+		if (ret < 0) {
+			pr_warn("Couldn't decode rsapss params\n");
+			goto error_decode;
+		}
+	}
+
 	/* Grab the signature bits */
 	ret = x509_get_sig_params(cert);
 	if (ret < 0)
@@ -211,6 +223,10 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 		ctx->cert->sig->hash_algo = "sha1";
 		goto rsa_pkcs1;
 
+	case OID_rsa_pss:
+		ctx->cert->sig->hash_algo = "sha1";
+		goto rsa_pss;
+
 	case OID_sha256WithRSAEncryption:
 		ctx->cert->sig->hash_algo = "sha256";
 		goto rsa_pkcs1;
@@ -265,6 +281,11 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 	ctx->cert->sig->encoding = "pkcs1";
 	ctx->algo_oid = ctx->last_oid;
 	return 0;
+rsa_pss:
+	ctx->cert->sig->pkey_algo = "rsa";
+	ctx->cert->sig->encoding = "pss";
+	ctx->algo_oid = ctx->last_oid;
+	return 0;
 ecrdsa:
 	ctx->cert->sig->pkey_algo = "ecrdsa";
 	ctx->cert->sig->encoding = "raw";
@@ -466,17 +487,59 @@ int x509_note_params(void *context, size_t hdrlen,
 	struct x509_parse_context *ctx = context;
 
 	/*
-	 * AlgorithmIdentifier is used three times in the x509, we should skip
-	 * first and ignore third, using second one which is after subject and
-	 * before subjectPublicKey.
+	 * AlgorithmIdentifier is used three times in the x509,
+	 * rsapss:
+	 * we skip first(same as third) and second(may omit params).
+	 * others:
+	 * we should skip first and ignore third, using second one
+	 * which is after subject and before subjectPublicKey.
 	 */
-	if (!ctx->cert->raw_subject || ctx->key)
+	if (!ctx->cert->raw_subject) {
+		return 0;
+	} else if (strcmp(ctx->cert->sig->pkey_algo, "rsa") ||
+		   strcmp(ctx->cert->sig->encoding, "pss")) {
+		if (ctx->key)
+			return 0;
+	} else if (!ctx->key) {
 		return 0;
+	}
+
 	ctx->params = value - hdrlen;
 	ctx->params_size = vlen + hdrlen;
 	return 0;
 }
 
+int x509_note_rsapss_hash(void *context, size_t hdrlen,
+			  unsigned char tag,
+			  const void *value, size_t vlen)
+{
+	struct x509_parse_context *ctx = context;
+	enum OID oid;
+
+	oid = look_up_OID(value, vlen);
+	switch (oid) {
+	case OID_sha1:
+		ctx->cert->sig->hash_algo = "sha1";
+		break;
+	case OID_sha224:
+		ctx->cert->sig->hash_algo = "sha224";
+		break;
+	case OID_sha256:
+		ctx->cert->sig->hash_algo = "sha256";
+		break;
+	case OID_sha384:
+		ctx->cert->sig->hash_algo = "sha384";
+		break;
+	case OID_sha512:
+		ctx->cert->sig->hash_algo = "sha512";
+		break;
+	default:
+		return -ENOPKG;
+	}
+
+	return 0;
+}
+
 /*
  * Extract the data for the public key algorithm
  */
diff --git a/crypto/asymmetric_keys/x509_rsapss_params.asn1 b/crypto/asymmetric_keys/x509_rsapss_params.asn1
new file mode 100644
index 0000000..d49166e
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_rsapss_params.asn1
@@ -0,0 +1,19 @@
+RSAPSS_Params ::= SEQUENCE {
+	hashAlgorithm		[0] HashAlgorithm OPTIONAL,
+	maskGenAlgorithm	[1] MaskGenAlgorithm OPTIONAL,
+	saltLen			[2] INTEGER OPTIONAL,
+	trailerField		[3] INTEGER OPTIONAL
+	}
+
+HashAlgorithm ::= SEQUENCE {
+	algorithm	OBJECT IDENTIFIER ({ x509_note_rsapss_hash })
+	}
+
+MaskGenAlgorithm ::= SEQUENCE {
+	algorithm	OBJECT IDENTIFIER,
+	hashAlgorithm	MgfHashAlgorithm
+	}
+
+MgfHashAlgorithm ::= SEQUENCE {
+	algorithm	OBJECT IDENTIFIER
+	}
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index cc64d94..f6eb783 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -34,6 +34,8 @@ enum OID {
 	OID_md3WithRSAEncryption,	/* 1.2.840.113549.1.1.3 */
 	OID_md4WithRSAEncryption,	/* 1.2.840.113549.1.1.4 */
 	OID_sha1WithRSAEncryption,	/* 1.2.840.113549.1.1.5 */
+	OID_rsa_mgf1,			/* 1.2.840.113549.1.1.8 */
+	OID_rsa_pss,			/* 1.2.840.113549.1.1.10 */
 	OID_sha256WithRSAEncryption,	/* 1.2.840.113549.1.1.11 */
 	OID_sha384WithRSAEncryption,	/* 1.2.840.113549.1.1.12 */
 	OID_sha512WithRSAEncryption,	/* 1.2.840.113549.1.1.13 */
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/4] crypto: support rsa-pss encoding
  2021-04-07  3:49 [PATCH v3 0/4] crypto: add rsa pss support for x509 Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 1/4] x509: add support for rsa-pss Hongbo Li
@ 2021-04-07  3:49 ` Hongbo Li
  2021-04-07  8:40   ` kernel test robot
  2021-04-07  3:49 ` [PATCH v3 3/4] crypto: add rsa pss test vector Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 4/4] ima: add support for rsa pss verification Hongbo Li
  3 siblings, 1 reply; 6+ messages in thread
From: Hongbo Li @ 2021-04-07  3:49 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, zohar, jarkko, herberthbli
  Cc: linux-kernel, linux-integrity, Hongbo Li

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 <herbert.tencent@gmail.com>
---
 crypto/Makefile               |   7 +-
 crypto/rsa-psspad.c           | 398 ++++++++++++++++++++++++++++++++++++++++++
 crypto/rsa.c                  |  14 +-
 crypto/rsa_helper.c           | 127 ++++++++++++++
 crypto/rsapss_params.asn1     |  21 +++
 include/crypto/internal/rsa.h |  25 ++-
 6 files changed, 583 insertions(+), 9 deletions(-)
 create mode 100644 crypto/rsa-psspad.c
 create mode 100644 crypto/rsapss_params.asn1

diff --git a/crypto/Makefile b/crypto/Makefile
index 10526d4..2c65744 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-psspad.c b/crypto/rsa-psspad.c
new file mode 100644
index 0000000..cf4d69f
--- /dev/null
+++ b/crypto/rsa-psspad.c
@@ -0,0 +1,398 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * RSA PSS padding templates.
+ *
+ * Copyright (c) 2021 Hongbo Li <herberthbli@tencent.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <crypto/hash.h>
+#include <crypto/internal/rsa.h>
+#include <crypto/internal/akcipher.h>
+
+struct psspad_inst_ctx {
+	struct crypto_akcipher_spawn spawn;
+};
+
+struct psspad_request {
+	struct scatterlist out_sg[1];
+	uint8_t *out_buf;
+	struct akcipher_request child_req;
+};
+
+static const u8 *psspad_unpack(void *dst, const void *src, size_t sz)
+{
+	memcpy(dst, src, sz);
+	return src + sz;
+}
+
+static int psspad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+			      unsigned int keylen)
+{
+	struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(tfm);
+	const u8 *ptr;
+	u32 algo, paramlen;
+	int err;
+
+	ctx->key_size = 0;
+
+	err = crypto_akcipher_set_pub_key(ctx->child, key, keylen);
+	if (err)
+		return err;
+
+	/* Find out new modulus size from rsa implementation */
+	err = crypto_akcipher_maxsize(ctx->child);
+	if (err > PAGE_SIZE)
+		return -EOPNOTSUPP;
+
+	ctx->key_size = err;
+
+	ptr = key + keylen;
+	ptr = psspad_unpack(&algo, ptr, sizeof(algo));
+	ptr = psspad_unpack(&paramlen, ptr, sizeof(paramlen));
+	err = rsa_parse_pss_params(ctx, ptr, paramlen);
+	if (err < 0)
+		return err;
+
+	if (!ctx->hash_algo)
+		ctx->hash_algo = "sha1";
+	if (!ctx->mgf_algo)
+		ctx->mgf_algo = "mgf1";
+	if (!ctx->mgf_hash_algo)
+		ctx->mgf_hash_algo = "sha1";
+	if (!ctx->salt_len)
+		ctx->salt_len = RSA_PSS_DEFAULT_SALT_LEN;
+
+	return 0;
+}
+
+static int psspad_mgf1(const char *hash_algo, u8 *seed, u32 seed_len, u8 *mask,
+		       u32 masklen)
+{
+	struct crypto_shash *tfm = NULL;
+	u32 hlen, cnt, tlen;
+	u8 c[4], digest[RSA_MAX_DIGEST_SIZE], buf[RSA_MAX_DIGEST_SIZE + 4];
+	int i, err = 0;
+	SHASH_DESC_ON_STACK(desc, tfm);
+
+	tfm = crypto_alloc_shash(hash_algo, 0, 0);
+	if (IS_ERR(tfm)) {
+		err = PTR_ERR(tfm);
+		return err;
+	}
+	desc->tfm = tfm;
+	hlen = crypto_shash_digestsize(tfm);
+	cnt = DIV_ROUND_UP(masklen, hlen);
+	tlen = 0;
+	for (i = 0; i < cnt; i++) {
+		/* C = I2OSP (counter, 4) */
+		c[0] = (i >> 24) & 0xff;
+		c[1] = (i >> 16) & 0xff;
+		c[2] = (i >> 8) & 0xff;
+		c[3] = i & 0xff;
+
+		memcpy(buf, seed, seed_len);
+		memcpy(buf + seed_len, c, 4);
+		err = crypto_shash_digest(desc, buf,
+					  seed_len + 4, digest);
+		if (err < 0)
+			goto free;
+
+		/* T = T || Hash(mgfSeed || C) */
+		tlen = i * hlen;
+		if (i == cnt - 1)
+			memcpy(mask + tlen, digest, masklen - tlen);
+		else
+			memcpy(mask + tlen, digest, hlen);
+	}
+free:
+	crypto_free_shash(tfm);
+	return err;
+}
+
+/* EMSA-PSS-VERIFY (M, EM, emBits) */
+static int psspad_verify_complete(struct akcipher_request *req, int err)
+{
+	struct crypto_akcipher *ak_tfm = crypto_akcipher_reqtfm(req);
+	struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(ak_tfm);
+	struct psspad_request *req_ctx = akcipher_request_ctx(req);
+	struct crypto_akcipher *rsa_tfm;
+	struct rsa_mpi_key *mpi_key;
+	struct crypto_shash *tfm = NULL;
+	u32 i, hlen, slen, modbits, embits, emlen, masklen, buflen;
+	u8 *em, *h, *maskeddb, *dbmask, *db, *salt;
+	u8 mhash[RSA_MAX_DIGEST_SIZE], digest[RSA_MAX_DIGEST_SIZE];
+	u8 *buf = NULL;
+	SHASH_DESC_ON_STACK(desc, tfm);
+
+	if (err)
+		goto free;
+
+	tfm = crypto_alloc_shash(ctx->hash_algo, 0, 0);
+	if (IS_ERR(tfm)) {
+		err = PTR_ERR(tfm);
+		tfm = NULL;
+		goto free;
+	}
+	desc->tfm = tfm;
+	hlen = crypto_shash_digestsize(tfm);
+
+	/* mhash */
+	sg_pcopy_to_buffer(req->src,
+			   sg_nents_for_len(req->src,
+					    req->src_len + req->dst_len),
+			   mhash, hlen, req->src_len);
+
+	err = -EINVAL;
+
+	/* section 8.1.2. emLen = \ceil ((modBits - 1)/8) */
+	rsa_tfm = crypto_akcipher_reqtfm(&req_ctx->child_req);
+	mpi_key = akcipher_tfm_ctx(rsa_tfm);
+	modbits = mpi_get_nbits(mpi_key->n);
+	embits = modbits - 1;
+	emlen = DIV_ROUND_UP(embits, 8);
+
+	/* 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop. */
+	slen = ctx->salt_len;
+	if (emlen < hlen + slen + 2)
+		goto free;
+
+	/* 4. If the rightmost octet of EM does not have hexadecimal value
+	 * 0xbc, output "inconsistent" and stop.
+	 */
+	em = req_ctx->out_buf;
+	if (em[emlen - 1] != 0xbc)
+		goto free;
+
+
+	/* 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM,
+	 * and let H be the next hLen octets.
+	 */
+	maskeddb = em;
+	masklen = emlen - hlen - 1;
+	h = em + masklen;
+
+	/* 6. If the leftmost 8emLen - emBits bits of the leftmost octet in
+	 * maskedDB are not all equal to zero, output "inconsistent" and
+	 * stop.
+	 */
+	if (maskeddb[0] & ~(0xff >> (8 * emlen - embits)))
+		goto free;
+
+	/* 7. Let dbMask = MGF(H, emLen - hLen - 1). */
+	buflen = max_t(u32, masklen, 8 + hlen + slen);
+	buf = kmalloc(buflen, GFP_KERNEL);
+	if (!buf) {
+		err = -ENOMEM;
+		goto free;
+	}
+	dbmask = buf;
+	err = psspad_mgf1(ctx->mgf_hash_algo, h, hlen, dbmask, masklen);
+	if (err)
+		goto free;
+
+	/* 8. Let DB = maskedDB \xor dbMask. */
+	db = maskeddb;
+	for (i = 0; i < masklen; i++)
+		db[i] = maskeddb[i] ^ dbmask[i];
+
+	/* 9. Set the leftmost 8emLen - emBits bits of the leftmost octet
+	 * in DB to zero.
+	 */
+	db[0] &= 0xff >> (8 * emlen - embits);
+
+	/* 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not
+	 * zero or if the octet at position emLen - hLen - sLen - 1 (the
+	 * leftmost position is "position 1") does not have hexadecimal
+	 * value 0x01, output "inconsistent" and stop.
+	 */
+	for (i = 0; i < emlen - hlen - slen - 2; i++) {
+		if (db[i]) {
+			err = -EINVAL;
+			goto free;
+		}
+	}
+	if (db[i] != 1)
+		goto free;
+
+	/* 11. Let salt be the last sLen octets of DB. */
+	salt = db + masklen - slen;
+
+	/* 12. M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ; */
+	memset(buf, 0, 8);
+	memcpy(buf + 8, mhash, hlen);
+	memcpy(buf + 8 + hlen, salt, slen);
+
+	/* 13. Let H' = Hash(M'), an octet string of length hLen. */
+	err = crypto_shash_digest(desc, buf, 8 + hlen + slen, digest);
+	if (err < 0)
+		goto free;
+
+	/* 14. If H = H', output "consistent". Otherwise, output
+	 * "inconsistent".
+	 */
+	if (memcmp(h, digest, hlen))
+		err = -EKEYREJECTED;
+
+free:
+	if (tfm)
+		crypto_free_shash(tfm);
+	kfree_sensitive(req_ctx->out_buf);
+	kfree(buf);
+	return err;
+}
+
+static void psspad_verify_complete_cb(
+	struct crypto_async_request *child_async_req, int err)
+{
+	struct akcipher_request *req = child_async_req->data;
+	struct crypto_async_request async_req;
+
+	if (err == -EINPROGRESS)
+		return;
+
+	async_req.data = req->base.data;
+	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
+	async_req.flags = child_async_req->flags;
+	req->base.complete(&async_req, psspad_verify_complete(req, err));
+}
+
+static int psspad_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct psspad_request *req_ctx = akcipher_request_ctx(req);
+	int err;
+
+	if (WARN_ON(req->dst) ||
+	    WARN_ON(!req->dst_len) ||
+	    !ctx->key_size || req->src_len < ctx->key_size)
+		return -EINVAL;
+
+	req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
+	if (!req_ctx->out_buf)
+		return -ENOMEM;
+
+	sg_init_table(req_ctx->out_sg, 1);
+	sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, ctx->key_size);
+
+	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
+	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
+				      psspad_verify_complete_cb, req);
+
+	/* Reuse input buffer, output to a new buffer */
+	akcipher_request_set_crypt(&req_ctx->child_req, req->src,
+				   req_ctx->out_sg, req->src_len,
+				   ctx->key_size);
+
+	err = crypto_akcipher_encrypt(&req_ctx->child_req);
+	if (err != -EINPROGRESS && err != -EBUSY)
+		return psspad_verify_complete(req, err);
+
+	return err;
+}
+
+static unsigned int psspad_get_max_size(struct crypto_akcipher *tfm)
+{
+	struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	return ctx->key_size;
+}
+
+static int psspad_init_tfm(struct crypto_akcipher *tfm)
+{
+	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+	struct psspad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct crypto_akcipher *child_tfm;
+
+	child_tfm = crypto_spawn_akcipher(&ictx->spawn);
+	if (IS_ERR(child_tfm))
+		return PTR_ERR(child_tfm);
+
+	ctx->child = child_tfm;
+	return 0;
+}
+
+static void psspad_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	crypto_free_akcipher(ctx->child);
+}
+
+static void psspad_free(struct akcipher_instance *inst)
+{
+	struct psspad_inst_ctx *ctx = akcipher_instance_ctx(inst);
+	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
+
+	crypto_drop_akcipher(spawn);
+	kfree(inst);
+}
+
+static int psspad_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+	u32 mask;
+	struct akcipher_instance *inst;
+	struct psspad_inst_ctx *ctx;
+	struct akcipher_alg *rsa_alg;
+	int err;
+
+	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask);
+	if (err)
+		return err;
+
+	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	ctx = akcipher_instance_ctx(inst);
+
+	err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst),
+				   crypto_attr_alg_name(tb[1]), 0, mask);
+	if (err)
+		goto err_free_inst;
+
+	rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
+
+	err = -ENAMETOOLONG;
+	if (snprintf(inst->alg.base.cra_name,
+		     CRYPTO_MAX_ALG_NAME, "psspad(%s)",
+		     rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
+		goto err_free_inst;
+
+	if (snprintf(inst->alg.base.cra_driver_name,
+		     CRYPTO_MAX_ALG_NAME, "psspad(%s)",
+		     rsa_alg->base.cra_driver_name) >=
+	    CRYPTO_MAX_ALG_NAME)
+		goto err_free_inst;
+
+	inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
+	inst->alg.base.cra_ctxsize = sizeof(struct rsa_pss_ctx);
+
+	inst->alg.init = psspad_init_tfm;
+	inst->alg.exit = psspad_exit_tfm;
+	inst->alg.verify = psspad_verify;
+	inst->alg.set_pub_key = psspad_set_pub_key;
+	inst->alg.max_size = psspad_get_max_size;
+	inst->alg.reqsize = sizeof(struct psspad_request) + rsa_alg->reqsize;
+
+	inst->free = psspad_free;
+
+	err = akcipher_register_instance(tmpl, inst);
+	if (err) {
+err_free_inst:
+		psspad_free(inst);
+	}
+	return err;
+}
+
+struct crypto_template rsa_psspad_tmpl = {
+	.name = "psspad",
+	.create = psspad_create,
+	.module = THIS_MODULE,
+};
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/crypto/rsapss_params.asn1 b/crypto/rsapss_params.asn1
new file mode 100644
index 0000000..4d6b0ba
--- /dev/null
+++ b/crypto/rsapss_params.asn1
@@ -0,0 +1,21 @@
+-- rfc4055 section 3.1.
+
+RSAPSS_Params ::= SEQUENCE {
+	hashAlgorithm		[0] HashAlgorithm OPTIONAL,
+	maskGenAlgorithm	[1] MaskGenAlgorithm OPTIONAL,
+	saltLen			[2] INTEGER OPTIONAL ({ rsa_get_pss_saltlen }),
+	trailerField		[3] INTEGER OPTIONAL ({ rsa_get_pss_trailerfield })
+	}
+
+HashAlgorithm ::= SEQUENCE {
+	algorithm		OBJECT IDENTIFIER ({ rsa_get_pss_hash })
+	}
+
+MaskGenAlgorithm ::= SEQUENCE {
+	algorithm	OBJECT IDENTIFIER  ({ rsa_get_pss_mgf }),
+	hashAlgorithm	MgfHashAlgorithm
+	}
+
+MgfHashAlgorithm ::= SEQUENCE {
+	algorithm	OBJECT IDENTIFIER ({ rsa_get_pss_mgf_hash })
+	}
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
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 3/4] crypto: add rsa pss test vector
  2021-04-07  3:49 [PATCH v3 0/4] crypto: add rsa pss support for x509 Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 1/4] x509: add support for rsa-pss Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 2/4] crypto: support rsa-pss encoding Hongbo Li
@ 2021-04-07  3:49 ` Hongbo Li
  2021-04-07  3:49 ` [PATCH v3 4/4] ima: add support for rsa pss verification Hongbo Li
  3 siblings, 0 replies; 6+ messages in thread
From: Hongbo Li @ 2021-04-07  3:49 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, zohar, jarkko, herberthbli
  Cc: linux-kernel, linux-integrity, Hongbo Li

This patch adds the test vector for rsa with pss encoding.

Signed-off-by: Hongbo Li <herbert.tencent@gmail.com>
---
 crypto/testmgr.c |  7 +++++
 crypto/testmgr.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 10c5b3b..2b07fdb 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5216,6 +5216,13 @@ static int alg_test_null(const struct alg_test_desc *desc,
 		.test = alg_test_null,
 		.fips_allowed = 1,
 	}, {
+		.alg = "psspad(rsa)",
+		.test = alg_test_akcipher,
+		.fips_allowed = 1,
+		.suite = {
+			.akcipher = __VECS(psspad_rsa_tv_template)
+		}
+	}, {
 		.alg = "poly1305",
 		.test = alg_test_hash,
 		.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 34e4a3d..0402db5 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -1239,6 +1239,96 @@ struct kpp_testvec {
 	}
 };
 
+/*
+ * RSA PSS test vectors. Obtained from 186-3rsatestvectors.zip
+ */
+static const struct akcipher_testvec psspad_rsa_tv_template[] = {
+	{
+	.key =
+	/* Sequence of n , e */
+	"\x30\x82\x02\x09"
+	/* n */
+	"\x02\x82\x01\x01\x00"
+	"\xc5\x06\x2b\x58\xd8\x53\x9c\x76\x5e\x1e\x5d\xba\xf1\x4c\xf7\x5d"
+	"\xd5\x6c\x2e\x13\x10\x5f\xec\xfd\x1a\x93\x0b\xbb\x59\x48\xff\x32"
+	"\x8f\x12\x6a\xbe\x77\x93\x59\xca\x59\xbc\xa7\x52\xc3\x08\xd2\x81"
+	"\x57\x3b\xc6\x17\x8b\x6c\x0f\xef\x7d\xc4\x45\xe4\xf8\x26\x43\x04"
+	"\x37\xb9\xf9\xd7\x90\x58\x1d\xe5\x74\x9c\x2c\xb9\xcb\x26\xd4\x2b"
+	"\x2f\xee\x15\xb6\xb2\x6f\x09\xc9\x96\x70\x33\x64\x23\xb8\x6b\xc5"
+	"\xbe\xc7\x11\x13\x15\x7b\xe2\xd9\x44\xd7\xff\x3e\xeb\xff\xb2\x84"
+	"\x13\x14\x3e\xa3\x67\x55\xdb\x0a\xe6\x2f\xf5\xb7\x24\xee\xcb\x3d"
+	"\x31\x6b\x6b\xac\x67\xe8\x9c\xac\xd8\x17\x19\x37\xe2\xab\x19\xbd"
+	"\x35\x3a\x89\xac\xea\x8c\x36\xf8\x1c\x89\xa6\x20\xd5\xfd\x2e\xff"
+	"\xea\x89\x66\x01\xc7\xf9\xda\xca\x7f\x03\x3f\x63\x5a\x3a\x94\x33"
+	"\x31\xd1\xb1\xb4\xf5\x28\x87\x90\xb5\x3a\xf3\x52\xf1\x12\x1c\xa1"
+	"\xbe\xf2\x05\xf4\x0d\xc0\x12\xc4\x12\xb4\x0b\xdd\x27\x58\x5b\x94"
+	"\x64\x66\xd7\x5f\x7e\xe0\xa7\xf9\xd5\x49\xb4\xbe\xce\x6f\x43\xac"
+	"\x3e\xe6\x5f\xe7\xfd\x37\x12\x33\x59\xd9\xf1\xa8\x50\xad\x45\x0a"
+	"\xaf\x5c\x94\xeb\x11\xde\xa3\xfc\x0f\xc6\xe9\x85\x6b\x18\x05\xef"
+	/* e */
+	"\x02\x82\x01\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xc9\x4f",
+	.key_len = 525,
+	.params =
+	"\x30\x30"
+	"\xa0\x0d\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\xa1"
+	"\x1a\x30\x18\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x08\x30\x0b"
+	"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\xa2\x03\x02\x01\x20",
+	.param_len = 50,
+	/*
+	 * m is SHA256 hash of following message:
+	 * "\xdf\xc2\x26\x04\xb9\x5d\x15\x32\x80\x59\x74\x5c\x6c\x98\xeb"
+	 * "\x9d\xfb\x34\x7c\xf9\xf1\x70\xaf\xf1\x9d\xee\xec\x55\x5f\x22"
+	 * "\x28\x5a\x67\x06\xc4\xec\xbf\x0f\xb1\x45\x8c\x60\xd9\xbf\x91"
+	 * "\x3f\xba\xe6\xf4\xc5\x54\xd2\x45\xd9\x46\xb4\xbc\x5f\x34\xae"
+	 * "\xc2\xac\x6b\xe8\xb3\x3d\xc8\xe0\xe3\xa9\xd6\x01\xdf\xd5\x36"
+	 * "\x78\xf5\x67\x44\x43\xf6\x7d\xf7\x8a\x3a\x9e\x09\x33\xe5\xf1"
+	 * "\x58\xb1\x69\xac\x8d\x1c\x4c\xd0\xfb\x87\x2c\x14\xca\x8e\x00"
+	 * "\x1e\x54\x2e\xa0\xf9\xcf\xda\x88\xc4\x2d\xca\xd8\xa7\x40\x97"
+	 * "\xa0\x0c\x22\x05\x5b\x0b\xd4\x1f"
+	 */
+	.m =
+	"\xb9\x8a\x0d\x22\xe8\x37\xb1\x01\x87\x4a\x5f\x0d\x7a\xd4\x98\x36"
+	"\xe6\x27\x3f\xc7\x5c\xd2\xd0\x73\xdc\x81\xd9\x6f\x05\xf5\x8f\x3c",
+	.m_size = 32,
+	.c =
+	"\x8b\x46\xf2\xc8\x89\xd8\x19\xf8\x60\xaf\x0a\x6c\x4c\x88\x9e\x4d"
+	"\x14\x36\xc6\xca\x17\x44\x64\xd2\x2a\xe1\x1b\x9c\xcc\x26\x5d\x74"
+	"\x3c\x67\xe5\x69\xac\xcb\xc5\xa8\x0d\x4d\xd5\xf1\xbf\x40\x39\xe2"
+	"\x3d\xe5\x2a\xec\xe4\x02\x91\xc7\x5f\x89\x36\xc5\x8c\x9a\x2f\x77"
+	"\xa7\x80\xbb\xe7\xad\x31\xeb\x76\x74\x2f\x7b\x2b\x8b\x14\xca\x1a"
+	"\x71\x96\xaf\x7e\x67\x3a\x3c\xfc\x23\x7d\x50\xf6\x15\xb7\x5c\xf4"
+	"\xa7\xea\x78\xa9\x48\xbe\xda\xf9\x24\x24\x94\xb4\x1e\x1d\xb5\x1f"
+	"\x43\x7f\x15\xfd\x25\x51\xbb\x5d\x24\xee\xfb\x1c\x3e\x60\xf0\x36"
+	"\x94\xd0\x03\x3a\x1e\x0a\x9b\x9f\x5e\x4a\xb9\x7d\x45\x7d\xff\x9b"
+	"\x9d\xa5\x16\xdc\x22\x6d\x6d\x65\x29\x50\x03\x08\xed\x74\xa2\xe6"
+	"\xd9\xf3\xc1\x05\x95\x78\x8a\x52\xa1\xbc\x06\x64\xae\xdf\x33\xef"
+	"\xc8\xba\xdd\x03\x7e\xb7\xb8\x80\x77\x2b\xdb\x04\xa6\x04\x6e\x9e"
+	"\xde\xee\x41\x97\xc2\x55\x07\xfb\x0f\x11\xab\x1c\x9f\x63\xf5\x3c"
+	"\x88\x20\xea\x84\x05\xcf\xd7\x72\x16\x92\x47\x5b\x4d\x72\x35\x5f"
+	"\xa9\xa3\x80\x4f\x29\xe6\xb6\xa7\xb0\x59\xc4\x44\x1d\x54\xb2\x8e"
+	"\x4e\xed\x25\x29\xc6\x10\x3b\x54\x32\xc7\x13\x32\xce\x74\x2b\xcc",
+	.c_size = 256,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	}
+};
+
 static const struct kpp_testvec dh_tv_template[] = {
 	{
 	.secret =
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 4/4] ima: add support for rsa pss verification
  2021-04-07  3:49 [PATCH v3 0/4] crypto: add rsa pss support for x509 Hongbo Li
                   ` (2 preceding siblings ...)
  2021-04-07  3:49 ` [PATCH v3 3/4] crypto: add rsa pss test vector Hongbo Li
@ 2021-04-07  3:49 ` Hongbo Li
  3 siblings, 0 replies; 6+ messages in thread
From: Hongbo Li @ 2021-04-07  3:49 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, zohar, jarkko, herberthbli
  Cc: linux-kernel, linux-integrity, Hongbo Li

This patch adds support for ima verification for rsa with
pss encoding.

And a patch for ima-evm-utils will be sent later.

Signed-off-by: Hongbo Li <herbert.tencent@gmail.com>
---
 security/integrity/digsig_asymmetric.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 23240d7..ef7a51a 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -85,6 +85,7 @@ int asymmetric_verify(struct key *keyring, const char *sig,
 	struct public_key_signature pks;
 	struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
 	const struct public_key *pk;
+	struct public_key_signature *cert_sig;
 	struct key *key;
 	int ret;
 
@@ -109,16 +110,21 @@ int asymmetric_verify(struct key *keyring, const char *sig,
 
 	pk = asymmetric_key_public_key(key);
 	pks.pkey_algo = pk->pkey_algo;
-	if (!strcmp(pk->pkey_algo, "rsa"))
-		pks.encoding = "pkcs1";
-	else if (!strncmp(pk->pkey_algo, "ecdsa-", 6))
+	if (!strcmp(pk->pkey_algo, "rsa")) {
+		cert_sig = key->payload.data[asym_auth];
+		if (cert_sig)
+			pks.encoding = cert_sig->encoding;
+		else
+			pks.encoding = "pkcs1";
+	} else if (!strncmp(pk->pkey_algo, "ecdsa-", 6)) {
 		/* edcsa-nist-p192 etc. */
 		pks.encoding = "x962";
-	else if (!strcmp(pk->pkey_algo, "ecrdsa") ||
-		   !strcmp(pk->pkey_algo, "sm2"))
+	} else if (!strcmp(pk->pkey_algo, "ecrdsa") ||
+		   !strcmp(pk->pkey_algo, "sm2")) {
 		pks.encoding = "raw";
-	else
+	} else {
 		return -ENOPKG;
+	}
 
 	pks.digest = (u8 *)data;
 	pks.digest_size = datalen;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 2/4] crypto: support rsa-pss encoding
  2021-04-07  3:49 ` [PATCH v3 2/4] crypto: support rsa-pss encoding Hongbo Li
@ 2021-04-07  8:40   ` kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-04-07  8:40 UTC (permalink / raw)
  To: Hongbo Li, keyrings, linux-crypto, herbert, dhowells, zohar,
	jarkko, herberthbli
  Cc: kbuild-all, linux-kernel, linux-integrity, Hongbo Li

[-- Attachment #1: Type: text/plain, Size: 2300 bytes --]

Hi Hongbo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on cryptodev/master]
[also build test WARNING on crypto/master security/next-testing linus/master v5.12-rc6 next-20210406]
[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/20210407-115152
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: x86_64-randconfig-s021-20210407 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-279-g6d5d9b42-dirty
        # https://github.com/0day-ci/linux/commit/cd6d6b64f74124a91cb5f0e5d5485d8b159c0ff7
        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/20210407-115152
        git checkout cd6d6b64f74124a91cb5f0e5d5485d8b159c0ff7
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

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


sparse warnings: (new ones prefixed by >>)
>> crypto/rsa_helper.c:247:33: sparse: sparse: cast to restricted __be16
>> crypto/rsa_helper.c:247:33: sparse: sparse: cast to restricted __be16
>> crypto/rsa_helper.c:247:33: sparse: sparse: cast to restricted __be16
>> crypto/rsa_helper.c:247:33: sparse: sparse: cast to restricted __be16

vim +247 crypto/rsa_helper.c

   235	
   236	int rsa_get_pss_saltlen(void *context, size_t hdrlen, unsigned char tag,
   237				const void *value, size_t vlen)
   238	{
   239		struct rsa_pss_ctx *ctx = context;
   240	
   241		if (!value || vlen < 1 || vlen > 2)
   242			return -EINVAL;
   243	
   244		if (vlen == 1)
   245			ctx->salt_len = *(u8 *)value;
   246		else if (vlen == 2)
 > 247			ctx->salt_len = ntohs(*(u16 *)value);
   248	
   249		return 0;
   250	}
   251	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35310 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-04-07  8:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-07  3:49 [PATCH v3 0/4] crypto: add rsa pss support for x509 Hongbo Li
2021-04-07  3:49 ` [PATCH v3 1/4] x509: add support for rsa-pss Hongbo Li
2021-04-07  3:49 ` [PATCH v3 2/4] crypto: support rsa-pss encoding Hongbo Li
2021-04-07  8:40   ` kernel test robot
2021-04-07  3:49 ` [PATCH v3 3/4] crypto: add rsa pss test vector Hongbo Li
2021-04-07  3:49 ` [PATCH v3 4/4] ima: add support for rsa pss verification Hongbo Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).