All of lore.kernel.org
 help / color / mirror / Atom feed
From: Varad Gautam <varad.gautam@suse.com>
To: linux-crypto@vger.kernel.org
Cc: varad.gautam@suse.com, dhowells@redhat.com,
	herbert@gondor.apana.org.au, davem@davemloft.net,
	vt@altlinux.org, tianjia.zhang@linux.alibaba.com,
	keyrings@vger.kernel.org, linux-kernel@vger.kernel.org,
	jarkko@kernel.org
Subject: [PATCH v2 01/18] X.509: Parse RSASSA-PSS style certificates
Date: Thu,  8 Apr 2021 16:14:59 +0200	[thread overview]
Message-ID: <20210408141516.11369-2-varad.gautam@suse.com> (raw)
In-Reply-To: <20210408141516.11369-1-varad.gautam@suse.com>

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.

References: https://tools.ietf.org/html/rfc8017#appendix-C
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
v2: Remove check to reject certificates with differing mgf hash and digest
  hash algorithms from x509_note_pkey_algo.

 crypto/asymmetric_keys/Makefile           |   5 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 148 ++++++++++++++++++++++
 crypto/asymmetric_keys/x509_rsassa.asn1   |  17 +++
 include/crypto/public_key.h               |   4 +
 include/linux/oid_registry.h              |   3 +
 5 files changed, 176 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 28b91adba2aed..f79ed8e8ef8e2 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 52c9b455fc7df..19cd162acdb06 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,35 @@ 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;
+
+		return 0;
 	}
 
 rsa_pkcs1:
@@ -439,6 +481,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 +759,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(*((__force __be16 *) 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 0000000000000..e524b978856d2
--- /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 47accec68cb0f..f36834c8bb139 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 4462ed2c18cdd..c247adc8a41e4 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


  reply	other threads:[~2021-04-08 14:16 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
2021-04-08 14:14 ` Varad Gautam [this message]
2021-04-08 14:15 ` [PATCH v2 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad Varad Gautam
2021-04-08 14:15 ` [PATCH v2 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper Varad Gautam
2021-04-08 14:15 ` [PATCH v2 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers Varad Gautam
2021-04-08 14:15 ` [PATCH v2 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_* Varad Gautam
2021-04-08 14:15 ` [PATCH v2 06/18] crypto: rsa: Start moving RSA common code to rsa-common Varad Gautam
2021-04-08 14:15 ` [PATCH v2 07/18] crypto: rsa: Move more " Varad Gautam
2021-04-08 14:15 ` [PATCH v2 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback " Varad Gautam
2021-04-08 14:15 ` [PATCH v2 09/18] crypto: Extend akcipher API to pass signature parameters Varad Gautam
2021-04-08 14:15 ` [PATCH v2 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h Varad Gautam
2021-04-08 14:15 ` [PATCH v2 11/18] crypto: Scaffolding for RSA-PSS signature style Varad Gautam
2021-04-08 14:15 ` [PATCH v2 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers Varad Gautam
2021-04-08 14:15 ` [PATCH v2 13/18] crypto: rsa-psspad: Get signature parameters from a given signature Varad Gautam
2021-04-08 14:15 ` [PATCH v2 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS Varad Gautam
2021-04-08 14:15 ` [PATCH v2 15/18] crypto: rsa-psspad: Provide PSS signature verify operation Varad Gautam
2021-04-08 14:15 ` [PATCH v2 16/18] crypto: rsa-psspad: Implement signature verify callback Varad Gautam
2021-04-08 14:15 ` [PATCH v2 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
2021-04-08 14:15 ` [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS Varad Gautam
2021-04-09 14:15   ` Ben Boeckel
2021-04-20 11:46     ` Varad Gautam
2021-04-08 15:05 ` David Howells
2021-04-08 15:08 ` [PATCH v2 00/18] Implement RSASSA-PSS signature verification David Howells
2021-04-20 11:47   ` Varad Gautam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210408141516.11369-2-varad.gautam@suse.com \
    --to=varad.gautam@suse.com \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=jarkko@kernel.org \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tianjia.zhang@linux.alibaba.com \
    --cc=vt@altlinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.