[PATCH 2/2] sign-file: Remove support for signing with PKCS#7

Petr Pavlu posted 2 patches 2 months, 4 weeks ago
[PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by Petr Pavlu 2 months, 4 weeks ago
The PKCS#7 code in sign-file allows for signing only with SHA-1. Since
SHA-1 support for module signing has been removed, drop PKCS#7 support in
favor of using only CMS.

The use of the PKCS#7 code is selected by the following:

 #if defined(LIBRESSL_VERSION_NUMBER) || \
 	OPENSSL_VERSION_NUMBER < 0x10000000L || \
 	defined(OPENSSL_NO_CMS)
 #define USE_PKCS7
 #endif

Looking at the individual ifdefs:

* LIBRESSL_VERSION_NUMBER: LibreSSL added the CMS implementation from
  OpenSSL in 3.1.0, making the ifdef no longer relevant. This version was
  released on April 8, 2020.

* OPENSSL_VERSION_NUMBER < 0x10000000L: OpenSSL 1.0.0 was released on March
  29, 2010. Supporting earlier versions should no longer be necessary. The
  file Documentation/process/changes.rst already states that at least
  version 1.0.0 is required to build the kernel.

* OPENSSL_NO_CMS: OpenSSL can be configured with "no-cms" to disable the
  CMS support. In this case, sign-file will no longer be usable. The CMS
  support is now required.

In practice, since distributions now typically sign modules with SHA-2, for
which sign-file already required CMS support, removing PKCS#7 shouldn't
cause any issues.

Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
 scripts/sign-file.c | 66 +++------------------------------------------
 1 file changed, 3 insertions(+), 63 deletions(-)

diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 7070245edfc1..16f2bf2e1e3c 100644
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -24,6 +24,7 @@
 #include <arpa/inet.h>
 #include <openssl/opensslv.h>
 #include <openssl/bio.h>
+#include <openssl/cms.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
@@ -39,29 +40,6 @@
 #endif
 #include "ssl-common.h"
 
-/*
- * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
- * assume that it's not available and its header file is missing and that we
- * should use PKCS#7 instead.  Switching to the older PKCS#7 format restricts
- * the options we have on specifying the X.509 certificate we want.
- *
- * Further, older versions of OpenSSL don't support manually adding signers to
- * the PKCS#7 message so have to accept that we get a certificate included in
- * the signature message.  Nor do such older versions of OpenSSL support
- * signing with anything other than SHA1 - so we're stuck with that if such is
- * the case.
- */
-#if defined(LIBRESSL_VERSION_NUMBER) || \
-	OPENSSL_VERSION_NUMBER < 0x10000000L || \
-	defined(OPENSSL_NO_CMS)
-#define USE_PKCS7
-#endif
-#ifndef USE_PKCS7
-#include <openssl/cms.h>
-#else
-#include <openssl/pkcs7.h>
-#endif
-
 struct module_signature {
 	uint8_t		algo;		/* Public-key crypto algorithm [0] */
 	uint8_t		hash;		/* Digest algorithm [0] */
@@ -228,15 +206,10 @@ int main(int argc, char **argv)
 	bool raw_sig = false;
 	unsigned char buf[4096];
 	unsigned long module_size, sig_size;
-	unsigned int use_signed_attrs;
 	const EVP_MD *digest_algo;
 	EVP_PKEY *private_key;
-#ifndef USE_PKCS7
 	CMS_ContentInfo *cms = NULL;
 	unsigned int use_keyid = 0;
-#else
-	PKCS7 *pkcs7 = NULL;
-#endif
 	X509 *x509;
 	BIO *bd, *bm;
 	int opt, n;
@@ -246,21 +219,13 @@ int main(int argc, char **argv)
 
 	key_pass = getenv("KBUILD_SIGN_PIN");
 
-#ifndef USE_PKCS7
-	use_signed_attrs = CMS_NOATTR;
-#else
-	use_signed_attrs = PKCS7_NOATTR;
-#endif
-
 	do {
 		opt = getopt(argc, argv, "sdpk");
 		switch (opt) {
 		case 's': raw_sig = true; break;
 		case 'p': save_sig = true; break;
 		case 'd': sign_only = true; save_sig = true; break;
-#ifndef USE_PKCS7
 		case 'k': use_keyid = CMS_USE_KEYID; break;
-#endif
 		case -1: break;
 		default: format();
 		}
@@ -289,14 +254,6 @@ int main(int argc, char **argv)
 		replace_orig = true;
 	}
 
-#ifdef USE_PKCS7
-	if (strcmp(hash_algo, "sha1") != 0) {
-		fprintf(stderr, "sign-file: %s only supports SHA1 signing\n",
-			OPENSSL_VERSION_TEXT);
-		exit(3);
-	}
-#endif
-
 	/* Open the module file */
 	bm = BIO_new_file(module_name, "rb");
 	ERR(!bm, "%s", module_name);
@@ -314,7 +271,6 @@ int main(int argc, char **argv)
 		digest_algo = EVP_get_digestbyname(hash_algo);
 		ERR(!digest_algo, "EVP_get_digestbyname");
 
-#ifndef USE_PKCS7
 		/* Load the signature message from the digest buffer. */
 		cms = CMS_sign(NULL, NULL, NULL, NULL,
 			       CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
@@ -323,19 +279,12 @@ int main(int argc, char **argv)
 
 		ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
 				     CMS_NOCERTS | CMS_BINARY |
-				     CMS_NOSMIMECAP | use_keyid |
-				     use_signed_attrs),
+				     CMS_NOSMIMECAP | CMS_NOATTR |
+				     use_keyid),
 		    "CMS_add1_signer");
 		ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1,
 		    "CMS_final");
 
