diff mbox series

[01/18] X.509: Parse RSASSA-PSS style certificates

Message ID 20210330202829.4825-2-varad.gautam@suse.com (mailing list archive)
State New
Headers show
Series Implement RSASSA-PSS signature verification | expand

Commit Message

Varad Gautam March 30, 2021, 8:28 p.m. UTC
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

Comments

kernel test robot March 31, 2021, 2:10 a.m. UTC | #1
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
Herbert Xu April 1, 2021, 1:09 a.m. UTC | #2
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,
Varad Gautam April 1, 2021, 7:43 a.m. UTC | #3
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,
>
Hongbo Li April 7, 2021, 8:27 a.m. UTC | #4
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
>
Varad Gautam April 7, 2021, 9:20 p.m. UTC | #5
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
>>
>
Varad Gautam April 8, 2021, 2:21 p.m. UTC | #6
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
>
diff mbox series

Patch

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
 };