CMS: Add support for hashless signing schemes (ML/SLH-DSA & EdDSA) for no-attributes case#28923
CMS: Add support for hashless signing schemes (ML/SLH-DSA & EdDSA) for no-attributes case#28923stefanberger wants to merge 5 commits into
Conversation
|
@DDvO @danvangeest FYI |
|
would you please sign a CLA? https://openssl-library.org/policies/cla/ |
|
Very nice! |
I saw that some CMS-related tests were already working for the key types I am extending it for in this PR, but the non-attributes case was not covered. I am not sure what to do about PKCS#7... One concern I have with the implementation is the BIO of the input data. I am wondering whether to make a copy of the data since the data may have to be read multiple times (for multiple keys in pure mode), even though this may cause issues with very large files but then on the other hand would improve performance. |
80e45d0 to
3b0423e
Compare
3b0423e to
771b240
Compare
There was a problem hiding this comment.
Thank you for very swiftly picking up my API suggestions and for adding doc entries.
For now, just spotted some doc nits.
Since this PR also documents the pre-existing functions CMS_dataFinal() and CMS_SignerInfo_verify_content(), you can (well, even should) remove them from util/missingcrypto.txt.
This extension is clearly worth an entry in NEWS.md.
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for hashless signing schemes (ML-DSA, SLH-DSA, and EdDSA) in CMS when no signed attributes are present. The implementation enables these schemes to directly sign raw data instead of pre-computed hashes by passing the original data BIO through to signing and verification functions.
Key changes:
- Added new public APIs
CMS_dataFinal_hashless()andCMS_SignerInfo_verify_hashless()to support hashless signing schemes - Modified internal signing/verification functions to handle both hash-based and hashless signing schemes
- Added comprehensive test coverage for EdDSA (Ed25519, Ed448), ML-DSA-44, and SLH-DSA-SHAKE-256s with the
-noattrflag
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| util/libcrypto.num | Exports new public API functions for hashless signing support |
| test/recipes/80-test_cms.t | Adds test cases for hashless signing schemes (EdDSA, ML-DSA, SLH-DSA) with -noattr |
| include/openssl/cms.h.in | Declares new public APIs for hashless signing and verification |
| doc/man3/CMS_verify.pod | Documents the new verification functions for hashless schemes |
| doc/man3/CMS_final.pod | Documents the new finalization functions for hashless schemes |
| crypto/cms/cms_smime.c | Updates high-level CMS functions to use hashless variants |
| crypto/cms/cms_sd.c | Implements core hashless signing/verification logic with algorithm-specific handling |
| crypto/cms/cms_local.h | Updates internal function signatures to support data BIO parameter |
| crypto/cms/cms_lib.c | Implements new public APIs and updates internal routing |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
There was no direct button for triggering the Copilot/AI review bot for some reason |
|
Please add to the message of the respective commit this line: |
|
CI failures are relevant; please check and fix issues. |
771b240 to
59f1706
Compare
There was a problem hiding this comment.
Two hints how to get rid of the doc-nits CI failure.
Again, since this PR also documents the pre-existing functions CMS_dataFinal() and CMS_SignerInfo_verify_content(), should remove them from util/missingcrypto.txt
And comments regarding minor improvements on the coding style.
| CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, | ||
| X509 *signer, EVP_PKEY *pk, const EVP_MD *md, | ||
| unsigned int flags) | ||
| { |
There was a problem hiding this comment.
BTW, the only remaining coding style issue reported by the CI is:
crypto/cms/cms_sd.c:421:function body length = 206 > 200 lines:CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
While this PR already downsizes the function body a little bit,
there would be good chances by tweaking some other parts in here to get below the given "limit" ;-)
There was a problem hiding this comment.
Is removing empty lines allowed?
59f1706 to
746619f
Compare
|
The check docs and pre-commit failures are relevant. |
746619f to
a961417
Compare
…gning) Enable signature verification for hashless signing schemes, such as ML-DSA and EdDSA, for the non-attribute case of CMS. Also in this case the BIO with the plain input data needs to be passed through to the signature verification function so that the pure-mode signature verification method can hash the plain data itself. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add CMS test cases for no-attribute signing for ML-DSA, SLH-DSA amd EdDSA (Ed448 and Ed25519 keys). Fixes: openssl#11915 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement EVP_SIGNATURE_hash_message_update() to check for support of EVP_PKEY_sign_message_update() and EVP_PKEY_verify_message_update() and use this function to replace the has_msg_update column in CMS. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
73c47f1 to
b82fa0b
Compare
|
This pull request is ready to merge |
|
Merged to the master branch. Thank you for your contribution. |
Get a default hash for hash-less signing schemes such as ML-DSA, SLH-DSA, and EdDSA in the case when signed attributes are present as well as for the no signed attributes case. For the latter case, EdDSA is the only signing scheme that has a required hash (sha512 for ED25519 and shake256 for ED448), all other ones have a suggested hash. Only use the suggested hash if the hash provided by the caller of CMS_add1_signer passed a NULL pointer for md. Use the required hash in any case, overriding any choice of the caller. Fixes: #13523 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #28923)
Enable the ability to sign with a hashless signing schemes, such as ML-DSA in pure mode, in case no attributes are used in CMS. To support this, pass the BIO with the plain data through to the signing function so that key's pure mode signing scheme can hash the data itself. The current implementation relies on a seek'able BIO so that the data stream can be read multiple times for support of multiple keys. Some signing schemes, such as ML-DSA, support the message_update function when signing data, others, such as EdDSA keys do not support it. The former allows for reading data in smaller chunks and calling EVP_PKEY_sign_message_update with the data, while the latter requires that all data are all read into memory and then passed for signing. This latter method could run into out-of-memory issue when signing very large files. Fixes: #28279 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #28923)
…gning) Enable signature verification for hashless signing schemes, such as ML-DSA and EdDSA, for the non-attribute case of CMS. Also in this case the BIO with the plain input data needs to be passed through to the signature verification function so that the pure-mode signature verification method can hash the plain data itself. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #28923)
Implement EVP_SIGNATURE_hash_message_update() to check for support of EVP_PKEY_sign_message_update() and EVP_PKEY_verify_message_update() and use this function to replace the has_msg_update column in CMS. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #28923)
Allow ML-DSA module signing to be enabled. Note that OpenSSL's CMS_*() function suite does not, as of OpenSSL-3.6, support the use of CMS_NOATTR with ML-DSA, so the prohibition against using signedAttrs with module signing has to be removed. The selected digest then applies only to the algorithm used to calculate the digest stored in the messageDigest attribute. The OpenSSL development branch has patches applied that fix this[1], but it appears that that will only be available in OpenSSL-4. [1] openssl/openssl#28923 sign-file won't set CMS_NOATTR if openssl is earlier than v4, resulting in the use of signed attributes. The ML-DSA algorithm takes the raw data to be signed without regard to what digest algorithm is specified in the CMS message. The CMS specified digest algorithm is ignored unless signedAttrs are used; in such a case, only SHA512 is permitted. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> cc: Eric Biggers <ebiggers@kernel.org> cc: Lukas Wunner <lukas@wunner.de> cc: Ignat Korchagin <ignat@cloudflare.com> cc: Stephan Mueller <smueller@chronox.de> cc: Herbert Xu <herbert@gondor.apana.org.au> cc: keyrings@vger.kernel.org cc: linux-crypto@vger.kernel.org
Allow ML-DSA module signing to be enabled. Note that OpenSSL's CMS_*() function suite does not, as of OpenSSL-3.6, support the use of CMS_NOATTR with ML-DSA, so the prohibition against using signedAttrs with module signing has to be removed. The selected digest then applies only to the algorithm used to calculate the digest stored in the messageDigest attribute. The OpenSSL development branch has patches applied that fix this[1], but it appears that that will only be available in OpenSSL-4. [1] openssl/openssl#28923 sign-file won't set CMS_NOATTR if openssl is earlier than v4, resulting in the use of signed attributes. The ML-DSA algorithm takes the raw data to be signed without regard to what digest algorithm is specified in the CMS message. The CMS specified digest algorithm is ignored unless signedAttrs are used; in such a case, only SHA512 is permitted. Signed-off-by: David Howells <dhowells@redhat.com> cc: Jarkko Sakkinen <jarkko@kernel.org> cc: Eric Biggers <ebiggers@kernel.org> cc: Lukas Wunner <lukas@wunner.de> cc: Ignat Korchagin <ignat@cloudflare.com> cc: Stephan Mueller <smueller@chronox.de> cc: Herbert Xu <herbert@gondor.apana.org.au> cc: keyrings@vger.kernel.org cc: linux-crypto@vger.kernel.org
Get a default hash for hash-less signing schemes such as ML-DSA, SLH-DSA, and EdDSA in the case when signed attributes are present as well as for the no signed attributes case. For the latter case, EdDSA is the only signing scheme that has a required hash (sha512 for ED25519 and shake256 for ED448), all other ones have a suggested hash. Only use the suggested hash if the hash provided by the caller of CMS_add1_signer passed a NULL pointer for md. Use the required hash in any case, overriding any choice of the caller. Fixes: #13523 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from openssl/openssl#28923)
Get a default hash for hash-less signing schemes such as ML-DSA, SLH-DSA, and EdDSA in the case when signed attributes are present as well as for the no signed attributes case. For the latter case, EdDSA is the only signing scheme that has a required hash (sha512 for ED25519 and shake256 for ED448), all other ones have a suggested hash. Only use the suggested hash if the hash provided by the caller of CMS_add1_signer passed a NULL pointer for md. Use the required hash in any case, overriding any choice of the caller. Fixes: #13523 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from openssl/openssl#28923)
Get a default hash for hash-less signing schemes such as ML-DSA, SLH-DSA, and EdDSA in the case when signed attributes are present as well as for the no signed attributes case. For the latter case, EdDSA is the only signing scheme that has a required hash (sha512 for ED25519 and shake256 for ED448), all other ones have a suggested hash. Only use the suggested hash if the hash provided by the caller of CMS_add1_signer passed a NULL pointer for md. Use the required hash in any case, overriding any choice of the caller. Fixes: #13523 Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from openssl/openssl#28923)
Add support for hashless signing schemes, such as ML-DSA, SLH-DSA, and EdDSA, for the case that signed attributes are absent. Add test cases for all newly supported signing schemes.
Enable the ability to sign (verify) with a hashless signing schemes, such as ML-DSA in pure mode, in case no attributes are used in CMS. To support this, pass the BIO with the plain data through to the signing (verification) function so that key's pure mode signing scheme can hash the data itself.
The current implementation relies on a seek'able BIO so that the data stream can be read multiple times for support of multiple keys.
Some signing schemes, such as ML-DSA, support the message_update function when signing data, others, such as EdDSA keys do not support it. The former allows for reading data in smaller chunks and calling
EVP_PKEY_sign_message_update()with the data, while the latter requires that all data are all read into memory and then passed for signing. This latter method could run into out-of-memory issue when signing very large files.Fixes #11915
Fixes #13523 (?)
Fixes #28279
Checklist