diff options
-rw-r--r-- | Cryptlib/Pk/CryptAuthenticode.c | 4 | ||||
-rw-r--r-- | Make.defaults | 2 | ||||
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | commit | 2 | ||||
-rwxr-xr-x | data/sbat.csv | 2 | ||||
-rw-r--r-- | elf_aarch64_efi.lds | 4 | ||||
-rw-r--r-- | elf_ia32_efi.lds | 4 | ||||
-rw-r--r-- | elf_ia64_efi.lds | 4 | ||||
-rw-r--r-- | elf_x86_64_efi.lds | 4 | ||||
-rw-r--r-- | include/cc.h | 85 | ||||
-rw-r--r-- | include/compiler.h | 6 | ||||
-rw-r--r-- | include/guid.h | 1 | ||||
-rw-r--r-- | include/sbat.h | 32 | ||||
-rw-r--r-- | include/sbat_var_defs.h | 45 | ||||
-rw-r--r-- | include/test.mk | 2 | ||||
-rw-r--r-- | include/ucs2.h | 18 | ||||
-rw-r--r-- | lib/guid.c | 1 | ||||
-rw-r--r-- | load-options.c | 7 | ||||
-rwxr-xr-x | make-archive | 4 | ||||
-rw-r--r-- | model.c | 23 | ||||
-rw-r--r-- | mok.c | 1 | ||||
-rw-r--r-- | pe.c | 5 | ||||
-rw-r--r-- | sbat.c | 21 | ||||
-rw-r--r-- | sbat_var.S | 20 | ||||
-rw-r--r-- | shim.c | 18 | ||||
-rw-r--r-- | shim.h | 2 | ||||
-rw-r--r-- | tpm.c | 48 |
28 files changed, 294 insertions, 82 deletions
diff --git a/Cryptlib/Pk/CryptAuthenticode.c b/Cryptlib/Pk/CryptAuthenticode.c index 74e50a2e..f6f988b8 100644 --- a/Cryptlib/Pk/CryptAuthenticode.c +++ b/Cryptlib/Pk/CryptAuthenticode.c @@ -9,7 +9,7 @@ AuthenticodeVerify() will get PE/COFF Authenticode and will do basic check for
data structure.
-Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -106,7 +106,7 @@ AuthenticodeVerify ( //
// Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
//
- if (!PKCS7_type_is_signed (Pkcs7)) {
+ if (!PKCS7_type_is_signed (Pkcs7) || PKCS7_get_detached (Pkcs7)) {
goto _Exit;
}
diff --git a/Make.defaults b/Make.defaults index dfed9c4a..c46164a3 100644 --- a/Make.defaults +++ b/Make.defaults @@ -71,7 +71,7 @@ ifeq ($(ARCH),x86_64) endif ifeq ($(ARCH),ia32) ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \ - $(CLANG_BUGS) -m32 \ + $(CLANG_BUGS) -m32 -malign-double \ -DMDE_CPU_IA32 -DPAGE_SIZE=4096 ARCH_GNUEFI ?= ia32 ARCH_SUFFIX ?= ia32 @@ -1,7 +1,7 @@ default : all NAME = shim -VERSION = 15.6 +VERSION = 15.7 ifneq ($(origin RELEASE),undefined) DASHRELEASE ?= -$(RELEASE) else @@ -38,9 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT else TARGETS += $(MMNAME) $(FBNAME) endif -OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o pe.o httpboot.o csv.o load-options.o +OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o httpboot.o csv.o load-options.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer -ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S +ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h) FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o @@ -253,7 +253,7 @@ endif $(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \ -j .dynamic -j .rodata -j .rel* \ -j .rela* -j .dyn -j .reloc -j .eh_frame \ - -j .vendor_cert -j .sbat \ + -j .vendor_cert -j .sbat -j .sbatlevel \ $(FORMAT) $< $@ ./post-process-pe -vv $@ @@ -269,6 +269,7 @@ endif $(OBJCOPY) -D -j .text -j .sdata -j .data \ -j .dynamic -j .rodata -j .rel* \ -j .rela* -j .dyn -j .reloc -j .eh_frame -j .sbat \ + -j .sbatlevel \ -j .debug_info -j .debug_abbrev -j .debug_aranges \ -j .debug_line -j .debug_str -j .debug_ranges \ -j .note.gnu.build-id \ @@ -23,3 +23,5 @@ pub.cer and build with `make VENDOR_CERT_FILE=pub.cer`. There are a couple of build options, and a couple of ways to customize the build, described in [BUILDING](BUILDING). + +See the [test plan](testplan.txt), and file a ticket if anything fails! @@ -1 +1 @@ -505cdb678b319fcf9a7fdee77c0f091b4147cbe5
\ No newline at end of file +11491619f4336fef41c3519877ba242161763580
\ No newline at end of file diff --git a/data/sbat.csv b/data/sbat.csv index 7a5169fb..2beec754 100755 --- a/data/sbat.csv +++ b/data/sbat.csv @@ -1,2 +1,2 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -shim,2,UEFI shim,shim,1,https://github.com/rhboot/shim +shim,3,UEFI shim,shim,1,https://github.com/rhboot/shim diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds index 60c55ba5..0861f5e8 100644 --- a/elf_aarch64_efi.lds +++ b/elf_aarch64_efi.lds @@ -34,6 +34,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/elf_ia32_efi.lds b/elf_ia32_efi.lds index 497a3a15..e8da91bd 100644 --- a/elf_ia32_efi.lds +++ b/elf_ia32_efi.lds @@ -28,6 +28,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/elf_ia64_efi.lds b/elf_ia64_efi.lds index 2669b856..a2195609 100644 --- a/elf_ia64_efi.lds +++ b/elf_ia64_efi.lds @@ -34,6 +34,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/elf_x86_64_efi.lds b/elf_x86_64_efi.lds index bcc65270..39aff6b0 100644 --- a/elf_x86_64_efi.lds +++ b/elf_x86_64_efi.lds @@ -35,6 +35,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/include/cc.h b/include/cc.h new file mode 100644 index 00000000..8b127208 --- /dev/null +++ b/include/cc.h @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifndef SHIM_CC_H +#define SHIM_CC_H + +typedef struct { + uint8_t Major; + uint8_t Minor; +} EFI_CC_VERSION; + +#define EFI_CC_TYPE_NONE 0 +#define EFI_CC_TYPE_SEV 1 +#define EFI_CC_TYPE_TDX 2 + +typedef struct { + uint8_t Type; + uint8_t SubType; +} EFI_CC_TYPE; + +typedef uint32_t EFI_CC_EVENT_LOG_BITMAP; +typedef uint32_t EFI_CC_EVENT_LOG_FORMAT; +typedef uint32_t EFI_CC_EVENT_ALGORITHM_BITMAP; +typedef uint32_t EFI_CC_MR_INDEX; + +#define TDX_MR_INDEX_MRTD 0 +#define TDX_MR_INDEX_RTMR0 1 +#define TDX_MR_INDEX_RTMR1 2 +#define TDX_MR_INDEX_RTMR2 3 +#define TDX_MR_INDEX_RTMR3 4 + +#define EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002 +#define EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004 +#define EFI_CC_EVENT_HEADER_VERSION 1 + +typedef struct tdEFI_CC_EVENT_HEADER { + uint32_t HeaderSize; + uint16_t HeaderVersion; + EFI_CC_MR_INDEX MrIndex; + uint32_t EventType; +} __attribute__((packed)) EFI_CC_EVENT_HEADER; + +typedef struct tdEFI_CC_EVENT { + uint32_t Size; + EFI_CC_EVENT_HEADER Header; + uint8_t Event[1]; +} __attribute__((packed)) EFI_CC_EVENT; + +typedef struct tdEFI_CC_BOOT_SERVICE_CAPABILITY { + uint8_t Size; + EFI_CC_VERSION StructureVersion; + EFI_CC_VERSION ProtocolVersion; + EFI_CC_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; + EFI_CC_EVENT_LOG_BITMAP SupportedEventLogs; + EFI_CC_TYPE CcType; +} EFI_CC_BOOT_SERVICE_CAPABILITY; + +struct efi_cc_protocol +{ + EFI_STATUS (EFIAPI *get_capability) ( + struct efi_cc_protocol *this, + EFI_CC_BOOT_SERVICE_CAPABILITY *ProtocolCapability); + EFI_STATUS (EFIAPI *get_event_log) ( + struct efi_cc_protocol *this, + EFI_CC_EVENT_LOG_FORMAT EventLogFormat, + EFI_PHYSICAL_ADDRESS *EventLogLocation, + EFI_PHYSICAL_ADDRESS *EventLogLastEntry, + BOOLEAN *EventLogTruncated); + EFI_STATUS (EFIAPI *hash_log_extend_event) ( + struct efi_cc_protocol *this, + uint64_t Flags, + EFI_PHYSICAL_ADDRESS DataToHash, + uint64_t DataToHashLen, + EFI_CC_EVENT *EfiCcEvent); + EFI_STATUS (EFIAPI *map_pcr_to_mr_index) ( + struct efi_cc_protocol *this, + uint32_t PcrIndex, + EFI_CC_MR_INDEX *MrIndex); +}; + +typedef struct efi_cc_protocol efi_cc_protocol_t; + +#define EFI_CC_FLAG_PE_COFF_IMAGE 0x0000000000000010 + +#endif /* SHIM_CC_H */ +// vim:fenc=utf-8:tw=75 diff --git a/include/compiler.h b/include/compiler.h index b4bf1031..b0d595f3 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -192,5 +192,11 @@ */ #define unreachable() __builtin_unreachable() +#if defined(__GNUC__) +#define cache_invalidate(begin, end) __builtin___clear_cache(begin, end) +#else /* __GNUC__ */ +#error shim has no cache_invalidate() implementation for this compiler +#endif /* __GNUC__ */ + #endif /* !COMPILER_H_ */ // vim:fenc=utf-8:tw=75:et diff --git a/include/guid.h b/include/guid.h index d9910ff1..dad63f0f 100644 --- a/include/guid.h +++ b/include/guid.h @@ -29,6 +29,7 @@ extern EFI_GUID EFI_IP6_CONFIG_GUID; extern EFI_GUID EFI_LOADED_IMAGE_GUID; extern EFI_GUID EFI_TPM_GUID; extern EFI_GUID EFI_TPM2_GUID; +extern EFI_GUID EFI_CC_MEASUREMENT_PROTOCOL_GUID; extern EFI_GUID EFI_SECURE_BOOT_DB_GUID; extern EFI_GUID EFI_SIMPLE_FILE_SYSTEM_GUID; extern EFI_GUID SECURITY_PROTOCOL_GUID; diff --git a/include/sbat.h b/include/sbat.h index aca43598..c94c4fba 100644 --- a/include/sbat.h +++ b/include/sbat.h @@ -6,38 +6,6 @@ #ifndef SBAT_H_ #define SBAT_H_ -#define SBAT_VAR_SIG "sbat," -#define SBAT_VAR_VERSION "1," -#define SBAT_VAR_ORIGINAL_DATE "2021030218" -#define SBAT_VAR_ORIGINAL \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_ORIGINAL_DATE "\n" - -#if defined(ENABLE_SHIM_DEVEL) -#define SBAT_VAR_PREVIOUS_DATE "2022020101" -#define SBAT_VAR_PREVIOUS_REVOCATIONS "component,2\n" -#define SBAT_VAR_PREVIOUS \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ - SBAT_VAR_PREVIOUS_REVOCATIONS - -#define SBAT_VAR_LATEST_DATE "2022050100" -#define SBAT_VAR_LATEST_REVOCATIONS "component,2\nothercomponent,2\n" -#define SBAT_VAR_LATEST \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ - SBAT_VAR_LATEST_REVOCATIONS -#else /* !ENABLE_SHIM_DEVEL */ -#define SBAT_VAR_PREVIOUS_DATE SBAT_VAR_ORIGINAL_DATE -#define SBAT_VAR_PREVIOUS_REVOCATIONS -#define SBAT_VAR_PREVIOUS \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ - SBAT_VAR_PREVIOUS_REVOCATIONS - -#define SBAT_VAR_LATEST_DATE "2022052400" -#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,2\n" -#define SBAT_VAR_LATEST \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ - SBAT_VAR_LATEST_REVOCATIONS -#endif /* ENABLE_SHIM_DEVEL */ - #define UEFI_VAR_NV_BS \ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) #define UEFI_VAR_NV_BS_RT \ diff --git a/include/sbat_var_defs.h b/include/sbat_var_defs.h new file mode 100644 index 00000000..6b01573e --- /dev/null +++ b/include/sbat_var_defs.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifndef SBAT_VAR_DEFS_H_ +#define SBAT_VAR_DEFS_H_ + +/* + * This is the entry for the sbat data format + */ +#define SBAT_VAR_SIG "sbat," +#define SBAT_VAR_VERSION "1," +#define SBAT_VAR_ORIGINAL_DATE "2021030218" +#define SBAT_VAR_ORIGINAL \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_ORIGINAL_DATE "\n" + +#if defined(ENABLE_SHIM_DEVEL) +#define SBAT_VAR_PREVIOUS_DATE "2022020101" +#define SBAT_VAR_PREVIOUS_REVOCATIONS "component,2\n" +#define SBAT_VAR_PREVIOUS \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ + SBAT_VAR_PREVIOUS_REVOCATIONS + +#define SBAT_VAR_LATEST_DATE "2022050100" +#define SBAT_VAR_LATEST_REVOCATIONS "component,2\nothercomponent,2\n" +#define SBAT_VAR_LATEST \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ + SBAT_VAR_LATEST_REVOCATIONS +#else /* !ENABLE_SHIM_DEVEL */ +/* + * As of 2022-11-16, most folks (including Ubuntu, SUSE, openSUSE) don't have + * a "shim,2" yet, so adding that here would end up unbootable. + */ +#define SBAT_VAR_PREVIOUS_DATE "2022052400" +#define SBAT_VAR_PREVIOUS_REVOCATIONS "grub,2\n" +#define SBAT_VAR_PREVIOUS \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ + SBAT_VAR_PREVIOUS_REVOCATIONS + +#define SBAT_VAR_LATEST_DATE "2022111500" +#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,3\n" +#define SBAT_VAR_LATEST \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ + SBAT_VAR_LATEST_REVOCATIONS +#endif /* ENABLE_SHIM_DEVEL */ + +#endif /* !SBAT_VAR_DEFS_H_ */ diff --git a/include/test.mk b/include/test.mk index e965c600..c0e24095 100644 --- a/include/test.mk +++ b/include/test.mk @@ -92,7 +92,7 @@ test-mock-variables: CFLAGS+=-DHAVE_SHIM_LOCK_GUID test-mok-mirror_FILES = mok.c globals.c tpm.c lib/guid.c lib/variables.c mock-variables.c test-mok-mirror: CFLAGS+=-DHAVE_START_IMAGE -DHAVE_SHIM_LOCK_GUID -test-sbat_FILES = csv.c lib/variables.c lib/guid.c +test-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S test-sbat :: CFLAGS+=-DHAVE_GET_VARIABLE -DHAVE_GET_VARIABLE_ATTR -DHAVE_SHIM_LOCK_GUID test-str_FILES = lib/string.c diff --git a/include/ucs2.h b/include/ucs2.h index ee038ce7..87eab32f 100644 --- a/include/ucs2.h +++ b/include/ucs2.h @@ -63,22 +63,4 @@ StrCSpn(const CHAR16 *s, const CHAR16 *reject) return ret; } -/* - * Test if an entire buffer is nothing but NUL characters. This - * implementation "gracefully" ignores the difference between the - * UTF-8/ASCII 1-byte NUL and the UCS-2 2-byte NUL. - */ -static inline bool -__attribute__((__unused__)) -is_all_nuls(UINT8 *data, UINTN data_size) -{ - UINTN i; - - for (i = 0; i < data_size; i++) { - if (data[i] != 0) - return false; - } - return true; -} - #endif /* SHIM_UCS2_H */ @@ -28,6 +28,7 @@ EFI_GUID EFI_IP6_CONFIG_GUID = { 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, EFI_GUID EFI_LOADED_IMAGE_GUID = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID EFI_TPM_GUID = { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }; EFI_GUID EFI_TPM2_GUID = { 0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }; +EFI_GUID EFI_CC_MEASUREMENT_PROTOCOL_GUID = { 0x96751a3d, 0x72f4, 0x41a6, {0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } }; EFI_GUID EFI_SECURE_BOOT_DB_GUID = { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f } }; EFI_GUID EFI_SIMPLE_FILE_SYSTEM_GUID = SIMPLE_FILE_SYSTEM_PROTOCOL; EFI_GUID SECURITY_PROTOCOL_GUID = { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } }; diff --git a/load-options.c b/load-options.c index c6bb7427..a8c6e1a3 100644 --- a/load-options.c +++ b/load-options.c @@ -404,8 +404,13 @@ parse_load_options(EFI_LOADED_IMAGE *li) /* * Apparently sometimes we get L"\0\0"? Which isn't useful at all. + * + * Possibly related, but some boards have additional data before the + * size which is garbage (it's a weird path to the directory + * containing the loaders). Known boards that do this: Kontron VX3040 + * (AMI), ASUS B85M-E, and at least one "older Dell laptop". */ - if (is_all_nuls(li->LoadOptions, li->LoadOptionsSize)) + if (((CHAR16 *)li->LoadOptions)[0] == 0) return EFI_SUCCESS; /* diff --git a/make-archive b/make-archive index d4f095f0..9ae9eef0 100755 --- a/make-archive +++ b/make-archive @@ -86,14 +86,16 @@ main() { cd .. if [ "x" = "x${SHIM_GIT_TAG}" ] ; then git archive --format=tar "$(git log -1 --pretty=format:%h)" | ( cd "${ARCHIVE_DIR}/shim-${VERSION}" ; tar x ) + TIMESTAMP=0 else # ORIGIN doesn't yet have this tag git archive --format=tar "${SHIM_GIT_TAG}" | ( cd "${ARCHIVE_DIR}/shim-${VERSION}" ; tar x ) + TIMESTAMP=$(git log -1 --pretty=%ct "${SHIM_GIT_TAG}") fi git log -1 --pretty=format:%H > "${ARCHIVE_DIR}/shim-${VERSION}/commit" DIR="$PWD" cd "${ARCHIVE_DIR}" - tar -c --bzip2 -f "${DIR}/shim-${VERSION}.tar.bz2" "shim-${VERSION}" + tar -c --sort=name --mtime="@${TIMESTAMP}" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --bzip2 -f "${DIR}/shim-${VERSION}.tar.bz2" "shim-${VERSION}" rm -rf "${ARCHIVE_DIR}" echo "The archive is in shim-${VERSION}.tar.bz2" exit 0 @@ -8,16 +8,18 @@ /* This is so vim's Syntastic checker won't yell about all these. */ extern void __coverity_string_size_sanitize__(int); extern void __coverity_negative_sink__(int); -extern void __coverity_alloc_nosize__(void); +extern void *__coverity_alloc_nosize__(void); +extern void __coverity_writeall0__(void *); extern void *__coverity_alloc__(int); extern void __coverity_sleep__(); extern void __coverity_tainted_data_sanitize__(void *); +extern void __coverity_free__(void *); #endif void * OBJ_dup(void *o) { - __coverity_alloc_nosize__(); + return __coverity_alloc_nosize__(); } int @@ -133,4 +135,21 @@ AllocatePages(EFI_ALLOCATE_TYPE Type, return EFI_OUT_OF_RESOURCES; } +void * +AllocateZeroPool(int sz) +{ + void *ptr; + + __coverity_negative_sink__(sz); + ptr = __coverity_alloc__(sz); + __coverity_writeall0__(ptr); + return ptr; +} + +void +FreePool(void *ptr) +{ + __coverity_free__(ptr); +} + // vim:fenc=utf-8:tw=75 @@ -178,7 +178,6 @@ struct mok_state_variable mok_state_variable_data[] = { EFI_VARIABLE_NON_VOLATILE, .no_attr = EFI_VARIABLE_RUNTIME_ACCESS, .flags = MOK_MIRROR_DELETE_FIRST | - MOK_VARIABLE_MEASURE | MOK_VARIABLE_INVERSE | MOK_VARIABLE_LOG, .pcr = 14, @@ -1196,6 +1196,9 @@ handle_image (void *data, unsigned int datasize, CopyMem(buffer, data, context.SizeOfHeaders); + /* Flush the instruction cache for the region holding the image */ + cache_invalidate(buffer, buffer + context.ImageSize); + *entry_point = ImageAddress(buffer, context.ImageSize, context.EntryPoint); if (!*entry_point) { perror(L"Entry point is invalid\n"); @@ -1256,7 +1259,7 @@ handle_image (void *data, unsigned int datasize, } if (Section->VirtualAddress <= context.EntryPoint && - (Section->VirtualAddress + Section->SizeOfRawData - 1) + (Section->VirtualAddress + Section->Misc.VirtualSize - 1) > context.EntryPoint) found_entry_point++; @@ -5,6 +5,11 @@ #include "shim.h" +extern struct { + UINT32 previous_offset; + UINT32 latest_offset; +} sbat_var_payload_header; + EFI_STATUS parse_sbat_section(char *section_base, size_t section_size, size_t *n_entries, @@ -399,6 +404,9 @@ set_sbat_uefi_variable(void) EFI_STATUS efi_status = EFI_SUCCESS; UINT32 attributes = 0; + char *sbat_var_previous; + char *sbat_var_latest; + UINT8 *sbat = NULL; UINT8 *sbat_policy = NULL; UINTN sbatsize = 0; @@ -407,27 +415,30 @@ set_sbat_uefi_variable(void) char *sbat_var = NULL; bool reset_sbat = false; + sbat_var_previous = (char *)&sbat_var_payload_header + sbat_var_payload_header.previous_offset; + sbat_var_latest = (char *)&sbat_var_payload_header + sbat_var_payload_header.latest_offset; + efi_status = get_variable_attr(SBAT_POLICY, &sbat_policy, &sbat_policysize, SHIM_LOCK_GUID, &attributes); if (EFI_ERROR(efi_status)) { dprint("Default sbat policy: previous\n"); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; } else { switch (*sbat_policy) { case SBAT_POLICY_LATEST: dprint("Custom sbat policy: latest\n"); - sbat_var = SBAT_VAR_LATEST; + sbat_var = sbat_var_latest; clear_sbat_policy(); break; case SBAT_POLICY_PREVIOUS: dprint("Custom sbat policy: previous\n"); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; break; case SBAT_POLICY_RESET: if (secure_mode()) { console_print(L"Cannot reset SBAT policy: Secure Boot is enabled.\n"); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; } else { dprint(L"Custom SBAT policy: reset OK\n"); reset_sbat = true; @@ -438,7 +449,7 @@ set_sbat_uefi_variable(void) default: console_error(L"SBAT policy state %llu is invalid", EFI_INVALID_PARAMETER); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; clear_sbat_policy(); break; } diff --git a/sbat_var.S b/sbat_var.S new file mode 100644 index 00000000..a115077a --- /dev/null +++ b/sbat_var.S @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#include "include/sbat_var_defs.h" + + .section .sbatlevel, "a", %progbits + .balignl 4, 0 + .4byte 0 /* format version for external parsers */ + .globl sbat_var_payload_header + .type sbat_var_payload_header, %object + .size sbat_var_payload_header, .Lsbat_var_payload_header_end - sbat_var_payload_header +sbat_var_payload_header: + .4byte .Lsbat_var_previous - sbat_var_payload_header + .4byte .Lsbat_var_latest - sbat_var_payload_header +.Lsbat_var_payload_header_end: + .balign 1, 0 +.Lsbat_var_previous: + .asciz SBAT_VAR_PREVIOUS + .balign 1, 0 +.Lsbat_var_latest: + .asciz SBAT_VAR_LATEST @@ -397,22 +397,22 @@ static EFI_STATUS check_allowlist (WIN_CERTIFICATE_EFI_PKCS *cert, } #endif - if (check_db_hash(L"MokList", SHIM_LOCK_GUID, sha256hash, + if (check_db_hash(L"MokListRT", SHIM_LOCK_GUID, sha256hash, SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID) == DATA_FOUND) { verification_method = VERIFIED_BY_HASH; update_verification_method(VERIFIED_BY_HASH); return EFI_SUCCESS; } else { - LogError(L"check_db_hash(MokList, sha256hash) != DATA_FOUND\n"); + LogError(L"check_db_hash(MokListRT, sha256hash) != DATA_FOUND\n"); } - if (cert && check_db_cert(L"MokList", SHIM_LOCK_GUID, cert, sha256hash) + if (cert && check_db_cert(L"MokListRT", SHIM_LOCK_GUID, cert, sha256hash) == DATA_FOUND) { verification_method = VERIFIED_BY_CERT; update_verification_method(VERIFIED_BY_CERT); return EFI_SUCCESS; } else if (cert) { - LogError(L"check_db_cert(MokList, sha256hash) != DATA_FOUND\n"); + LogError(L"check_db_cert(MokListRT, sha256hash) != DATA_FOUND\n"); } update_verification_method(VERIFIED_BY_NOTHING); @@ -1395,7 +1395,6 @@ EFI_STATUS load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) { EFI_STATUS efi_status; - EFI_LOADED_IMAGE li; PE_COFF_LOADER_IMAGE_CONTEXT context; EFI_IMAGE_SECTION_HEADER *Section; EFI_SIGNATURE_LIST *certlist; @@ -1410,10 +1409,7 @@ load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) if (EFI_ERROR(efi_status)) return efi_status; - memset(&li, 0, sizeof(li)); - memcpy(&li.FilePath[0], filename, MIN(StrSize(filename), sizeof(li.FilePath))); - - efi_status = verify_image(data, datasize, &li, &context); + efi_status = verify_image(data, datasize, shim_li, &context); if (EFI_ERROR(efi_status)) return efi_status; @@ -1433,8 +1429,8 @@ load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) user_cert_size += certlist->SignatureListSize;; user_cert = ReallocatePool(user_cert, original, user_cert_size); - memcpy(user_cert + original, pointer, - certlist->SignatureListSize); + CopyMem(user_cert + original, pointer, + certlist->SignatureListSize); } } FreePool(data); @@ -179,12 +179,14 @@ #include "include/pe.h" #include "include/replacements.h" #include "include/sbat.h" +#include "include/sbat_var_defs.h" #if defined(OVERRIDE_SECURITY_POLICY) #include "include/security_policy.h" #endif #include "include/simple_file.h" #include "include/str.h" #include "include/tpm.h" +#include "include/cc.h" #include "include/ucs2.h" #include "include/variables.h" #include "include/hexdump.h" @@ -108,6 +108,45 @@ static EFI_STATUS tpm_locate_protocol(efi_tpm_protocol_t **tpm, return EFI_NOT_FOUND; } +static EFI_STATUS cc_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, + UINT8 pcr, const CHAR8 *log, UINTN logsize, + UINT32 type, BOOLEAN is_pe_image) +{ + EFI_STATUS efi_status; + EFI_CC_EVENT *event; + efi_cc_protocol_t *cc; + EFI_CC_MR_INDEX mr; + uint64_t flags = is_pe_image ? EFI_CC_FLAG_PE_COFF_IMAGE : 0; + + efi_status = LibLocateProtocol(&EFI_CC_MEASUREMENT_PROTOCOL_GUID, + (VOID **)&cc); + if (EFI_ERROR(efi_status) || !cc) + return EFI_SUCCESS; + + efi_status = cc->map_pcr_to_mr_index(cc, pcr, &mr); + if (EFI_ERROR(efi_status)) + return EFI_NOT_FOUND; + + UINTN event_size = sizeof(*event) - sizeof(event->Event) + logsize; + + event = AllocatePool(event_size); + if (!event) { + perror(L"Unable to allocate event structure\n"); + return EFI_OUT_OF_RESOURCES; + } + + event->Header.HeaderSize = sizeof(EFI_CC_EVENT_HEADER); + event->Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION; + event->Header.MrIndex = mr; + event->Header.EventType = type; + event->Size = event_size; + CopyMem(event->Event, (VOID *)log, logsize); + efi_status = cc->hash_log_extend_event(cc, flags, buf, (UINT64)size, + event); + FreePool(event); + return efi_status; +} + static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr, const CHAR8 *log, UINTN logsize, UINT32 type, CHAR8 *hash) @@ -118,6 +157,15 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, BOOLEAN old_caps; EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; + /* CC guest like TDX or SEV will measure the buffer and log the event, + extend the result into a specific CC MR like TCG's PCR. It could + coexists with TCG's TPM 1.2 and TPM 2. + */ + efi_status = cc_log_event_raw(buf, size, pcr, log, logsize, type, + (hash != NULL)); + if (EFI_ERROR(efi_status)) + return efi_status; + efi_status = tpm_locate_protocol(&tpm, &tpm2, &old_caps, &caps); if (EFI_ERROR(efi_status)) { #ifdef REQUIRE_TPM |