linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-31  2:10   ` kernel test robot
                     ` (2 more replies)
  2021-03-30 20:28 ` [PATCH 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad Varad Gautam
                   ` (16 subsequent siblings)
  17 siblings, 3 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto
  Cc: Varad Gautam, David Howells, Herbert Xu, David S. Miller,
	Vitaly Chikunov, Tianjia Zhang, open list:ASYMMETRIC KEYS,
	open list

An X.509 wrapper for a RSASSA-PSS signature contains additional
signature parameters over the PKCSv.15 encoding scheme. Extend the
x509 parser to allow parsing RSASSA-PSS encoded certificates, with
the defaults taken from RFC8017.

A certificate is rejected if the hash function used for the MGF is
different from the hash function used for signature generation,
although this is allowed in RFC8017.

References: https://tools.ietf.org/html/rfc8017#appendix-C
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/asymmetric_keys/Makefile           |   5 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 152 ++++++++++++++++++++++
 crypto/asymmetric_keys/x509_rsassa.asn1   |  17 +++
 include/crypto/public_key.h               |   4 +
 include/linux/oid_registry.h              |   3 +
 5 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100644 crypto/asymmetric_keys/x509_rsassa.asn1

diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 28b91adba2ae..f79ed8e8ef8e 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -20,15 +20,18 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
 x509_key_parser-y := \
 	x509.asn1.o \
 	x509_akid.asn1.o \
+	x509_rsassa.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_rsassa.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_rsassa.asn1.o: $(obj)/x509_rsassa.asn1.c $(obj)/x509_rsassa.asn1.h
 
 #
 # PKCS#8 private key handling
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 52c9b455fc7d..3738355618cd 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_rsassa.asn1.h"
 
 struct x509_parse_context {
 	struct x509_certificate	*cert;		/* Certificate being constructed */
@@ -38,6 +39,8 @@ struct x509_parse_context {
 	const void	*raw_akid;		/* Raw authorityKeyId in ASN.1 */
 	const void	*akid_raw_issuer;	/* Raw directoryName in authorityKeyId */
 	unsigned	akid_raw_issuer_size;
+	const void	*raw_sig_params;	/* Signature AlgorithmIdentifier.parameters */
+	unsigned	raw_sig_params_size;
 };
 
 /*
@@ -101,6 +104,15 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
 		}
 	}
 
+	if (strcmp(ctx->cert->sig->encoding, "pss") == 0) {
+		pr_devel("rsa enc=pss hash=%s mgf=%s mgf_hash=%s salt=0x%x tf=0x%x\n",
+			 ctx->cert->sig->hash_algo,
+			 ctx->cert->sig->mgf,
+			 ctx->cert->sig->mgf_hash_algo,
+			 ctx->cert->sig->salt_length,
+			 ctx->cert->sig->trailer_field);
+	}
+
 	ret = -ENOMEM;
 	cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
 	if (!cert->pub->key)
@@ -194,6 +206,7 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 			const void *value, size_t vlen)
 {
 	struct x509_parse_context *ctx = context;
+	int ret = 0;
 
 	pr_debug("PubKey Algo: %u\n", ctx->last_oid);
 
@@ -238,6 +251,39 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 	case OID_SM2_with_SM3:
 		ctx->cert->sig->hash_algo = "sm3";
 		goto sm2;
+
+	case OID_rsassaPSS:
+		/* For rsassaPSS, the hash algorithm is packed as a mandatory
+		 * parameter in AlgorithmIdentifier.parameters.
+		 */
+		if (ctx->raw_sig_params == NULL && ctx->raw_sig_params_size != 1)
+			return -EBADMSG;
+
+		ctx->cert->sig->pkey_algo = "rsa";
+		ctx->cert->sig->encoding = "pss";
+		ctx->algo_oid = ctx->last_oid;
+		if (ctx->raw_sig_params) {
+			ret = asn1_ber_decoder(&x509_rsassa_decoder, ctx,
+					       ctx->raw_sig_params,
+					       ctx->raw_sig_params_size);
+			if (ret < 0)
+				return ret;
+		}
+
+		/* Fill in RSASSA-PSS-params defaults if left out. */
+		if (!ctx->cert->sig->hash_algo)
+			ctx->cert->sig->hash_algo = "sha1";
+		if (!ctx->cert->sig->mgf)
+			ctx->cert->sig->mgf = "mgf1";
+		if (!ctx->cert->sig->mgf_hash_algo)
+			ctx->cert->sig->mgf_hash_algo = "sha1";
+		ctx->cert->sig->trailer_field = 0xbc;
+
+		/* Reject if digest and mgf use different hashalgs. */
+		if (strcmp(ctx->cert->sig->hash_algo, ctx->cert->sig->mgf_hash_algo) != 0)
+			return -ENOPKG;
+
+		return 0;
 	}
 
 rsa_pkcs1:
@@ -439,6 +485,18 @@ int x509_note_params(void *context, size_t hdrlen,
 {
 	struct x509_parse_context *ctx = context;
 
+	if (ctx->last_oid == OID_rsassaPSS && !ctx->raw_sig_params) {
+		/* Stash AlgorithmIdentifier.parameters for RSASSA-PSS. */
+		ctx->raw_sig_params_size = vlen + hdrlen;
+		if (ctx->raw_sig_params_size) {
+			ctx->raw_sig_params = value - hdrlen;
+		} else {
+			ctx->raw_sig_params = NULL;
+			ctx->raw_sig_params_size = 1;
+		}
+		return 0;
+	}
+
 	/*
 	 * AlgorithmIdentifier is used three times in the x509, we should skip
 	 * first and ignore third, using second one which is after subject and
@@ -705,3 +763,97 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
 	ctx->cert->sig->auth_ids[0] = kid;
 	return 0;
 }
+
+int x509_note_hash_algo(void *context, size_t hdrlen,
+			unsigned char tag,
+			const void *value, size_t vlen)
+{
+	struct x509_parse_context *ctx = context;
+	const char **ptr = NULL;
+
+	if (ctx->last_oid != OID_rsassaPSS)
+		return -EBADMSG;
+
+	if (ctx->cert->sig->mgf)
+		ptr = &ctx->cert->sig->mgf_hash_algo;
+	else
+		ptr = &ctx->cert->sig->hash_algo;
+
+	switch (look_up_OID(value, vlen)) {
+	case OID_sha224:
+		*ptr = "sha224";
+		break;
+	case OID_sha256:
+		*ptr = "sha256";
+		break;
+	case OID_sha384:
+		*ptr = "sha384";
+		break;
+	case OID_sha512:
+		*ptr = "sha512";
+		break;
+	case OID_sha1:
+	default:
+		*ptr = "sha1";
+		break;
+	}
+
+	return 0;
+}
+
+int x509_note_hash_algo_params(void *context, size_t hdrlen,
+			       unsigned char tag,
+			       const void *value, size_t vlen)
+{
+	return -EOPNOTSUPP;
+}
+
+int x509_note_mgf(void *context, size_t hdrlen,
+		  unsigned char tag,
+		  const void *value, size_t vlen)
+{
+	struct x509_parse_context *ctx = context;
+
+	if (ctx->last_oid != OID_rsassaPSS)
+		return -EBADMSG;
+
+	/* RFC8017 PKCS1MGFAlgorithms */
+	if (look_up_OID(value, vlen) != OID_mgf1)
+		return -EINVAL;
+
+	ctx->cert->sig->mgf = "mgf1";
+
+	return 0;
+}
+
+int x509_note_salt_length(void *context, size_t hdrlen,
+			  unsigned char tag,
+			  const void *value, size_t vlen)
+{
+	struct x509_parse_context *ctx = context;
+
+	if (ctx->last_oid != OID_rsassaPSS)
+		return -EBADMSG;
+
+	if (!value || !vlen || vlen > sizeof(ctx->cert->sig->salt_length))
+		return -EINVAL;
+
+	ctx->cert->sig->salt_length = (vlen == 2) ?
+		be16_to_cpu(*((u16 *) value)) : *((u8 *) value);
+
+	return 0;
+}
+
+int x509_note_trailer_field(void *context, size_t hdrlen,
+			    unsigned char tag,
+			    const void *value, size_t vlen)
+{
+	struct x509_parse_context *ctx = context;
+
+	if (ctx->last_oid != OID_rsassaPSS)
+		return -EBADMSG;
+
+	/* trailerField 0xbc per RFC8017 A.2.3 regardless of if
+	 * specified. */
+	return 0;
+}
diff --git a/crypto/asymmetric_keys/x509_rsassa.asn1 b/crypto/asymmetric_keys/x509_rsassa.asn1
new file mode 100644
index 000000000000..e524b978856d
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_rsassa.asn1
@@ -0,0 +1,17 @@
+-- RFC8017
+RSASSA-PSS-params ::= SEQUENCE {
+	hashAlgorithm      [0] HashAlgorithm DEFAULT,
+	maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT,
+	saltLength         [2] INTEGER DEFAULT ({ x509_note_salt_length }),
+	trailerField       [3] INTEGER DEFAULT ({ x509_note_trailer_field })
+}
+
+HashAlgorithm ::= SEQUENCE {
+	algorithm		OBJECT IDENTIFIER ({ x509_note_hash_algo }),
+	parameters		ANY OPTIONAL ({ x509_note_hash_algo_params })
+}
+
+MaskGenAlgorithm ::= SEQUENCE {
+	mgf	OBJECT IDENTIFIER ({ x509_note_mgf }),
+	parameters	HashAlgorithm
+}
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 47accec68cb0..f36834c8bb13 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -46,6 +46,10 @@ struct public_key_signature {
 	const char *encoding;
 	const void *data;
 	unsigned int data_size;
+	const char *mgf;
+	const char *mgf_hash_algo;
+	u16 salt_length;
+	u16 trailer_field;
 };
 
 extern void public_key_signature_free(struct public_key_signature *sig);
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index 4462ed2c18cd..c247adc8a41e 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -113,6 +113,9 @@ enum OID {
 	OID_SM2_with_SM3,		/* 1.2.156.10197.1.501 */
 	OID_sm3WithRSAEncryption,	/* 1.2.156.10197.1.504 */
 
+	OID_mgf1,			/* 1.2.840.113549.1.1.8 */
+	OID_rsassaPSS,			/* 1.2.840.113549.1.1.10 */
+
 	OID__NR
 };
 
-- 
2.30.2


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

* [PATCH 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
  2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper Varad Gautam
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

The existing RSA implementation supports PKCSv1.5 style signature
paddings via rsa-pkcs1pad. A lot of the functionality implemented
for rsa-pkcs1pad can be reused across other RSA padding schemes.
Rename such functions as rsapad_* before moving them out of
rsa-pkcs1pad.c.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-pkcs1pad.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 8ac3e73e8ea6..83ba7540a53a 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -104,7 +104,7 @@ struct pkcs1pad_request {
 	struct akcipher_request child_req;
 };
 
-static int pkcs1pad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 		unsigned int keylen)
 {
 	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -125,7 +125,7 @@ static int pkcs1pad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 	return 0;
 }
 
-static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
 		unsigned int keylen)
 {
 	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -146,7 +146,7 @@ static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
 	return 0;
 }
 
-static unsigned int pkcs1pad_get_max_size(struct crypto_akcipher *tfm)
+static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
 {
 	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
 
@@ -159,8 +159,8 @@ static unsigned int pkcs1pad_get_max_size(struct crypto_akcipher *tfm)
 	return ctx->key_size;
 }
 
-static void pkcs1pad_sg_set_buf(struct scatterlist *sg, void *buf, size_t len,
-		struct scatterlist *next)
+static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
+				       size_t len, struct scatterlist *next)
 {
 	int nsegs = next ? 2 : 1;
 
@@ -256,7 +256,7 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
 		req_ctx->in_buf[i] = 1 + prandom_u32_max(255);
 	req_ctx->in_buf[ps_end] = 0x00;
 
-	pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
+	rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
 			ctx->key_size - 1 - req->src_len, req->src);
 
 	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -357,7 +357,7 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
 	if (!req_ctx->out_buf)
 		return -ENOMEM;
 
-	pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
+	rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
 			    ctx->key_size, NULL);
 
 	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -415,7 +415,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
 		memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data,
 		       digest_info->size);
 
-	pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
+	rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
 			ctx->key_size - 1 - req->src_len, req->src);
 
 	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -545,7 +545,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
 	if (!req_ctx->out_buf)
 		return -ENOMEM;
 
-	pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
+	rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
 			    ctx->key_size, NULL);
 
 	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -564,7 +564,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
 	return err;
 }
 
-static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm)
+static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
 {
 	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
 	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
@@ -579,14 +579,14 @@ static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm)
 	return 0;
 }
 
-static void pkcs1pad_exit_tfm(struct crypto_akcipher *tfm)
+static void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
 {
 	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
 
 	crypto_free_akcipher(ctx->child);
 }
 
-static void pkcs1pad_free(struct akcipher_instance *inst)
+static void rsapad_akcipher_free(struct akcipher_instance *inst)
 {
 	struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst);
 	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