-#else
-		pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
-				   PKCS7_NOCERTS | PKCS7_BINARY |
-				   PKCS7_DETACHED | use_signed_attrs);
-		ERR(!pkcs7, "PKCS7_sign");
-#endif
-
 		if (save_sig) {
 			char *sig_file_name;
 			BIO *b;
@@ -344,13 +293,8 @@ int main(int argc, char **argv)
 			    "asprintf");
 			b = BIO_new_file(sig_file_name, "wb");
 			ERR(!b, "%s", sig_file_name);
-#ifndef USE_PKCS7
 			ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) != 1,
 			    "%s", sig_file_name);
-#else
-			ERR(i2d_PKCS7_bio(b, pkcs7) != 1,
-			    "%s", sig_file_name);
-#endif
 			BIO_free(b);
 		}
 
@@ -377,11 +321,7 @@ int main(int argc, char **argv)
 	module_size = BIO_number_written(bd);
 
 	if (!raw_sig) {
-#ifndef USE_PKCS7
 		ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) != 1, "%s", dest_name);
-#else
-		ERR(i2d_PKCS7_bio(bd, pkcs7) != 1, "%s", dest_name);
-#endif
 	} else {
 		BIO *b;
 
-- 
2.51.1
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by James Bottomley 2 months, 4 weeks ago
On Tue, 2025-11-11 at 16:48 +0100, Petr Pavlu wrote:
> The PKCS#7 code in sign-file allows for signing only with SHA-1.
> Since SHA-1 support for module signing has been removed, drop PKCS#7
> support in favor of using only CMS.

The change log is a bit alarmist.  CMS really *is* PKCS7 and most
literature will refer to CMS as PKCS7.  What you're really deprecating
is the use of the PKCS7_sign() API which can only produce SHA-1
Signatures ... openssl is fully capable of producing any hash PKCS7
signatures using a different PKCS7_... API set but the CMS_... API is
newer.

The point being the module signature type is still set to PKEY_ID_PKCS7
so it doesn't square with the commit log saying "drop PKCS#7 support".
What you really mean is only use the openssl CMS_... API for producing
PKCS7 signatures.

Regards,

James
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by Petr Pavlu 2 months, 4 weeks ago
On 11/11/25 5:53 PM, James Bottomley wrote:
> On Tue, 2025-11-11 at 16:48 +0100, Petr Pavlu wrote:
>> The PKCS#7 code in sign-file allows for signing only with SHA-1.
>> Since SHA-1 support for module signing has been removed, drop PKCS#7
>> support in favor of using only CMS.
> 
> The change log is a bit alarmist.  CMS really *is* PKCS7 and most
> literature will refer to CMS as PKCS7.  What you're really deprecating
> is the use of the PKCS7_sign() API which can only produce SHA-1
> Signatures ... openssl is fully capable of producing any hash PKCS7
> signatures using a different PKCS7_... API set but the CMS_... API is
> newer.
> 
> The point being the module signature type is still set to PKEY_ID_PKCS7
> so it doesn't square with the commit log saying "drop PKCS#7 support".
> What you really mean is only use the openssl CMS_... API for producing
> PKCS7 signatures.

Ok, I plan to update the description to the following in v2:

sign-file: Use only the OpenSSL CMS API for signing

The USE_PKCS7 code in sign-file utilizes PKCS7_sign(), which allows signing
only with SHA-1. Since SHA-1 support for module signing has been removed,
drop the use of the OpenSSL PKCS7 API by the tool in favor of using only
the newer CMS API.

The use of the PKCS7 API is selected by the following:

 #if defined(LIBRESSL_VERSION_NUMBER) || \
 	OPENSSL_VERSION_NUMBER < 0x10000000L || \
 	defined(OPENSSL_NO_CMS)
 #define USE_PKCS7
 #endif

Looking at the individual ifdefs:

* LIBRESSL_VERSION_NUMBER: LibreSSL added the CMS API implementation from
  OpenSSL in 3.1.0, making the ifdef no longer relevant. This version was
  released on April 8, 2020.

* OPENSSL_VERSION_NUMBER < 0x10000000L: OpenSSL 1.0.0 was released on March
  29, 2010. Supporting earlier versions should no longer be necessary. The
  file Documentation/process/changes.rst already states that at least
  version 1.0.0 is required to build the kernel.

* OPENSSL_NO_CMS: OpenSSL can be configured with "no-cms" to disable CMS
  support. In this case, sign-file will no longer be usable. The CMS API
  support is now required.

In practice, since distributions now typically sign modules with SHA-2, for
which sign-file already required CMS API support, removing the USE_PKCS7
code shouldn't cause any issues.

-- 
Thanks,
Petr
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by David Howells 2 months, 4 weeks ago
Petr Pavlu <petr.pavlu@suse.com> wrote:

> In practice, since distributions now typically sign modules with SHA-2, for
> which sign-file already required CMS API support, removing the USE_PKCS7
> code shouldn't cause any issues.

We're looking at moving to ML-DSA, and the CMS support there is slightly dodgy
at the moment, so we need to hold off a bit on this change.

Patch 1, removing the option to sign with SHA-1 from the kernel is fine, but
doesn't stop things that are signed with SHA-1 from being verified.

David
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by James Bottomley 2 months, 4 weeks ago
On Wed, 2025-11-12 at 15:36 +0000, David Howells wrote:
> Petr Pavlu <petr.pavlu@suse.com> wrote:
> 
> > In practice, since distributions now typically sign modules with
> > SHA-2, for which sign-file already required CMS API support,
> > removing the USE_PKCS7 code shouldn't cause any issues.
> 
> We're looking at moving to ML-DSA, and the CMS support there is
> slightly dodgy at the moment, so we need to hold off a bit on this
> change.

How will removing PKCS7_sign, which can only do sha1 signatures affect
that? Is the dodginess that the PKCS7_... API is better than CMS_...
for PQS at the moment?  In which case we could pretty much do a rip and
replace of the CMS_ API if necessary, but that would be a completely
separate patch.

Regards,

James
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by David Howells 2 months, 4 weeks ago
James Bottomley <James.Bottomley@HansenPartnership.com> wrote:

> > We're looking at moving to ML-DSA, and the CMS support there is
> > slightly dodgy at the moment, so we need to hold off a bit on this
> > change.
> 
> How will removing PKCS7_sign, which can only do sha1 signatures affect
> that? Is the dodginess that the PKCS7_... API is better than CMS_...
> for PQS at the moment?  In which case we could pretty much do a rip and
> replace of the CMS_ API if necessary, but that would be a completely
> separate patch.

OpenSSL-3.5.1's ML-DSA support isn't completely right - in particular
CMS_NOATTR is not currently supported.  I believe there is a fix in the works
there, but I doubt it has made it to all the distributions yet.  I'm only
asking that we hold off a cycle; that will probably suffice.

David
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by James Bottomley 2 months, 4 weeks ago
On Wed, 2025-11-12 at 15:52 +0000, David Howells wrote:
> James Bottomley <James.Bottomley@HansenPartnership.com> wrote:
> 
> > > We're looking at moving to ML-DSA, and the CMS support there is
> > > slightly dodgy at the moment, so we need to hold off a bit on
> > > this change.
> > 
> > How will removing PKCS7_sign, which can only do sha1 signatures
> > affect that? Is the dodginess that the PKCS7_... API is better than
> > CMS_... for PQS at the moment?  In which case we could pretty much
> > do a rip and replace of the CMS_ API if necessary, but that would
> > be a completely separate patch.
> 
> OpenSSL-3.5.1's ML-DSA support isn't completely right - in particular
> CMS_NOATTR is not currently supported.  I believe there is a fix in
> the works there, but I doubt it has made it to all the distributions
> yet.

I get that PQC in openssl-3.5 is highly experimental, but that merely
means we tell people not to use it for a while.  However, what I don't
see is how this impacts PKCS7_sign removal.  The CMS API can do a sha1
signature if that's what people want and keeping the PKCS7_sign API
won't prevent anyone with openssl-3.5 installed from trying a PQ
signature. 

>   I'm only asking that we hold off a cycle; that will probably
> suffice.

Right but why?  Is your thought that we'll have to change the CMS_ code
slightly and this might conflict?

Regards,

James
Re: [PATCH 2/2] sign-file: Remove support for signing with PKCS#7
Posted by James Bottomley 2 months, 4 weeks ago
On Wed, 2025-11-12 at 14:51 +0100, Petr Pavlu wrote:
> On 11/11/25 5:53 PM, James Bottomley wrote:
> > On Tue, 2025-11-11 at 16:48 +0100, Petr Pavlu wrote:
> > > The PKCS#7 code in sign-file allows for signing only with SHA-1.
> > > Since SHA-1 support for module signing has been removed, drop
> > > PKCS#7 support in favor of using only CMS.
> > 
> > The change log is a bit alarmist.  CMS really *is* PKCS7 and most
> > literature will refer to CMS as PKCS7.  What you're really
> > deprecating is the use of the PKCS7_sign() API which can only
> > produce SHA-1 Signatures ... openssl is fully capable of producing
> > any hash PKCS7 signatures using a different PKCS7_... API set but
> > the CMS_... API is newer.
> > 
> > The point being the module signature type is still set to
> > PKEY_ID_PKCS7 so it doesn't square with the commit log saying "drop
> > PKCS#7 support". What you really mean is only use the openssl
> > CMS_... API for producing PKCS7 signatures.
> 
> Ok, I plan to update the description to the following in v2:
> 
> sign-file: Use only the OpenSSL CMS API for signing
> 
> The USE_PKCS7 code in sign-file utilizes PKCS7_sign(), which allows
> signing only with SHA-1. Since SHA-1 support for module signing has
> been removed, drop the use of the OpenSSL PKCS7 API by the tool in
> favor of using only the newer CMS API.

Much better, thanks!

Regards,

James
[PATCH] sign-file, pkcs7: Honour the hash parameter to sign-file
Posted by David Howells 6 days, 20 hours ago
Here's an alternative patch that will allow PKCS#7 with the hash specified on
the command line, removing the SHA1 restriction.

David
---
sign-file, pkcs7: Honour the hash parameter to sign-file

Currently, the sign-file program rejects anything other than "sha1" as the
hash parameter if it is going to produce a PKCS#7 message-based signature
rather than a CMS message-based signature (though it then ignores this
argument and uses whatever is selected as the default which might not be
SHA1 and may actually reflect whatever is used to sign the X.509
certificate).

Fix sign-file to actually use the specified hash when producing a PKCS#7
message rather than just accepting the default.

Fixes: 283e8ba2dfde ("MODSIGN: Change from CMS to PKCS#7 signing if the openssl is too old")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Jarkko Sakkinen <jarkko@kernel.org>
cc: Stephan Mueller <smueller@chronox.de>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Eric Biggers <ebiggers@kernel.org>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org

diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 547b97097230..f0b7e5616b9a 100644
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -56,6 +56,7 @@
 	defined(OPENSSL_NO_CMS)
 #define USE_PKCS7
 #endif
+#define USE_PKCS7
 #ifndef USE_PKCS7
 #include <openssl/cms.h>
 #else
@@ -289,14 +290,6 @@ int main(int argc, char **argv)
 		replace_orig = true;
 	}
 
