diff options
-rw-r--r-- | src/arch/i386/scripts/i386-kir.lds | 2 | ||||
-rw-r--r-- | src/arch/i386/scripts/linux.lds | 2 | ||||
-rw-r--r-- | src/arch/x86/scripts/pcbios.lds | 2 | ||||
-rw-r--r-- | src/arch/x86/scripts/prefixonly.lds | 2 | ||||
-rw-r--r-- | src/arch/x86_64/scripts/linux.lds | 2 | ||||
-rw-r--r-- | src/config/branding.h | 18 | ||||
-rw-r--r-- | src/core/version.c | 30 | ||||
-rw-r--r-- | src/include/ipxe/sbat.h | 68 | ||||
-rw-r--r-- | src/scripts/efi.lds | 13 |
9 files changed, 139 insertions, 0 deletions
diff --git a/src/arch/i386/scripts/i386-kir.lds b/src/arch/i386/scripts/i386-kir.lds index 66bf804e6..13c36f2bf 100644 --- a/src/arch/i386/scripts/i386-kir.lds +++ b/src/arch/i386/scripts/i386-kir.lds @@ -136,6 +136,8 @@ SECTIONS { *(.note.*) *(.discard) *(.discard.*) + *(.sbat) + *(.sbat.*) } /* diff --git a/src/arch/i386/scripts/linux.lds b/src/arch/i386/scripts/linux.lds index 9f2eeaf3c..8c3a7b0ba 100644 --- a/src/arch/i386/scripts/linux.lds +++ b/src/arch/i386/scripts/linux.lds @@ -100,5 +100,7 @@ SECTIONS { *(.rel.*) *(.discard) *(.discard.*) + *(.sbat) + *(.sbat.*) } } diff --git a/src/arch/x86/scripts/pcbios.lds b/src/arch/x86/scripts/pcbios.lds index de59adca9..e208b174b 100644 --- a/src/arch/x86/scripts/pcbios.lds +++ b/src/arch/x86/scripts/pcbios.lds @@ -229,6 +229,8 @@ SECTIONS { *(.einfo.*) *(.discard) *(.discard.*) + *(.sbat) + *(.sbat.*) } /* diff --git a/src/arch/x86/scripts/prefixonly.lds b/src/arch/x86/scripts/prefixonly.lds index dce0930b5..2fe5b03be 100644 --- a/src/arch/x86/scripts/prefixonly.lds +++ b/src/arch/x86/scripts/prefixonly.lds @@ -24,6 +24,8 @@ SECTIONS { *(.einfo.*) *(.discard) *(.discard.*) + *(.sbat) + *(.sbat.*) } } diff --git a/src/arch/x86_64/scripts/linux.lds b/src/arch/x86_64/scripts/linux.lds index 47db21745..a093787e5 100644 --- a/src/arch/x86_64/scripts/linux.lds +++ b/src/arch/x86_64/scripts/linux.lds @@ -100,5 +100,7 @@ SECTIONS { *(.rel.*) *(.discard) *(.discard.*) + *(.sbat) + *(.sbat.*) } } diff --git a/src/config/branding.h b/src/config/branding.h index e503dff9a..454bf0c03 100644 --- a/src/config/branding.h +++ b/src/config/branding.h @@ -169,6 +169,24 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ #define PRODUCT_SETTING_URI "https://ipxe.org/cfg/%s" +/* + * Product security name suffix + * + * Vendors creating signed iPXE binaries must set this to a non-empty + * value (e.g. "2pint"). + */ +#define PRODUCT_SBAT_NAME "" + +/* + * Product security generation + * + * Vendors creating signed iPXE binaries must set this to a non-zero + * value, and must increment the value whenever a Secure Boot exploit + * is fixed (unless the upstream IPXE_SBAT_GENERATION has already been + * incremented as part of that fix). + */ +#define PRODUCT_SBAT_GENERATION 0 + #include <config/local/branding.h> #endif /* CONFIG_BRANDING_H */ diff --git a/src/core/version.c b/src/core/version.c index c984335c2..22f444065 100644 --- a/src/core/version.c +++ b/src/core/version.c @@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <wchar.h> #include <ipxe/features.h> #include <ipxe/version.h> +#include <ipxe/sbat.h> #include <config/general.h> #include <config/branding.h> @@ -92,3 +93,32 @@ const wchar_t build_wname[] = WSTRING ( BUILD_NAME ); /** Copy of build name string within ".prefix" */ const char build_name_prefix[] __attribute__ (( section ( ".prefix.name" ) )) = BUILD_NAME; + +/** SBAT upstream iPXE line + * + * This line represents the security generation of the upstream + * codebase from which this build is derived. + */ +#define SBAT_IPXE \ + SBAT_LINE ( "ipxe", IPXE_SBAT_GENERATION, \ + "iPXE", BUILD_NAME, VERSION, "https://ipxe.org" ) + +/** SBAT local build line + * + * This line states the security generation of the local build, which + * may include non-default features or non-upstreamed modifications. + */ +#if PRODUCT_SBAT_GENERATION +#define SBAT_PRODUCT \ + SBAT_LINE ( "ipxe." PRODUCT_SBAT_NAME, PRODUCT_SBAT_GENERATION, \ + PRODUCT_SHORT_NAME, BUILD_NAME, VERSION, \ + PRODUCT_URI ) +#else +#define SBAT_PRODUCT "" +#endif + +/** SBAT data */ +#define SBAT_DATA SBAT_HEADER "" SBAT_IPXE "" SBAT_PRODUCT + +/** SBAT data (without any NUL terminator) */ +const char sbat[ sizeof ( SBAT_DATA ) - 1 ] __sbat = SBAT_DATA; diff --git a/src/include/ipxe/sbat.h b/src/include/ipxe/sbat.h new file mode 100644 index 000000000..4b74670ed --- /dev/null +++ b/src/include/ipxe/sbat.h @@ -0,0 +1,68 @@ +#ifndef _IPXE_SBAT_H +#define _IPXE_SBAT_H + +/** @file + * + * Secure Boot Advanced Targeting (SBAT) + * + * SBAT defines an encoding for security generation numbers stored as + * a CSV file within a special ".sbat" section in the signed binary. + * If a Secure Boot exploit is discovered then the generation number + * will be incremented alongside the corresponding fix. + * + * Platforms may then record the minimum generation number required + * for any given product. This allows for an efficient revocation + * mechanism that consumes minimal flash storage space (in contrast to + * the DBX mechanism, which allows for only a single-digit number of + * revocation events to ever take place across all possible signed + * binaries). + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** + * A single line within an SBAT CSV file + * + * @v name Machine-readable component name + * @v generation Security generation number + * @v vendor Human-readable vendor name + * @v package Human-readable package name + * @v version Human-readable package version + * @v uri Contact URI + * @ret line CSV line + */ +#define SBAT_LINE( name, generation, vendor, package, version, uri ) \ + name "," _S2 ( generation ) "," vendor "," package "," \ + version "," uri "\n" + +/** SBAT format generation */ +#define SBAT_GENERATION 1 + +/** Upstream security generation + * + * This represents the security generation of the upstream codebase. + * It will be incremented whenever a Secure Boot exploit is fixed in + * the upstream codebase. + * + * If you do not have commit access to the upstream iPXE repository, + * then you may not modify this value under any circumstances. + */ +#define IPXE_SBAT_GENERATION 1 + +/* Seriously, do not modify this value */ +#if IPXE_SBAT_GENERATION != 1 +#error "You may not modify IPXE_SBAT_GENERATION" +#endif + +/** SBAT header line */ +#define SBAT_HEADER \ + SBAT_LINE ( "sbat", SBAT_GENERATION, "SBAT Version", "sbat", \ + _S2 ( SBAT_GENERATION ), \ + "https://github.com/rhboot/shim/blob/main/SBAT.md" ) + +/** Mark variable as being in the ".sbat" section */ +#define __sbat __attribute__ (( section ( ".sbat" ), aligned ( 512 ) )) + +extern const char sbat[] __sbat; + +#endif /* _IPXE_SBAT_H */ diff --git a/src/scripts/efi.lds b/src/scripts/efi.lds index dd7b3f019..218b1df66 100644 --- a/src/scripts/efi.lds +++ b/src/scripts/efi.lds @@ -75,6 +75,19 @@ SECTIONS { } /* + * The SBAT section + * + */ + + . = ALIGN ( _page_align ); + .sbat : { + _sbat = .; + KEEP(*(.sbat)) + KEEP(*(.sbat.*)) + _esbat = .; + } + + /* * Weak symbols that need zero values if not otherwise defined * */ |