@@ -656,24 +656,24 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
 	inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
 	inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
 
-	inst->alg.init = pkcs1pad_init_tfm;
-	inst->alg.exit = pkcs1pad_exit_tfm;
+	inst->alg.init = rsapad_akcipher_init_tfm;
+	inst->alg.exit = rsapad_akcipher_exit_tfm;
 
 	inst->alg.encrypt = pkcs1pad_encrypt;
 	inst->alg.decrypt = pkcs1pad_decrypt;
 	inst->alg.sign = pkcs1pad_sign;
 	inst->alg.verify = pkcs1pad_verify;
-	inst->alg.set_pub_key = pkcs1pad_set_pub_key;
-	inst->alg.set_priv_key = pkcs1pad_set_priv_key;
-	inst->alg.max_size = pkcs1pad_get_max_size;
+	inst->alg.set_pub_key = rsapad_set_pub_key;
+	inst->alg.set_priv_key = rsapad_set_priv_key;
+	inst->alg.max_size = rsapad_get_max_size;
 	inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
 
-	inst->free = pkcs1pad_free;
+	inst->free = rsapad_akcipher_free;
 
 	err = akcipher_register_instance(tmpl, inst);
 	if (err) {
 err_free_inst:
-		pkcs1pad_free(inst);
+		rsapad_akcipher_free(inst);
 	}
 	return err;
 }
-- 
2.30.2


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

