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
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
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
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
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
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
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
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
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) {
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
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
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
© 2016 - 2026 Red Hat, Inc.