Hello,
I have been thinking about implementing RSASSA-PSS in Nettle.
I would like to propose the following API for performing and verifying signatures:
diff --git a/rsa.h b/rsa.h
index 6d2574b..b9faffe 100644 --- a/rsa.h +++ b/rsa.h @@ -35,6 +35,7 @@ #define NETTLE_RSA_H_INCLUDED
#include "nettle-types.h" +#include "nettle-meta.h" #include "bignum.h"
#include "md5.h" @@ -188,6 +189,27 @@ int rsa_private_key_prepare(struct rsa_private_key *key);
+/* PSS style signatures */ +int +rsa_pss_sign(const struct rsa_private_key *key,
size_t length, const uint8_t *digest_info,
mpz_t s, const struct nettle_hash *hash_func,
size_t salt_length, const uint8_t *salt);
+int +rsa_pss_sign_tr(const struct rsa_public_key *pub,
const struct rsa_private_key *key,
void *random_ctx, nettle_random_func *random,
size_t length, const uint8_t *digest_info,
mpz_t s, const struct nettle_hash *hash_func,
size_t salt_length, const uint8_t *salt);
+int +rsa_pss_verify(const struct rsa_public_key *key,
size_t length, const uint8_t *digest_info,
const mpz_t signature, const struct nettle_hash *hash_func,
size_t salt_length);
/* PKCS#1 style signatures */ int rsa_pkcs1_sign(const struct rsa_private_key *key,
It is fairly similar to PKCS#1 API but with the addition of a hash function and salt. If this sounds reasonable then I will have a go at writing the implementations.
Best wishes,
Andrew Lawrence
andy lawrence ajlawrence@acm.org writes:
I have been thinking about implementing RSASSA-PSS in Nettle.
Thanks. As I said earlier, I haven't looked at PSS for a long time, so please excuse my ignorance. I would also like to ask if we have any list members who are more familiar with it and willing to help with code review? (Otherwise, I'll just have to read up on it, of course).
Are there any particular application or protocol you have in mind which needs pss?
+/* PSS style signatures */ +int +rsa_pss_sign(const struct rsa_private_key *key,
size_t length, const uint8_t *digest_info,
mpz_t s, const struct nettle_hash *hash_func,
size_t salt_length, const uint8_t *salt);
Try as far as possible to be consistent with the argument order in the pkcs1 functions. I think length, digest_info and signature should be the final three arguments (for all three functions). There are no simple rules here, but I tend to put constant things like the hash algorithm early, and per-message data, like the salt, later.
What's the salt? If it's supposed to be randomly generated by the signing application, I think it's better to pass in a randomness source to the signature function (similarly to dsa and ecdsa, and the _tr RSA functions).
We're also in a process to promote the _tr functions and deprecate the older ones. Maybe we should do *only* the _tr version for the new pss code?
+int +rsa_pss_verify(const struct rsa_public_key *key,
size_t length, const uint8_t *digest_info,
const mpz_t signature, const struct nettle_hash *hash_func,
size_t salt_length);
It looks like the salt_length is an algorithm parameter; the verifier has to know it to be able to verify a signature? Is it usually packaged together with the signature, or is it agreed upon in advance?
And speaking of parameters, is the hash function above required to be the same as the one encoded into the asn.1 digest_info and used to hash the message? If so, maybe we shouldn't make the interface flexible enough to allow different hash functions?
Regards, /Niels
On Wed, Dec 2, 2015 at 9:33 PM, Niels Möller nisse@lysator.liu.se wrote:
andy lawrence ajlawrence@acm.org writes:
I have been thinking about implementing RSASSA-PSS in Nettle.
Thanks. As I said earlier, I haven't looked at PSS for a long time, so please excuse my ignorance. I would also like to ask if we have any list members who are more familiar with it and willing to help with code review? (Otherwise, I'll just have to read up on it, of course). Are there any particular application or protocol you have in mind which needs pss?
X.509 certificate signing (I've seen certificates signed with RSASSA-PSS) and in the future, TLS 1.3 will be using it.
Nikos Mavrogiannopoulos n.mavrogiannopoulos@gmail.com writes:
X.509 certificate signing (I've seen certificates signed with RSASSA-PSS) and in the future, TLS 1.3 will be using it.
I see. Do you how x.509 and tls-1.3 handles the salt length? Is it prespecified, like in the definition of a tls cipher suite, or bundled with the public key, or included with each signature?
Regards, /Niels
On Tue, 2015-12-08 at 07:24 +0100, Niels Möller wrote:
Nikos Mavrogiannopoulos n.mavrogiannopoulos@gmail.com writes:
X.509 certificate signing (I've seen certificates signed with RSASSA-PSS) and in the future, TLS 1.3 will be using it.
I see. Do you how x.509 and tls-1.3 handles the salt length? Is it prespecified, like in the definition of a tls cipher suite, or bundled with the public key, or included with each signature?
In PKIX it is part of the certificate parameters: https://tools.ietf.org/html/rfc4055#section-3
I have not checked the TLS 1.3 draft but I'd expect something similar.
regards, Nikos
I was looking for a security project to work on and saw that implementing RSA-PSS in was listed on the GNUTLS website.
I will attempt to make the argument order consistent.
Yes the salt is supposed to be randomly generated by the signing application. I will modify the function definition to include a randomness source as you have suggested.
I agree in that it will be less work to only implement the _tr versions of rsa-pss. I do not know what the consumers of Nettle want so this decision is better taken by you. There may be some reason to use the older version.
The verifier has to know the salt length in order to recover the salt and verify the signature. It is usually packaged together with the signature in the algorithm parameters:
RSASSA-PSS-params ::= SEQUENCE { hashAlgorithm [0] HashAlgorithm DEFAULT sha1, maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, saltLength [2] INTEGER DEFAULT 20, trailerField [3] TrailerField DEFAULT trailerFieldBC }
As seen in the above parameters, it should be possible to choose both the hash algorithm for the message and the hash algorithm for the mask generation function. I had envisaged the one currently specified in the function definition being used for the MGF. The choice of this hash function is independent of the one used to hash the message. I was planning on following the convention with the existing RSA code and supplying a pile of different functions, one for each hash algorithm. Do you have a suggestion on how to prevent this repetition?
Best wishes,
Andrew Lawrence
On Wed, Dec 2, 2015 at 8:33 PM, Niels Möller nisse@lysator.liu.se wrote:
andy lawrence ajlawrence@acm.org writes:
I have been thinking about implementing RSASSA-PSS in Nettle.
Thanks. As I said earlier, I haven't looked at PSS for a long time, so please excuse my ignorance. I would also like to ask if we have any list members who are more familiar with it and willing to help with code review? (Otherwise, I'll just have to read up on it, of course).
Are there any particular application or protocol you have in mind which needs pss?
+/* PSS style signatures */ +int +rsa_pss_sign(const struct rsa_private_key *key,
size_t length, const uint8_t *digest_info,
mpz_t s, const struct nettle_hash *hash_func,
size_t salt_length, const uint8_t *salt);
Try as far as possible to be consistent with the argument order in the pkcs1 functions. I think length, digest_info and signature should be the final three arguments (for all three functions). There are no simple rules here, but I tend to put constant things like the hash algorithm early, and per-message data, like the salt, later.
What's the salt? If it's supposed to be randomly generated by the signing application, I think it's better to pass in a randomness source to the signature function (similarly to dsa and ecdsa, and the _tr RSA functions).
We're also in a process to promote the _tr functions and deprecate the older ones. Maybe we should do *only* the _tr version for the new pss code?
+int +rsa_pss_verify(const struct rsa_public_key *key,
size_t length, const uint8_t *digest_info,
const mpz_t signature, const struct nettle_hash *hash_func,
size_t salt_length);
It looks like the salt_length is an algorithm parameter; the verifier has to know it to be able to verify a signature? Is it usually packaged together with the signature, or is it agreed upon in advance?
And speaking of parameters, is the hash function above required to be the same as the one encoded into the asn.1 digest_info and used to hash the message? If so, maybe we shouldn't make the interface flexible enough to allow different hash functions?
Regards, /Niels
-- Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26. Internet email is subject to wholesale government surveillance.
andy lawrence ajlawrence@acm.org writes:
I agree in that it will be less work to only implement the _tr versions of rsa-pss. I do not know what the consumers of Nettle want so this decision is better taken by you. There may be some reason to use the older version.
Start with the _tr version then.
RSASSA-PSS-params ::= SEQUENCE { hashAlgorithm [0] HashAlgorithm DEFAULT sha1, maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, saltLength [2] INTEGER DEFAULT 20, trailerField [3] TrailerField DEFAULT trailerFieldBC }
Is this for a signature on arbitrary data, or in the context of x.509? If a signature is always packed up in some asn.1 structure, we should perhaps use that representation in the interface, instead of a plain mpz_t.
As seen in the above parameters, it should be possible to choose both the hash algorithm for the message and the hash algorithm for the mask generation function.
But at least the hashAlgorithm above is required to be the same as inside the digestInfo?
I had envisaged the one currently specified in the function definition being used for the MGF.
Make sense to me, until there's some actual use of different MGF.
I was planning on following the convention with the existing RSA code and supplying a pile of different functions, one for each hash algorithm. Do you have a suggestion on how to prevent this repetition?
Try to write the helper functions needed to make each of the hash-specific functions small and trivial. One could even define some shared macro to expand to the function definition, but that's probably not worth the effort.
Regards, /Niels
nettle-bugs@lists.lysator.liu.se