* [PATCH 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
  2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
  2021-03-30 20:28 ` [PATCH 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers Varad Gautam
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

which can be reused by other signature padding schemes as
rsapad_akcipher_create. This will be moved out of rsa-pkcs1pad.c to
be used across rsa-*pad implementations.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-pkcs1pad.c | 48 ++++++++++++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 83ba7540a53a..849573f6b44b 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -595,7 +595,21 @@ static void rsapad_akcipher_free(struct akcipher_instance *inst)
 	kfree(inst);
 }
 
-static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
+static struct akcipher_alg pkcs1pad_alg = {
+	.init = rsapad_akcipher_init_tfm,
+	.exit = rsapad_akcipher_exit_tfm,
+
+	.encrypt = pkcs1pad_encrypt,
+	.decrypt = pkcs1pad_decrypt,
+	.sign = pkcs1pad_sign,
+	.verify = pkcs1pad_verify,
+	.set_pub_key = rsapad_set_pub_key,
+	.set_priv_key = rsapad_set_priv_key,
+	.max_size = rsapad_get_max_size
+};
+
+static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
+				  struct akcipher_alg *alg)
 {
 	u32 mask;
 	struct akcipher_instance *inst;
@@ -625,12 +639,12 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
 	hash_name = crypto_attr_alg_name(tb[2]);
 	if (IS_ERR(hash_name)) {
 		if (snprintf(inst->alg.base.cra_name,
-			     CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
+			     CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
 			     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, "pkcs1pad(%s)",
+			     CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
 			     rsa_alg->base.cra_driver_name) >=
 			     CRYPTO_MAX_ALG_NAME)
 			goto err_free_inst;
@@ -642,12 +656,13 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
 		}
 
 		if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
-			     "pkcs1pad(%s,%s)", rsa_alg->base.cra_name,
+			     "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name,
 			     hash_name) >= CRYPTO_MAX_ALG_NAME)
 			goto err_free_inst;
 
 		if (snprintf(inst->alg.base.cra_driver_name,
-			     CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)",
+			     CRYPTO_MAX_ALG_NAME, "%s(%s,%s)",
+			     tmpl->name,
 			     rsa_alg->base.cra_driver_name,
 			     hash_name) >= CRYPTO_MAX_ALG_NAME)
 			goto err_free_inst;
@@ -656,16 +671,16 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
 	inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
 	inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
 
-	inst->alg.init = rsapad_akcipher_init_tfm;
-	inst->alg.exit = rsapad_akcipher_exit_tfm;
+	inst->alg.init = alg->init;
+	inst->alg.exit = alg->exit;
 
-	inst->alg.encrypt = pkcs1pad_encrypt;
-	inst->alg.decrypt = pkcs1pad_decrypt;
-	inst->alg.sign = pkcs1pad_sign;
-	inst->alg.verify = pkcs1pad_verify;
-	inst->alg.set_pub_key = rsapad_set_pub_key;
-	inst->alg.set_priv_key = rsapad_set_priv_key;
-	inst->alg.max_size = rsapad_get_max_size;
+	inst->alg.encrypt = alg->encrypt;
+	inst->alg.decrypt = alg->decrypt;
+	inst->alg.sign = alg->sign;
+	inst->alg.verify = alg->verify;
+	inst->alg.set_pub_key = alg->set_pub_key;
+	inst->alg.set_priv_key = alg->set_priv_key;
+	inst->alg.max_size = alg->max_size;
 	inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
 
 	inst->free = rsapad_akcipher_free;
@@ -678,6 +693,11 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
 	return err;
 }
 
+static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+	return rsapad_akcipher_create(tmpl, tb, &pkcs1pad_alg);
+}
+
 struct crypto_template rsa_pkcs1pad_tmpl = {
 	.name = "pkcs1pad",
 	.create = pkcs1pad_create,
-- 
2.30.2


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

* [PATCH 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (2 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_* Varad Gautam
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

rsa-pkcs1pad operations that require using RSA primitives rely on
creating an akcipher child RSA transform and processing the results
in the operation-specific callback. Add helpers
rsapad_akcipher_setup_child and rsapad_akcipher_req_complete for req
setup and callback handling, and switch pkcs1pad operations to use
these.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-pkcs1pad.c | 106 +++++++++++++++++++-----------------------
 1 file changed, 49 insertions(+), 57 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 849573f6b44b..6329c79316d2 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -171,6 +171,38 @@ static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
 		sg_chain(sg, nsegs, next);
 }
 
+typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
+static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
+					 int err, rsa_akcipher_complete_cb cb)
+{
+	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, cb(req, err));
+}
+
+static void rsapad_akcipher_setup_child(struct akcipher_request *req,
+					struct scatterlist *src_sg,
+					struct scatterlist *dst_sg,
+					unsigned int src_len,
+					unsigned int dst_len,
+					crypto_completion_t cb)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+
+	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
+	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
+	akcipher_request_set_crypt(&req_ctx->child_req, src_sg, dst_sg, src_len, dst_len);
+}
+
 static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
@@ -213,17 +245,8 @@ static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
 static void pkcs1pad_encrypt_sign_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,
-			pkcs1pad_encrypt_sign_complete(req, err));
+	rsapad_akcipher_req_complete(child_async_req, err,
+				     pkcs1pad_encrypt_sign_complete);
 }
 
 static int pkcs1pad_encrypt(struct akcipher_request *req)
@@ -259,13 +282,10 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
 	rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
 			ctx->key_size - 1 - req->src_len, req->src);
 
-	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
-			pkcs1pad_encrypt_sign_complete_cb, req);
-
 	/* Reuse output buffer */
-	akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
-				   req->dst, ctx->key_size - 1, req->dst_len);
+	rsapad_akcipher_setup_child(req, req_ctx->in_sg, req->dst,
+				    ctx->key_size - 1, req->dst_len,
+				    pkcs1pad_encrypt_sign_complete_cb);
 
 	err = crypto_akcipher_encrypt(&req_ctx->child_req);
 	if (err != -EINPROGRESS && err != -EBUSY)
@@ -331,16 +351,7 @@ static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
 static void pkcs1pad_decrypt_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, pkcs1pad_decrypt_complete(req, err));
+	rsapad_akcipher_req_complete(child_async_req, err, pkcs1pad_decrypt_complete);
 }
 
 static int pkcs1pad_decrypt(struct akcipher_request *req)
@@ -360,14 +371,10 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
 	rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
 			    ctx->key_size, NULL);
 
-	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
-			pkcs1pad_decrypt_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);
+	rsapad_akcipher_setup_child(req, req->src, req_ctx->out_sg,
+				    req->src_len, ctx->key_size,
+				    pkcs1pad_decrypt_complete_cb);
 
 	err = crypto_akcipher_decrypt(&req_ctx->child_req);
 	if (err != -EINPROGRESS && err != -EBUSY)
@@ -418,13 +425,10 @@ static int pkcs1pad_sign(struct akcipher_request *req)
 	rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
 			ctx->key_size - 1 - req->src_len, req->src);
 
-	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
-			pkcs1pad_encrypt_sign_complete_cb, req);
-
 	/* Reuse output buffer */
-	akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
-				   req->dst, ctx->key_size - 1, req->dst_len);
+	rsapad_akcipher_setup_child(req, req_ctx->in_sg, req->dst,
+				    ctx->key_size - 1, req->dst_len,
+				    pkcs1pad_encrypt_sign_complete_cb);
 
 	err = crypto_akcipher_decrypt(&req_ctx->child_req);
 	if (err != -EINPROGRESS && err != -EBUSY)
@@ -509,16 +513,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
 static void pkcs1pad_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, pkcs1pad_verify_complete(req, err));
+	rsapad_akcipher_req_complete(child_async_req, err,
+				     pkcs1pad_verify_complete);
 }
 
 /*
@@ -548,14 +544,10 @@ static int pkcs1pad_verify(struct akcipher_request *req)
 	rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
 			    ctx->key_size, NULL);
 
-	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
-			pkcs1pad_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);
+	rsapad_akcipher_setup_child(req, req->src, req_ctx->out_sg,
+				    req->src_len, ctx->key_size,
+				    pkcs1pad_verify_complete_cb);
 
 	err = crypto_akcipher_encrypt(&req_ctx->child_req);
 	if (err != -EINPROGRESS && err != -EBUSY)
-- 
2.30.2


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

* [PATCH 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_*
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (3 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 06/18] crypto: rsa: Start moving RSA common code to rsa-common Varad Gautam
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Use generic naming to share with other padding scheme implementations.
These will be moved out of rsa-pkcs1pad.c.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-pkcs1pad.c | 62 +++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 6329c79316d2..e76fc98a537a 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -88,17 +88,17 @@ static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
 	return NULL;
 }
 
-struct pkcs1pad_ctx {
+struct rsapad_tfm_ctx {
 	struct crypto_akcipher *child;
 	unsigned int key_size;
 };
 
-struct pkcs1pad_inst_ctx {
+struct rsapad_inst_ctx {
 	struct crypto_akcipher_spawn spawn;
 	const struct rsa_asn1_template *digest_info;
 };
 
-struct pkcs1pad_request {
+struct rsapad_akciper_req_ctx {
 	struct scatterlist in_sg[2], out_sg[1];
 	uint8_t *in_buf, *out_buf;
 	struct akcipher_request child_req;
@@ -107,7 +107,7 @@ struct pkcs1pad_request {
 static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 		unsigned int keylen)
 {
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
 	int err;
 
 	ctx->key_size = 0;
@@ -128,7 +128,7 @@ static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
 		unsigned int keylen)
 {
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
 	int err;
 
 	ctx->key_size = 0;
@@ -148,7 +148,7 @@ static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
 
 static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
 {
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
 
 	/*
 	 * The maximum destination buffer size for the encrypt/sign operations
@@ -195,8 +195,8 @@ static void rsapad_akcipher_setup_child(struct akcipher_request *req,
 					crypto_completion_t cb)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 
 	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
 	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
@@ -206,8 +206,8 @@ static void rsapad_akcipher_setup_child(struct akcipher_request *req,
 static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	unsigned int pad_len;
 	unsigned int len;
 	u8 *out_buf;
@@ -252,8 +252,8 @@ static void pkcs1pad_encrypt_sign_complete_cb(
 static int pkcs1pad_encrypt(struct akcipher_request *req)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	int err;
 	unsigned int i, ps_end;
 
@@ -297,8 +297,8 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
 static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	unsigned int dst_len;
 	unsigned int pos;
 	u8 *out_buf;
@@ -357,8 +357,8 @@ static void pkcs1pad_decrypt_complete_cb(
 static int pkcs1pad_decrypt(struct akcipher_request *req)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	int err;
 
 	if (!ctx->key_size || req->src_len != ctx->key_size)
@@ -386,10 +386,10 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
 static int pkcs1pad_sign(struct akcipher_request *req)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
-	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
 	const struct rsa_asn1_template *digest_info = ictx->digest_info;
 	int err;
 	unsigned int ps_end, digest_size = 0;
@@ -440,10 +440,10 @@ static int pkcs1pad_sign(struct akcipher_request *req)
 static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
-	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
 	const struct rsa_asn1_template *digest_info = ictx->digest_info;
 	unsigned int dst_len;
 	unsigned int pos;
@@ -528,8 +528,8 @@ static void pkcs1pad_verify_complete_cb(
 static int pkcs1pad_verify(struct akcipher_request *req)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
 	int err;
 
 	if (WARN_ON(req->dst) ||
@@ -559,8 +559,8 @@ static int pkcs1pad_verify(struct akcipher_request *req)
 static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
 {
 	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
-	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
 	struct crypto_akcipher *child_tfm;
 
 	child_tfm = crypto_spawn_akcipher(&ictx->spawn);
@@ -573,14 +573,14 @@ static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
 
 static void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
 {
-	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
 
 	crypto_free_akcipher(ctx->child);
 }
 
 static void rsapad_akcipher_free(struct akcipher_instance *inst)
 {
-	struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst);
+	struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst);
 	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
 
 	crypto_drop_akcipher(spawn);
@@ -605,7 +605,7 @@ static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **
 {
 	u32 mask;
 	struct akcipher_instance *inst;
-	struct pkcs1pad_inst_ctx *ctx;
+	struct rsapad_inst_ctx *ctx;
 	struct akcipher_alg *rsa_alg;
 	const char *hash_name;
 	int err;
@@ -661,7 +661,7 @@ static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **
 	}
 
 	inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
-	inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
+	inst->alg.base.cra_ctxsize = sizeof(struct rsapad_tfm_ctx);
 
 	inst->alg.init = alg->init;
 	inst->alg.exit = alg->exit;
@@ -673,7 +673,7 @@ static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **
 	inst->alg.set_pub_key = alg->set_pub_key;
 	inst->alg.set_priv_key = alg->set_priv_key;
 	inst->alg.max_size = alg->max_size;
-	inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
+	inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
 
 	inst->free = rsapad_akcipher_free;
 
-- 
2.30.2


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

* [PATCH 06/18] crypto: rsa: Start moving RSA common code to rsa-common
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (4 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_* Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 07/18] crypto: rsa: Move more " Varad Gautam
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Move out helpers from rsa-pkcs1pad.c which will be shared across
rsa-*pad implementations.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/Makefile                      |  1 +
 crypto/rsa-common.c                  | 76 ++++++++++++++++++++++
 crypto/rsa-pkcs1pad.c                | 97 +---------------------------
 include/crypto/internal/rsa-common.h | 37 +++++++++++
 4 files changed, 115 insertions(+), 96 deletions(-)
 create mode 100644 crypto/rsa-common.c
 create mode 100644 include/crypto/internal/rsa-common.h

diff --git a/crypto/Makefile b/crypto/Makefile
index cf23affb1678..57a85b2b3429 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -39,6 +39,7 @@ rsa_generic-y := rsapubkey.asn1.o
 rsa_generic-y += rsaprivkey.asn1.o
 rsa_generic-y += rsa.o
 rsa_generic-y += rsa_helper.o
+rsa_generic-y += rsa-common.o
 rsa_generic-y += rsa-pkcs1pad.o
 obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
 
diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
new file mode 100644
index 000000000000..60073c56e374
--- /dev/null
+++ b/crypto/rsa-common.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2015  Intel Corporation
+ * Copyright (C) 2021 SUSE
+ *
+ */
+
+#include <crypto/internal/rsa-common.h>
+
+/*
+ * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
+ */
+static const u8 rsa_digest_info_md5[] = {
+	0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
+	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
+	0x05, 0x00, 0x04, 0x10
+};
+
+static const u8 rsa_digest_info_sha1[] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+	0x2b, 0x0e, 0x03, 0x02, 0x1a,
+	0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 rsa_digest_info_rmd160[] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+	0x2b, 0x24, 0x03, 0x02, 0x01,
+	0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 rsa_digest_info_sha224[] = {
+	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
+	0x05, 0x00, 0x04, 0x1c
+};
+
+static const u8 rsa_digest_info_sha256[] = {
+	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+	0x05, 0x00, 0x04, 0x20
+};
+
+static const u8 rsa_digest_info_sha384[] = {
+	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
+	0x05, 0x00, 0x04, 0x30
+};
+
+static const u8 rsa_digest_info_sha512[] = {
+	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+	0x05, 0x00, 0x04, 0x40
+};
+
+static const struct rsa_asn1_template rsa_asn1_templates[] = {
+#define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }
+	_(md5),
+	_(sha1),
+	_(rmd160),
+	_(sha256),
+	_(sha384),
+	_(sha512),
+	_(sha224),
+	{ NULL }
+#undef _
+};
+
+const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
+{
+	const struct rsa_asn1_template *p;
+
+	for (p = rsa_asn1_templates; p->name; p++)
+		if (strcmp(name, p->name) == 0)
+			return p;
+	return NULL;
+}
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index e76fc98a537a..ffb7220b3d10 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -5,104 +5,9 @@
  * Copyright (c) 2015  Intel Corporation
  */
 
-#include <crypto/algapi.h>
-#include <crypto/akcipher.h>
-#include <crypto/internal/akcipher.h>
-#include <crypto/internal/rsa.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
+#include <crypto/internal/rsa-common.h>
 #include <linux/module.h>
 #include <linux/random.h>
-#include <linux/scatterlist.h>
-
-/*
- * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
- */
-static const u8 rsa_digest_info_md5[] = {
-	0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
-	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
-	0x05, 0x00, 0x04, 0x10
-};
-
-static const u8 rsa_digest_info_sha1[] = {
-	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-	0x2b, 0x0e, 0x03, 0x02, 0x1a,
-	0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 rsa_digest_info_rmd160[] = {
-	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-	0x2b, 0x24, 0x03, 0x02, 0x01,
-	0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 rsa_digest_info_sha224[] = {
-	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
-	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
-	0x05, 0x00, 0x04, 0x1c
-};
-
-static const u8 rsa_digest_info_sha256[] = {
-	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
-	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-	0x05, 0x00, 0x04, 0x20
-};
-
-static const u8 rsa_digest_info_sha384[] = {
-	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
-	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
-	0x05, 0x00, 0x04, 0x30
-};
-
-static const u8 rsa_digest_info_sha512[] = {
-	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
-	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
-	0x05, 0x00, 0x04, 0x40
-};
-
-static const struct rsa_asn1_template {
-	const char	*name;
-	const u8	*data;
-	size_t		size;
-} rsa_asn1_templates[] = {
-#define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }
-	_(md5),
-	_(sha1),
-	_(rmd160),
-	_(sha256),
-	_(sha384),
-	_(sha512),
-	_(sha224),
-	{ NULL }
-#undef _
-};
-
-static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
-{
-	const struct rsa_asn1_template *p;
-
-	for (p = rsa_asn1_templates; p->name; p++)
-		if (strcmp(name, p->name) == 0)
-			return p;
-	return NULL;
-}
-
-struct rsapad_tfm_ctx {
-	struct crypto_akcipher *child;
-	unsigned int key_size;
-};
-
-struct rsapad_inst_ctx {
-	struct crypto_akcipher_spawn spawn;
-	const struct rsa_asn1_template *digest_info;
-};
-
-struct rsapad_akciper_req_ctx {
-	struct scatterlist in_sg[2], out_sg[1];
-	uint8_t *in_buf, *out_buf;
-	struct akcipher_request child_req;
-};
 
 static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 		unsigned int keylen)
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
new file mode 100644
index 000000000000..ecdce0cdafaa
--- /dev/null
+++ b/include/crypto/internal/rsa-common.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2015  Intel Corporation
+ * Copyright (C) 2021 SUSE
+ *
+ */
+#ifndef _RSA_COMMON_
+#define _RSA_COMMON_
+
+#include <crypto/algapi.h>
+#include <crypto/internal/akcipher.h>
+#include <linux/scatterlist.h>
+
+struct rsa_asn1_template {
+	const char	*name;
+	const u8	*data;
+	size_t		size;
+};
+const struct rsa_asn1_template *rsa_lookup_asn1(const char *name);
+
+struct rsapad_tfm_ctx {
+	struct crypto_akcipher *child;
+	unsigned int key_size;
+};
+
+struct rsapad_inst_ctx {
+	struct crypto_akcipher_spawn spawn;
+	const struct rsa_asn1_template *digest_info;
+};
+
+struct rsapad_akciper_req_ctx {
+	struct scatterlist in_sg[2], out_sg[1];
+	uint8_t *in_buf, *out_buf;
+	struct akcipher_request child_req;
+};
+
+#endif
-- 
2.30.2


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

* [PATCH 07/18] crypto: rsa: Move more common code to rsa-common
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (5 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 06/18] crypto: rsa: Start moving RSA common code to rsa-common Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback " Varad Gautam
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Move helpers for setting public/private keys, RSA akcipher
instance setup, keysize querying etc. to rsa-common.c.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-common.c                  | 183 +++++++++++++++++++++++++++
 crypto/rsa-pkcs1pad.c                | 183 ---------------------------
 include/crypto/internal/rsa-common.h |  13 ++
 3 files changed, 196 insertions(+), 183 deletions(-)

diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
index 60073c56e374..d70d7d405165 100644
--- a/crypto/rsa-common.c
+++ b/crypto/rsa-common.c
@@ -74,3 +74,186 @@ const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
 			return p;
 	return NULL;
 }
+
+int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+		       unsigned int keylen)
+{
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	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;
+	return 0;
+}
+
+int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+			unsigned int keylen)
+{
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	int err;
+
+	ctx->key_size = 0;
+
+	err = crypto_akcipher_set_priv_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;
+	return 0;
+}
+
+unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
+{
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	/*
+	 * The maximum destination buffer size for the encrypt/sign operations
+	 * will be the same as for RSA, even though it's smaller for
+	 * decrypt/verify.
+	 */
+
+	return ctx->key_size;
+}
+
+void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
+				size_t len, struct scatterlist *next)
+{
+	int nsegs = next ? 2 : 1;
+
+	sg_init_table(sg, nsegs);
+	sg_set_buf(sg, buf, len);
+
+	if (next)
+		sg_chain(sg, nsegs, next);
+}
+
+int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
+{
+	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	struct rsapad_tfm_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;
+}
+
+void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	crypto_free_akcipher(ctx->child);
+}
+
+void rsapad_akcipher_free(struct akcipher_instance *inst)
+{
+	struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst);
+	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
+
+	crypto_drop_akcipher(spawn);
+	kfree(inst);
+}
+
+int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
+			   struct akcipher_alg *alg)
+{
+	u32 mask;
+	struct akcipher_instance *inst;
+	struct rsapad_inst_ctx *ctx;
+	struct akcipher_alg *rsa_alg;
+	const char *hash_name;
+	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;
+	hash_name = crypto_attr_alg_name(tb[2]);
+	if (IS_ERR(hash_name)) {
+		if (snprintf(inst->alg.base.cra_name,
+			     CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
+			     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, "%s(%s)", tmpl->name,
+			     rsa_alg->base.cra_driver_name) >=
+			     CRYPTO_MAX_ALG_NAME)
+			goto err_free_inst;
+	} else {
+		ctx->digest_info = rsa_lookup_asn1(hash_name);
+		if (!ctx->digest_info) {
+			err = -EINVAL;
+			goto err_free_inst;
+		}
+
+		if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
+			     "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name,
+			     hash_name) >= CRYPTO_MAX_ALG_NAME)
+			goto err_free_inst;
+
+		if (snprintf(inst->alg.base.cra_driver_name,
+			     CRYPTO_MAX_ALG_NAME, "%s(%s,%s)",
+			     tmpl->name,
+			     rsa_alg->base.cra_driver_name,
+			     hash_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 rsapad_tfm_ctx);
+
+	inst->alg.init = alg->init;
+	inst->alg.exit = alg->exit;
+
+	inst->alg.encrypt = alg->encrypt;
+	inst->alg.decrypt = alg->decrypt;
+	inst->alg.sign = alg->sign;
+	inst->alg.verify = alg->verify;
+	inst->alg.set_pub_key = alg->set_pub_key;
+	inst->alg.set_priv_key = alg->set_priv_key;
+	inst->alg.max_size = alg->max_size;
+	inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
+
+	inst->free = rsapad_akcipher_free;
+
+	err = akcipher_register_instance(tmpl, inst);
+	if (err) {
+err_free_inst:
+		rsapad_akcipher_free(inst);
+	}
+	return err;
+}
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index ffb7220b3d10..30b0193b7352 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -9,73 +9,6 @@
 #include <linux/module.h>
 #include <linux/random.h>
 
-static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
-		unsigned int keylen)
-{
-	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-	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 -ENOTSUPP;
-
-	ctx->key_size = err;
-	return 0;
-}
-
-static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
-		unsigned int keylen)
-{
-	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-	int err;
-
-	ctx->key_size = 0;
-
-	err = crypto_akcipher_set_priv_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 -ENOTSUPP;
-
-	ctx->key_size = err;
-	return 0;
-}
-
-static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
-{
-	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-
-	/*
-	 * The maximum destination buffer size for the encrypt/sign operations
-	 * will be the same as for RSA, even though it's smaller for
-	 * decrypt/verify.
-	 */
-
-	return ctx->key_size;
-}
-
-static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
-				       size_t len, struct scatterlist *next)
-{
-	int nsegs = next ? 2 : 1;
-
-	sg_init_table(sg, nsegs);
-	sg_set_buf(sg, buf, len);
-
-	if (next)
-		sg_chain(sg, nsegs, next);
-}
-
 typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
 static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
 					 int err, rsa_akcipher_complete_cb cb)
@@ -461,37 +394,6 @@ static int pkcs1pad_verify(struct akcipher_request *req)
 	return err;
 }
 
-static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
-{
-	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
-	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
-	struct rsapad_tfm_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 rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
-{
-	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-
-	crypto_free_akcipher(ctx->child);
-}
-
-static void rsapad_akcipher_free(struct akcipher_instance *inst)
-{
-	struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst);
-	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
-
-	crypto_drop_akcipher(spawn);
-	kfree(inst);
-}
-
 static struct akcipher_alg pkcs1pad_alg = {
 	.init = rsapad_akcipher_init_tfm,
 	.exit = rsapad_akcipher_exit_tfm,
@@ -505,91 +407,6 @@ static struct akcipher_alg pkcs1pad_alg = {
 	.max_size = rsapad_get_max_size
 };
 
-static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
-				  struct akcipher_alg *alg)
-{
-	u32 mask;
-	struct akcipher_instance *inst;
-	struct rsapad_inst_ctx *ctx;
-	struct akcipher_alg *rsa_alg;
-	const char *hash_name;
-	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;
-	hash_name = crypto_attr_alg_name(tb[2]);
-	if (IS_ERR(hash_name)) {
-		if (snprintf(inst->alg.base.cra_name,
-			     CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
-			     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, "%s(%s)", tmpl->name,
-			     rsa_alg->base.cra_driver_name) >=
-			     CRYPTO_MAX_ALG_NAME)
-			goto err_free_inst;
-	} else {
-		ctx->digest_info = rsa_lookup_asn1(hash_name);
-		if (!ctx->digest_info) {
-			err = -EINVAL;
-			goto err_free_inst;
-		}
-
-		if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
-			     "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name,
-			     hash_name) >= CRYPTO_MAX_ALG_NAME)
-			goto err_free_inst;
-
-		if (snprintf(inst->alg.base.cra_driver_name,
-			     CRYPTO_MAX_ALG_NAME, "%s(%s,%s)",
-			     tmpl->name,
-			     rsa_alg->base.cra_driver_name,
-			     hash_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 rsapad_tfm_ctx);
-
-	inst->alg.init = alg->init;
-	inst->alg.exit = alg->exit;
-
-	inst->alg.encrypt = alg->encrypt;
-	inst->alg.decrypt = alg->decrypt;
-	inst->alg.sign = alg->sign;
-	inst->alg.verify = alg->verify;
-	inst->alg.set_pub_key = alg->set_pub_key;
-	inst->alg.set_priv_key = alg->set_priv_key;
-	inst->alg.max_size = alg->max_size;
-	inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
-
-	inst->free = rsapad_akcipher_free;
-
-	err = akcipher_register_instance(tmpl, inst);
-	if (err) {
-err_free_inst:
-		rsapad_akcipher_free(inst);
-	}
-	return err;
-}
-
 static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
 {
 	return rsapad_akcipher_create(tmpl, tb, &pkcs1pad_alg);
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
index ecdce0cdafaa..a6f20cce610a 100644
--- a/include/crypto/internal/rsa-common.h
+++ b/include/crypto/internal/rsa-common.h
@@ -34,4 +34,17 @@ struct rsapad_akciper_req_ctx {
 	struct akcipher_request child_req;
 };
 
+int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+		       unsigned int keylen);
+int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+			unsigned int keylen);
+unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm);
+void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
+				size_t len, struct scatterlist *next);
+int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm);
+void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm);
+void rsapad_akcipher_free(struct akcipher_instance *inst);
+int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
+			   struct akcipher_alg *alg);
+
 #endif
-- 
2.30.2


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

* [PATCH 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback to rsa-common
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (6 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 07/18] crypto: rsa: Move more " Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 09/18] crypto: Extend akcipher API to pass signature parameters Varad Gautam
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Pull out more common code from rsa-pkcs1pad into rsa-common.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-common.c                  | 31 +++++++++++++++++++++++++++
 crypto/rsa-pkcs1pad.c                | 32 ----------------------------
 include/crypto/internal/rsa-common.h |  9 ++++++++
 3 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
index d70d7d405165..6ed258a78287 100644
--- a/crypto/rsa-common.c
+++ b/crypto/rsa-common.c
@@ -75,6 +75,37 @@ const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
 	return NULL;
 }
 
+void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
+				  int err, rsa_akcipher_complete_cb cb)
+{
+	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, cb(req, err));
+}
+
+void rsapad_akcipher_setup_child(struct akcipher_request *req,
+				 struct scatterlist *src_sg,
+				 struct scatterlist *dst_sg,
+				 unsigned int src_len,
+				 unsigned int dst_len,
+				 crypto_completion_t cb)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
+
+	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
+	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
+	akcipher_request_set_crypt(&req_ctx->child_req, src_sg, dst_sg, src_len, dst_len);
+}
+
 int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 		       unsigned int keylen)
 {
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 30b0193b7352..6fa207732fcb 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -9,38 +9,6 @@
 #include <linux/module.h>
 #include <linux/random.h>
 
-typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
-static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
-					 int err, rsa_akcipher_complete_cb cb)
-{
-	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, cb(req, err));
-}
-
-static void rsapad_akcipher_setup_child(struct akcipher_request *req,
-					struct scatterlist *src_sg,
-					struct scatterlist *dst_sg,
-					unsigned int src_len,
-					unsigned int dst_len,
-					crypto_completion_t cb)
-{
-	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
-
-	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
-	akcipher_request_set_crypt(&req_ctx->child_req, src_sg, dst_sg, src_len, dst_len);
-}
-
 static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
index a6f20cce610a..4fa3cf5a989c 100644
--- a/include/crypto/internal/rsa-common.h
+++ b/include/crypto/internal/rsa-common.h
@@ -34,6 +34,15 @@ struct rsapad_akciper_req_ctx {
 	struct akcipher_request child_req;
 };
 
+typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
+void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
+				  int err, rsa_akcipher_complete_cb cb);
+void rsapad_akcipher_setup_child(struct akcipher_request *req,
+				 struct scatterlist *src_sg,
+				 struct scatterlist *dst_sg,
+				 unsigned int src_len,
+				 unsigned int dst_len,
+				 crypto_completion_t cb);
 int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 		       unsigned int keylen);
 int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
-- 
2.30.2


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

* [PATCH 09/18] crypto: Extend akcipher API to pass signature parameters
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (7 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback " Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h Varad Gautam
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

For certain signature encoding schemes (eg. RSASSA-PSS), the
verify/sign operation behavior depends on information contained in
the signature blob. Allow passing this down to the crypto_template by
introducing a crypto_akcipher_set_sig_params() call.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-common.c       |  1 +
 include/crypto/akcipher.h | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
index 6ed258a78287..f80cdfcc1f9e 100644
--- a/crypto/rsa-common.c
+++ b/crypto/rsa-common.c
@@ -277,6 +277,7 @@ int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
 	inst->alg.set_pub_key = alg->set_pub_key;
 	inst->alg.set_priv_key = alg->set_priv_key;
 	inst->alg.max_size = alg->max_size;
+	inst->alg.set_sig_params = alg->set_sig_params;
 	inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
 
 	inst->free = rsapad_akcipher_free;
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 1d3aa252caba..a0e872029429 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -101,6 +101,8 @@ struct akcipher_alg {
 	unsigned int (*max_size)(struct crypto_akcipher *tfm);
 	int (*init)(struct crypto_akcipher *tfm);
 	void (*exit)(struct crypto_akcipher *tfm);
+	int (*set_sig_params)(struct crypto_akcipher *tfm, const void *sig,
+			      unsigned int sig_len);
 
 	unsigned int reqsize;
 	struct crypto_alg base;
@@ -413,4 +415,28 @@ static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,
 
 	return alg->set_priv_key(tfm, key, keylen);
 }
+
+/**
+ * crypto_akcipher_set_sig_params() - Invoke set sig params operation
+ *
+ * Use this if the verification/signing operation behavior depends on
+ * parameters contained in the signature.
+ *
+ * @tfm:	tfm handle
+ * @sig:	ptr to a struct public_key_signature to extract info from
+ * @siglen:	Length of sig - should be unnecessary if you pass the struct.
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_set_sig_params(struct crypto_akcipher *tfm,
+						 const void *sig,
+						 unsigned int siglen)
+{
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	if (alg->set_sig_params)
+		return alg->set_sig_params(tfm, sig, siglen);
+	else
+		return -EOPNOTSUPP;
+}
 #endif
-- 
2.30.2


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

* [PATCH 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (8 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 09/18] crypto: Extend akcipher API to pass signature parameters Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 11/18] crypto: Scaffolding for RSA-PSS signature style Varad Gautam
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

The RSASSA-PSS signature scheme requires knowing the RSA modulus size
in bits. The rsa akcipher_alg max_size call is insufficient for this,
as the returned keysize is rounded up to the next byte.

Since the RSA modulus is stored as an MPI accessible via
struct rsa_mpi_key, move the struct definition to rsa.h to help RSA
sub-implementations query the MPI values.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa.c                  | 6 ------
 include/crypto/internal/rsa.h | 7 +++++++
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4cdbec95d077..5c4eece5b802 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -12,12 +12,6 @@
 #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;
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index e870133f4b77..e73c61f788e6 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -7,6 +7,7 @@
  */
 #ifndef _RSA_HELPER_
 #define _RSA_HELPER_
+#include <linux/mpi.h>
 #include <linux/types.h>
 
 /**
@@ -53,5 +54,11 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
 int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
 		       unsigned int key_len);
 
+struct rsa_mpi_key {
+	MPI n;
+	MPI e;
+	MPI d;
+};
+
 extern struct crypto_template rsa_pkcs1pad_tmpl;
 #endif
-- 
2.30.2


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

* [PATCH 11/18] crypto: Scaffolding for RSA-PSS signature style
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (9 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers Varad Gautam
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Add a crypto_template for rsa-psspad, hidden behind
CONFIG_CRYPTO_RSASSA_PSS. Set the sign/verify/encrypt/decrypt
operations to return -EOPNOTSUPP, to be implemented in the future

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/Kconfig                |  6 ++++++
 crypto/Makefile               |  1 +
 crypto/rsa-psspad.c           | 39 +++++++++++++++++++++++++++++++++++
 crypto/rsa.c                  | 20 +++++++++++++++---
 include/crypto/internal/rsa.h |  3 +++
 5 files changed, 66 insertions(+), 3 deletions(-)
 create mode 100644 crypto/rsa-psspad.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 5809cc198fa7..3aedb40aa08f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -224,6 +224,12 @@ config CRYPTO_RSA
 	help
 	  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_RSASSA_PSS
+	bool "RSASSA-PSS algorithm"
+	select CRYPTO_RSA
+	help
+	  RSASSA-PSS signature verification scheme.
+
 config CRYPTO_DH
 	tristate "Diffie-Hellman algorithm"
 	select CRYPTO_KPP
diff --git a/crypto/Makefile b/crypto/Makefile
index 57a85b2b3429..88be24b9bcb2 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -42,6 +42,7 @@ rsa_generic-y += rsa_helper.o
 rsa_generic-y += rsa-common.o
 rsa_generic-y += rsa-pkcs1pad.o
 obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+obj-$(CONFIG_CRYPTO_RSASSA_PSS) += rsa-psspad.o
 
 $(obj)/sm2signature.asn1.o: $(obj)/sm2signature.asn1.c $(obj)/sm2signature.asn1.h
 $(obj)/sm2.o: $(obj)/sm2signature.asn1.h
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
new file mode 100644
index 000000000000..0e5422b05c08
--- /dev/null
+++ b/crypto/rsa-psspad.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RSASSA-PSS signature scheme.
+ *
+ * Copyright (C) 2021, SUSE
+ * Authors: Varad Gautam <varad.gautam@suse.com>
+ */
+
+#include <crypto/internal/akcipher.h>
+#include <crypto/internal/rsa-common.h>
+
+static int psspad_s_v_e_d(struct akcipher_request *req)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct akcipher_alg psspad_alg = {
+	.init = rsapad_akcipher_init_tfm,
+	.exit = rsapad_akcipher_exit_tfm,
+
+	.encrypt = psspad_s_v_e_d,
+	.decrypt = psspad_s_v_e_d,
+	.sign = psspad_s_v_e_d,
+	.verify = psspad_s_v_e_d,
+	.set_pub_key = rsapad_set_pub_key,
+	.set_priv_key = rsapad_set_priv_key,
+	.max_size = rsapad_get_max_size
+};
+
+static int psspad_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+	return rsapad_akcipher_create(tmpl, tb, &psspad_alg);
+}
+
+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 5c4eece5b802..de4ad34f9cd9 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -258,17 +258,31 @@ static int rsa_init(void)
 		return err;
 
 	err = crypto_register_template(&rsa_pkcs1pad_tmpl);
+	if (err)
+		goto out_err;
+
+#ifdef CONFIG_CRYPTO_RSASSA_PSS
+	err = crypto_register_template(&rsa_psspad_tmpl);
 	if (err) {
-		crypto_unregister_akcipher(&rsa);
-		return err;
+		crypto_unregister_template(&rsa_pkcs1pad_tmpl);
+		goto out_err;
 	}
+#endif
 
-	return 0;
+	goto out;
+
+out_err:
+	crypto_unregister_akcipher(&rsa);
+out:
+	return err;
 }
 
 static void rsa_exit(void)
 {
 	crypto_unregister_template(&rsa_pkcs1pad_tmpl);
+#ifdef CONFIG_CRYPTO_RSASSA_PSS
+	crypto_unregister_template(&rsa_psspad_tmpl);
+#endif
 	crypto_unregister_akcipher(&rsa);
 }
 
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index e73c61f788e6..4c168ea2f050 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -61,4 +61,7 @@ struct rsa_mpi_key {
 };
 
 extern struct crypto_template rsa_pkcs1pad_tmpl;
+#ifdef CONFIG_CRYPTO_RSASSA_PSS
+extern struct crypto_template rsa_psspad_tmpl;
+#endif /* CONFIG_CRYPTO_RSASSA_PSS */
 #endif
-- 
2.30.2


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

* [PATCH 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (10 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 11/18] crypto: Scaffolding for RSA-PSS signature style Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 13/18] crypto: rsa-psspad: Get signature salt length from a given signature Varad Gautam
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

RSASSA-PSS verify operation needs to compute digests for its
Mask Generation Function (MGF1), and for digest comparison.

Add helpers to populate a crypto_shash and desc for use in both cases.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-psspad.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 0e5422b05c08..855e82ca071a 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -6,9 +6,33 @@
  * Authors: Varad Gautam <varad.gautam@suse.com>
  */
 
+#include <crypto/hash.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/internal/rsa-common.h>
 
+static int psspad_setup_shash(struct crypto_shash **hash_tfm, struct shash_desc **desc,
+			      const char *hash_algo)
+{
+	*hash_tfm = crypto_alloc_shash(hash_algo, 0, 0);
+	if (IS_ERR(*hash_tfm))
+		return PTR_ERR(*hash_tfm);
+
+	*desc = kzalloc(crypto_shash_descsize(*hash_tfm) + sizeof(**desc),
+			GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	(*desc)->tfm = *hash_tfm;
+
+	return 0;
+}
+
+static void psspad_free_shash(struct crypto_shash *hash_tfm, struct shash_desc *desc)
+{
+	kfree(desc);
+	crypto_free_shash(hash_tfm);
+}
+
 static int psspad_s_v_e_d(struct akcipher_request *req)
 {
 	return -EOPNOTSUPP;
-- 
2.30.2


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

* [PATCH 13/18] crypto: rsa-psspad: Get signature salt length from a given signature
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (11 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS Varad Gautam
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Implement akcipher_alg->set_sig_params for rsassa-psspad to receive the
salt length for the signature being verified.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-psspad.c                  | 20 +++++++++++++++++++-
 include/crypto/internal/rsa-common.h |  1 +
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 855e82ca071a..bb8052821982 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -9,6 +9,7 @@
 #include <crypto/hash.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/internal/rsa-common.h>
+#include <crypto/public_key.h>
 
 static int psspad_setup_shash(struct crypto_shash **hash_tfm, struct shash_desc **desc,
 			      const char *hash_algo)
@@ -33,6 +34,22 @@ static void psspad_free_shash(struct crypto_shash *hash_tfm, struct shash_desc *
 	crypto_free_shash(hash_tfm);
 }
 
+static int psspad_set_sig_params(struct crypto_akcipher *tfm,
+				 const void *sig,
+				 unsigned int siglen)
+{
+	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	const struct public_key_signature *s = sig;
+
+	if (!sig)
+		return -EINVAL;
+
+	ictx->salt_len = s->salt_length;
+
+	return 0;
+}
+
 static int psspad_s_v_e_d(struct akcipher_request *req)
 {
 	return -EOPNOTSUPP;
@@ -48,7 +65,8 @@ static struct akcipher_alg psspad_alg = {
 	.verify = psspad_s_v_e_d,
 	.set_pub_key = rsapad_set_pub_key,
 	.set_priv_key = rsapad_set_priv_key,
-	.max_size = rsapad_get_max_size
+	.max_size = rsapad_get_max_size,
+	.set_sig_params = psspad_set_sig_params
 };
 
 static int psspad_create(struct crypto_template *tmpl, struct rtattr **tb)
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
index 4fa3cf5a989c..84c63830577e 100644
--- a/include/crypto/internal/rsa-common.h
+++ b/include/crypto/internal/rsa-common.h
@@ -26,6 +26,7 @@ struct rsapad_tfm_ctx {
 struct rsapad_inst_ctx {
 	struct crypto_akcipher_spawn spawn;
 	const struct rsa_asn1_template *digest_info;
+	u16 salt_len;
 };
 
 struct rsapad_akciper_req_ctx {
-- 
2.30.2


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

* [PATCH 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (12 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 13/18] crypto: rsa-psspad: Get signature salt length from a given signature Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 15/18] crypto: rsa-psspad: Provide PSS signature verify operation Varad Gautam
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

This generates a "mask" byte array of size mask_len bytes as a
concatenation of digests, where each digest is calculated on a
concatenation of an input seed and a running counter to fill up
mask_len bytes - as described by RFC8017 sec B.2.1. "MGF1".

The mask is useful for RSA signing/verification process with
encoding RSASSA-PSS.

Reference: https://tools.ietf.org/html/rfc8017#appendix-B.2.1
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-psspad.c | 54 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index bb8052821982..46578b8b14b1 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -50,6 +50,60 @@ static int psspad_set_sig_params(struct crypto_akcipher *tfm,
 	return 0;
 }
 
+/* MGF1 per RFC8017 B.2.1. */
+static int pkcs1_mgf1(u8 *seed, unsigned int seed_len,
+		      struct shash_desc *desc,
+		      u8 *mask, unsigned int mask_len)
+{
+	unsigned int pos, h_len, i, c;
+	u8 *tmp;
+	int ret = 0;
+
+	h_len = crypto_shash_digestsize(desc->tfm);
+
+	pos = i = 0;
+	while ((i < (mask_len / h_len) + 1) && pos < mask_len) {
+		/* Compute T = T || Hash(mgfSeed || C) into mask at pos. */
+		c = cpu_to_be32(i);
+
+		ret = crypto_shash_init(desc);
+		if (ret < 0)
+			goto out_err;
+
+		ret = crypto_shash_update(desc, seed, seed_len);
+		if (ret < 0)
+			goto out_err;
+
+		ret = crypto_shash_update(desc, (u8 *) &c, sizeof(c));
+		if (ret < 0)
+			goto out_err;
+
+		if (mask_len - pos >= h_len) {
+			ret = crypto_shash_final(desc, mask + pos);
+			pos += h_len;
+		} else {
+			tmp = kzalloc(h_len, GFP_KERNEL);
+			if (!tmp) {
+				ret = -ENOMEM;
+				goto out_err;
+			}
+			ret = crypto_shash_final(desc, tmp);
+			/* copy the last hash */
+			memcpy(mask + pos, tmp, mask_len - pos);
+			kfree(tmp);
+			pos = mask_len;
+		}
+		if (ret < 0) {
+			goto out_err;
+		}
+
+		i++;
+	}
+
+out_err:
+	return ret;
+}
+
 static int psspad_s_v_e_d(struct akcipher_request *req)
 {
 	return -EOPNOTSUPP;
-- 
2.30.2


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

* [PATCH 15/18] crypto: rsa-psspad: Provide PSS signature verify operation
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (13 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 16/18] crypto: rsa-psspad: Implement signature verify callback Varad Gautam
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

Trigger RSA transform on the signature being verified from
psspad_verify, to produce intermediary data which will be handled
in the psspad_verify_complete callback.

Reference: https://tools.ietf.org/html/rfc8017#section-8.1.2
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-psspad.c | 53 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 46578b8b14b1..1ca17b8b93f2 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -104,7 +104,50 @@ static int pkcs1_mgf1(u8 *seed, unsigned int seed_len,
 	return ret;
 }
 
-static int psspad_s_v_e_d(struct akcipher_request *req)
+static int psspad_verify_complete(struct akcipher_request *req, int err)
+{
+	return -EOPNOTSUPP;
+}
+
+static void psspad_verify_complete_cb(struct crypto_async_request *child_async_req,
+				      int err)
+{
+	rsapad_akcipher_req_complete(child_async_req, err,
+				     psspad_verify_complete);
+}
+
+static int psspad_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *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;
+
+	rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
+			    ctx->key_size, NULL);
+
+	/* Reuse input buffer, output to a new buffer */
+	rsapad_akcipher_setup_child(req, req->src, req_ctx->out_sg,
+				    req->src_len, ctx->key_size,
+				    psspad_verify_complete_cb);
+
+	err = crypto_akcipher_encrypt(&req_ctx->child_req);
+	if (err != -EINPROGRESS && err != -EBUSY)
+		return psspad_verify_complete(req, err);
+
+	return err;
+}
+
+static int psspad_s_e_d(struct akcipher_request *req)
 {
 	return -EOPNOTSUPP;
 }
@@ -113,10 +156,10 @@ static struct akcipher_alg psspad_alg = {
 	.init = rsapad_akcipher_init_tfm,
 	.exit = rsapad_akcipher_exit_tfm,
 
-	.encrypt = psspad_s_v_e_d,
-	.decrypt = psspad_s_v_e_d,
-	.sign = psspad_s_v_e_d,
-	.verify = psspad_s_v_e_d,
+	.encrypt = psspad_s_e_d,
+	.decrypt = psspad_s_e_d,
+	.sign = psspad_s_e_d,
+	.verify = psspad_verify,
 	.set_pub_key = rsapad_set_pub_key,
 	.set_priv_key = rsapad_set_priv_key,
 	.max_size = rsapad_get_max_size,
-- 
2.30.2


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

* [PATCH 16/18] crypto: rsa-psspad: Implement signature verify callback
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (14 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 15/18] crypto: rsa-psspad: Provide PSS signature verify operation Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-30 20:28 ` [PATCH 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
  2021-03-30 20:28 ` [PATCH 18/18] keyctl_pkey: Add pkey parameter slen to pass in PSS salt length Varad Gautam
  17 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto; +Cc: Varad Gautam, Herbert Xu, David S. Miller, open list

The RSA output must be processed as per the EMSA-PSS-VERIFY operation
from RFC8017, which forms the core of the PSS signature verification.

Implement the verification callback, which operates on the RSA output
buffer.

Reference: https://tools.ietf.org/html/rfc8017#section-9.1.2
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/rsa-psspad.c | 107 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 106 insertions(+), 1 deletion(-)

diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 1ca17b8b93f2..2ce750c5a23f 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -8,6 +8,7 @@
 
 #include <crypto/hash.h>
 #include <crypto/internal/akcipher.h>
+#include <crypto/internal/rsa.h>
 #include <crypto/internal/rsa-common.h>
 #include <crypto/public_key.h>
 
@@ -106,7 +107,111 @@ static int pkcs1_mgf1(u8 *seed, unsigned int seed_len,
 
 static int psspad_verify_complete(struct akcipher_request *req, int err)
 {
-	return -EOPNOTSUPP;
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
+	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+	struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+	const struct rsa_asn1_template *digest_info = ictx->digest_info;
+	struct crypto_shash *hash_tfm = NULL;
+	struct shash_desc *desc = NULL;
+	struct rsa_mpi_key *pkey = akcipher_tfm_ctx(ctx->child);
+
+	u8 *em, *h, *salt, *maskeddb;
+	unsigned int em_len, em_bits, h_len, s_len, maskeddb_len;
+	u8 *m_hash, *db_mask, *db, *h_;
+	static u8 zeroes[8] = { 0 };
+	unsigned int pos;
+
+	if (err)
+		goto out;
+
+	err = -EINVAL;
+	if (!digest_info)
+		goto out;
+
+	em = req_ctx->out_buf;
+	em_len = ctx->key_size;
+	em_bits = mpi_get_nbits(pkey->n) - 1;
+	if ((em_bits & 0x7) == 0) {
+		em_len--;
+		em++;
+	}
+
+	h_len = req->dst_len;
+	s_len = ictx->salt_len;
+
+	if (em_len < h_len + s_len + 2)
+		goto out;
+
+	if (em[em_len - 1] != 0xbc)
+		goto out;
+
+	maskeddb = em;
+	maskeddb_len = em_len - h_len - 1;
+	h = em + maskeddb_len;
+
+	if (em[0] & ~((u8) 0xff >> (8 * em_len - em_bits)))
+		goto out;
+
+	db_mask = kzalloc(maskeddb_len, GFP_KERNEL);
+	if (!db_mask) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = psspad_setup_shash(&hash_tfm, &desc, digest_info->name);
+	if (err < 0)
+		goto out_db_mask;
+
+	err = pkcs1_mgf1(h, h_len, desc, db_mask, maskeddb_len);
+	if (err < 0)
+		goto out_shash;
+
+	for (pos = 0; pos < maskeddb_len; pos++)
+		maskeddb[pos] ^= db_mask[pos];
+	db = maskeddb;
+
+	db[0] &= ((u8) 0xff >> (8 * em_len - em_bits));
+
+	err = -EINVAL;
+	for (pos = 0; pos < em_len - h_len - s_len - 2; pos++) {
+		if (db[pos] != 0)
+			goto out_shash;
+	}
+	if (db[pos] != 0x01)
+		goto out_shash;
+
+	salt = db + (maskeddb_len - s_len);
+
+	m_hash = req_ctx->out_buf + ctx->key_size;
+	sg_pcopy_to_buffer(req->src,
+			   sg_nents_for_len(req->src, req->src_len + req->dst_len),
+			   m_hash,
+			   req->dst_len, ctx->key_size);
+
+	err = crypto_shash_init(desc);
+	if (!err)
+		err = crypto_shash_update(desc, zeroes, 8);
+	if (!err)
+		err = crypto_shash_update(desc, m_hash, h_len);
+	if (!err)
+		err = crypto_shash_finup(desc, salt, s_len, m_hash);
+	if (err < 0)
+		goto out_shash;
+
+	h_ = m_hash;
+
+	if (memcmp(h_, h, h_len) != 0)
+		err = -EKEYREJECTED;
+
+out_shash:
+	psspad_free_shash(hash_tfm, desc);
+out_db_mask:
+	kfree(db_mask);
+out:
+	kfree_sensitive(req_ctx->out_buf);
+	return err;
 }
 
 static void psspad_verify_complete_cb(struct crypto_async_request *child_async_req,
-- 
2.30.2


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

* [PATCH 17/18] crypto: Accept pss as valid encoding during signature verification
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (15 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 16/18] crypto: rsa-psspad: Implement signature verify callback Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-31 23:14   ` Jarkko Sakkinen
  2021-03-30 20:28 ` [PATCH 18/18] keyctl_pkey: Add pkey parameter slen to pass in PSS salt length Varad Gautam
  17 siblings, 1 reply; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto
  Cc: Varad Gautam, David Howells, Herbert Xu, David S. Miller,
	open list:ASYMMETRIC KEYS, open list

Accept pss encoding for public_key_verify_signature. If
CONFIG_CRYPTO_RSASSA_PSS is disabled, crypto_alloc_akcipher will
fail to find a pss backend anyway.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/asymmetric_keys/public_key.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 788a4ba1e2e7..b9cc83ba7a12 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -69,19 +69,20 @@ int software_key_determine_akcipher(const char *encoding,
 {
 	int n;
 
-	if (strcmp(encoding, "pkcs1") == 0) {
+	if (strcmp(encoding, "pkcs1") == 0 || strcmp(encoding, "pss") == 0) {
 		/* The data wangled by the RSA algorithm is typically padded
 		 * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
-		 * sec 8.2].
+		 * sec 8.2] or EMSA-PSS [RFC8017 sec 9.1].
 		 */
 		if (!hash_algo)
 			n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
-				     "pkcs1pad(%s)",
+				     "%spad(%s)",
+				     encoding,
 				     pkey->pkey_algo);
 		else
 			n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
-				     "pkcs1pad(%s,%s)",
-				     pkey->pkey_algo, hash_algo);
+				     "%spad(%s,%s)",
+				     encoding, pkey->pkey_algo, hash_algo);
 		return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
 	}
 
@@ -363,6 +364,13 @@ int public_key_verify_signature(const struct public_key *pkey,
 			goto error_free_key;
 	}
 
+	if (strcmp(sig->encoding, "pss") == 0) {
+		ret = crypto_akcipher_set_sig_params(tfm, sig, sizeof(*sig));
+		if (ret) {
+			goto error_free_key;
+		}
+	}
+
 	sg_init_table(src_sg, 2);
 	sg_set_buf(&src_sg[0], sig->s, sig->s_size);
 	sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
-- 
2.30.2


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

* [PATCH 18/18] keyctl_pkey: Add pkey parameter slen to pass in PSS salt length
  2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
                   ` (16 preceding siblings ...)
  2021-03-30 20:28 ` [PATCH 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
@ 2021-03-30 20:28 ` Varad Gautam
  2021-03-31 23:13   ` Jarkko Sakkinen
  17 siblings, 1 reply; 27+ messages in thread
From: Varad Gautam @ 2021-03-30 20:28 UTC (permalink / raw)
  To: linux-crypto
  Cc: Varad Gautam, David Howells, Herbert Xu, David S. Miller,
	Jarkko Sakkinen, James Morris, Serge E. Hallyn,
	open list:ASYMMETRIC KEYS, open list,
	open list:SECURITY SUBSYSTEM

keyctl pkey_* operations accept enc and hash parameters at present.
RSASSA-PSS signatures also require passing in the signature salt
length.

Add another parameter 'slen' to feed in salt length of a PSS
signature.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 crypto/asymmetric_keys/asymmetric_type.c | 1 +
 include/linux/keyctl.h                   | 1 +
 security/keys/keyctl_pkey.c              | 6 ++++++
 3 files changed, 8 insertions(+)

diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index ad8af3d70ac0..eb2ef4a07f8e 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -571,6 +571,7 @@ static int asymmetric_key_verify_signature(struct kernel_pkey_params *params,
 		.hash_algo	= params->hash_algo,
 		.digest		= (void *)in,
 		.s		= (void *)in2,
+		.salt_length	= params->slen,
 	};
 
 	return verify_signature(params->key, &sig);
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 5b79847207ef..970c7bed3082 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -37,6 +37,7 @@ struct kernel_pkey_params {
 		__u32	in2_len;	/* 2nd input data size (verify) */
 	};
 	enum kernel_pkey_operation op : 8;
+	__u32		slen;
 };
 
 #endif /* __LINUX_KEYCTL_H */
diff --git a/security/keys/keyctl_pkey.c b/security/keys/keyctl_pkey.c
index 5de0d599a274..b54a021e16b1 100644
--- a/security/keys/keyctl_pkey.c
+++ b/security/keys/keyctl_pkey.c
@@ -24,11 +24,13 @@ enum {
 	Opt_err,
 	Opt_enc,		/* "enc=<encoding>" eg. "enc=oaep" */
 	Opt_hash,		/* "hash=<digest-name>" eg. "hash=sha1" */
+	Opt_slen,		/* "slen=<salt-length>" eg. "slen=32" */
 };
 
 static const match_table_t param_keys = {
 	{ Opt_enc,	"enc=%s" },
 	{ Opt_hash,	"hash=%s" },
+	{ Opt_slen,	"slen=%u" },
 	{ Opt_err,	NULL }
 };
 
@@ -63,6 +65,10 @@ static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
 			params->hash_algo = q;
 			break;
 
+		case Opt_slen:
+			if (kstrtouint(q, 0, &params->slen))
+				return -EINVAL;
+			break;
 		default:
 			return -EINVAL;
 		}
-- 
2.30.2


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

* Re: [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
  2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
@ 2021-03-31  2:10   ` kernel test robot
  2021-04-01  1:09   ` Herbert Xu
  2021-04-07  8:27   ` hongbo li
  2 siblings, 0 replies; 27+ messages in thread
From: kernel test robot @ 2021-03-31  2:10 UTC (permalink / raw)
  To: Varad Gautam, linux-crypto
  Cc: kbuild-all, Varad Gautam, David Howells, Herbert Xu,
	Vitaly Chikunov, Tianjia Zhang, keyrings, linux-kernel

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

Hi Varad,

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-rc5 next-20210330]
[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/Varad-Gautam/Implement-RSASSA-PSS-signature-verification/20210331-043846
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: x86_64-randconfig-s022-20210330 (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/5fa5152bbf75d015ed5e85d2f0631c902bb8fbe0
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Varad-Gautam/Implement-RSASSA-PSS-signature-verification/20210331-043846
        git checkout 5fa5152bbf75d015ed5e85d2f0631c902bb8fbe0
        # 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/asymmetric_keys/x509_cert_parser.c:887:17: sparse: sparse: cast to restricted __be16
>> crypto/asymmetric_keys/x509_cert_parser.c:887:17: sparse: sparse: cast to restricted __be16
>> crypto/asymmetric_keys/x509_cert_parser.c:887:17: sparse: sparse: cast to restricted __be16
>> crypto/asymmetric_keys/x509_cert_parser.c:887:17: sparse: sparse: cast to restricted __be16

vim +887 crypto/asymmetric_keys/x509_cert_parser.c

   873	
   874	int x509_note_salt_length(void *context, size_t hdrlen,
   875				  unsigned char tag,
   876				  const void *value, size_t vlen)
   877	{
   878		struct x509_parse_context *ctx = context;
   879	
   880		if (ctx->last_oid != OID_rsassaPSS)
   881			return -EBADMSG;
   882	
   883		if (!value || !vlen || vlen > sizeof(ctx->cert->sig->salt_length))
   884			return -EINVAL;
   885	
   886		ctx->cert->sig->salt_length = (vlen == 2) ?
 > 887			be16_to_cpu(*((u16 *) value)) : *((u8 *) value);
   888	
   889		return 0;
   890	}
   891	

---
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: 34465 bytes --]

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

* Re: [PATCH 18/18] keyctl_pkey: Add pkey parameter slen to pass in PSS salt length
  2021-03-30 20:28 ` [PATCH 18/18] keyctl_pkey: Add pkey parameter slen to pass in PSS salt length Varad Gautam
@ 2021-03-31 23:13   ` Jarkko Sakkinen
  0 siblings, 0 replies; 27+ messages in thread
From: Jarkko Sakkinen @ 2021-03-31 23:13 UTC (permalink / raw)
  To: Varad Gautam
  Cc: linux-crypto, David Howells, Herbert Xu, David S. Miller,
	James Morris, Serge E. Hallyn, open list:ASYMMETRIC KEYS,
	open list, open list:SECURITY SUBSYSTEM

On Tue, Mar 30, 2021 at 10:28:29PM +0200, Varad Gautam wrote:
> keyctl pkey_* operations accept enc and hash parameters at present.
> RSASSA-PSS signatures also require passing in the signature salt
> length.
> 
> Add another parameter 'slen' to feed in salt length of a PSS
> signature.
> 
> Signed-off-by: Varad Gautam <varad.gautam@suse.com>
> ---


Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

/Jarkko

>  crypto/asymmetric_keys/asymmetric_type.c | 1 +
>  include/linux/keyctl.h                   | 1 +
>  security/keys/keyctl_pkey.c              | 6 ++++++
>  3 files changed, 8 insertions(+)
> 
> diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
> index ad8af3d70ac0..eb2ef4a07f8e 100644
> --- a/crypto/asymmetric_keys/asymmetric_type.c
> +++ b/crypto/asymmetric_keys/asymmetric_type.c
> @@ -571,6 +571,7 @@ static int asymmetric_key_verify_signature(struct kernel_pkey_params *params,
>  		.hash_algo	= params->hash_algo,
>  		.digest		= (void *)in,
>  		.s		= (void *)in2,
> +		.salt_length	= params->slen,
>  	};
>  
>  	return verify_signature(params->key, &sig);
> diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
> index 5b79847207ef..970c7bed3082 100644
> --- a/include/linux/keyctl.h
> +++ b/include/linux/keyctl.h
> @@ -37,6 +37,7 @@ struct kernel_pkey_params {
>  		__u32	in2_len;	/* 2nd input data size (verify) */
>  	};
>  	enum kernel_pkey_operation op : 8;
> +	__u32		slen;
>  };
>  
>  #endif /* __LINUX_KEYCTL_H */
> diff --git a/security/keys/keyctl_pkey.c b/security/keys/keyctl_pkey.c
> index 5de0d599a274..b54a021e16b1 100644
> --- a/security/keys/keyctl_pkey.c
> +++ b/security/keys/keyctl_pkey.c
> @@ -24,11 +24,13 @@ enum {
>  	Opt_err,
>  	Opt_enc,		/* "enc=<encoding>" eg. "enc=oaep" */
>  	Opt_hash,		/* "hash=<digest-name>" eg. "hash=sha1" */
> +	Opt_slen,		/* "slen=<salt-length>" eg. "slen=32" */
>  };
>  
>  static const match_table_t param_keys = {
>  	{ Opt_enc,	"enc=%s" },
>  	{ Opt_hash,	"hash=%s" },
> +	{ Opt_slen,	"slen=%u" },
>  	{ Opt_err,	NULL }
>  };
>  
> @@ -63,6 +65,10 @@ static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
>  			params->hash_algo = q;
>  			break;
>  
> +		case Opt_slen:
> +			if (kstrtouint(q, 0, &params->slen))
> +				return -EINVAL;
> +			break;
>  		default:
>  			return -EINVAL;
>  		}
> -- 
> 2.30.2
> 
> 

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