-#ifdef USE_PKCS7
-	if (strcmp(hash_algo, "sha1") != 0) {
-		fprintf(stderr, "sign-file: %s only supports SHA1 signing\n",
-			OPENSSL_VERSION_TEXT);
-		exit(3);
-	}
-#endif
-
 	/* Open the module file */
 	bm = BIO_new_file(module_name, "rb");
 	ERR(!bm, "%s", module_name);
@@ -348,10 +341,17 @@ int main(int argc, char **argv)
 		    "CMS_final");
 
 #else
-		pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
-				   PKCS7_NOCERTS | PKCS7_BINARY |
-				   PKCS7_DETACHED | use_signed_attrs);
+		unsigned int flags =
+			PKCS7_NOCERTS |
+			PKCS7_BINARY |
+			PKCS7_DETACHED |
+			use_signed_attrs;
+		pkcs7 = PKCS7_sign(NULL, NULL, NULL, bm, flags);
 		ERR(!pkcs7, "PKCS7_sign");
+
+		ERR(!PKCS7_sign_add_signer(pkcs7, x509, private_key, digest_algo, flags),
+		    "PKS7_sign_add_signer");
+		ERR(PKCS7_final(pkcs7, bm, flags) != 1, "PKCS7_final");
 #endif
 
 		if (save_sig) {
Re: [PATCH] sign-file, pkcs7: Honour the hash parameter to sign-file
Posted by Petr Pavlu 6 days, 19 hours ago
On 2/2/26 12:24 PM, David Howells wrote:
> Here's an alternative patch that will allow PKCS#7 with the hash specified on
> the command line, removing the SHA1 restriction.
> 
> David
> ---
> sign-file, pkcs7: Honour the hash parameter to sign-file
> 
> Currently, the sign-file program rejects anything other than "sha1" as the
> hash parameter if it is going to produce a PKCS#7 message-based signature
> rather than a CMS message-based signature (though it then ignores this
> argument and uses whatever is selected as the default which might not be
> SHA1 and may actually reflect whatever is used to sign the X.509
> certificate).
> 
> Fix sign-file to actually use the specified hash when producing a PKCS#7
> message rather than just accepting the default.

Is it worth keeping this sign-file code that uses the OpenSSL PKCS7 API
instead of having only one variant that uses the newer CMS API?

-- 
Thanks,
Petr
Re: [PATCH] sign-file, pkcs7: Honour the hash parameter to sign-file
Posted by Sami Tolvanen 6 days, 15 hours ago
On Mon, Feb 2, 2026 at 4:25 AM Petr Pavlu <petr.pavlu@suse.com> wrote:
>
> On 2/2/26 12:24 PM, David Howells wrote:
> > Here's an alternative patch that will allow PKCS#7 with the hash specified on
> > the command line, removing the SHA1 restriction.
> >
> > David
> > ---
> > sign-file, pkcs7: Honour the hash parameter to sign-file
> >
> > Currently, the sign-file program rejects anything other than "sha1" as the
> > hash parameter if it is going to produce a PKCS#7 message-based signature
> > rather than a CMS message-based signature (though it then ignores this
> > argument and uses whatever is selected as the default which might not be
> > SHA1 and may actually reflect whatever is used to sign the X.509
> > certificate).
> >
> > Fix sign-file to actually use the specified hash when producing a PKCS#7
> > message rather than just accepting the default.
>
> Is it worth keeping this sign-file code that uses the OpenSSL PKCS7 API
> instead of having only one variant that uses the newer CMS API?

I agree that keeping only the CMS variant makes more sense. However,
David, please let me know if you'd prefer that I drop the patch
removing PKCS7 support from sign-file for now. I assumed you had no
further objections since the discussion in the other sub-thread
tapered off, but perhaps I misread that.

Sami
Re: [PATCH] sign-file, pkcs7: Honour the hash parameter to sign-file
Posted by David Howells 6 days, 20 hours ago
David Howells <dhowells@redhat.com> wrote:

> @@ -56,6 +56,7 @@
>  	defined(OPENSSL_NO_CMS)
>  #define USE_PKCS7
>  #endif
> +#define USE_PKCS7
>  #ifndef USE_PKCS7
>  #include <openssl/cms.h>
>  #else

Apologies, that line was so I could debug it and should've been removed.

David