Message ID | 20231110222751.219836-7-ross.philipson@oracle.com (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | Herbert Xu |
Headers | show |
Series | x86: Trenchboot secure dynamic launch Linux kernel support | expand |
On Fri, Nov 10, 2023 at 05:27:44PM -0500, Ross Philipson wrote: > arch/x86/boot/compressed/early_sha1.c | 12 ++++ > lib/crypto/sha1.c | 81 +++++++++++++++++++++++++ It's surprising to still see this new use of SHA-1 after so many people objected to it in the v6 patchset. It's also frustrating that the SHA-1 support is still being obfuscated by being combined in one patch with SHA-2 support, perhaps in an attempt to conflate the two algorithms and avoid having to give a rationale for the inclusion of SHA-1. Finally, new functions should not be added to lib/crypto/sha1.c unless those functions have multiple users. - Eric
On 11/11/2023 5:44 pm, Eric Biggers wrote: > On Fri, Nov 10, 2023 at 05:27:44PM -0500, Ross Philipson wrote: >> arch/x86/boot/compressed/early_sha1.c | 12 ++++ >> lib/crypto/sha1.c | 81 +++++++++++++++++++++++++ > It's surprising to still see this new use of SHA-1 after so many people objected > to it in the v6 patchset. It's also frustrating that the SHA-1 support is still > being obfuscated by being combined in one patch with SHA-2 support, perhaps in > an attempt to conflate the two algorithms and avoid having to give a rationale > for the inclusion of SHA-1. Finally, new functions should not be added to > lib/crypto/sha1.c unless those functions have multiple users. The rational was given. Let me reiterate it. There are real TPMs in the world that can't use SHA-2. The use of SHA-1 is necessary to support DRTM on such systems, and there are real users of such configurations. DRTM with SHA-1-only is a damnsight better than no DTRM, even if SHA-1 is getting a little long in the tooth. So unless you have a credible plan to upgrade every non-SHA-2 TPM in the world, you are deliberately breaking part of the usecase paying for the effort of trying to upstream DRTM support into Linux. ~Andrew
On Sat, 2023-11-11 at 18:19 +0000, Andrew Cooper wrote: > On 11/11/2023 5:44 pm, Eric Biggers wrote: > > On Fri, Nov 10, 2023 at 05:27:44PM -0500, Ross Philipson wrote: > > > arch/x86/boot/compressed/early_sha1.c | 12 ++++ > > > lib/crypto/sha1.c | 81 > > > +++++++++++++++++++++++++ > > It's surprising to still see this new use of SHA-1 after so many > > people objected to it in the v6 patchset. It's also frustrating > > that the SHA-1 support is still being obfuscated by being combined > > in one patch with SHA-2 support, perhaps in an attempt to conflate > > the two algorithms and avoid having to give a rationale for the > > inclusion of SHA-1. Finally, new functions should not be added to > > lib/crypto/sha1.c unless those functions have multiple users. > > The rational was given. Let me reiterate it. > > There are real TPMs in the world that can't use SHA-2. The use of > SHA-1 is necessary to support DRTM on such systems, and there are > real users of such configurations. Given that TPM 2.0 has been shipping in bulk since Windows 10 (2015) and is required for Windows 11 (2021), are there really such huge numbers of TPM 1.2 systems involved in security functions? > DRTM with SHA-1-only is a damnsight better than no DTRM, even if SHA- > 1 is getting a little long in the tooth. That's not the problem. The problem is that sha1 is seen as a compromised algorithm by NIST which began deprecating it in 2011 and is now requiring it to be removed from all systems supplied to the US government by 2030 https://www.nist.gov/news-events/news/2022/12/nist-retires-sha-1-cryptographic-algorithm That means we have to control all uses of sha1 in the kernel and have an option to build without it. FIPS has an even tighter timetable: it requires sha1 to be out by 2025. > So unless you have a credible plan to upgrade every non-SHA-2 TPM in > the world, you are deliberately breaking part of the usecase paying > for the effort of trying to upstream DRTM support into Linux. Given that most CSOs follow NIST and FIPS it seems a little strange that there would be a huge demand for such an intricate security protocol as Dynamic Launch on a system that can't be FIPS 140-3 certified. James
On 11/11/2023 8:36 pm, James Bottomley wrote: > On Sat, 2023-11-11 at 18:19 +0000, Andrew Cooper wrote: >> On 11/11/2023 5:44 pm, Eric Biggers wrote: >>> On Fri, Nov 10, 2023 at 05:27:44PM -0500, Ross Philipson wrote: >>>> arch/x86/boot/compressed/early_sha1.c | 12 ++++ >>>> lib/crypto/sha1.c | 81 >>>> +++++++++++++++++++++++++ >>> It's surprising to still see this new use of SHA-1 after so many >>> people objected to it in the v6 patchset. It's also frustrating >>> that the SHA-1 support is still being obfuscated by being combined >>> in one patch with SHA-2 support, perhaps in an attempt to conflate >>> the two algorithms and avoid having to give a rationale for the >>> inclusion of SHA-1. Finally, new functions should not be added to >>> lib/crypto/sha1.c unless those functions have multiple users. >> The rational was given. Let me reiterate it. >> >> There are real TPMs in the world that can't use SHA-2. The use of >> SHA-1 is necessary to support DRTM on such systems, and there are >> real users of such configurations. > Given that TPM 2.0 has been shipping in bulk since Windows 10 (2015) > and is required for Windows 11 (2021), are there really such huge > numbers of TPM 1.2 systems involved in security functions? Yes. As ever, it's not as simple as a straight TPM version issue. AMD's firmware-TPM2 isn't compatible with their DRTM implementation. Users are limited to whatever headers are available on the motherboard. Furthermore, even with a TPM2, it is the firmware (Intel TXT ACM) or hardware (AMD SKINIT) which chooses the hash algorithms to use, and in a lot of cases the end user doesn't get a choice. So yes - there really are modern systems which you can't use SHA-2-only with. >> DRTM with SHA-1-only is a damnsight better than no DTRM, even if SHA- >> 1 is getting a little long in the tooth. > That's not the problem. The problem is that sha1 is seen as a > compromised algorithm by NIST which began deprecating it in 2011 and is > now requiring it to be removed from all systems supplied to the US > government by 2030 This is a non-issue. People who care about having no SHA-1 can not compile in DRTM support. But there are people who will tolerate SHA-1 code to get DTRM support. ~Andrew
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 71fc531b95b4..07a2f56cd571 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -118,6 +118,8 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a +vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/early_sha1.o $(obj)/early_sha256.o + $(obj)/vmlinux: $(vmlinux-objs-y) FORCE $(call if_changed,ld) diff --git a/arch/x86/boot/compressed/early_sha1.c b/arch/x86/boot/compressed/early_sha1.c new file mode 100644 index 000000000000..0c7cf6f8157a --- /dev/null +++ b/arch/x86/boot/compressed/early_sha1.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Apertus Solutions, LLC. + */ + +#include <linux/init.h> +#include <linux/linkage.h> +#include <linux/string.h> +#include <asm/boot.h> +#include <asm/unaligned.h> + +#include "../../../../lib/crypto/sha1.c" diff --git a/arch/x86/boot/compressed/early_sha256.c b/arch/x86/boot/compressed/early_sha256.c new file mode 100644 index 000000000000..54930166ffee --- /dev/null +++ b/arch/x86/boot/compressed/early_sha256.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Apertus Solutions, LLC + */ + +#include "../../../../lib/crypto/sha256.c" diff --git a/include/crypto/sha1.h b/include/crypto/sha1.h index 044ecea60ac8..d715dd5332e1 100644 --- a/include/crypto/sha1.h +++ b/include/crypto/sha1.h @@ -42,5 +42,6 @@ extern int crypto_sha1_finup(struct shash_desc *desc, const u8 *data, #define SHA1_WORKSPACE_WORDS 16 void sha1_init(__u32 *buf); void sha1_transform(__u32 *digest, const char *data, __u32 *W); +void sha1(const u8 *data, unsigned int len, u8 *out); #endif /* _CRYPTO_SHA1_H */ diff --git a/lib/crypto/sha1.c b/lib/crypto/sha1.c index 1aebe7be9401..10152125b338 100644 --- a/lib/crypto/sha1.c +++ b/lib/crypto/sha1.c @@ -137,4 +137,85 @@ void sha1_init(__u32 *buf) } EXPORT_SYMBOL(sha1_init); +static void __sha1_transform(u32 *digest, const char *data) +{ + u32 ws[SHA1_WORKSPACE_WORDS]; + + sha1_transform(digest, data, ws); + + memzero_explicit(ws, sizeof(ws)); +} + +static void sha1_update(struct sha1_state *sctx, const u8 *data, unsigned int len) +{ + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; + + sctx->count += len; + + if (likely((partial + len) >= SHA1_BLOCK_SIZE)) { + int blocks; + + if (partial) { + int p = SHA1_BLOCK_SIZE - partial; + + memcpy(sctx->buffer + partial, data, p); + data += p; + len -= p; + + __sha1_transform(sctx->state, sctx->buffer); + } + + blocks = len / SHA1_BLOCK_SIZE; + len %= SHA1_BLOCK_SIZE; + + if (blocks) { + while (blocks--) { + __sha1_transform(sctx->state, data); + data += SHA1_BLOCK_SIZE; + } + } + partial = 0; + } + + if (len) + memcpy(sctx->buffer + partial, data, len); +} + +static void sha1_final(struct sha1_state *sctx, u8 *out) +{ + const int bit_offset = SHA1_BLOCK_SIZE - sizeof(__be64); + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; + __be64 *bits = (__be64 *)(sctx->buffer + bit_offset); + __be32 *digest = (__be32 *)out; + int i; + + sctx->buffer[partial++] = 0x80; + if (partial > bit_offset) { + memset(sctx->buffer + partial, 0x0, SHA1_BLOCK_SIZE - partial); + partial = 0; + + __sha1_transform(sctx->state, sctx->buffer); + } + + memset(sctx->buffer + partial, 0x0, bit_offset - partial); + *bits = cpu_to_be64(sctx->count << 3); + __sha1_transform(sctx->state, sctx->buffer); + + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++) + put_unaligned_be32(sctx->state[i], digest++); + + *sctx = (struct sha1_state){}; +} + +void sha1(const u8 *data, unsigned int len, u8 *out) +{ + struct sha1_state sctx = {0}; + + sha1_init(sctx.state); + sctx.count = 0; + sha1_update(&sctx, data, len); + sha1_final(&sctx, out); +} +EXPORT_SYMBOL(sha1); + MODULE_LICENSE("GPL");