* Re: [PATCH 17/18] crypto: Accept pss as valid encoding during signature verification
  2021-03-30 20:28 ` [PATCH 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
@ 2021-03-31 23:14   ` Jarkko Sakkinen
  0 siblings, 0 replies; 27+ messages in thread
From: Jarkko Sakkinen @ 2021-03-31 23:14 UTC (permalink / raw)
  To: Varad Gautam
  Cc: linux-crypto, David Howells, Herbert Xu, David S. Miller,
	open list:ASYMMETRIC KEYS, open list

On Tue, Mar 30, 2021 at 10:28:28PM +0200, Varad Gautam wrote:
> Accept pss encoding for public_key_verify_signature. If
> CONFIG_CRYPTO_RSASSA_PSS is disabled, crypto_alloc_akcipher will
> fail to find a pss backend anyway.
> 
> Signed-off-by: Varad Gautam <varad.gautam@suse.com>
> ---

Acked-by: Jarkko Sakkinen <jarkko@kernel.org>

/Jarkko

>  crypto/asymmetric_keys/public_key.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
> index 788a4ba1e2e7..b9cc83ba7a12 100644
> --- a/crypto/asymmetric_keys/public_key.c
> +++ b/crypto/asymmetric_keys/public_key.c
> @@ -69,19 +69,20 @@ int software_key_determine_akcipher(const char *encoding,
>  {
>  	int n;
>  
> -	if (strcmp(encoding, "pkcs1") == 0) {
> +	if (strcmp(encoding, "pkcs1") == 0 || strcmp(encoding, "pss") == 0) {
>  		/* The data wangled by the RSA algorithm is typically padded
>  		 * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
> -		 * sec 8.2].
> +		 * sec 8.2] or EMSA-PSS [RFC8017 sec 9.1].
>  		 */
>  		if (!hash_algo)
>  			n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
> -				     "pkcs1pad(%s)",
> +				     "%spad(%s)",
> +				     encoding,
>  				     pkey->pkey_algo);
>  		else
>  			n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
> -				     "pkcs1pad(%s,%s)",
> -				     pkey->pkey_algo, hash_algo);
> +				     "%spad(%s,%s)",
> +				     encoding, pkey->pkey_algo, hash_algo);
>  		return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
>  	}
>  
> @@ -363,6 +364,13 @@ int public_key_verify_signature(const struct public_key *pkey,
>  			goto error_free_key;
>  	}
>  
> +	if (strcmp(sig->encoding, "pss") == 0) {
> +		ret = crypto_akcipher_set_sig_params(tfm, sig, sizeof(*sig));
> +		if (ret) {
> +			goto error_free_key;
> +		}
> +	}
> +
>  	sg_init_table(src_sg, 2);
>  	sg_set_buf(&src_sg[0], sig->s, sig->s_size);
>  	sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
> -- 
> 2.30.2
> 
> 

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

* Re: [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
  2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
  2021-03-31  2:10   ` kernel test robot
@ 2021-04-01  1:09   ` Herbert Xu
  2021-04-01  7:43     ` Varad Gautam
  2021-04-07  8:27   ` hongbo li
  2 siblings, 1 reply; 27+ messages in thread
From: Herbert Xu @ 2021-04-01  1:09 UTC (permalink / raw)
  To: Varad Gautam
  Cc: linux-crypto, David Howells, David S. Miller, Vitaly Chikunov,
	Tianjia Zhang, open list:ASYMMETRIC KEYS, open list

On Tue, Mar 30, 2021 at 10:28:12PM +0200, Varad Gautam wrote:
> An X.509 wrapper for a RSASSA-PSS signature contains additional
> signature parameters over the PKCSv.15 encoding scheme. Extend the
> x509 parser to allow parsing RSASSA-PSS encoded certificates, with
> the defaults taken from RFC8017.

Where is the cover letter for this series?

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* [PATCH 00/18] Implement RSASSA-PSS signature verification
@ 2021-04-01  7:31 Varad Gautam
  2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
                   ` (17 more replies)
  0 siblings, 18 replies; 27+ messages in thread
From: Varad Gautam @ 2021-04-01  7:31 UTC (permalink / raw)
  Cc: Varad Gautam, David Howells, Herbert Xu, David S. Miller,
	Vitaly Chikunov, Tianjia Zhang, open list:ASYMMETRIC KEYS,
	open list

Linux currently supports RSA PKCSv1.5 encoding scheme for
signing / verification. This adds support for RSASSA PSS signature
verification as described in RFC8017 [1].

Patch 1 extends the x509 certificate parser to unpack PSS signature
  parameters.
Patches 2-8 pull out the common functions / struct definitions from
  rsa-pkcs1pad.c into rsa-common.c, to be shared across RSA encoding
  scheme implementations.
Patches 9, 10 provide some more plumbing to export the data needed to
  perform PSS operations (salt length, RSA modulus).
Patches 11-16 set up PSS scaffolding and provide the verification
  operation per RFC8017.
Patches 17, 18 turn the final knobs on to allow lowering PSS signatures
  for verification via keyctl.

The patchset is available as a git tree at [2].

Testing:
The implementation was tested by adding reference public keys to the
kernel's keyring via `keyctl padd` and then verifying a known
message digest / signature against this public key via `keyctl pkey_verify`.
The reference vectors were taken from:
- the Wycheproof testsuite [3]
- FIPS 186-2 and 186-4 test vectors [4]

The test harness is available at [5].

Example keyctl usage for PSS verification:
rsa_bits=4096 # 2048/3072/4096
hash_algo=sha256 # sha1/sha224/sha256/sha384/sha512
saltlen=32
# Generate keys, certificate:
openssl req -x509 -newkey rsa:$rsa_bits -nodes -keyout private.pem -out cert.der \
  -days 100 -outform der -$hash_algo -sigopt rsa_padding_mode:pss \
  -sigopt rsa_pss_saltlen:$saltlen -sigopt rsa_mgf1_md:$hash_algo

# Sign data.txt:
openssl dgst -${hash_algo} -sign private.pem -sigopt rsa_padding_mode:pss \
  -sigopt rsa_pss_saltlen:${saltlen} -out sig.bin data.txt

# Digest data.txt:
openssl dgst -${hash_algo} -binary -out data.${hash_algo}.raw data.txt

# Load pubkey into the kernel's keyring:
kv=$(keyctl padd asymmetric "test-key" @u < cert.der)

# Verify with `enc=pss`:
keyctl pkey_verify $kv "0" data.${hash_algo}.raw sig.bin "enc=pss hash=${hash_algo} slen=${saltlen}"

[1] https://tools.ietf.org/html/rfc8017#section-8.1
[2] https://github.com/varadgautam/kernel/tree/rsassa-psspad
[3] https://github.com/google/wycheproof/blob/master/testvectors/
[4] https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/digital-signatures#rsavs
[5] https://github.com/varadgautam/keyctl-rsa-tests

Varad Gautam (18):
  X.509: Parse RSASSA-PSS style certificates
  crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad
  crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper
  crypto: rsa-pkcs1pad: Pull out child req processing code into helpers
  crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_*
  crypto: rsa: Start moving RSA common code to rsa-common
  crypto: rsa: Move more common code to rsa-common
  crypto: rsa: Move rsapad_akcipher_setup_child and callback to
    rsa-common
  crypto: Extend akcipher API to pass signature parameters
  crypto: rsa: Move struct rsa_mpi_key definition to rsa.h
  crypto: Scaffolding for RSA-PSS signature style
  crypto: rsa-psspad: Introduce shash alloc/dealloc helpers
  crypto: rsa-psspad: Get signature salt length from a given signature
  crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS
  crypto: rsa-psspad: Provide PSS signature verify operation
  crypto: rsa-psspad: Implement signature verify callback
  crypto: Accept pss as valid encoding during signature verification
  keyctl_pkey: Add pkey parameter slen to pass in PSS salt length

 crypto/Kconfig                            |   6 +
 crypto/Makefile                           |   2 +
 crypto/asymmetric_keys/Makefile           |   5 +-
 crypto/asymmetric_keys/asymmetric_type.c  |   1 +
 crypto/asymmetric_keys/public_key.c       |  18 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 152 ++++++++
 crypto/asymmetric_keys/x509_rsassa.asn1   |  17 +
 crypto/rsa-common.c                       | 291 ++++++++++++++++
 crypto/rsa-pkcs1pad.c                     | 400 +++-------------------
 crypto/rsa-psspad.c                       | 283 +++++++++++++++
 crypto/rsa.c                              |  26 +-
 include/crypto/akcipher.h                 |  26 ++
 include/crypto/internal/rsa-common.h      |  60 ++++
 include/crypto/internal/rsa.h             |   8 +
 include/crypto/public_key.h               |   4 +
 include/linux/keyctl.h                    |   1 +
 include/linux/oid_registry.h              |   3 +
 security/keys/keyctl_pkey.c               |   6 +
 18 files changed, 945 insertions(+), 364 deletions(-)
 create mode 100644 crypto/asymmetric_keys/x509_rsassa.asn1
 create mode 100644 crypto/rsa-common.c
 create mode 100644 crypto/rsa-psspad.c
 create mode 100644 include/crypto/internal/rsa-common.h

-- 
2.30.2


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

* Re: [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
  2021-04-01  1:09   ` Herbert Xu
@ 2021-04-01  7:43     ` Varad Gautam
  0 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-04-01  7:43 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-crypto, David Howells, David S. Miller, Vitaly Chikunov,
	Tianjia Zhang, open list:ASYMMETRIC KEYS, open list

On 4/1/21 3:09 AM, Herbert Xu wrote:
> On Tue, Mar 30, 2021 at 10:28:12PM +0200, Varad Gautam wrote:
>> An X.509 wrapper for a RSASSA-PSS signature contains additional
>> signature parameters over the PKCSv.15 encoding scheme. Extend the
>> x509 parser to allow parsing RSASSA-PSS encoded certificates, with
>> the defaults taken from RFC8017.
> 
> Where is the cover letter for this series?
> 

I realized the cover letter initially only went to linux-crypto@.
I've resent it to the missing destinations with the original Message-ID
to plug it back into the series [1].

[1] https://lore.kernel.org/lkml/20210330202829.4825-1-varad.gautam@suse.com/

Thanks,
Varad

> Thanks,
> 

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5
90409 Nürnberg
Germany

HRB 36809, AG Nürnberg
Geschäftsführer: Felix Imendörffer


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

* Re: [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
  2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
  2021-03-31  2:10   ` kernel test robot
  2021-04-01  1:09   ` Herbert Xu
@ 2021-04-07  8:27   ` hongbo li
  2021-04-07 21:20     ` Varad Gautam
  2 siblings, 1 reply; 27+ messages in thread
From: hongbo li @ 2021-04-07  8:27 UTC (permalink / raw)
  To: Varad Gautam
  Cc: linux-crypto, David Howells, Herbert Xu, David S. Miller,
	Vitaly Chikunov, Tianjia Zhang, open list:ASYMMETRIC KEYS,
	open list

Hello Varad,

I also made an implementation of rsa pss: "[PATCH v3 0/4] crypto: add
rsa pss support for x509".
I notice your patches and did some review,  find the following
differences between our patches:
1. You rework the rsa pad framework. This is reasonable.
2. You did some changes on the keyctl and asymmetric struct. I don't
see the reason.
    Because for x509 layer, it only need to know the hash param, and
could ignore other params(salt len, mgfhash).
    Let rsa-pss itself parse the pss related params. So it seems we
don't need to change asymmetric's
    common struct.
3. Why reject the cert whose MGF is different from the hash function
used for signature generation?
   My implementation could support different hashes, so don't get your point.
4. I add a test vector and a patch to support using rsa-pss for iam.
5. Other implementation difference, i.e. the mgf and verify functions.

Maybe we could merge our patches, what's your opinion?

Best regards

Hongbo

Varad Gautam <varad.gautam@suse.com> 于2021年3月31日周三 上午4:31写道:
>
> An X.509 wrapper for a RSASSA-PSS signature contains additional
> signature parameters over the PKCSv.15 encoding scheme. Extend the
> x509 parser to allow parsing RSASSA-PSS encoded certificates, with
> the defaults taken from RFC8017.
>
> A certificate is rejected if the hash function used for the MGF is
> different from the hash function used for signature generation,
> although this is allowed in RFC8017.
>
> References: https://tools.ietf.org/html/rfc8017#appendix-C
> Signed-off-by: Varad Gautam <varad.gautam@suse.com>
> ---
>  crypto/asymmetric_keys/Makefile           |   5 +-
>  crypto/asymmetric_keys/x509_cert_parser.c | 152 ++++++++++++++++++++++
>  crypto/asymmetric_keys/x509_rsassa.asn1   |  17 +++
>  include/crypto/public_key.h               |   4 +
>  include/linux/oid_registry.h              |   3 +
>  5 files changed, 180 insertions(+), 1 deletion(-)
>  create mode 100644 crypto/asymmetric_keys/x509_rsassa.asn1
>

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

* Re: [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
  2021-04-07  8:27   ` hongbo li
@ 2021-04-07 21:20     ` Varad Gautam
       [not found]       ` <CABpmuw+br=4N7OV8KXR7iZosGj7SVKMS=DV_-axgMgsh-+189A@mail.gmail.com>
  0 siblings, 1 reply; 27+ messages in thread
From: Varad Gautam @ 2021-04-07 21:20 UTC (permalink / raw)
  To: hongbo li
  Cc: linux-crypto, David Howells, Herbert Xu, David S. Miller,
	Vitaly Chikunov, Tianjia Zhang, open list:ASYMMETRIC KEYS,
	open list

Hi Hongbo,

On 4/7/21 10:27 AM, hongbo li wrote:
> Hello Varad,
> 
> I also made an implementation of rsa pss: "[PATCH v3 0/4] crypto: add
> rsa pss support for x509".
> I notice your patches and did some review,  find the following
> differences between our patches:
> 1. You rework the rsa pad framework. This is reasonable.
> 2. You did some changes on the keyctl and asymmetric struct. I don't
> see the reason.
>     Because for x509 layer, it only need to know the hash param, and
> could ignore other params(salt len, mgfhash).
>     Let rsa-pss itself parse the pss related params. So it seems we
> don't need to change asymmetric's
>     common struct.

A signature might be generated with a different set of params than those
used for signing the x509 certificate that wraps the corresponding pubkey.
In this case, using the params that came in when the pubkey was loaded,
instead of params for the actual signature would be incorrect. I see
struct public_key_signature as the right place to store such state,
regardless of where the signature came from (detached or selfsigned).

For the same reason, I also prefer the parsing machinery for signature
params be kept in x509_cert_parser instead of unpacking a buffer in the
PSS akcipher's set_pub_key implementation [1]. Going that way, we also end
up parsing these params twice, since x509 needs to unpack the hash
algorithm in a pss-specific way anyway.

For the IMA usecase, since x509_key_preparse() would have already filled
in the params in public_key_signature, asymmetric_verify should be able
to find and set these from key->payload before calling verify_signature().

> 3. Why reject the cert whose MGF is different from the hash function
> used for signature generation?
>    My implementation could support different hashes, so don't get your point.

The verify operation (psspad_verify_complete [3]) in theory supports it,
which I've tested against such certificates crafted via openssl.

I chose to reject such certificates early on during x509 parsing since,
- these are not a common occurence in practice, and
- testing (besides via openssl) without a set of reference vectors to harden
  the verification against seemed insufficient.

I've had some more test runs complete in the meantime, and I'll drop that
check in the next round.

> 4. I add a test vector and a patch to support using rsa-pss for iam.
> 5. Other implementation difference, i.e. the mgf and verify functions.
> 
> Maybe we could merge our patches, what's your opinion?
> 

Sounds good. I'll send out a v2 soon, and if you agree, the test vector [4]
and IMA [5] can go on top of it?

[1] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-3-git-send-email-herbert.tencent@gmail.com/
[2] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-5-git-send-email-herbert.tencent@gmail.com/
[3] https://patchwork.kernel.org/project/linux-crypto/patch/20210330202829.4825-2-varad.gautam@suse.com/
[4] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-4-git-send-email-herbert.tencent@gmail.com/

Regards,
Varad

> Best regards
> 
> Hongbo
> 
> Varad Gautam <varad.gautam@suse.com> 于2021年3月31日周三 上午4:31写道:
>>
>> An X.509 wrapper for a RSASSA-PSS signature contains additional
>> signature parameters over the PKCSv.15 encoding scheme. Extend the
>> x509 parser to allow parsing RSASSA-PSS encoded certificates, with
>> the defaults taken from RFC8017.
>>
>> A certificate is rejected if the hash function used for the MGF is
>> different from the hash function used for signature generation,
>> although this is allowed in RFC8017.
>>
>> References: https://tools.ietf.org/html/rfc8017#appendix-C
>> Signed-off-by: Varad Gautam <varad.gautam@suse.com>
>> ---
>>  crypto/asymmetric_keys/Makefile           |   5 +-
>>  crypto/asymmetric_keys/x509_cert_parser.c | 152 ++++++++++++++++++++++
>>  crypto/asymmetric_keys/x509_rsassa.asn1   |  17 +++
>>  include/crypto/public_key.h               |   4 +
>>  include/linux/oid_registry.h              |   3 +
>>  5 files changed, 180 insertions(+), 1 deletion(-)
>>  create mode 100644 crypto/asymmetric_keys/x509_rsassa.asn1
>>
> 

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5
90409 Nürnberg
Germany

HRB 36809, AG Nürnberg
Geschäftsführer: Felix Imendörffer


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

* Re: [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates
       [not found]       ` <CABpmuw+br=4N7OV8KXR7iZosGj7SVKMS=DV_-axgMgsh-+189A@mail.gmail.com>
@ 2021-04-08 14:21         ` Varad Gautam
  0 siblings, 0 replies; 27+ messages in thread
From: Varad Gautam @ 2021-04-08 14:21 UTC (permalink / raw)
  To: hongbo li
  Cc: linux-crypto, David Howells, Herbert Xu, David S. Miller,
	Vitaly Chikunov, Tianjia Zhang, open list:ASYMMETRIC KEYS,
	open list

On 4/8/21 4:29 AM, hongbo li wrote:
> Hi Varad,
> 
> Varad Gautam <varad.gautam@suse.com <mailto:varad.gautam@suse.com>> 于2021年4月8日周四 上午5:20写道:
>>
>> Hi Hongbo,
>>
>> On 4/7/21 10:27 AM, hongbo li wrote:
>> > Hello Varad,
>> >
>> > I also made an implementation of rsa pss: "[PATCH v3 0/4] crypto: add
>> > rsa pss support for x509".
>> > I notice your patches and did some review,  find the following
>> > differences between our patches:
>> > 1. You rework the rsa pad framework. This is reasonable.
>> > 2. You did some changes on the keyctl and asymmetric struct. I don't
>> > see the reason.
>> >     Because for x509 layer, it only need to know the hash param, and
>> > could ignore other params(salt len, mgfhash).
>> >     Let rsa-pss itself parse the pss related params. So it seems we
>> > don't need to change asymmetric's
>> >     common struct.
>>
>> A signature might be generated with a different set of params than those
>> used for signing the x509 certificate that wraps the corresponding pubkey.
>> In this case, using the params that came in when the pubkey was loaded,
>> instead of params for the actual signature would be incorrect. I see
>> struct public_key_signature as the right place to store such state,
>> regardless of where the signature came from (detached or selfsigned).
>>
> 
> As what the comments in x509_note_params()  say:
> In crypto/asymmetric_keys/x509.asn1, AlgorithmIdentifier is used three times :
> 1. The signature AlgorithmIdentifier in TBSCertificate.
> 2. The algorithm in SubjectPublicKeyInfo
> 3. The signatureAlgorithm after tbsCertificate.
> When the pubkey was loaded, it is the third one. According to rfc5280 [1],
> the third has the same value as the first one.  Your patch use the first, and I
> use the third, I think both are fine.
> 

Consider the following to illustrate my point:

# Generate a key pair:
slen=20
mgfhash=sha384
openssl req -x509 -newkey rsa:4096 -nodes -keyout private.pem -out pss-0.der \
    -days 100 -outform der -config x509.genkey -sha384 -sigopt rsa_padding_mode:pss \
    -sigopt rsa_pss_saltlen:$slen -sigopt rsa_mgf1_md:$mgfhash

openssl x509 -in pss-0.der -inform der -pubkey -noout > public.pem

# Sign some data:
echo data > data.txt
slen=30
mgfhash=sha256
openssl dgst -sha384 -sign private.pem -sigopt rsa_padding_mode:pss \
    -sigopt rsa_pss_saltlen:$slen -sigopt rsa_mgf1_md:$mgfhash \
    -out sig.bin data.txt

sig.bin has a different slen and mgfhash vs the signature stored in pss-0.der.
Since psspad_set_pub_key() here [1] will unpack the params that correspond to
pss-0.der, verifying sig.bin (eg via keyctl pkey_verify) would fail.

>> For the same reason, I also prefer the parsing machinery for signature
>> params be kept in x509_cert_parser instead of unpacking a buffer in the
>> PSS akcipher's set_pub_key implementation [1]. Going that way, we also end
>> up parsing these params twice, since x509 needs to unpack the hash
>> algorithm in a pss-specific way anyway.
>>
> 
> Yes, my patch needs to parse the params twice, my purpose is to make small
> change to x509 layer.
> 
>> For the IMA usecase, since x509_key_preparse() would have already filled
>> in the params in public_key_signature, asymmetric_verify should be able
>> to find and set these from key->payload before calling verify_signature().
>>
>> > 3. Why reject the cert whose MGF is different from the hash function
>> > used for signature generation?
>> >    My implementation could support different hashes, so don't get your point.
>>
>> The verify operation (psspad_verify_complete [3]) in theory supports it,
>> which I've tested against such certificates crafted via openssl.
>>
>> I chose to reject such certificates early on during x509 parsing since,
>> - these are not a common occurence in practice, and
>> - testing (besides via openssl) without a set of reference vectors to harden
>>   the verification against seemed insufficient.
>>
>> I've had some more test runs complete in the meantime, and I'll drop that
>> check in the next round.
>>
>> > 4. I add a test vector and a patch to support using rsa-pss for iam.
>> > 5. Other implementation difference, i.e. the mgf and verify functions.
>> >
>> > Maybe we could merge our patches, what's your opinion?
>> >
>>
>> Sounds good. I'll send out a v2 soon, and if you agree, the test vector [4]
>> and IMA [5] can go on top of it?
> 
> Sure, Thank you.

I've posted a v2 at [2].

[1] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-3-git-send-email-herbert.tencent@gmail.com/
[2] https://lkml.org/lkml/2021/4/8/775

Regards,
Varad

>>
>> [1] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-3-git-send-email-herbert.tencent@gmail.com/ <https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-3-git-send-email-herbert.tencent@gmail.com/>
>> [2] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-5-git-send-email-herbert.tencent@gmail.com/ <https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-5-git-send-email-herbert.tencent@gmail.com/>
>> [3] https://patchwork.kernel.org/project/linux-crypto/patch/20210330202829.4825-2-varad.gautam@suse.com/ <https://patchwork.kernel.org/project/linux-crypto/patch/20210330202829.4825-2-varad.gautam@suse.com/>
>> [4] https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-4-git-send-email-herbert.tencent@gmail.com/ <https://patchwork.kernel.org/project/linux-crypto/patch/1617802906-30513-4-git-send-email-herbert.tencent@gmail.com/>
>>
>> Regards,
>> Varad
>>
>> > Best regards
>> >
> 
> [1] https://tools.ietf.org/html/rfc5280#section-4.1.1.2 <https://tools.ietf.org/html/rfc5280#section-4.1.1.2>
> 
> Best Regards
> Hongbo
> 

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5
90409 Nürnberg
Germany

HRB 36809, AG Nürnberg
Geschäftsführer: Felix Imendörffer


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

end of thread, other threads:[~2021-04-08 14:22 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-01  7:31 [PATCH 00/18] Implement RSASSA-PSS signature verification Varad Gautam
2021-03-30 20:28 ` [PATCH 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
2021-03-31  2:10   ` kernel test robot
2021-04-01  1:09   ` Herbert Xu
2021-04-01  7:43     ` Varad Gautam
2021-04-07  8:27   ` hongbo li
2021-04-07 21:20     ` Varad Gautam
     [not found]       ` <CABpmuw+br=4N7OV8KXR7iZosGj7SVKMS=DV_-axgMgsh-+189A@mail.gmail.com>
2021-04-08 14:21         ` Varad Gautam
2021-03-30 20:28 ` [PATCH 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad Varad Gautam
2021-03-30 20:28 ` [PATCH 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper Varad Gautam
2021-03-30 20:28 ` [PATCH 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers Varad Gautam
2021-03-30 20:28 ` [PATCH 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_* Varad Gautam
2021-03-30 20:28 ` [PATCH 06/18] crypto: rsa: Start moving RSA common code to rsa-common Varad Gautam
2021-03-30 20:28 ` [PATCH 07/18] crypto: rsa: Move more " Varad Gautam
2021-03-30 20:28 ` [PATCH 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback " Varad Gautam
2021-03-30 20:28 ` [PATCH 09/18] crypto: Extend akcipher API to pass signature parameters Varad Gautam
2021-03-30 20:28 ` [PATCH 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h Varad Gautam
2021-03-30 20:28 ` [PATCH 11/18] crypto: Scaffolding for RSA-PSS signature style Varad Gautam
2021-03-30 20:28 ` [PATCH 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers Varad Gautam
2021-03-30 20:28 ` [PATCH 13/18] crypto: rsa-psspad: Get signature salt length from a given signature Varad Gautam
2021-03-30 20:28 ` [PATCH 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS Varad Gautam
2021-03-30 20:28 ` [PATCH 15/18] crypto: rsa-psspad: Provide PSS signature verify operation Varad Gautam
2021-03-30 20:28 ` [PATCH 16/18] crypto: rsa-psspad: Implement signature verify callback Varad Gautam
2021-03-30 20:28 ` [PATCH 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
2021-03-31 23:14   ` Jarkko Sakkinen
2021-03-30 20:28 ` [PATCH 18/18] keyctl_pkey: Add pkey parameter slen to pass in PSS salt length Varad Gautam
2021-03-31 23:13   ` Jarkko Sakkinen

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).