From 3e5c3337e4fa4cb8d08f7e57ab7fb53ed2e8e4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BByjewski?= Date: Wed, 8 Mar 2023 11:20:17 +0100 Subject: [PATCH 1/5] Add patches for Intel TXT support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set of patches which adds TPM1.2 support for Intel TXT in GRUB2 for TrenchBoot. This is necessary to create Proof of Concept for TrenchBoot Anti Evil Maid for QubesOS. The TrenchBoot support hasn't been implemented and verified with TPM 1.2 on Intel TXT path. This changes ensures the TPM 1.2 is also supported for older Intel hardware with Intel TXT. Signed-off-by: Tomasz Żyjewski --- ...Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch | 131 +++ ...ame-grub_msr_read-and-grub_msr_write.patch | 67 ++ ...-and-improve-MSR-support-detection-c.patch | 137 +++ ...Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch | 176 ++++ ...me-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch | 170 ++++ ...ap_get_lowest-and-grub_mmap_get_high.patch | 110 ++ ...pm-Rename-tpm-module-to-tpm_verifier.patch | 96 ++ ...-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch | 249 +++++ ...-basic-platform-support-for-secure-l.patch | 416 ++++++++ ...dd-Intel-TXT-definitions-header-file.patch | 712 +++++++++++++ ...xt-Add-Intel-TXT-core-implementation.patch | 938 ++++++++++++++++++ ...txt-Add-Intel-TXT-ACM-module-support.patch | 596 +++++++++++ ...-Add-Intel-TXT-verification-routines.patch | 318 ++++++ ...-secure-launch-framework-and-command.patch | 891 +++++++++++++++++ ...ialize-TPM-1.2-event-log-in-TXT-heap.patch | 163 +++ ...slparams-accessible-by-other-modules.patch | 222 +++++ ...ader-i386-txt-txt.c-add-debug-prints.patch | 108 ++ ...iboot2-Implement-TXT-slaunch-support.patch | 303 ++++++ grub2.spec.in | 20 + 19 files changed, 5823 insertions(+) create mode 100644 1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch create mode 100644 1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch create mode 100644 1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch create mode 100644 1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch create mode 100644 1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch create mode 100644 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch create mode 100644 1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch create mode 100644 1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch create mode 100644 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch create mode 100644 1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch create mode 100644 1111-i386-txt-Add-Intel-TXT-core-implementation.patch create mode 100644 1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch create mode 100644 1113-i386-txt-Add-Intel-TXT-verification-routines.patch create mode 100644 1114-i386-slaunch-Add-secure-launch-framework-and-command.patch create mode 100644 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch create mode 100644 1116-slaunch-Make-slparams-accessible-by-other-modules.patch create mode 100644 1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch create mode 100644 1118-multiboot2-Implement-TXT-slaunch-support.patch diff --git a/1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch b/1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch new file mode 100644 index 0000000..97bde5c --- /dev/null +++ b/1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch @@ -0,0 +1,131 @@ +From a78796a23a33f12934ad45169be57735b05cdd81 Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Tue, 17 Dec 2019 17:51:29 +0100 +Subject: [PATCH 1101/1118] i386/msr: Merge rdmsr.h and wrmsr.h into msr.h + +It does not make sense to have separate headers for separate static +functions. Additionally, we have to add some constants with MSR addresses +in subsequent patches. So, make one common place to store them. + +Signed-off-by: Daniel Kiper +--- + grub-core/commands/i386/rdmsr.c | 2 +- + grub-core/commands/i386/wrmsr.c | 2 +- + include/grub/i386/{wrmsr.h => msr.h} | 16 +++++++++--- + include/grub/i386/rdmsr.h | 37 ---------------------------- + 4 files changed, 15 insertions(+), 42 deletions(-) + rename include/grub/i386/{wrmsr.h => msr.h} (78%) + delete mode 100644 include/grub/i386/rdmsr.h + +diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c +index 46c4346da1b6..fa4622f9e8a1 100644 +--- a/grub-core/commands/i386/rdmsr.c ++++ b/grub-core/commands/i386/rdmsr.c +@@ -26,7 +26,7 @@ + #include + #include + #include +-#include ++#include + + GRUB_MOD_LICENSE("GPLv3+"); + +diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c +index 1b143b8882a4..8f352f205ffd 100644 +--- a/grub-core/commands/i386/wrmsr.c ++++ b/grub-core/commands/i386/wrmsr.c +@@ -27,7 +27,7 @@ + #include + #include + #include +-#include ++#include + + GRUB_MOD_LICENSE("GPLv3+"); + +diff --git a/include/grub/i386/wrmsr.h b/include/grub/i386/msr.h +similarity index 78% +rename from include/grub/i386/wrmsr.h +rename to include/grub/i386/msr.h +index dea60aed1fc0..7b52b5d61229 100644 +--- a/include/grub/i386/wrmsr.h ++++ b/include/grub/i386/msr.h +@@ -16,14 +16,24 @@ + * along with GRUB. If not, see . + */ + +-#ifndef GRUB_WRMSR_H +-#define GRUB_WRMSR_H 1 ++#ifndef GRUB_I386_MSR_H ++#define GRUB_I386_MSR_H 1 + + /* + * TODO: Add a general protection exception handler. + * Accessing a reserved or unimplemented MSR address results in a GP#. + */ + ++static inline grub_uint64_t ++grub_msr_read (grub_uint32_t msr_id) ++{ ++ grub_uint32_t low, high; ++ ++ asm volatile ("rdmsr" : "=a" (low), "=d" (high) : "c" (msr_id)); ++ ++ return ((grub_uint64_t) high << 32) | low; ++} ++ + static inline void + grub_msr_write(grub_uint32_t msr_id, grub_uint64_t msr_value) + { +@@ -32,4 +42,4 @@ grub_msr_write(grub_uint32_t msr_id, grub_uint64_t msr_value) + asm volatile ("wrmsr" : : "c" (msr_id), "a" (low), "d" (high)); + } + +-#endif /* GRUB_WRMSR_H */ ++#endif /* GRUB_I386_MSR_H */ +diff --git a/include/grub/i386/rdmsr.h b/include/grub/i386/rdmsr.h +deleted file mode 100644 +index c0a0c717a0e9..000000000000 +--- a/include/grub/i386/rdmsr.h ++++ /dev/null +@@ -1,37 +0,0 @@ +-/* +- * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2019 Free Software Foundation, Inc. +- * +- * GRUB is free software: you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * GRUB is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with GRUB. If not, see . +- */ +- +-#ifndef GRUB_RDMSR_H +-#define GRUB_RDMSR_H 1 +- +-/* +- * TODO: Add a general protection exception handler. +- * Accessing a reserved or unimplemented MSR address results in a GP#. +- */ +- +-static inline grub_uint64_t +-grub_msr_read (grub_uint32_t msr_id) +-{ +- grub_uint32_t low, high; +- +- asm volatile ("rdmsr" : "=a" (low), "=d" (high) : "c" (msr_id)); +- +- return ((grub_uint64_t)high << 32) | low; +-} +- +-#endif /* GRUB_RDMSR_H */ +-- +2.17.1 + diff --git a/1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch b/1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch new file mode 100644 index 0000000..197e093 --- /dev/null +++ b/1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch @@ -0,0 +1,67 @@ +From 4529bfd79f5ba84a9fd11cef803bd8c8f8aa9f8f Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Tue, 17 Dec 2019 20:02:37 +0100 +Subject: [PATCH 1102/1118] i386/msr: Rename grub_msr_read() and + grub_msr_write() + +... to grub_rdmsr() and grub_wrmsr() respectively. New names are more +obvious than older ones. + +Signed-off-by: Daniel Kiper +--- + grub-core/commands/i386/rdmsr.c | 2 +- + grub-core/commands/i386/wrmsr.c | 2 +- + include/grub/i386/msr.h | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c +index fa4622f9e8a1..89ece7657f27 100644 +--- a/grub-core/commands/i386/rdmsr.c ++++ b/grub-core/commands/i386/rdmsr.c +@@ -76,7 +76,7 @@ grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) + if (*ptr != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); + +- value = grub_msr_read (addr); ++ value = grub_rdmsr (addr); + + if (ctxt->state[0].set) + { +diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c +index 8f352f205ffd..cf6bf6c8fe43 100644 +--- a/grub-core/commands/i386/wrmsr.c ++++ b/grub-core/commands/i386/wrmsr.c +@@ -77,7 +77,7 @@ grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char + if (*ptr != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); + +- grub_msr_write (addr, value); ++ grub_wrmsr (addr, value); + + return GRUB_ERR_NONE; + } +diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h +index 7b52b5d61229..4fba1b8e0d04 100644 +--- a/include/grub/i386/msr.h ++++ b/include/grub/i386/msr.h +@@ -25,7 +25,7 @@ + */ + + static inline grub_uint64_t +-grub_msr_read (grub_uint32_t msr_id) ++grub_rdmsr (grub_uint32_t msr_id) + { + grub_uint32_t low, high; + +@@ -35,7 +35,7 @@ grub_msr_read (grub_uint32_t msr_id) + } + + static inline void +-grub_msr_write(grub_uint32_t msr_id, grub_uint64_t msr_value) ++grub_wrmsr (grub_uint32_t msr_id, grub_uint64_t msr_value) + { + grub_uint32_t low = msr_value, high = msr_value >> 32; + +-- +2.17.1 + diff --git a/1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch b/1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch new file mode 100644 index 0000000..4e9f7f3 --- /dev/null +++ b/1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch @@ -0,0 +1,137 @@ +From ccee3f6377ecf0fba2edda7518911b3167657838 Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Sat, 25 Apr 2020 16:43:52 +0200 +Subject: [PATCH 1103/1118] i386/msr: Extract and improve MSR support detection + code + +Currently rdmsr and wrmsr commands have own MSR support detection code. +This code is the same. So, it is duplicated. Additionally, this code +cannot be reused by others. Hence, extract this code to a function and +make it public. By the way, improve a code a bit. + +Additionally, use GRUB_ERR_BAD_DEVICE instead of GRUB_ERR_BUG to signal +an error because errors encountered by this new routine are not bugs. + +Signed-off-by: Daniel Kiper +--- + grub-core/commands/i386/rdmsr.c | 21 +++++---------------- + grub-core/commands/i386/wrmsr.c | 21 +++++---------------- + include/grub/i386/msr.h | 29 +++++++++++++++++++++++++++++ + 3 files changed, 39 insertions(+), 32 deletions(-) + +diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c +index 89ece7657f27..2e42f6197648 100644 +--- a/grub-core/commands/i386/rdmsr.c ++++ b/grub-core/commands/i386/rdmsr.c +@@ -42,27 +42,16 @@ static const struct grub_arg_option options[] = + static grub_err_t + grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) + { +- grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr; ++ grub_err_t err; ++ grub_uint32_t addr; + grub_uint64_t value; + const char *ptr; + char buf[sizeof("1122334455667788")]; + +- /* +- * The CPUID instruction should be used to determine whether MSRs +- * are supported. (CPUID.01H:EDX[5] = 1) +- */ +- if (! grub_cpu_is_cpuid_supported ()) +- return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); ++ err = grub_cpu_is_msr_supported (); + +- grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]); +- +- if (max_cpuid < 1) +- return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); +- +- grub_cpuid (1, a, b, c, features); +- +- if (!(features & (1 << 5))) +- return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); ++ if (err != GRUB_ERR_NONE) ++ return grub_error (err, N_("RDMSR is unsupported")); + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); +diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c +index cf6bf6c8fe43..7fbedaed95ba 100644 +--- a/grub-core/commands/i386/wrmsr.c ++++ b/grub-core/commands/i386/wrmsr.c +@@ -36,26 +36,15 @@ static grub_command_t cmd_write; + static grub_err_t + grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv) + { +- grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr; ++ grub_err_t err; ++ grub_uint32_t addr; + grub_uint64_t value; + const char *ptr; + +- /* +- * The CPUID instruction should be used to determine whether MSRs +- * are supported. (CPUID.01H:EDX[5] = 1) +- */ +- if (!grub_cpu_is_cpuid_supported ()) +- return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); ++ err = grub_cpu_is_msr_supported (); + +- grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]); +- +- if (max_cpuid < 1) +- return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); +- +- grub_cpuid (1, a, b, c, features); +- +- if (!(features & (1 << 5))) +- return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); ++ if (err != GRUB_ERR_NONE) ++ return grub_error (err, N_("WRMSR is unsupported")); + + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); +diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h +index 4fba1b8e0d04..1e838c022f41 100644 +--- a/include/grub/i386/msr.h ++++ b/include/grub/i386/msr.h +@@ -19,6 +19,35 @@ + #ifndef GRUB_I386_MSR_H + #define GRUB_I386_MSR_H 1 + ++#include ++#include ++#include ++ ++static inline grub_err_t ++grub_cpu_is_msr_supported (void) ++{ ++ grub_uint32_t eax, ebx, ecx, edx; ++ ++ /* ++ * The CPUID instruction should be used to determine whether MSRs ++ * are supported, CPUID.01H:EDX[5] = 1. ++ */ ++ if (!grub_cpu_is_cpuid_supported ()) ++ return GRUB_ERR_BAD_DEVICE; ++ ++ grub_cpuid (0, eax, ebx, ecx, edx); ++ ++ if (eax < 1) ++ return GRUB_ERR_BAD_DEVICE; ++ ++ grub_cpuid (1, eax, ebx, ecx, edx); ++ ++ if (!(edx & (1 << 5))) ++ return GRUB_ERR_BAD_DEVICE; ++ ++ return GRUB_ERR_NONE; ++} ++ + /* + * TODO: Add a general protection exception handler. + * Accessing a reserved or unimplemented MSR address results in a GP#. +-- +2.17.1 + diff --git a/1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch b/1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch new file mode 100644 index 0000000..bd28eef --- /dev/null +++ b/1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch @@ -0,0 +1,176 @@ +From e6e4cf0b0e1f2ee45706203ba8f30a7954acc83d Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Wed, 20 Nov 2019 12:40:42 +0100 +Subject: [PATCH 1104/1118] i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT + +...to avoid potential conflicts and confusion. + +Signed-off-by: Daniel Kiper +--- + grub-core/lib/i386/xen/relocator.S | 6 +++--- + grub-core/lib/x86_64/xen/relocator.S | 4 ++-- + grub-core/loader/i386/xen.c | 28 ++++++++++++++-------------- + include/grub/i386/memory.h | 2 +- + 4 files changed, 20 insertions(+), 20 deletions(-) + +diff --git a/grub-core/lib/i386/xen/relocator.S b/grub-core/lib/i386/xen/relocator.S +index 96e51b59adfb..dab4d8aceb74 100644 +--- a/grub-core/lib/i386/xen/relocator.S ++++ b/grub-core/lib/i386/xen/relocator.S +@@ -75,10 +75,10 @@ VARIABLE(grub_relocator_xen_mfn_list) + .long 0 + movl 0(%eax, %ebp, 4), %ecx /* mfn */ + movl %ebp, %ebx +- shll $PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */ ++ shll $GRUB_PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */ + movl %ecx, %edx +- shll $PAGE_SHIFT, %ecx /* prepare pte low part */ +- shrl $(32 - PAGE_SHIFT), %edx /* pte high part */ ++ shll $GRUB_PAGE_SHIFT, %ecx /* prepare pte low part */ ++ shrl $(32 - GRUB_PAGE_SHIFT), %edx /* pte high part */ + orl $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %ecx /* pte low */ + movl $UVMF_INVLPG, %esi + movl $__HYPERVISOR_update_va_mapping, %eax +diff --git a/grub-core/lib/x86_64/xen/relocator.S b/grub-core/lib/x86_64/xen/relocator.S +index f5364ed0f4c8..852cd40aa08b 100644 +--- a/grub-core/lib/x86_64/xen/relocator.S ++++ b/grub-core/lib/x86_64/xen/relocator.S +@@ -60,9 +60,9 @@ LOCAL(cont): + jz 3f + 2: + movq %r12, %rdi +- shlq $PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */ ++ shlq $GRUB_PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */ + movq (%rbx, %r12, 8), %rsi /* mfn */ +- shlq $PAGE_SHIFT, %rsi ++ shlq $GRUB_PAGE_SHIFT, %rsi + orq $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %rsi /* Build pte */ + movq $UVMF_INVLPG, %rdx + movq %rcx, %r9 /* %rcx clobbered by hypercall */ +diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c +index cd24874ca324..1810c1dbc8b0 100644 +--- a/grub-core/loader/i386/xen.c ++++ b/grub-core/loader/i386/xen.c +@@ -92,7 +92,7 @@ static struct xen_loader_state xen_state; + + static grub_dl_t my_mod; + +-#define PAGE_SIZE (1UL << PAGE_SHIFT) ++#define PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) + #define MAX_MODULES (PAGE_SIZE / sizeof (struct xen_multiboot_mod_list)) + #define STACK_SIZE 1048576 + #define ADDITIONAL_SIZE (1 << 19) +@@ -103,7 +103,7 @@ static grub_dl_t my_mod; + static grub_uint64_t + page2offset (grub_uint64_t page) + { +- return page << PAGE_SHIFT; ++ return page << GRUB_PAGE_SHIFT; + } + + static grub_err_t +@@ -142,7 +142,7 @@ get_pgtable_size (grub_uint64_t from, grub_uint64_t to, grub_uint64_t pfn) + continue; + } + +- bits = PAGE_SHIFT + (i + 1) * LOG_POINTERS_PER_PAGE; ++ bits = GRUB_PAGE_SHIFT + (i + 1) * LOG_POINTERS_PER_PAGE; + mask = (1ULL << bits) - 1; + map->lvls[i].virt_start = map->area.virt_start & ~mask; + map->lvls[i].virt_end = map->area.virt_end | mask; +@@ -247,11 +247,11 @@ generate_page_table (grub_xen_mfn_t *mfn_list) + if (lvl->virt_start >= end || lvl->virt_end <= start) + continue; + p_s = (grub_max (start, lvl->virt_start) - start) >> +- (PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); ++ (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); + p_e = (grub_min (end, lvl->virt_end) - start) >> +- (PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); ++ (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); + pfn = ((grub_max (start, lvl->virt_start) - lvl->virt_start) >> +- (PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE)) + lvl->pfn_start; ++ (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE)) + lvl->pfn_start; + grub_dprintf ("xen", "write page table entries level %d pg %p " + "mapping %d/%d index %lx-%lx pfn %llx\n", + l, pg, m1, m2, p_s, p_e, (unsigned long long) pfn); +@@ -329,16 +329,16 @@ grub_xen_p2m_alloc (void) + { + err = get_pgtable_size (xen_state.xen_inf.p2m_base, + xen_state.xen_inf.p2m_base + p2msize, +- (xen_state.max_addr + p2msize) >> PAGE_SHIFT); ++ (xen_state.max_addr + p2msize) >> GRUB_PAGE_SHIFT); + if (err) + return err; + +- map->area.pfn_start = xen_state.max_addr >> PAGE_SHIFT; ++ map->area.pfn_start = xen_state.max_addr >> GRUB_PAGE_SHIFT; + p2malloc = p2msize + page2offset (map->area.n_pt_pages); + xen_state.n_mappings++; + xen_state.next_start.mfn_list = xen_state.xen_inf.p2m_base; + xen_state.next_start.first_p2m_pfn = map->area.pfn_start; +- xen_state.next_start.nr_p2m_frames = p2malloc >> PAGE_SHIFT; ++ xen_state.next_start.nr_p2m_frames = p2malloc >> GRUB_PAGE_SHIFT; + } + else + { +@@ -381,7 +381,7 @@ grub_xen_special_alloc (void) + xen_state.virt_start_info = get_virtual_current_address (ch); + xen_state.max_addr = + ALIGN_UP (xen_state.max_addr + sizeof (xen_state.next_start), PAGE_SIZE); +- xen_state.console_pfn = xen_state.max_addr >> PAGE_SHIFT; ++ xen_state.console_pfn = xen_state.max_addr >> GRUB_PAGE_SHIFT; + xen_state.max_addr += 2 * PAGE_SIZE; + + xen_state.next_start.nr_pages = grub_xen_start_page_addr->nr_pages; +@@ -413,7 +413,7 @@ grub_xen_pt_alloc (void) + + xen_state.next_start.pt_base = + xen_state.max_addr + xen_state.xen_inf.virt_base; +- nr_info_pages = xen_state.max_addr >> PAGE_SHIFT; ++ nr_info_pages = xen_state.max_addr >> GRUB_PAGE_SHIFT; + nr_need_pages = nr_info_pages; + + while (1) +@@ -461,7 +461,7 @@ grub_xen_pt_alloc (void) + xen_state.max_addr + STACK_SIZE + xen_state.xen_inf.virt_base; + xen_state.next_start.nr_pt_frames = nr_need_pages; + xen_state.max_addr = try_virt_end - xen_state.xen_inf.virt_base; +- xen_state.pgtbl_end = xen_state.max_addr >> PAGE_SHIFT; ++ xen_state.pgtbl_end = xen_state.max_addr >> GRUB_PAGE_SHIFT; + xen_state.map_reloc->where = (grub_uint64_t *) ((char *) map->where + + page2offset (map->area.n_pt_pages)); + +@@ -515,7 +515,7 @@ grub_xen_boot (void) + if (err) + return err; + +- nr_pages = xen_state.max_addr >> PAGE_SHIFT; ++ nr_pages = xen_state.max_addr >> GRUB_PAGE_SHIFT; + + grub_dprintf ("xen", "bootstrap domain %llx+%llx\n", + (unsigned long long) xen_state.xen_inf.virt_base, +@@ -819,7 +819,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + if (xen_state.xen_inf.unmapped_initrd) + { + xen_state.next_start.flags |= SIF_MOD_START_PFN; +- xen_state.next_start.mod_start = xen_state.max_addr >> PAGE_SHIFT; ++ xen_state.next_start.mod_start = xen_state.max_addr >> GRUB_PAGE_SHIFT; + } + else + xen_state.next_start.mod_start = +diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h +index 5cb607fb4667..7be57d6d7ecc 100644 +--- a/include/grub/i386/memory.h ++++ b/include/grub/i386/memory.h +@@ -20,7 +20,7 @@ + #ifndef GRUB_MEMORY_CPU_HEADER + #define GRUB_MEMORY_CPU_HEADER 1 + +-#define PAGE_SHIFT 12 ++#define GRUB_PAGE_SHIFT 12 + + /* The flag for protected mode. */ + #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +-- +2.17.1 + diff --git a/1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch b/1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch new file mode 100644 index 0000000..8167e82 --- /dev/null +++ b/1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch @@ -0,0 +1,170 @@ +From be6df1e0e6b5fcbf26389e27288c54675d7e1aa5 Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Wed, 20 Nov 2019 12:52:16 +0100 +Subject: [PATCH 1105/1118] i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and + make it global + +Subsequent patches will use that constant. + +Signed-off-by: Daniel Kiper +--- + grub-core/loader/i386/xen.c | 35 +++++++++++++++++------------------ + include/grub/i386/memory.h | 1 + + 2 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c +index 1810c1dbc8b0..45c24c45f18d 100644 +--- a/grub-core/loader/i386/xen.c ++++ b/grub-core/loader/i386/xen.c +@@ -92,8 +92,7 @@ static struct xen_loader_state xen_state; + + static grub_dl_t my_mod; + +-#define PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) +-#define MAX_MODULES (PAGE_SIZE / sizeof (struct xen_multiboot_mod_list)) ++#define MAX_MODULES (GRUB_PAGE_SIZE / sizeof (struct xen_multiboot_mod_list)) + #define STACK_SIZE 1048576 + #define ADDITIONAL_SIZE (1 << 19) + #define ALIGN_SIZE (1 << 22) +@@ -229,7 +228,7 @@ generate_page_table (grub_xen_mfn_t *mfn_list) + + for (m1 = 0; m1 < xen_state.n_mappings; m1++) + grub_memset (xen_state.mappings[m1].where, 0, +- xen_state.mappings[m1].area.n_pt_pages * PAGE_SIZE); ++ xen_state.mappings[m1].area.n_pt_pages * GRUB_PAGE_SIZE); + + for (l = NUMBER_OF_LEVELS - 1; l >= 0; l--) + { +@@ -324,7 +323,7 @@ grub_xen_p2m_alloc (void) + + map = xen_state.mappings + xen_state.n_mappings; + p2msize = ALIGN_UP (sizeof (grub_xen_mfn_t) * +- grub_xen_start_page_addr->nr_pages, PAGE_SIZE); ++ grub_xen_start_page_addr->nr_pages, GRUB_PAGE_SIZE); + if (xen_state.xen_inf.has_p2m_base) + { + err = get_pgtable_size (xen_state.xen_inf.p2m_base, +@@ -380,9 +379,9 @@ grub_xen_special_alloc (void) + xen_state.state.start_info = xen_state.max_addr + xen_state.xen_inf.virt_base; + xen_state.virt_start_info = get_virtual_current_address (ch); + xen_state.max_addr = +- ALIGN_UP (xen_state.max_addr + sizeof (xen_state.next_start), PAGE_SIZE); ++ ALIGN_UP (xen_state.max_addr + sizeof (xen_state.next_start), GRUB_PAGE_SIZE); + xen_state.console_pfn = xen_state.max_addr >> GRUB_PAGE_SHIFT; +- xen_state.max_addr += 2 * PAGE_SIZE; ++ xen_state.max_addr += 2 * GRUB_PAGE_SIZE; + + xen_state.next_start.nr_pages = grub_xen_start_page_addr->nr_pages; + grub_memcpy (xen_state.next_start.magic, grub_xen_start_page_addr->magic, +@@ -431,9 +430,9 @@ grub_xen_pt_alloc (void) + /* Map the relocator page either at virtual 0 or after end of area. */ + nr_need_pages = nr_info_pages + map->area.n_pt_pages; + if (xen_state.xen_inf.virt_base) +- err = get_pgtable_size (0, PAGE_SIZE, nr_need_pages); ++ err = get_pgtable_size (0, GRUB_PAGE_SIZE, nr_need_pages); + else +- err = get_pgtable_size (try_virt_end, try_virt_end + PAGE_SIZE, ++ err = get_pgtable_size (try_virt_end, try_virt_end + GRUB_PAGE_SIZE, + nr_need_pages); + if (err) + return err; +@@ -538,7 +537,7 @@ grub_xen_boot (void) + + return grub_relocator_xen_boot (xen_state.relocator, xen_state.state, nr_pages, + xen_state.xen_inf.virt_base < +- PAGE_SIZE ? page2offset (nr_pages) : 0, ++ GRUB_PAGE_SIZE ? page2offset (nr_pages) : 0, + xen_state.pgtbl_end - 1, + page2offset (xen_state.pgtbl_end - 1) + + xen_state.xen_inf.virt_base); +@@ -677,7 +676,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- if (xen_state.xen_inf.virt_base & (PAGE_SIZE - 1)) ++ if (xen_state.xen_inf.virt_base & (GRUB_PAGE_SIZE - 1)) + { + grub_error (GRUB_ERR_BAD_OS, "unaligned virt_base"); + goto fail; +@@ -700,10 +699,10 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), + kern_start = grub_min (kern_start, xen_state.xen_inf.hypercall_page - + xen_state.xen_inf.virt_base); + kern_end = grub_max (kern_end, xen_state.xen_inf.hypercall_page - +- xen_state.xen_inf.virt_base + PAGE_SIZE); ++ xen_state.xen_inf.virt_base + GRUB_PAGE_SIZE); + } + +- xen_state.max_addr = ALIGN_UP (kern_end, PAGE_SIZE); ++ xen_state.max_addr = ALIGN_UP (kern_end, GRUB_PAGE_SIZE); + + + if (grub_sub (kern_end, kern_start, &sz)) +@@ -730,7 +729,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), + if (xen_state.xen_inf.has_hypercall_page) + { + unsigned i; +- for (i = 0; i < PAGE_SIZE / HYPERCALL_INTERFACE_SIZE; i++) ++ for (i = 0; i < GRUB_PAGE_SIZE / HYPERCALL_INTERFACE_SIZE; i++) + set_hypercall_interface ((grub_uint8_t *) kern_chunk_src + + i * HYPERCALL_INTERFACE_SIZE + + xen_state.xen_inf.hypercall_page - +@@ -829,7 +828,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + (unsigned) (xen_state.max_addr + xen_state.xen_inf.virt_base), + (unsigned) size); + +- xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, PAGE_SIZE); ++ xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, GRUB_PAGE_SIZE); + + fail: + grub_initrd_close (&initrd_ctx); +@@ -883,7 +882,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + { + xen_state.xen_inf.unmapped_initrd = 0; + xen_state.n_modules = 0; +- xen_state.max_addr = ALIGN_UP (xen_state.max_addr, PAGE_SIZE); ++ xen_state.max_addr = ALIGN_UP (xen_state.max_addr, GRUB_PAGE_SIZE); + xen_state.modules_target_start = xen_state.max_addr; + xen_state.next_start.mod_start = + xen_state.max_addr + xen_state.xen_inf.virt_base; +@@ -903,7 +902,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + MAX_MODULES * sizeof (xen_state.module_info_page[0]); + } + +- xen_state.max_addr = ALIGN_UP (xen_state.max_addr, PAGE_SIZE); ++ xen_state.max_addr = ALIGN_UP (xen_state.max_addr, GRUB_PAGE_SIZE); + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_INITRD | + (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS : GRUB_FILE_TYPE_NONE)); +@@ -926,7 +925,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + + xen_state.module_info_page[xen_state.n_modules].cmdline = + xen_state.max_addr - xen_state.modules_target_start; +- xen_state.max_addr = ALIGN_UP (xen_state.max_addr + cmdline_len, PAGE_SIZE); ++ xen_state.max_addr = ALIGN_UP (xen_state.max_addr + cmdline_len, GRUB_PAGE_SIZE); + + if (size) + { +@@ -953,7 +952,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + xen_state.n_modules++; + grub_dprintf ("xen", "module, addr=0x%x, size=0x%x\n", + (unsigned) xen_state.max_addr, (unsigned) size); +- xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, PAGE_SIZE); ++ xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, GRUB_PAGE_SIZE); + + + fail: +diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h +index 7be57d6d7ecc..c64529630f19 100644 +--- a/include/grub/i386/memory.h ++++ b/include/grub/i386/memory.h +@@ -21,6 +21,7 @@ + #define GRUB_MEMORY_CPU_HEADER 1 + + #define GRUB_PAGE_SHIFT 12 ++#define GRUB_PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) + + /* The flag for protected mode. */ + #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +-- +2.17.1 + diff --git a/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch b/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch new file mode 100644 index 0000000..0b663e2 --- /dev/null +++ b/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch @@ -0,0 +1,110 @@ +From 534e9d569caa75c0e36a80134dea6bf0f9350bc7 Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Mon, 4 May 2020 22:34:59 +0200 +Subject: [PATCH 1106/1118] mmap: Add grub_mmap_get_lowest() and + grub_mmap_get_highest() + +The functions calculate lowest and highest available RAM +addresses respectively. + +Both functions are needed to calculate PMR boundaries for +Intel TXT secure launcher introduced by subsequent patches. + +Signed-off-by: Daniel Kiper +--- + grub-core/mmap/mmap.c | 64 +++++++++++++++++++++++++++++++++++++++++++ + include/grub/memory.h | 3 ++ + 2 files changed, 67 insertions(+) + +diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c +index c8c8312c56f2..270730fc770f 100644 +--- a/grub-core/mmap/mmap.c ++++ b/grub-core/mmap/mmap.c +@@ -343,6 +343,70 @@ grub_mmap_unregister (int handle) + + #endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ + ++typedef struct ++{ ++ grub_uint64_t addr; ++ grub_uint64_t limit; ++} addr_limit_t; ++ ++/* Helper for grub_mmap_get_lowest(). */ ++static int ++lowest_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ addr_limit_t *al = data; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ ++ if (addr >= al->limit) ++ al->addr = grub_min (al->addr, addr); ++ ++ if ((addr < al->limit) && ((addr + size) > al->limit)) ++ al->addr = al->limit; ++ ++ return 0; ++} ++ ++grub_uint64_t ++grub_mmap_get_lowest (grub_uint64_t limit) ++{ ++ addr_limit_t al = {~0, limit}; ++ ++ grub_mmap_iterate (lowest_hook, &al); ++ ++ return al.addr; ++} ++ ++/* Helper for grub_mmap_get_highest(). */ ++static int ++highest_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ addr_limit_t *al = data; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ ++ if ((addr + size) < al->limit) ++ al->addr = grub_max (al->addr, addr + size); ++ ++ if ((addr < al->limit) && ((addr + size) >= al->limit)) ++ al->addr = al->limit; ++ ++ return 0; ++} ++ ++grub_uint64_t ++grub_mmap_get_highest (grub_uint64_t limit) ++{ ++ addr_limit_t al = {0, limit}; ++ ++ grub_mmap_iterate (highest_hook, &al); ++ ++ return al.addr; ++} ++ + #define CHUNK_SIZE 0x400 + + struct badram_entry { +diff --git a/include/grub/memory.h b/include/grub/memory.h +index 6da114a1bdc1..8f22f752502b 100644 +--- a/include/grub/memory.h ++++ b/include/grub/memory.h +@@ -69,6 +69,9 @@ void *grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, + + void grub_mmap_free_and_unregister (int handle); + ++extern grub_uint64_t grub_mmap_get_lowest (grub_uint64_t limit); ++extern grub_uint64_t grub_mmap_get_highest (grub_uint64_t limit); ++ + #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE + + struct grub_mmap_region +-- +2.17.1 + diff --git a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch new file mode 100644 index 0000000..948eb3e --- /dev/null +++ b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch @@ -0,0 +1,96 @@ +From 6933cf0a6011f6c9eb951a2375c204c699b635ee Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Wed, 22 Apr 2020 21:41:24 +0200 +Subject: [PATCH 1107/1118] i386/tpm: Rename tpm module to tpm_verifier + +...to avoid naming collision with TPM TIS and CRB driver introduced +by subsequent patch. + +Signed-off-by: Daniel Kiper +--- + docs/grub.texi | 15 ++++++++------- + grub-core/Makefile.core.def | 4 ++-- + grub-core/commands/{tpm.c => tpm_verifier.c} | 6 +++--- + 3 files changed, 13 insertions(+), 12 deletions(-) + rename grub-core/commands/{tpm.c => tpm_verifier.c} (96%) + +diff --git a/docs/grub.texi b/docs/grub.texi +index 96c85927ad36..d0525023bbb8 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -6008,10 +6008,10 @@ grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efine + @node Measured Boot + @section Measuring boot components + +-If the tpm module is loaded and the platform has a Trusted Platform Module +-installed, GRUB will log each command executed and each file loaded into the +-TPM event log and extend the PCR values in the TPM correspondingly. All events +-will be logged into the PCR described below with a type of EV_IPL and an ++If the tpm_verifier module is loaded and the platform has a Trusted Platform ++Module installed, GRUB will log each command executed and each file loaded into ++the TPM event log and extend the PCR values in the TPM correspondingly. All ++events will be logged into the PCR described below with a type of EV_IPL and an + event description as described below. + + @multitable @columnfractions 0.3 0.1 0.6 +@@ -6036,9 +6036,10 @@ corresponding to the filename. + + GRUB will not measure its own @file{core.img} - it is expected that firmware + will carry this out. GRUB will also not perform any measurements until the +-tpm module is loaded. As such it is recommended that the tpm module be built +-into @file{core.img} in order to avoid a potential gap in measurement between +-@file{core.img} being loaded and the tpm module being loaded. ++tpm_verifier module is loaded. As such it is recommended that the tpm_verifier ++module be built into @file{core.img} in order to avoid a potential gap in ++measurement between @file{core.img} being loaded and the tpm_verifier module ++being loaded. + + Measured boot is currently only supported on EFI platforms. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 452a30adab89..e6b41ede92c4 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2505,8 +2505,8 @@ module = { + }; + + module = { +- name = tpm; +- common = commands/tpm.c; ++ name = tpm_verifier; ++ common = commands/tpm_verifier.c; + efi = commands/efi/tpm.c; + enable = efi; + }; +diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm_verifier.c +similarity index 96% +rename from grub-core/commands/tpm.c +rename to grub-core/commands/tpm_verifier.c +index 2052c36eaba5..1d820a774b3b 100644 +--- a/grub-core/commands/tpm.c ++++ b/grub-core/commands/tpm_verifier.c +@@ -78,18 +78,18 @@ grub_tpm_verify_string (char *str, enum grub_verify_string_type type) + } + + struct grub_file_verifier grub_tpm_verifier = { +- .name = "tpm", ++ .name = "tpm_verifier", + .init = grub_tpm_verify_init, + .write = grub_tpm_verify_write, + .verify_string = grub_tpm_verify_string, + }; + +-GRUB_MOD_INIT (tpm) ++GRUB_MOD_INIT (tpm_verifier) + { + grub_verifier_register (&grub_tpm_verifier); + } + +-GRUB_MOD_FINI (tpm) ++GRUB_MOD_FINI (tpm_verifier) + { + grub_verifier_unregister (&grub_tpm_verifier); + } +-- +2.17.1 + diff --git a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch new file mode 100644 index 0000000..d9f014a --- /dev/null +++ b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch @@ -0,0 +1,249 @@ +From 4b1ce3e251cc45963cb69fffdf8916e638f543f9 Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Mon, 4 May 2020 22:30:58 +0200 +Subject: [PATCH 1108/1118] i386/tpm: Add TPM TIS and CRB driver + +It will be used by Intel TXT secure launcher introduced +by subsequent patches. + +Signed-off-by: Daniel Kiper +--- + grub-core/commands/i386/tpm.c | 182 ++++++++++++++++++++++++++++++++++ + include/grub/i386/tpm.h | 36 +++++++ + 2 files changed, 218 insertions(+) + create mode 100644 grub-core/commands/i386/tpm.c + create mode 100644 include/grub/i386/tpm.h + +diff --git a/grub-core/commands/i386/tpm.c b/grub-core/commands/i386/tpm.c +new file mode 100644 +index 000000000000..ff29c2e85070 +--- /dev/null ++++ b/grub-core/commands/i386/tpm.c +@@ -0,0 +1,182 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * TPM TIS and CRB driver. ++ * ++ * Note: It is suggested to not use this driver together with UEFI TPM driver. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#define TPM_MMIO_BASE 0xfed40000 ++ ++/* TIS registers. */ ++#define TPM_ACCESS 0x0000 ++#define TPM_INTF_CAPABILITY 0x0014 ++#define TPM_INTERFACE_ID 0x0030 ++ ++/* CRB registers. */ ++#define TPM_LOC_CTRL 0x0008 ++ ++#define TPM_12_TIS_INTF_12 0x0 ++#define TPM_12_TIS_INTF_13 0x2 ++#define TPM_20_TIS_INTF_13 0x3 ++ ++#define TPM_CRB_INTF_ACTIVE 0x1 ++ ++#define TIS_RELINQUISH_LCL 0x20 ++#define CRB_RELINQUISH_LCL 0x0002 ++ ++/* TODO: Do we need GRUB_PACKED for unions below??? */ ++ ++union tpm_interface_id ++{ ++ grub_uint32_t raw; ++ struct ++ { ++ grub_uint32_t interface_type:4; ++ grub_uint32_t interface_version:4; ++ grub_uint32_t cap_locality:1; ++ grub_uint32_t reserved_0:4; ++ grub_uint32_t cap_tis:1; ++ grub_uint32_t cap_crb:1; ++ grub_uint32_t cap_ifres:2; ++ grub_uint32_t interface_selector:2; ++ grub_uint32_t intf_sel_lock:1; ++ grub_uint32_t reserved_1:4; ++ grub_uint32_t reserved_2:8; ++ }; ++} GRUB_PACKED; ++typedef union tpm_interface_id tpm_interface_id_t; ++ ++union tpm_intf_capability ++{ ++ grub_uint32_t raw; ++ struct ++ { ++ grub_uint32_t data_avail_int_support:1; ++ grub_uint32_t sts_valid_int_support:1; ++ grub_uint32_t locality_change_int_support:1; ++ grub_uint32_t interrupt_level_high:1; ++ grub_uint32_t interrupt_level_low:1; ++ grub_uint32_t interrupt_edge_rising:1; ++ grub_uint32_t interrupt_edge_falling:1; ++ grub_uint32_t command_ready_int_support:1; ++ grub_uint32_t burst_count_static:1; ++ grub_uint32_t data_transfer_size_support:2; ++ grub_uint32_t reserved_0:17; ++ grub_uint32_t interface_version:3; ++ grub_uint32_t reserved_1:1; ++ }; ++} GRUB_PACKED; ++typedef union tpm_intf_capability tpm_intf_capability_t; ++ ++typedef enum ++ { ++ TPM_INTF_NONE = 0, ++ TPM_INTF_TIS, ++ TPM_INTF_CRB ++ } ++tpm_intf_t; ++ ++static grub_tpm_ver_t tpm_ver = GRUB_TPM_NONE; ++static tpm_intf_t tpm_intf = TPM_INTF_NONE; ++ ++grub_tpm_ver_t ++grub_get_tpm_ver (void) ++{ ++ return tpm_ver; ++} ++ ++/* Localities 0-4 are supported only. */ ++void ++grub_tpm_relinquish_lcl (grub_uint8_t lcl) ++{ ++ grub_addr_t addr = TPM_MMIO_BASE + lcl * GRUB_PAGE_SIZE; ++ ++ if (tpm_intf == TPM_INTF_TIS) ++ grub_writeb (TIS_RELINQUISH_LCL, (void *) (addr + TPM_ACCESS)); ++ else if (tpm_intf == TPM_INTF_CRB) ++ grub_writel (CRB_RELINQUISH_LCL, (void *) (addr + TPM_LOC_CTRL)); ++} ++ ++static grub_err_t ++grub_cmd_tpm_type (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ const char *tpm_ver_s = "NONE"; ++ const char *tpm_intf_s = "NONE"; ++ ++ if (tpm_ver == GRUB_TPM_12) ++ tpm_ver_s = "1.2"; ++ else if (tpm_ver == GRUB_TPM_20) ++ tpm_ver_s = "2.0"; ++ ++ if (tpm_intf == TPM_INTF_TIS) ++ tpm_intf_s = "TIS"; ++ else if (tpm_intf == TPM_INTF_CRB) ++ tpm_intf_s = "CRB"; ++ ++ grub_printf ("TPM VER: %s\nTPM INTF: %s\n", tpm_ver_s, tpm_intf_s); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_command_t cmd_tpm_type; ++ ++GRUB_MOD_INIT (tpm) ++{ ++ tpm_interface_id_t intf_id; ++ tpm_intf_capability_t intf_cap; ++ ++ cmd_tpm_type = grub_register_command ("tpm_type", grub_cmd_tpm_type, ++ NULL, N_("Show TPM version and interface type.")); ++ ++ intf_cap.raw = grub_readl ((void *)(grub_addr_t) (TPM_MMIO_BASE + TPM_INTF_CAPABILITY)); ++ ++ if (intf_cap.interface_version == TPM_12_TIS_INTF_12 || ++ intf_cap.interface_version == TPM_12_TIS_INTF_13) ++ { ++ tpm_ver = GRUB_TPM_12; ++ tpm_intf = TPM_INTF_TIS; ++ return; ++ } ++ ++ if (intf_cap.interface_version != TPM_20_TIS_INTF_13) ++ return; ++ ++ tpm_ver = GRUB_TPM_20; ++ ++ intf_id.raw = grub_readl ((void *)(grub_addr_t) (TPM_MMIO_BASE + TPM_INTERFACE_ID)); ++ ++ tpm_intf = (intf_id.interface_type == TPM_CRB_INTF_ACTIVE) ? TPM_INTF_CRB : TPM_INTF_TIS; ++} ++ ++GRUB_MOD_FINI (tpm) ++{ ++ grub_unregister_command (cmd_tpm_type); ++} +diff --git a/include/grub/i386/tpm.h b/include/grub/i386/tpm.h +new file mode 100644 +index 000000000000..ae8d4a27def7 +--- /dev/null ++++ b/include/grub/i386/tpm.h +@@ -0,0 +1,36 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ */ ++ ++#ifndef GRUB_I386_TPM_H ++#define GRUB_I386_TPM_H 1 ++ ++#include ++ ++typedef enum ++ { ++ GRUB_TPM_NONE = 0, ++ GRUB_TPM_12, ++ GRUB_TPM_20 ++ } ++grub_tpm_ver_t; ++ ++extern grub_tpm_ver_t grub_get_tpm_ver (void); ++extern void grub_tpm_relinquish_lcl (grub_uint8_t lcl); ++ ++#endif /* GRUB_I386_TPM_H */ +-- +2.17.1 + diff --git a/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch b/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch new file mode 100644 index 0000000..063513e --- /dev/null +++ b/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch @@ -0,0 +1,416 @@ +From 92abb1b1c33a697d51d3c95ee0861f65c939e092 Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Wed, 7 Aug 2019 13:50:14 -0400 +Subject: [PATCH 1109/1118] i386/slaunch: Add basic platform support for secure + launch + +Signed-off-by: Ross Philipson +Signed-off-by: Daniel Kiper +--- + include/grub/i386/cpuid.h | 13 +++ + include/grub/i386/crfr.h | 186 ++++++++++++++++++++++++++++++++++++++ + include/grub/i386/mmio.h | 90 ++++++++++++++++++ + include/grub/i386/msr.h | 61 +++++++++++++ + 4 files changed, 350 insertions(+) + create mode 100644 include/grub/i386/crfr.h + create mode 100644 include/grub/i386/mmio.h + +diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h +index f7ae4b0a4641..8176e5d113d8 100644 +--- a/include/grub/i386/cpuid.h ++++ b/include/grub/i386/cpuid.h +@@ -19,6 +19,19 @@ + #ifndef GRUB_CPU_CPUID_HEADER + #define GRUB_CPU_CPUID_HEADER 1 + ++/* General */ ++#define GRUB_X86_CPUID_VENDOR 0x00000000 ++#define GRUB_X86_CPUID_FEATURES 0x00000001 ++ ++/* Intel */ ++#define GRUB_VMX_CPUID_FEATURE (1<<5) ++#define GRUB_SMX_CPUID_FEATURE (1<<6) ++ ++/* AMD */ ++#define GRUB_AMD_CPUID_FEATURES 0x80000001 ++#define GRUB_SVM_CPUID_FEATURE (1<<2) ++#define GRUB_AMD_CPUID_FUNC 0x8000000a ++ + extern unsigned char grub_cpuid_has_longmode; + extern unsigned char grub_cpuid_has_pae; + +diff --git a/include/grub/i386/crfr.h b/include/grub/i386/crfr.h +new file mode 100644 +index 000000000000..284d6967be4b +--- /dev/null ++++ b/include/grub/i386/crfr.h +@@ -0,0 +1,186 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_CRFR_H ++#define GRUB_CRFR_H 1 ++ ++#include ++ ++/* Routines for R/W of control and flags registers */ ++ ++#define GRUB_CR0_X86_PE 0x00000001 /* Enable Protected Mode */ ++#define GRUB_CR0_X86_MP 0x00000002 /* "Math" (FPU) Present */ ++#define GRUB_CR0_X86_EM 0x00000004 /* EMulate FPU */ ++#define GRUB_CR0_X86_TS 0x00000008 /* Task Switched */ ++#define GRUB_CR0_X86_PG 0x80000000 /* Enable PaGing */ ++ ++#define GRUB_CR0_X86_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */ ++#define GRUB_CR0_X86_WP 0x00010000 /* Write Protect */ ++#define GRUB_CR0_X86_AM 0x00040000 /* Alignment Mask */ ++#define GRUB_CR0_X86_NW 0x20000000 /* Not Write-through */ ++#define GRUB_CR0_X86_CD 0x40000000 /* Cache Disable */ ++ ++#define GRUB_CR4_X86_VME 0x00000001 /* Virtual 8086 mode extensions */ ++#define GRUB_CR4_X86_PVI 0x00000002 /* Protected-mode virtual interrupts */ ++#define GRUB_CR4_X86_TSD 0x00000004 /* Time stamp disable */ ++#define GRUB_CR4_X86_DE 0x00000008 /* Debugging extensions */ ++#define GRUB_CR4_X86_PSE 0x00000010 /* Page size extensions */ ++#define GRUB_CR4_X86_PAE 0x00000020 /* Physical address extension */ ++#define GRUB_CR4_X86_MCE 0x00000040 /* Enable Machine check enable */ ++#define GRUB_CR4_X86_PGE 0x00000080 /* Enable Page global */ ++#define GRUB_CR4_X86_PCE 0x00000100 /* Enable Performance monitoring counter */ ++#define GRUB_CR4_X86_FXSR 0x00000200 /* Fast FPU save/restore */ ++#define GRUB_CR4_X86_XMM 0x00000400 /* Enable SIMD/MMX2 to use except 16 */ ++#define GRUB_CR4_X86_VMXE 0x00002000 /* Enable VMX */ ++#define GRUB_CR4_X86_SMXE 0x00004000 /* Enable SMX */ ++#define GRUB_CR4_X86_PCIDE 0x00020000 /* Enable PCID */ ++ ++static inline unsigned long ++grub_read_cr4 (void) ++{ ++ unsigned long val; ++ ++ asm volatile ("mov %%cr4, %0" : "=r" (val) : : "memory"); ++ ++ return val; ++} ++ ++static inline void ++grub_write_cr4 (unsigned long val) ++{ ++ asm volatile ("mov %0, %%cr4" : : "r" (val) : "memory"); ++} ++ ++#define GRUB_CR0 0 ++#define GRUB_CR1 1 ++#define GRUB_CR2 2 ++#define GRUB_CR3 3 ++#define GRUB_CR4 4 ++ ++#ifdef __x86_64__ ++#define read_cr(r, d) asm volatile ("movq %%cr" r ", %0" : "=r" (d)) ++#else ++#define read_cr(r, d) asm volatile ("movl %%cr" r ", %0" : "=r" (d)) ++#endif ++ ++static inline unsigned long ++grub_read_control_register(grub_uint8_t reg) ++{ ++ unsigned long data; ++ ++ switch (reg) ++ { ++ case GRUB_CR0: ++ read_cr("0", data); ++ break; ++ case GRUB_CR1: ++ read_cr("1", data); ++ break; ++ case GRUB_CR2: ++ read_cr("2", data); ++ break; ++ case GRUB_CR3: ++ read_cr("3", data); ++ break; ++ case GRUB_CR4: ++ read_cr("4", data); ++ break; ++ default: ++ /* TODO: Loudly complain if this is called. Even some kind of BUG() */ ++ data = ~0UL; ++ break; ++ } ++ ++ return data; ++} ++ ++#ifdef __x86_64__ ++#define write_cr(r, d) asm volatile ("movq %0, %%cr" r : : "r" (d)) ++#else ++#define write_cr(r, d) asm volatile ("movl %0, %%cr" r : : "r" (d)) ++#endif ++ ++static inline void ++grub_write_control_register(grub_uint8_t reg, unsigned long data) ++{ ++ switch (reg) ++ { ++ case GRUB_CR0: ++ write_cr("0", data); ++ break; ++ case GRUB_CR1: ++ write_cr("1", data); ++ break; ++ case GRUB_CR2: ++ write_cr("2", data); ++ break; ++ case GRUB_CR3: ++ write_cr("3", data); ++ break; ++ case GRUB_CR4: ++ write_cr("4", data); ++ break; ++ default: ++ /* TODO: Loudly complain if this is called. Even some kind of BUG() */ ++ ; ++ } ++} ++ ++#define GRUB_EFLAGS_X86_CF 0x00000001 /* Carry Flag */ ++#define GRUB_EFLAGS_X86_PF 0x00000004 /* Parity Flag */ ++#define GRUB_EFLAGS_X86_AF 0x00000010 /* Auxillary carry Flag */ ++#define GRUB_EFLAGS_X86_ZF 0x00000040 /* Zero Flag */ ++#define GRUB_EFLAGS_X86_SF 0x00000080 /* Sign Flag */ ++#define GRUB_EFLAGS_X86_TF 0x00000100 /* Trap Flag */ ++#define GRUB_EFLAGS_X86_IF 0x00000200 /* Interrupt Flag */ ++#define GRUB_EFLAGS_X86_DF 0x00000400 /* Direction Flag */ ++#define GRUB_EFLAGS_X86_OF 0x00000800 /* Overflow Flag */ ++#define GRUB_EFLAGS_X86_IOPL 0x00003000 /* IOPL mask */ ++#define GRUB_EFLAGS_X86_NT 0x00004000 /* Nested Task */ ++#define GRUB_EFLAGS_X86_RF 0x00010000 /* Resume Flag */ ++#define GRUB_EFLAGS_X86_VM 0x00020000 /* Virtual Mode */ ++#define GRUB_EFLAGS_X86_AC 0x00040000 /* Alignment Check */ ++#define GRUB_EFLAGS_X86_VIF 0x00080000 /* Virtual Interrupt Flag */ ++#define GRUB_EFLAGS_X86_VIP 0x00100000 /* Virtual Interrupt Pending */ ++#define GRUB_EFLAGS_X86_ID 0x00200000 /* CPUID detection flag */ ++ ++static inline unsigned long ++grub_read_flags_register(void) ++{ ++ unsigned long flags; ++ ++#ifdef __x86_64__ ++ asm volatile ("pushfq; popq %0" : "=r" (flags)); ++#else ++ asm volatile ("pushfl; popl %0" : "=r" (flags)); ++#endif ++ ++ return flags; ++} ++ ++static inline void ++grub_write_flags_register(unsigned long flags) ++{ ++#ifdef __x86_64__ ++ asm volatile ("pushq %0; popfq" : : "r" (flags)); ++#else ++ asm volatile ("pushl %0; popfl" : : "r" (flags)); ++#endif ++} ++ ++#endif +diff --git a/include/grub/i386/mmio.h b/include/grub/i386/mmio.h +new file mode 100644 +index 000000000000..6f5bf18ce3ac +--- /dev/null ++++ b/include/grub/i386/mmio.h +@@ -0,0 +1,90 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_I386_MMIO_H ++#define GRUB_I386_MMIO_H 1 ++ ++#include ++ ++/* TODO: Are these barirers really needed??? */ ++#define grub_mb() asm volatile ("mfence" : : : "memory") ++#define grub_rmb() asm volatile ("lfence" : : : "memory") ++#define grub_wmb() asm volatile ("sfence" : : : "memory") ++#define grub_barrier() asm volatile ("" : : : "memory") ++ ++static inline grub_uint8_t ++grub_readb (const volatile void *addr) ++{ ++ grub_uint8_t val; ++ ++ grub_barrier (); ++ val = (*(volatile grub_uint8_t *) (addr)); ++ grub_rmb (); ++ ++ return val; ++} ++ ++static inline grub_uint32_t ++grub_readl (const volatile void *addr) ++{ ++ grub_uint32_t val; ++ ++ grub_barrier (); ++ val = (*(volatile grub_uint32_t *) (addr)); ++ grub_rmb (); ++ ++ return val; ++} ++ ++static inline grub_uint64_t ++grub_readq (const volatile void *addr) ++{ ++ grub_uint64_t val; ++ ++ grub_barrier (); ++ val = (*(volatile grub_uint64_t *) (addr)); ++ grub_rmb (); ++ ++ return val; ++} ++ ++static inline void ++grub_writeb (grub_uint8_t val, volatile void *addr) ++{ ++ grub_wmb (); ++ (*(volatile grub_uint8_t *) (addr)) = val; ++ grub_barrier (); ++} ++ ++static inline void ++grub_writel (grub_uint32_t val, volatile void *addr) ++{ ++ grub_wmb (); ++ (*(volatile grub_uint32_t *) (addr)) = val; ++ grub_barrier (); ++} ++ ++static inline void ++grub_writeq (grub_uint64_t val, volatile void *addr) ++{ ++ grub_wmb (); ++ (*(volatile grub_uint64_t *) (addr)) = val; ++ grub_barrier (); ++} ++ ++#endif /* GRUB_I386_MMIO_H */ +diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h +index 1e838c022f41..f2552ecbc6d4 100644 +--- a/include/grub/i386/msr.h ++++ b/include/grub/i386/msr.h +@@ -2,6 +2,9 @@ + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * ++ * Some definitions in this header are extracted from the Trusted Computing ++ * Group's "TPM Main Specification", Parts 1-3. ++ * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or +@@ -19,6 +22,62 @@ + #ifndef GRUB_I386_MSR_H + #define GRUB_I386_MSR_H 1 + ++/* General */ ++#define GRUB_MSR_X86_PLATFORM_ID 0x00000017 ++ ++#define GRUB_MSR_X86_APICBASE 0x0000001b ++#define GRUB_MSR_X86_APICBASE_BSP (1<<8) ++#define GRUB_MSR_X86_APICBASE_ENABLE (1<<11) ++#define GRUB_MSR_X86_APICBASE_BASE (0xfffff<<12) ++ ++#define GRUB_MSR_X86_FEATURE_CONTROL 0x0000003a ++#define GRUB_MSR_X86_ENABLE_VMX_IN_SMX (1<<1) ++#define GRUB_MSR_X86_SENTER_FUNCTIONS (0x7f<<8) ++#define GRUB_MSR_X86_SENTER_ENABLE (1<<15) ++ ++#define GRUB_MSR_X86_MTRRCAP 0x000000fe ++#define GRUB_MSR_X86_VCNT_MASK 0xff ++ ++#define GRUB_MSR_X86_MCG_CAP 0x00000179 ++#define GRUB_MSR_MCG_BANKCNT_MASK 0xff /* Number of banks */ ++#define GRUB_MSR_X86_MCG_STATUS 0x0000017a ++#define GRUB_MSR_MCG_STATUS_MCIP (1ULL<<2) /* MC in progress */ ++ ++#define GRUB_MSR_X86_MISC_ENABLE 0x000001a0 ++#define GRUB_MSR_X86_ENABLE_MONITOR_FSM (1<<18) ++ ++#define GRUB_MSR_X86_MTRR_PHYSBASE0 0x00000200 ++#define GRUB_MSR_X86_MTRR_PHYSMASK0 0x00000201 ++#define GRUB_MSR_X86_BASE_DEF_TYPE_MASK 0xff ++#define GRUB_MSR_X86_MASK_VALID (1<<11) ++ ++#define GRUB_MSR_X86_MTRR_DEF_TYPE 0x000002ff ++#define GRUB_MSR_X86_DEF_TYPE_MASK 0xff ++#define GRUB_MSR_X86_MTRR_ENABLE_FIXED (1<<10) ++#define GRUB_MSR_X86_MTRR_ENABLE (1<<11) ++ ++#define GRUB_MSR_X86_MC0_STATUS 0x00000401 ++ ++#define GRUB_MSR_X86_EFER 0xc0000080 /* Extended features */ ++#define GRUB_MSR_EFER_LME (1<<8) /* Enable Long Mode/IA-32e */ ++#define GRUB_MSR_EFER_LMA (1<<10) /* Long Mode/IA-32e Actuve */ ++#define GRUB_MSR_EFER_SVME (1<<12) /* Enable virtualization */ ++ ++/* AMD Specific */ ++#define GRUB_MSR_AMD64_PATCH_LEVEL 0x0000008b ++#define GRUB_MSR_AMD64_PATCH_CLEAR 0xc0010021 /* AMD-specific microcode patch clear */ ++#define GRUB_MSR_AMD64_VM_CR 0xc0010114 ++#define GRUB_MSR_SVM_VM_CR_SVM_DISABLE 4 ++ ++/* MTRR Specific */ ++#define GRUB_MTRR_MEMORY_TYPE_UC 0 ++#define GRUB_MTRR_MEMORY_TYPE_WC 1 ++#define GRUB_MTRR_MEMORY_TYPE_WT 4 ++#define GRUB_MTRR_MEMORY_TYPE_WP 5 ++#define GRUB_MTRR_MEMORY_TYPE_WB 6 ++ ++#ifndef ASM_FILE ++ + #include + #include + #include +@@ -71,4 +130,6 @@ grub_wrmsr (grub_uint32_t msr_id, grub_uint64_t msr_value) + asm volatile ("wrmsr" : : "c" (msr_id), "a" (low), "d" (high)); + } + ++#endif /* ASM_FILE */ ++ + #endif /* GRUB_I386_MSR_H */ +-- +2.17.1 + diff --git a/1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch b/1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch new file mode 100644 index 0000000..2796385 --- /dev/null +++ b/1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch @@ -0,0 +1,712 @@ +From 5f6b716437c7606e5505838ff824875954da23b1 Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Wed, 7 Aug 2019 13:53:06 -0400 +Subject: [PATCH 1110/1118] i386/txt: Add Intel TXT definitions header file + +Signed-off-by: Ross Philipson +Signed-off-by: Daniel Kiper +--- + include/grub/i386/txt.h | 691 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 691 insertions(+) + create mode 100644 include/grub/i386/txt.h + +diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h +new file mode 100644 +index 000000000000..7d57af68841f +--- /dev/null ++++ b/include/grub/i386/txt.h +@@ -0,0 +1,691 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * Intel TXT definitions header file. ++ */ ++ ++#ifndef GRUB_TXT_H ++#define GRUB_TXT_H 1 ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Intel TXT Software Developers Guide */ ++ ++/* Chapter 2, Table 2 MLE/SINIT Capabilities Field Bit Definitions */ ++ ++#define GRUB_TXT_PCR_EXT_MAX_AGILITY_POLICY 0 ++#define GRUB_TXT_PCR_EXT_MAX_PERF_POLICY 1 ++ ++#define GRUB_TXT_PLATFORM_TYPE_LEGACY 0 ++#define GRUB_TXT_PLATFORM_TYPE_CLIENT 1 ++#define GRUB_TXT_PLATFORM_TYPE_SERVER 2 ++#define GRUB_TXT_PLATFORM_TYPE_RESERVED 3 ++ ++#define GRUB_TXT_CAPS_GETSEC_WAKE_SUPPORT (1<<0) ++#define GRUB_TXT_CAPS_MONITOR_SUPPORT (1<<1) ++#define GRUB_TXT_CAPS_ECX_PT_SUPPORT (1<<2) ++#define GRUB_TXT_CAPS_STM_SUPPORT (1<<3) ++#define GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE (1<<4) ++#define GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE (1<<5) ++#define GRUB_TXT_CAPS_PLATFORM_TYPE (3<<6) ++#define GRUB_TXT_CAPS_MAXPHYSADDR_SUPPORT (1<<8) ++#define GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT (1<<9) ++#define GRUB_TXT_CAPS_CBNT_SUPPORT (1<<10) ++/* Rest is reserved */ ++ ++/* Appendix A TXT Execution Technology Authenticated Code Modules */ ++/* A.1 Authenticated Code Module Format */ ++ ++#define GRUB_TXT_ACM_MODULE_TYPE 2 ++ ++#define GRUB_TXT_ACM_MODULE_SUB_TYPE_TXT_ACM 0 ++#define GRUB_TXT_ACM_MODULE_SUB_TYPE_S_ACM 1 ++ ++#define GRUB_TXT_ACM_HEADER_LEN_0_0 161 ++#define GRUB_TXT_ACM_HEADER_LEN_3_0 224 ++ ++#define GRUB_TXT_ACM_HEADER_VERSION_0_0 0x0000 ++#define GRUB_TXT_ACM_HEADER_VERSION_3_0 0x0300 ++ ++#define GRUB_TXT_ACM_FLAG_PREPRODUCTION (1<<14) ++#define GRUB_TXT_ACM_FLAG_DEBUG_SIGNED (1<<15) ++ ++#define GRUB_TXT_ACM_MODULE_VENDOR_INTEL 0x00008086 ++ ++#define GRUB_TXT_MLE_MAX_SIZE 0x40000000 ++ ++#define GRUB_MLE_AP_WAKE_BLOCK_SIZE (4 * GRUB_PAGE_SIZE) ++ ++struct grub_txt_acm_header ++{ ++ grub_uint16_t module_type; ++ grub_uint16_t module_sub_type; ++ grub_uint32_t header_len; ++ grub_uint32_t header_version; ++ grub_uint16_t chipset_id; ++ grub_uint16_t flags; ++ grub_uint32_t module_vendor; ++ grub_uint32_t date; /* e.g 20131231H == December 31, 2013 */ ++ grub_uint32_t size; /* multiples of 4 bytes */ ++ grub_uint16_t txt_svn; ++ grub_uint16_t se_svn; ++ grub_uint32_t code_control; ++ grub_uint32_t error_entry_point; ++ grub_uint32_t gdt_limit; ++ grub_uint32_t gdt_base; ++ grub_uint32_t seg_sel; ++ grub_uint32_t entry_point; ++ grub_uint8_t reserved2[64]; ++ grub_uint32_t key_size; ++ grub_uint32_t scratch_size; ++ /* RSA Pub Key and Signature */ ++} GRUB_PACKED; ++ ++#define GRUB_TXT_ACM_UUID "\xaa\x3a\xc0\x7f\xa7\x46\xdb\x18\x2e\xac\x69\x8f\x8d\x41\x7f\x5a" ++ ++#define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS 0 ++#define GRUB_TXT_ACM_CHIPSET_TYPE_SINIT 1 ++#define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS_RACM 8 ++#define GRUB_TXT_ACM_CHIPSET_TYPE_SINIT_RACM 9 ++ ++struct grub_txt_acm_info_table ++{ ++ grub_uint8_t uuid[16]; ++ grub_uint8_t chipset_acm_type; ++ grub_uint8_t version; ++ grub_uint16_t length; ++ grub_uint32_t chipset_id_list; ++ grub_uint32_t os_sinit_data_ver; ++ grub_uint32_t min_mle_header_ver; ++ grub_uint32_t capabilities; ++ grub_uint32_t acm_version_revision; ++ grub_uint32_t processor_id_list; ++ /* Version >= 5 */ ++ grub_uint32_t tpm_info_list; ++} GRUB_PACKED; ++ ++struct grub_txt_acm_chipset_id_list ++{ ++ grub_uint32_t count; ++ /* Array of chipset ID structs */ ++} GRUB_PACKED; ++ ++#define GRUB_TXT_ACM_REVISION_ID_MASK (1<<0) ++ ++struct grub_txt_acm_chipset_id ++{ ++ grub_uint32_t flags; ++ grub_uint16_t vendor_id; ++ grub_uint16_t device_id; ++ grub_uint16_t revision_id; ++ grub_uint16_t reserved; ++ grub_uint32_t extended_id; ++} GRUB_PACKED; ++ ++struct grub_txt_acm_processor_id_list ++{ ++ grub_uint32_t count; ++ /* Array of processor ID structs */ ++} GRUB_PACKED; ++ ++struct grub_txt_acm_processor_id ++{ ++ grub_uint32_t fms; ++ grub_uint32_t fms_mask; ++ grub_uint64_t platform_id; ++ grub_uint64_t platform_mask; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_TPM_CAPS_EXTPOL_NONE 0 /* TPM 1.2 */ ++#define GRUB_TXT_TPM_CAPS_EXTPOL_MA 1 ++#define GRUB_TXT_TPM_CAPS_EXTPOL_MP 2 ++#define GRUB_TXT_TPM_CAPS_EXTPOL_BOTH 3 ++ ++#define GRUB_TXT_TPM_CAPS_FAMILY_DISCRETE_12 1 ++#define GRUB_TXT_TPM_CAPS_FAMILY_DISCRETE_20 2 ++#define GRUB_TXT_TPM_CAPS_FAMILY_FIRMWARE_20 8 ++ ++#define GRUB_TXT_TPM_CAPS_INITIAL_NV_INDICES 0 ++#define GRUB_TXT_TPM_CAPS_TCP_NV_INDICES 1 ++ ++struct grub_txt_acm_tpm_info ++{ ++ grub_uint32_t capabilities; ++ grub_uint16_t count; ++ /* List of supported hash algorithm per TPM2 spec */ ++} GRUB_PACKED; ++ ++/* Appendix B SMX Interaction with Platform */ ++/* B.1 Intel Trusted Execution Technology Configuration Registers */ ++ ++#ifdef __x86_64__ ++#define GRUB_TXT_CFG_REGS_PUB 0xfed30000ULL ++#else ++#define GRUB_TXT_CFG_REGS_PUB 0xfed30000 ++#endif ++ ++#define GRUB_TXT_STS 0x0000 ++#define GRUB_TXT_ESTS 0x0008 ++#define GRUB_TXT_ERRORCODE 0x0030 ++#define GRUB_TXT_CMD_RESET 0x0038 ++#define GRUB_TXT_CMD_CLOSE_PRIVATE 0x0048 ++#define GRUB_TXT_VER_FSBIF 0x0100 ++#define GRUB_TXT_DIDVID 0x0110 ++#define GRUB_TXT_VER_QPIIF 0x0200 ++#define GRUB_TXT_CMD_UNLOCK_MEM_CONFIG 0x0218 ++#define GRUB_TXT_SINIT_BASE 0x0270 ++#define GRUB_TXT_SINIT_SIZE 0x0278 ++#define GRUB_TXT_MLE_JOIN 0x0290 ++#define GRUB_TXT_HEAP_BASE 0x0300 ++#define GRUB_TXT_HEAP_SIZE 0x0308 ++#define GRUB_TXT_MSEG_BASE 0x0310 ++#define GRUB_TXT_MSEG_SIZE 0x0318 ++#define GRUB_TXT_DPR 0x0330 ++#define GRUB_TXT_CMD_OPEN_LOCALITY1 0x0380 ++#define GRUB_TXT_CMD_CLOSE_LOCALITY1 0x0388 ++#define GRUB_TXT_CMD_OPEN_LOCALITY2 0x0390 ++#define GRUB_TXT_CMD_CLOSE_LOCALITY2 0x0398 ++#define GRUB_TXT_PUBLIC_KEY 0x0400 ++#define GRUB_TXT_CMD_SECRETS 0x08e0 ++#define GRUB_TXT_CMD_NO_SECRETS 0x08e8 ++#define GRUB_TXT_E2STS 0x08f0 ++ ++#define GRUB_TXT_STS_SENTER_DONE (1 << 0) ++#define GRUB_TXT_STS_SEXIT_DONE (1 << 1) ++#define GRUB_TXT_STS_MEM_CONFIG_LOCK (1 << 6) ++#define GRUB_TXT_STS_PRIVATE_OPEN (1 << 7) ++#define GRUB_TXT_STS_LOCALITY1_OPEN (1 << 15) ++#define GRUB_TXT_STS_LOCALITY2_OPEN (1 << 16) ++ ++#define GRUB_TXT_ESTS_TXT_RESET (1 << 0) ++ ++#define GRUB_TXT_VER_FSBIF_DEBUG_FUSE (1 << 31) ++ ++#define GRUB_TXT_VER_QPIIF_DEBUG_FUSE (1 << 31) ++ ++#define GRUB_TXT_E2STS_SECRETS (1 << 1) ++ ++union grub_txt_didvid ++{ ++ grub_uint64_t value; ++ struct ++ { ++ grub_uint16_t vid; ++ grub_uint16_t did; ++ grub_uint16_t rid; ++ grub_uint16_t id_ext; ++ }; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_VERSION_DEBUG_FUSED (1<<31) ++ ++/* Appendix C Intel TXT Heap Memory */ ++ ++/* Ext Data Structs */ ++ ++struct grub_txt_heap_uuid ++{ ++ grub_uint32_t data1; ++ grub_uint16_t data2; ++ grub_uint16_t data3; ++ grub_uint16_t data4; ++ grub_uint8_t data5[6]; ++} GRUB_PACKED; ++ ++struct grub_txt_heap_ext_data_element ++{ ++ grub_uint32_t type; ++ grub_uint32_t size; ++ grub_uint8_t data[]; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_END 0 ++ ++struct grub_txt_heap_end_element ++{ ++ grub_uint32_t type; ++ grub_uint32_t size; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_BIOS_SPEC_VER 1 ++ ++struct grub_txt_heap_bios_spec_ver_element ++{ ++ grub_uint16_t spec_ver_major; ++ grub_uint16_t spec_ver_minor; ++ grub_uint16_t spec_ver_revision; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_ACM 2 ++ ++struct grub_txt_heap_acm_element ++{ ++ grub_uint32_t num_acms; ++ /* Array of num_acms grub_uint64_t addresses */ ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_STM 3 ++ ++struct grub_txt_heap_stm_element ++{ ++ /* STM specific BIOS properties */ ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_CUSTOM 4 ++ ++struct grub_txt_heap_custom_element ++{ ++ struct grub_txt_heap_uuid uuid; ++ /* Vendor Data */ ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR 5 ++ ++struct grub_txt_heap_tpm_event_log_element ++{ ++ grub_uint32_t type; ++ grub_uint32_t size; ++ grub_uint64_t event_log_phys_addr; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_MADT 6 ++ ++struct grub_txt_heap_madt_element ++{ ++ /* Copy of ACPI MADT table */ ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1 8 ++ ++struct grub_txt_heap_event_log_pointer2_1_element ++{ ++ grub_uint32_t type; ++ grub_uint32_t size; ++ grub_uint64_t phys_addr; ++ grub_uint32_t allocated_event_container_size; ++ grub_uint32_t first_record_offset; ++ grub_uint32_t next_record_offset; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_EXTDATA_TYPE_MCFG 9 ++ ++struct grub_txt_heap_mcfg_element ++{ ++ /* Copy of ACPI MCFG table */ ++} GRUB_PACKED; ++ ++/* TXT Heap Tables */ ++ ++struct grub_txt_bios_data ++{ ++ grub_uint32_t version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */ ++ grub_uint32_t bios_sinit_size; ++ grub_uint64_t reserved1; ++ grub_uint64_t reserved22; ++ grub_uint32_t num_logical_procs; ++ /* Versions >= 5 with updates in version 6 */ ++ grub_uint32_t sinit_flags; ++ grub_uint32_t mle_flags; ++ /* Versions >= 4 */ ++ /* Ext Data Elements */ ++} GRUB_PACKED; ++ ++/* GRUB SLAUNCH specific definitions OS-MLE data */ ++#define GRUB_SL_BOOTPARAMS_OFFSET 0x12c ++#define GRUB_SL_MAX_EVENT_LOG_SIZE (5*4*1024) /* 4k*5 */ ++#define GRUB_SL_MAX_VARIABLE_MTRRS 32 ++#define GRUB_SL_OS_MLE_STRUCT_VERSION 1 ++ ++struct grub_slaunch_mtrr_pair ++{ ++ grub_uint64_t mtrr_physbase; ++ grub_uint64_t mtrr_physmask; ++} GRUB_PACKED; ++ ++struct grub_slaunch_mtrr_state ++{ ++ grub_uint64_t default_mem_type; ++ grub_uint64_t mtrr_vcnt; ++ struct grub_slaunch_mtrr_pair mtrr_pair[GRUB_SL_MAX_VARIABLE_MTRRS]; ++} GRUB_PACKED; ++ ++struct grub_txt_os_mle_data ++{ ++ grub_uint32_t version; ++ grub_uint32_t boot_params_addr; ++ grub_uint64_t saved_misc_enable_msr; ++ struct grub_slaunch_mtrr_state saved_bsp_mtrrs; ++ grub_uint32_t ap_wake_block; ++ grub_uint32_t ap_wake_block_size; ++ grub_uint64_t evtlog_addr; ++ grub_uint32_t evtlog_size; ++ grub_uint8_t mle_scratch[64]; ++} GRUB_PACKED; ++ ++struct grub_txt_os_sinit_data ++{ ++ grub_uint32_t version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */ ++ grub_uint32_t flags; ++ grub_uint64_t mle_ptab; ++ grub_uint64_t mle_size; ++ grub_uint64_t mle_hdr_base; ++ grub_uint64_t vtd_pmr_lo_base; ++ grub_uint64_t vtd_pmr_lo_size; ++ grub_uint64_t vtd_pmr_hi_base; ++ grub_uint64_t vtd_pmr_hi_size; ++ grub_uint64_t lcp_po_base; ++ grub_uint64_t lcp_po_size; ++ grub_uint32_t capabilities; ++ /* Version = 5 */ ++ grub_uint64_t efi_rsdt_ptr; ++ /* Versions >= 6 */ ++ /* Ext Data Elements */ ++ grub_uint8_t ext_data_elts[]; ++} GRUB_PACKED; ++ ++struct grub_txt_sinit_mle_data ++{ ++ grub_uint32_t version; /* Current values are 6 through 9 */ ++ /* Versions <= 8 */ ++ grub_uint8_t bios_acm_id[20]; ++ grub_uint32_t edx_senter_flags; ++ grub_uint64_t mseg_valid; ++ grub_uint8_t sinit_hash[20]; ++ grub_uint8_t mle_hash[20]; ++ grub_uint8_t stm_hash[20]; ++ grub_uint8_t lcp_policy_hash[20]; ++ grub_uint32_t lcp_policy_control; ++ /* Versions >= 7 */ ++ grub_uint32_t rlp_wakeup_addr; ++ grub_uint32_t reserved; ++ grub_uint32_t num_of_sinit_mdrs; ++ grub_uint32_t sinit_mdrs_table_offset; ++ grub_uint32_t sinit_vtd_dmar_table_size; ++ grub_uint32_t sinit_vtd_dmar_table_offset; ++ /* Versions >= 8 */ ++ grub_uint32_t processor_scrtm_status; ++ /* Versions >= 9 */ ++ /* Ext Data Elements */ ++} GRUB_PACKED; ++ ++struct grub_txt_sinit_memory_descriptor_records ++{ ++ grub_uint64_t address; ++ grub_uint64_t length; ++ grub_uint8_t type; ++ grub_uint8_t reserved[7]; ++} GRUB_PACKED; ++ ++/* Section 2 Measured Launch Environment */ ++/* 2.1 MLE Architecture Overview */ ++/* Table 1. MLE Header structure */ ++ ++struct grub_txt_mle_header ++{ ++ grub_uint8_t uuid[16]; ++ grub_uint32_t header_len; ++ grub_uint32_t version; ++ grub_uint32_t entry_point; ++ grub_uint32_t first_valid_page; ++ grub_uint32_t mle_start; ++ grub_uint32_t mle_end; ++ grub_uint32_t capabilities; ++ grub_uint32_t cmdline_start; ++ grub_uint32_t cmdline_end; ++} GRUB_PACKED; ++ ++struct grub_txt_heap_event_log_ptr_elt ++{ ++ grub_uint64_t event_log_phys_addr; ++} GRUB_PACKED; ++ ++struct grub_txt_heap_event_log_ptr_elt2_1 ++{ ++ grub_uint64_t phys_addr; ++ grub_uint32_t allcoated_event_container_size; ++ grub_uint32_t first_record_offset; ++ grub_uint32_t next_record_offset; ++} GRUB_PACKED; ++ ++/* TXT register and heap access */ ++ ++static inline grub_uint64_t ++grub_txt_reg_pub_readq (grub_uint32_t reg) ++{ ++ return grub_readq ((void *) (GRUB_TXT_CFG_REGS_PUB + reg)); ++} ++ ++static inline grub_uint8_t * ++grub_txt_get_heap (void) ++{ ++ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE); ++} ++ ++static inline grub_uint64_t ++grub_txt_bios_data_size (grub_uint8_t *heap) ++{ ++ return *(grub_uint64_t *)heap; ++} ++ ++static inline struct grub_txt_bios_data* ++grub_txt_bios_data_start (grub_uint8_t *heap) ++{ ++ return (struct grub_txt_bios_data*)(heap + sizeof (grub_uint64_t)); ++} ++ ++static inline grub_uint64_t ++grub_txt_os_mle_data_size (grub_uint8_t *heap) ++{ ++ return *(grub_uint64_t *)(heap + grub_txt_bios_data_size (heap)); ++} ++ ++static inline struct grub_txt_os_mle_data* ++grub_txt_os_mle_data_start (grub_uint8_t *heap) ++{ ++ return (struct grub_txt_os_mle_data*)(heap + grub_txt_bios_data_size (heap) + ++ sizeof (grub_uint64_t)); ++} ++ ++static inline grub_uint64_t ++grub_txt_os_sinit_data_size (grub_uint8_t *heap) ++{ ++ return *(grub_uint64_t *)(heap + grub_txt_bios_data_size (heap) + ++ grub_txt_os_mle_data_size (heap)); ++} ++ ++static inline struct grub_txt_os_sinit_data * ++grub_txt_os_sinit_data_start (grub_uint8_t *heap) ++{ ++ return (struct grub_txt_os_sinit_data*)(heap + ++ grub_txt_bios_data_size (heap) + ++ grub_txt_os_mle_data_size (heap) + sizeof (grub_uint64_t)); ++} ++ ++static inline grub_uint64_t ++grub_txt_sinit_mle_data_size (grub_uint8_t *heap) ++{ ++ return *(grub_uint64_t *)(heap + grub_txt_bios_data_size (heap) + ++ grub_txt_os_mle_data_size (heap) + ++ grub_txt_os_sinit_data_size (heap)); ++} ++ ++static inline struct grub_txt_sinit_mle_data* ++grub_txt_sinit_mle_data_start (grub_uint8_t *heap) ++{ ++ return (struct grub_txt_sinit_mle_data*)(heap + ++ grub_txt_bios_data_size (heap) + ++ grub_txt_os_mle_data_size (heap) + ++ grub_txt_os_sinit_data_size (heap) + ++ sizeof (grub_uint64_t)); ++} ++ ++/* Intel 64 and IA-32 Architectures Software Developer’s Manual */ ++/* Volume 2 (2A, 2B, 2C & 2D): Instruction Set Reference, A-Z */ ++ ++/* CHAPTER 6 SAFER MODE EXTENSIONS REFERENCE */ ++ ++#define GRUB_SMX_LEAF_CAPABILITIES 0 ++#define GRUB_SMX_LEAF_UNDEFINED 1 ++#define GRUB_SMX_LEAF_ENTERACCS 2 ++#define GRUB_SMX_LEAF_EXITAC 3 ++#define GRUB_SMX_LEAF_SENTER 4 ++#define GRUB_SMX_LEAF_SEXIT 5 ++#define GRUB_SMX_LEAF_PARAMETERS 6 ++#define GRUB_SMX_LEAF_SMCTRL 7 ++#define GRUB_SMX_LEAF_WAKEUP 8 ++ ++#define GRUB_SMX_CAPABILITY_CHIPSET_PRESENT (1<<0) ++#define GRUB_SMX_CAPABILITY_UNDEFINED (1<<1) ++#define GRUB_SMX_CAPABILITY_ENTERACCS (1<<2) ++#define GRUB_SMX_CAPABILITY_EXITAC (1<<3) ++#define GRUB_SMX_CAPABILITY_SENTER (1<<4) ++#define GRUB_SMX_CAPABILITY_SEXIT (1<<5) ++#define GRUB_SMX_CAPABILITY_PARAMETERS (1<<6) ++#define GRUB_SMX_CAPABILITY_SMCTRL (1<<7) ++#define GRUB_SMX_CAPABILITY_WAKEUP (1<<8) ++#define GRUB_SMX_CAPABILITY_EXTENDED_LEAFS (1<<31) ++ ++static inline grub_uint32_t ++grub_txt_getsec_capabilities (grub_uint32_t index) ++{ ++ grub_uint32_t caps; ++ ++ asm volatile (".byte 0x0f,0x37\n" ++ : "=a" (caps) ++ : "a" (GRUB_SMX_LEAF_CAPABILITIES), "b" (index)); ++ return caps; ++} ++ ++static inline void ++grub_txt_getsec_enteraccs (grub_uint32_t acm_phys_addr, grub_uint32_t acm_size) ++{ ++ asm volatile (".byte 0x0f,0x37\n" : ++ : "a" (GRUB_SMX_LEAF_ENTERACCS), ++ "b" (acm_phys_addr), "c" (acm_size)); ++} ++ ++static inline void ++grub_txt_getsec_exitac (grub_uint32_t near_jump) ++{ ++ asm volatile (".byte 0x0f,0x37\n" : ++ : "a" (GRUB_SMX_LEAF_EXITAC), "b" (near_jump)); ++} ++ ++static inline void ++grub_txt_getsec_senter (grub_uint32_t acm_phys_addr, grub_uint32_t acm_size) ++{ ++ asm volatile (".byte 0x0f,0x37\n" : ++ : "a" (GRUB_SMX_LEAF_SENTER), ++ "b" (acm_phys_addr), "c" (acm_size)); ++} ++ ++static inline void ++grub_txt_getsec_sexit (void) ++{ ++ asm volatile (".byte 0x0f,0x37\n" : : "a" (GRUB_SMX_LEAF_SEXIT)); ++} ++ ++#define GRUB_SMX_PARAMETER_TYPE_MASK 0x1f ++#define GRUB_SMX_PARAMETER_NULL 0 ++#define GRUB_SMX_PARAMETER_ACM_VERSIONS 1 ++#define GRUB_SMX_PARAMETER_MAX_ACM_SIZE 2 ++#define GRUB_SMX_PARAMETER_ACM_MEMORY_TYPES 3 ++#define GRUB_SMX_PARAMETER_SENTER_CONTROLS 4 ++#define GRUB_SMX_PARAMETER_TXT_EXTENSIONS 5 ++ ++ ++#define GRUB_SMX_PARAMETER_MAX_VERSIONS 0x20 ++ ++#define GRUB_SMX_GET_MAX_ACM_SIZE(v) ((v & ~GRUB_SMX_PARAMETER_TYPE_MASK)*0x20) ++ ++#define GRUB_SMX_ACM_MEMORY_TYPE_UC 0x00000100 ++#define GRUB_SMX_ACM_MEMORY_TYPE_WC 0x00000200 ++#define GRUB_SMX_ACM_MEMORY_TYPE_WT 0x00001000 ++#define GRUB_SMX_ACM_MEMORY_TYPE_WP 0x00002000 ++#define GRUB_SMX_ACM_MEMORY_TYPE_WB 0x00004000 ++ ++#define GRUB_SMX_GET_ACM_MEMORY_TYPES(v) (v & ~GRUB_SMX_PARAMETER_TYPE_MASK) ++ ++#define GRUB_SMX_GET_SENTER_CONTROLS(v) ((v & 0x7f00) >> 8) ++ ++#define GRUB_SMX_PROCESSOR_BASE_SCRTM 0x00000020 ++#define GRUB_SMX_MACHINE_CHECK_HANLDING 0x00000040 ++#define GRUB_SMX_GET_TXT_EXT_FEATURES(v) (v & (GRUB_SMX_PROCESSOR_BASE_SCRTM|GRUB_SMX_MACHINE_CHECK_HANLDING)) ++ ++#define GRUB_SMX_DEFAULT_VERSION 0x0 ++#define GRUB_SMX_DEFAULT_VERSION_MASK 0xffffffff ++#define GRUB_SMX_DEFAULT_MAX_ACM_SIZE 0x8000 /* 32K */ ++#define GRUB_SMX_DEFAULT_ACM_MEMORY_TYPE GRUB_SMX_ACM_MEMORY_TYPE_UC ++#define GRUB_SMX_DEFAULT_SENTER_CONTROLS 0x0 ++ ++#define GRUB_TXT_PMR_ALIGN_SHIFT 21 ++#define GRUB_TXT_PMR_ALIGN (1 << GRUB_TXT_PMR_ALIGN_SHIFT) ++ ++struct grub_smx_supported_versions ++{ ++ grub_uint32_t mask; ++ grub_uint32_t version; ++} GRUB_PACKED; ++ ++struct grub_smx_parameters ++{ ++ struct grub_smx_supported_versions versions[GRUB_SMX_PARAMETER_MAX_VERSIONS]; ++ grub_uint32_t version_count; ++ grub_uint32_t max_acm_size; ++ grub_uint32_t acm_memory_types; ++ grub_uint32_t senter_controls; ++ grub_uint32_t txt_feature_ext_flags; ++} GRUB_PACKED; ++ ++static inline void ++grub_txt_getsec_parameters (grub_uint32_t index, grub_uint32_t *eax_out, ++ grub_uint32_t *ebx_out, grub_uint32_t *ecx_out) ++{ ++ if (!eax_out || !ebx_out || !ecx_out) ++ return; ++ ++ asm volatile (".byte 0x0f,0x37\n" ++ : "=a" (*eax_out), "=b" (*ebx_out), "=c" (*ecx_out) ++ : "0" (GRUB_SMX_LEAF_PARAMETERS), "1" (index)); ++} ++ ++extern grub_uint32_t grub_txt_supported_os_sinit_data_ver (struct grub_txt_acm_header* hdr); ++ ++extern grub_uint32_t grub_txt_get_sinit_capabilities (struct grub_txt_acm_header* hdr); ++ ++extern int grub_txt_is_sinit_acmod (const void *acmod_base, grub_uint32_t acmod_size); ++ ++extern int grub_txt_acmod_match_platform (struct grub_txt_acm_header *hdr); ++ ++extern struct grub_txt_acm_header* grub_txt_sinit_select (struct grub_txt_acm_header *sinit); ++ ++extern grub_err_t grub_txt_verify_platform (void); ++extern grub_err_t grub_txt_prepare_cpu (void); ++ ++extern grub_uint32_t grub_txt_get_mle_ptab_size (grub_uint32_t mle_size); ++extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); ++ ++extern grub_err_t grub_txt_init (void); ++extern void grub_txt_shutdown (void); ++extern void grub_txt_state_show (void); ++extern grub_err_t grub_txt_boot_prepare (struct grub_slaunch_params *slparams); ++ ++#endif +-- +2.17.1 + diff --git a/1111-i386-txt-Add-Intel-TXT-core-implementation.patch b/1111-i386-txt-Add-Intel-TXT-core-implementation.patch new file mode 100644 index 0000000..9dded95 --- /dev/null +++ b/1111-i386-txt-Add-Intel-TXT-core-implementation.patch @@ -0,0 +1,938 @@ +From 52435a735ec9807383adc1ac77209ad77057f00c Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Wed, 7 Aug 2019 13:57:33 -0400 +Subject: [PATCH 1111/1118] i386/txt: Add Intel TXT core implementation + +Signed-off-by: Ross Philipson +Signed-off-by: Daniel Kiper +--- + grub-core/loader/i386/txt/txt.c | 891 ++++++++++++++++++++++++++++++++ + include/grub/i386/memory.h | 5 + + 2 files changed, 896 insertions(+) + create mode 100644 grub-core/loader/i386/txt/txt.c + +diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c +new file mode 100644 +index 000000000000..201167ce9a44 +--- /dev/null ++++ b/grub-core/loader/i386/txt/txt.c +@@ -0,0 +1,891 @@ ++/* ++ * txt.c: Intel(r) TXT support functions, including initiating measured ++ * launch, post-launch, AP wakeup, etc. ++ * ++ * Copyright (c) 2003-2011, Intel Corporation ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following ++ * disclaimer in the documentation and/or other materials provided ++ * with the distribution. ++ * * Neither the name of the Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define OS_SINIT_DATA_TPM_12_VER 6 ++#define OS_SINIT_DATA_TPM_20_VER 7 ++ ++#define OS_SINIT_DATA_MIN_VER OS_SINIT_DATA_TPM_12_VER ++ ++static grub_err_t ++enable_smx_mode (void) ++{ ++ grub_uint32_t caps; ++ ++ /* Enable SMX mode. */ ++ grub_write_cr4 (grub_read_cr4 () | GRUB_CR4_X86_SMXE); ++ ++ caps = grub_txt_getsec_capabilities (0); ++ ++ if (!(caps & GRUB_SMX_CAPABILITY_CHIPSET_PRESENT)) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("TXT-capable chipset is not present")); ++ goto fail; ++ } ++ ++ if (!(caps & GRUB_SMX_CAPABILITY_SENTER)) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("GETSEC[SENTER] is not available")); ++ goto fail; ++ } ++ ++ if (!(caps & GRUB_SMX_CAPABILITY_PARAMETERS)) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("GETSEC[PARAMETERS] is not available")); ++ goto fail; ++ } ++ ++ return GRUB_ERR_NONE; ++ ++ fail: ++ /* Disable SMX mode on failure. */ ++ grub_write_cr4 (grub_read_cr4 () & ~GRUB_CR4_X86_SMXE); ++ ++ return grub_errno; ++} ++ ++static void ++grub_txt_smx_parameters (struct grub_smx_parameters *params) ++{ ++ grub_uint32_t index = 0, eax, ebx, ecx, param_type; ++ ++ grub_memset (params, 0, sizeof(struct grub_smx_supported_versions)); ++ ++ params->max_acm_size = GRUB_SMX_DEFAULT_MAX_ACM_SIZE; ++ params->acm_memory_types = GRUB_SMX_DEFAULT_ACM_MEMORY_TYPE; ++ params->senter_controls = GRUB_SMX_DEFAULT_SENTER_CONTROLS; ++ ++ do ++ { ++ grub_txt_getsec_parameters (index, &eax, &ebx, &ecx); ++ param_type = eax & GRUB_SMX_PARAMETER_TYPE_MASK; ++ ++ switch (param_type) ++ { ++ case GRUB_SMX_PARAMETER_NULL: ++ break; /* This means done. */ ++ ++ case GRUB_SMX_PARAMETER_ACM_VERSIONS: ++ if (params->version_count == GRUB_SMX_PARAMETER_MAX_VERSIONS) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Too many ACM versions")); ++ break; ++ } ++ params->versions[params->version_count].mask = ebx; ++ params->versions[params->version_count++].version = ecx; ++ break; ++ ++ case GRUB_SMX_PARAMETER_MAX_ACM_SIZE: ++ params->max_acm_size = GRUB_SMX_GET_MAX_ACM_SIZE (eax); ++ break; ++ ++ case GRUB_SMX_PARAMETER_ACM_MEMORY_TYPES: ++ params->acm_memory_types = GRUB_SMX_GET_ACM_MEMORY_TYPES (eax); ++ break; ++ ++ case GRUB_SMX_PARAMETER_SENTER_CONTROLS: ++ params->senter_controls = GRUB_SMX_GET_SENTER_CONTROLS (eax); ++ break; ++ ++ case GRUB_SMX_PARAMETER_TXT_EXTENSIONS: ++ params->txt_feature_ext_flags = GRUB_SMX_GET_TXT_EXT_FEATURES (eax); ++ break; ++ ++ default: ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown SMX parameter")); ++ param_type = GRUB_SMX_PARAMETER_NULL; ++ } ++ ++ ++index; ++ ++ } while (param_type != GRUB_SMX_PARAMETER_NULL); ++ ++ /* If no ACM versions were found, set the default one. */ ++ if (!params->version_count) ++ { ++ params->versions[0].mask = GRUB_SMX_DEFAULT_VERSION_MASK; ++ params->versions[0].version = GRUB_SMX_DEFAULT_VERSION; ++ params->version_count++; ++ } ++} ++ ++grub_err_t ++grub_txt_prepare_cpu (void) ++{ ++ struct grub_smx_parameters params; ++ grub_uint32_t i; ++ grub_uint64_t mcg_cap, mcg_stat; ++ unsigned long cr0; ++ ++ cr0 = grub_read_control_register (GRUB_CR0); ++ ++ /* Cache must be enabled (CR0.CD = CR0.NW = 0). */ ++ cr0 &= ~(GRUB_CR0_X86_CD | GRUB_CR0_X86_NW); ++ ++ /* Native FPU error reporting must be enabled for proper interaction behavior. */ ++ cr0 |= GRUB_CR0_X86_NE; ++ ++ grub_write_control_register (GRUB_CR0, cr0); ++ ++ /* Disable virtual-8086 mode (EFLAGS.VM = 0). */ ++ grub_write_flags_register (grub_read_flags_register () & ~GRUB_EFLAGS_X86_VM); ++ ++ /* ++ * Verify all machine check status registers are clear (unless ++ * support preserving them). ++ */ ++ ++ /* Is machine check in progress? */ ++ if ( grub_rdmsr (GRUB_MSR_X86_MCG_STATUS) & GRUB_MSR_MCG_STATUS_MCIP ) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("machine check in progress during secure launch")); ++ ++ grub_txt_smx_parameters (¶ms); ++ ++ if (params.txt_feature_ext_flags & GRUB_SMX_PROCESSOR_BASE_SCRTM) ++ grub_dprintf ("slaunch", "CPU supports processor-based S-CRTM\n"); ++ ++ if (params.txt_feature_ext_flags & GRUB_SMX_MACHINE_CHECK_HANLDING) ++ grub_dprintf ("slaunch", "CPU supports preserving machine check errors\n"); ++ else ++ { ++ grub_dprintf ("slaunch", "CPU does not support preserving machine check errors\n"); ++ ++ /* Check if all machine check registers are clear. */ ++ mcg_cap = grub_rdmsr (GRUB_MSR_X86_MCG_CAP); ++ for (i = 0; i < (mcg_cap & GRUB_MSR_MCG_BANKCNT_MASK); ++i) ++ { ++ mcg_stat = grub_rdmsr (GRUB_MSR_X86_MC0_STATUS + i * 4); ++ if (mcg_stat & (1ULL << 63)) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("secure launch MCG[%u] = %Lx ERROR"), i, mcg_stat); ++ } ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static void ++save_mtrrs (struct grub_txt_os_mle_data *os_mle_data) ++{ ++ grub_uint64_t i; ++ ++ os_mle_data->saved_bsp_mtrrs.default_mem_type = ++ grub_rdmsr (GRUB_MSR_X86_MTRR_DEF_TYPE); ++ ++ os_mle_data->saved_bsp_mtrrs.mtrr_vcnt = ++ grub_rdmsr (GRUB_MSR_X86_MTRRCAP) & GRUB_MSR_X86_VCNT_MASK; ++ ++ if (os_mle_data->saved_bsp_mtrrs.mtrr_vcnt > GRUB_SL_MAX_VARIABLE_MTRRS) ++ { ++ /* Print warning but continue saving what we can... */ ++ grub_printf ("WARNING: Actual number of variable MTRRs (%" PRIuGRUB_UINT64_T ++ ") > GRUB_SL_MAX_VARIABLE_MTRRS (%d)\n", ++ os_mle_data->saved_bsp_mtrrs.mtrr_vcnt, ++ GRUB_SL_MAX_VARIABLE_MTRRS); ++ os_mle_data->saved_bsp_mtrrs.mtrr_vcnt = GRUB_SL_MAX_VARIABLE_MTRRS; ++ } ++ ++ for (i = 0; i < os_mle_data->saved_bsp_mtrrs.mtrr_vcnt; ++i) ++ { ++ os_mle_data->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physmask = ++ grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + i * 2); ++ os_mle_data->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physbase = ++ grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + i * 2); ++ } ++} ++ ++static void ++set_all_mtrrs (int enable) ++{ ++ grub_uint64_t mtrr_def_type; ++ ++ mtrr_def_type = grub_rdmsr (GRUB_MSR_X86_MTRR_DEF_TYPE); ++ ++ if ( enable ) ++ mtrr_def_type |= GRUB_MSR_X86_MTRR_ENABLE; ++ else ++ mtrr_def_type &= ~GRUB_MSR_X86_MTRR_ENABLE; ++ ++ grub_wrmsr (GRUB_MSR_X86_MTRR_DEF_TYPE, mtrr_def_type); ++} ++ ++#define SINIT_MTRR_MASK 0xFFFFFF /* SINIT requires 36b mask */ ++ ++union mtrr_physbase_t ++{ ++ grub_uint64_t raw; ++ struct ++ { ++ grub_uint64_t type : 8; ++ grub_uint64_t reserved1 : 4; ++ grub_uint64_t base : 52; /* Define as max width and mask w/ */ ++ /* MAXPHYADDR when using */ ++ }; ++} GRUB_PACKED; ++ ++union mtrr_physmask_t ++{ ++ grub_uint64_t raw; ++ struct ++ { ++ grub_uint64_t reserved1 : 11; ++ grub_uint64_t v : 1; /* valid */ ++ grub_uint64_t mask : 52; /* define as max width and mask w/ */ ++ /* MAXPHYADDR when using */ ++ }; ++} GRUB_PACKED; ++ ++static inline grub_uint32_t ++bsrl (grub_uint32_t mask) ++{ ++ grub_uint32_t result; ++ ++ asm ("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc"); ++ ++ return result; ++} ++ ++static inline int ++fls (int mask) ++{ ++ return (mask == 0 ? mask : (int)bsrl ((grub_uint32_t)mask) + 1); ++} ++ ++/* ++ * set the memory type for specified range (base to base+size) ++ * to mem_type and everything else to UC ++ */ ++static grub_err_t ++set_mtrr_mem_type (const grub_uint8_t *base, grub_uint32_t size, ++ grub_uint32_t mem_type) ++{ ++ grub_uint64_t mtrr_def_type; ++ grub_uint64_t mtrr_cap; ++ union mtrr_physbase_t mtrr_physbase; ++ union mtrr_physmask_t mtrr_physmask; ++ grub_uint32_t vcnt, pages_in_range; ++ unsigned long ndx, base_v; ++ int i = 0, j, num_pages, mtrr_s; ++ ++ /* Disable all fixed MTRRs, set default type to UC */ ++ mtrr_def_type = grub_rdmsr (GRUB_MSR_X86_MTRR_DEF_TYPE); ++ mtrr_def_type &= ~(GRUB_MSR_X86_MTRR_ENABLE_FIXED | GRUB_MSR_X86_DEF_TYPE_MASK); ++ mtrr_def_type |= GRUB_MTRR_MEMORY_TYPE_UC; ++ grub_wrmsr (GRUB_MSR_X86_MTRR_DEF_TYPE, mtrr_def_type); ++ ++ /* Initially disable all variable MTRRs (we'll enable the ones we use) */ ++ mtrr_cap = grub_rdmsr (GRUB_MSR_X86_MTRRCAP); ++ vcnt = (mtrr_cap & GRUB_MSR_X86_VCNT_MASK); ++ ++ for ( ndx = 0; ndx < vcnt; ndx++ ) ++ { ++ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2); ++ mtrr_physmask.v = 0; ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2, mtrr_physmask.raw); ++ } ++ ++ /* Map all AC module pages as mem_type */ ++ num_pages = GRUB_PAGE_UP(size) >> GRUB_PAGE_SHIFT; ++ ++ grub_dprintf ("slaunch", "setting MTRRs for acmod: base=%p, size=%x, num_pages=%d\n", ++ base, size, num_pages); ++ ++ /* Each VAR MTRR base must be a multiple if that MTRR's Size */ ++ base_v = (unsigned long)base; ++ /* MTRR size in pages */ ++ mtrr_s = 1; ++ ++ while ( (base_v & 0x01) == 0 ) ++ { ++ i++; ++ base_v = base_v >> 1; ++ } ++ ++ for (j = i - 12; j > 0; j--) ++ mtrr_s = mtrr_s*2; /* mtrr_s = mtrr_s << 1 */ ++ ++ grub_dprintf ("slaunch", "The maximum allowed MTRR range size=%d Pages \n", mtrr_s); ++ ++ ndx = 0; ++ ++ while ( num_pages >= mtrr_s ) ++ { ++ mtrr_physbase.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2); ++ mtrr_physbase.base = ((unsigned long)base >> GRUB_PAGE_SHIFT) & ++ SINIT_MTRR_MASK; ++ mtrr_physbase.type = mem_type; ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2, mtrr_physbase.raw); ++ ++ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2); ++ mtrr_physmask.mask = ~(mtrr_s - 1) & SINIT_MTRR_MASK; ++ mtrr_physmask.v = 1; ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2, mtrr_physmask.raw); ++ ++ base += (mtrr_s * GRUB_PAGE_SIZE); ++ num_pages -= mtrr_s; ++ ndx++; ++ if ( ndx == vcnt ) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("exceeded number of var MTRRs when mapping range")); ++ } ++ ++ ndx = 0; ++ ++ while ( num_pages > 0 ) ++ { ++ /* Set the base of the current MTRR */ ++ mtrr_physbase.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2); ++ mtrr_physbase.base = ((unsigned long)base >> GRUB_PAGE_SHIFT) & ++ SINIT_MTRR_MASK; ++ mtrr_physbase.type = mem_type; ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2, mtrr_physbase.raw); ++ ++ /* ++ * Calculate MTRR mask ++ * MTRRs can map pages in power of 2 ++ * may need to use multiple MTRRS to map all of region ++ */ ++ pages_in_range = 1 << (fls (num_pages) - 1); ++ ++ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2); ++ mtrr_physmask.mask = ~(pages_in_range - 1) & SINIT_MTRR_MASK; ++ mtrr_physmask.v = 1; ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2, mtrr_physmask.raw); ++ ++ /* ++ * Prepare for the next loop depending on number of pages ++ * We figure out from the above how many pages could be used in this ++ * mtrr. Then we decrement the count, increment the base, ++ * increment the mtrr we are dealing with, and if num_pages is ++ * still not zero, we do it again. ++ */ ++ base += (pages_in_range * GRUB_PAGE_SIZE); ++ num_pages -= pages_in_range; ++ ndx++; ++ if ( ndx == vcnt ) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("exceeded number of var MTRRs when mapping range")); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++/* ++ * this must be done for each processor so that all have the same ++ * memory types ++ */ ++static grub_err_t ++set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) ++{ ++ unsigned long eflags; ++ unsigned long cr0, cr4; ++ grub_err_t err; ++ ++ /* ++ * need to do some things before we start changing MTRRs ++ * ++ * since this will modify some of the MTRRs, they should be saved first ++ * so that they can be restored once the AC mod is done ++ */ ++ ++ /* Disable interrupts */ ++ eflags = grub_read_flags_register (); ++ grub_write_flags_register (eflags & ~GRUB_EFLAGS_X86_IF); ++ ++ /* Save CR0 then disable cache (CRO.CD=1, CR0.NW=0) */ ++ cr0 = grub_read_control_register (GRUB_CR0); ++ grub_write_control_register (GRUB_CR0, ++ (cr0 & ~GRUB_CR0_X86_NW) | GRUB_CR0_X86_CD); ++ ++ /* Flush caches */ ++ asm volatile ("wbinvd"); ++ ++ /* Save CR4 and disable global pages (CR4.PGE=0) */ ++ cr4 = grub_read_control_register (GRUB_CR4); ++ grub_write_control_register (GRUB_CR4, cr4 & ~GRUB_CR4_X86_PGE); ++ ++ /* Disable MTRRs */ ++ set_all_mtrrs (0); ++ ++ /* Set MTRRs for AC mod and rest of memory */ ++ err = set_mtrr_mem_type ((grub_uint8_t*)hdr, hdr->size*4, ++ GRUB_MTRR_MEMORY_TYPE_WB); ++ if ( err ) ++ return err; ++ ++ /* Undo some of earlier changes and enable our new settings */ ++ ++ /* Flush caches */ ++ asm volatile ("wbinvd"); ++ ++ /* Enable MTRRs */ ++ set_all_mtrrs (1); ++ ++ /* Restore CR0 (cacheing) */ ++ grub_write_control_register (GRUB_CR0, cr0); ++ ++ /* Restore CR4 (global pages) */ ++ grub_write_control_register (GRUB_CR4, cr4); ++ ++ /* Restore flags */ ++ grub_write_flags_register (eflags); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header *sinit) ++{ ++ grub_uint8_t *txt_heap; ++ grub_uint32_t os_sinit_data_ver, sinit_caps; ++ grub_uint64_t *size; ++ struct grub_txt_os_mle_data *os_mle_data; ++ struct grub_txt_os_sinit_data *os_sinit_data; ++ struct grub_txt_heap_end_element *heap_end_element; ++ struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; ++#ifdef GRUB_MACHINE_EFI ++ struct grub_acpi_rsdp_v20 *rsdp; ++#endif ++ ++ /* BIOS data already verified in grub_txt_verify_platform(). */ ++ ++ txt_heap = grub_txt_get_heap (); ++ ++ /* OS/loader to MLE data. */ ++ ++ os_mle_data = grub_txt_os_mle_data_start (txt_heap); ++ size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); ++ *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); ++ ++ grub_memset (os_mle_data, 0, sizeof (*os_mle_data)); ++ ++ os_mle_data->version = GRUB_SL_OS_MLE_STRUCT_VERSION; ++ os_mle_data->boot_params_addr = slparams->boot_params_addr; ++ os_mle_data->saved_misc_enable_msr = grub_rdmsr (GRUB_MSR_X86_MISC_ENABLE); ++ ++ os_mle_data->ap_wake_block = slparams->ap_wake_block; ++ os_mle_data->ap_wake_block_size = slparams->ap_wake_block_size; ++ ++ os_mle_data->evtlog_addr = slparams->tpm_evt_log_base; ++ os_mle_data->evtlog_size = slparams->tpm_evt_log_size; ++ ++ save_mtrrs (os_mle_data); ++ ++ /* OS/loader to SINIT data. */ ++ ++ os_sinit_data_ver = grub_txt_supported_os_sinit_data_ver (sinit); ++ ++ if (os_sinit_data_ver < OS_SINIT_DATA_MIN_VER) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("unsupported OS to SINIT data version in SINIT ACM: %d" ++ " expected >= %d"), os_sinit_data_ver, OS_SINIT_DATA_MIN_VER); ++ ++ os_sinit_data = grub_txt_os_sinit_data_start (txt_heap); ++ size = (grub_uint64_t *) ((grub_addr_t) os_sinit_data - sizeof (grub_uint64_t)); ++ ++ *size = sizeof(grub_uint64_t) + sizeof (struct grub_txt_os_sinit_data) + ++ sizeof (struct grub_txt_heap_end_element); ++ ++ if (grub_get_tpm_ver () == GRUB_TPM_12) ++ *size += sizeof (struct grub_txt_heap_tpm_event_log_element); ++ else if (grub_get_tpm_ver () == GRUB_TPM_20) ++ *size += sizeof (struct grub_txt_heap_event_log_pointer2_1_element); ++ else ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("unsupported TPM version")); ++ ++ grub_memset (os_sinit_data, 0, *size); ++ ++#ifdef GRUB_MACHINE_EFI ++ rsdp = grub_acpi_get_rsdpv2 (); ++ ++ if (rsdp == NULL) ++ return grub_printf ("WARNING: ACPI RSDP 2.0 missing\n"); ++ ++ os_sinit_data->efi_rsdt_ptr = (grub_uint64_t)(grub_addr_t) rsdp; ++#endif ++ ++ os_sinit_data->mle_ptab = slparams->mle_ptab_target; ++ os_sinit_data->mle_size = slparams->mle_size; ++ ++ os_sinit_data->mle_hdr_base = slparams->mle_header_offset; ++ ++ /* TODO: Check low PMR with RMRR. Look at relevant tboot code too. */ ++ /* TODO: Kernel should not allocate any memory outside of PMRs regions!!! */ ++ os_sinit_data->vtd_pmr_lo_base = 0; ++ os_sinit_data->vtd_pmr_lo_size = ALIGN_DOWN (grub_mmap_get_highest (0x100000000), ++ GRUB_TXT_PMR_ALIGN); ++ ++ os_sinit_data->vtd_pmr_hi_base = ALIGN_UP (grub_mmap_get_lowest (0x100000000), ++ GRUB_TXT_PMR_ALIGN); ++ os_sinit_data->vtd_pmr_hi_size = ALIGN_DOWN (grub_mmap_get_highest (0xffffffffffffffff), ++ GRUB_TXT_PMR_ALIGN); ++ os_sinit_data->vtd_pmr_hi_size -= os_sinit_data->vtd_pmr_hi_base; ++ ++ grub_dprintf ("slaunch", ++ "vtd_pmr_lo_base: 0x%" PRIxGRUB_UINT64_T " vtd_pmr_lo_size: 0x%" ++ PRIxGRUB_UINT64_T " vtd_pmr_hi_base: 0x%" PRIxGRUB_UINT64_T ++ " vtd_pmr_hi_size: 0x%" PRIxGRUB_UINT64_T "\n", ++ os_sinit_data->vtd_pmr_lo_base, os_sinit_data->vtd_pmr_lo_size, ++ os_sinit_data->vtd_pmr_hi_base, os_sinit_data->vtd_pmr_hi_size); ++ ++ sinit_caps = grub_txt_get_sinit_capabilities (sinit); ++ ++ /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ ++ os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE | ++ GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; ++ ++ /* Choose monitor RLP wakeup mechanism first. */ ++ if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) ++ os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; ++ else if (sinit_caps & GRUB_TXT_CAPS_GETSEC_WAKE_SUPPORT) ++ os_sinit_data->capabilities |= GRUB_TXT_CAPS_GETSEC_WAKE_SUPPORT; ++ else ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("lack of RLP wakeup mechanism")); ++ ++ if (sinit_caps & GRUB_TXT_CAPS_ECX_PT_SUPPORT) ++ os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; ++ ++ if (grub_get_tpm_ver () == GRUB_TPM_12) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("TPM 1.2 is not supported")); ++ else ++ { ++ if (!(sinit_caps & GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT)) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("original TXT TPM 2.0 event log format is not supported")); ++ ++ os_sinit_data->capabilities |= GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT; ++ ++ os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; ++ ++ os_sinit_data->version = OS_SINIT_DATA_TPM_20_VER; ++ ++ heap_event_log_pointer2_1_element = ++ (struct grub_txt_heap_event_log_pointer2_1_element *) os_sinit_data->ext_data_elts; ++ heap_event_log_pointer2_1_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1; ++ heap_event_log_pointer2_1_element->size = sizeof (*heap_event_log_pointer2_1_element); ++ heap_event_log_pointer2_1_element->phys_addr = slparams->tpm_evt_log_base; ++ heap_event_log_pointer2_1_element->allocated_event_container_size = slparams->tpm_evt_log_size; ++ ++ heap_end_element = (struct grub_txt_heap_end_element *) ++ ((grub_addr_t) heap_event_log_pointer2_1_element + heap_event_log_pointer2_1_element->size); ++ heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; ++ heap_end_element->size = sizeof (*heap_end_element); ++ } ++ ++ /* ++ * TODO: TXT spec: Note: BiosDataSize + OsMleDataSize + OsSinitDataSize + SinitMleDataSize ++ * must be less than or equal to TXT.HEAP.SIZE, TXT spec, p. 102. ++ */ ++ ++ return GRUB_ERR_NONE; ++} ++ ++/* ++ * TODO: Why 1 GiB limit? It does not seem that it is required by TXT spec. ++ * If there is a limit then it should be checked before allocation and image load. ++ * ++ * If enough room is available in front of the MLE, the maximum size of an ++ * MLE that can be covered is 1G. This is due to having 512 PDEs pointing ++ * to 512 page tables with 512 PTEs each. ++ */ ++grub_uint32_t ++grub_txt_get_mle_ptab_size (grub_uint32_t mle_size) ++{ ++ /* ++ * #PT + 1 PT + #PD + 1 PD + 1 PDT ++ * ++ * Why do we need 2 extra PTEs and PDEs? Yes, because MLE image may not ++ * start and end at PTE (page) and PDE (2 MiB) boundary... ++ */ ++ return ((((mle_size / GRUB_PAGE_SIZE) + 2) / 512) + 1 + ++ (((mle_size / (512 * GRUB_PAGE_SIZE)) + 2) / 512) + 1 + 1) * GRUB_PAGE_SIZE; ++} ++ ++/* Page directory and table entries only need Present set */ ++#define MAKE_PT_MLE_ENTRY(addr) (((grub_uint64_t)(grub_addr_t)(addr) & GRUB_PAGE_MASK) | 0x01) ++ ++/* ++ * The MLE page tables have to be below the MLE and have no special regions in ++ * between them and the MLE (this is a bit of an unwritten rule). ++ * 20 pages are carved out of memory below the MLE. That leave 18 page table ++ * pages that can cover up to 36M . ++ * can only contain 4k pages ++ * ++ * TODO: TXT Spec p.32; List section name and number with PT MLE requirments here. ++ * ++ * TODO: This function is not able to cover MLEs larger than 1 GiB. Fix it!!! ++ * After fixing inrease GRUB_TXT_MLE_MAX_SIZE too. ++ */ ++void ++grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams) ++{ ++ grub_uint8_t *pg_dir, *pg_dir_ptr_tab = slparams->mle_ptab_mem, *pg_tab; ++ grub_uint32_t mle_off = 0, pd_off = 0; ++ grub_uint64_t *pde, *pte; ++ ++ grub_memset (pg_dir_ptr_tab, 0, slparams->mle_ptab_size); ++ ++ pg_dir = pg_dir_ptr_tab + GRUB_PAGE_SIZE; ++ pg_tab = pg_dir + GRUB_PAGE_SIZE; ++ ++ /* Only use first entry in page dir ptr table */ ++ *(grub_uint64_t *)pg_dir_ptr_tab = MAKE_PT_MLE_ENTRY(pg_dir); ++ ++ /* Start with first entry in page dir */ ++ *(grub_uint64_t *)pg_dir = MAKE_PT_MLE_ENTRY(pg_tab); ++ ++ pte = (grub_uint64_t *)pg_tab; ++ pde = (grub_uint64_t *)pg_dir; ++ ++ do ++ { ++ *pte = MAKE_PT_MLE_ENTRY(slparams->mle_start + mle_off); ++ ++ pte++; ++ mle_off += GRUB_PAGE_SIZE; ++ ++ if (!(++pd_off % 512)) ++ { ++ /* Break if we don't need any additional page entries */ ++ if (mle_off >= slparams->mle_size) ++ break; ++ pde++; ++ *pde = MAKE_PT_MLE_ENTRY(pte); ++ } ++ } while (mle_off < slparams->mle_size); ++} ++ ++grub_err_t ++grub_txt_init (void) ++{ ++ grub_err_t err; ++ ++ err = grub_txt_verify_platform (); ++ ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ err = enable_smx_mode (); ++ ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ return GRUB_ERR_NONE; ++} ++ ++void ++grub_txt_shutdown (void) ++{ ++ /* Disable SMX mode. */ ++ grub_write_cr4 (grub_read_cr4 () & ~GRUB_CR4_X86_SMXE); ++} ++ ++void ++grub_txt_state_show (void) ++{ ++ grub_uint64_t data; ++ grub_uint8_t *data8 = (grub_uint8_t *) &data; ++ int i; ++ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_STS); ++ grub_printf (" TXT.STS: 0x%016" PRIxGRUB_UINT64_T "\n" ++ " SENTER.DONE.STS: %d\n" ++ " SEXIT.DONE.STS: %d\n" ++ " MEM-CONFIGLOCK.STS: %d\n" ++ " PRIVATEOPEN.STS: %d\n" ++ " TXT.LOCALITY1.OPEN.STS: %d\n" ++ " TXT.LOCALITY2.OPEN.STS: %d\n", ++ data, !!(data & GRUB_TXT_STS_SENTER_DONE), ++ !!(data & GRUB_TXT_STS_SEXIT_DONE), ++ !!(data & GRUB_TXT_STS_MEM_CONFIG_LOCK), ++ !!(data & GRUB_TXT_STS_PRIVATE_OPEN), ++ !!(data & GRUB_TXT_STS_LOCALITY1_OPEN), ++ !!(data & GRUB_TXT_STS_LOCALITY2_OPEN)); ++ ++ /* Only least significant byte has a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_ESTS) & 0x00000000000000ff; ++ grub_printf (" TXT.ESTS: 0x%02" PRIxGRUB_UINT64_T "\n" ++ " TXT_RESET.STS: %d\n", data, ++ !!(data & GRUB_TXT_ESTS_TXT_RESET)); ++ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_E2STS); ++ grub_printf (" TXT.E2STS: 0x%016" PRIxGRUB_UINT64_T "\n" ++ " SECRETS.STS: %d\n", data, ++ !!(data & GRUB_TXT_E2STS_SECRETS)); ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_ERRORCODE) & 0x00000000ffffffff; ++ grub_printf (" TXT.ERRORCODE: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); ++ grub_printf (" TXT.DIDVID: 0x%016" PRIxGRUB_UINT64_T "\n" ++ " VID: 0x%04" PRIxGRUB_UINT64_T "\n" ++ " DID: 0x%04" PRIxGRUB_UINT64_T "\n" ++ " RID: 0x%04" PRIxGRUB_UINT64_T "\n" ++ " ID-EXT: 0x%04" PRIxGRUB_UINT64_T "\n", ++ data, data & 0x000000000000ffff, ++ (data & 0x00000000ffff0000) >> 16, ++ (data & 0x0000ffff00000000) >> 32, data >> 48); ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_VER_FSBIF) & 0x00000000ffffffff; ++ grub_printf (" TXT.VER.FSBIF: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ ++ if ((data != 0x00000000) && (data != 0xffffffff)) ++ grub_printf (" DEBUG.FUSE: %d\n", !!(data & GRUB_TXT_VER_FSBIF_DEBUG_FUSE)); ++ else ++ { ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_VER_QPIIF) & 0x00000000ffffffff; ++ grub_printf (" TXT.VER.QPIIF: 0x%08" PRIxGRUB_UINT64_T "\n" ++ " DEBUG.FUSE: %d\n", data, ++ !!(data & GRUB_TXT_VER_QPIIF_DEBUG_FUSE)); ++ } ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_SINIT_BASE) & 0x00000000ffffffff; ++ grub_printf (" TXT.SINIT.BASE: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_SINIT_SIZE) & 0x00000000ffffffff; ++ grub_printf (" TXT.SINIT.SIZE: %" PRIuGRUB_UINT64_T ++ " B (0x%" PRIxGRUB_UINT64_T ")\n", data, data); ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE) & 0x00000000ffffffff; ++ grub_printf (" TXT.HEAP.BASE: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_SIZE) & 0x00000000ffffffff; ++ grub_printf (" TXT.HEAP.SIZE: %" PRIuGRUB_UINT64_T ++ " B (0x%" PRIxGRUB_UINT64_T ")\n", data, data); ++ ++ /* Only least significant 4 bytes have a meaning. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_DPR) & 0x00000000ffffffff; ++ grub_printf (" TXT.DPR: 0x%08" PRIxGRUB_UINT64_T "\n" ++ " LOCK: %d\n" ++ " TOP: 0x%08" PRIxGRUB_UINT64_T "\n" ++ " SIZE: %" PRIuGRUB_UINT64_T " MiB\n", ++ data, !!(data & (1 << 0)), (data & 0xfff00000), ++ (data & 0x00000ff0) >> 4); ++ ++ grub_printf (" TXT.PUBLIC.KEY:\n"); ++ ++ for (i = 0; i < 4; ++i) ++ { ++ /* TODO: Check relevant MSRs on SGX platforms. */ ++ data = grub_txt_reg_pub_readq (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t)); ++ grub_printf (" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x%s", data8[0], data8[1], ++ data8[2], data8[3], data8[4], data8[5], data8[6], data8[7], ++ (i < 3) ? ":\n" : "\n"); ++ } ++} ++ ++grub_err_t ++grub_txt_boot_prepare (struct grub_slaunch_params *slparams) ++{ ++ grub_err_t err; ++ struct grub_txt_mle_header *mle_header; ++ struct grub_txt_acm_header *sinit_base; ++ ++ sinit_base = grub_txt_sinit_select (grub_slaunch_module ()); ++ ++ if (sinit_base == NULL) ++ return grub_errno; ++ ++ err = init_txt_heap (slparams, sinit_base); ++ ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ /* Update the MLE header. */ ++ mle_header = (struct grub_txt_mle_header *)(grub_addr_t) (slparams->mle_start + slparams->mle_header_offset); ++ mle_header->first_valid_page = 0; ++ mle_header->mle_end = slparams->mle_size; ++ ++ slparams->sinit_acm_base = (grub_uint32_t)(grub_addr_t) sinit_base; ++ slparams->sinit_acm_size = sinit_base->size * 4; ++ ++ grub_tpm_relinquish_lcl (0); ++ ++ err = set_mtrrs_for_acmod (sinit_base); ++ if (err) ++ return grub_error (err, N_("secure launch failed to set MTRRs for ACM")); ++ ++ err = grub_txt_prepare_cpu (); ++ if ( err ) ++ return err; ++ ++ if (!(grub_rdmsr (GRUB_MSR_X86_APICBASE) & GRUB_MSR_X86_APICBASE_BSP)) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("secure launch must run on BSP")); ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h +index c64529630f19..56f64855be7e 100644 +--- a/include/grub/i386/memory.h ++++ b/include/grub/i386/memory.h +@@ -22,6 +22,7 @@ + + #define GRUB_PAGE_SHIFT 12 + #define GRUB_PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) ++#define GRUB_PAGE_MASK (~(GRUB_PAGE_SIZE - 1)) + + /* The flag for protected mode. */ + #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +@@ -43,8 +44,12 @@ + + #define GRUB_MMAP_MALLOC_LOW 1 + ++#include + #include + ++#define GRUB_PAGE_UP(p) ALIGN_UP (p, GRUB_PAGE_SIZE) ++#define GRUB_PAGE_DOWN(p) ALIGN_DOWN (p, GRUB_PAGE_SIZE) ++ + struct grub_e820_mmap_entry + { + grub_uint64_t addr; +-- +2.17.1 + diff --git a/1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch b/1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch new file mode 100644 index 0000000..9116c07 --- /dev/null +++ b/1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch @@ -0,0 +1,596 @@ +From 2ff5828c221797a0165f7f9fd1459457ee1b499f Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Wed, 7 Aug 2019 13:59:18 -0400 +Subject: [PATCH 1112/1118] i386/txt: Add Intel TXT ACM module support + +Signed-off-by: Ross Philipson +Signed-off-by: Daniel Kiper +--- + grub-core/loader/i386/txt/acmod.c | 575 ++++++++++++++++++++++++++++++ + 1 file changed, 575 insertions(+) + create mode 100644 grub-core/loader/i386/txt/acmod.c + +diff --git a/grub-core/loader/i386/txt/acmod.c b/grub-core/loader/i386/txt/acmod.c +new file mode 100644 +index 000000000000..ed2fbab7b0da +--- /dev/null ++++ b/grub-core/loader/i386/txt/acmod.c +@@ -0,0 +1,575 @@ ++/* ++ * acmod.c: support functions for use of Intel(r) TXT Authenticated ++ * Code (AC) Modules ++ * ++ * Copyright (c) 2003-2011, Intel Corporation ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following ++ * disclaimer in the documentation and/or other materials provided ++ * with the distribution. ++ * * Neither the name of the Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * This checks to see if two numbers multiplied together are larger ++ * than the type that they are. Returns TRUE if OVERFLOWING. ++ * If the first parameter "x" is greater than zero and ++ * if that is true, that the largest possible value 0xFFFFFFFF / "x" ++ * is less than the second parameter "y". If "y" is zero then ++ * it will also fail because no unsigned number is less than zero. ++ */ ++static inline int ++multiply_overflow_u32 (grub_uint32_t x, grub_uint32_t y) ++{ ++ /* Use x instead of (x > 0)? */ ++ return (x > 0) ? ((((grub_uint32_t)(~0))/x) < y) : 0; ++} ++ ++/* ++ * These three "plus overflow" functions take a "x" value ++ * and add the "y" value to it and if the two values are ++ * greater than the size of the variable type, they will ++ * overflow the type and end up with a smaller value and ++ * return TRUE - that they did overflow. i.e. ++ */ ++static inline int plus_overflow_u32 (grub_uint32_t x, grub_uint32_t y) ++{ ++ return ((((grub_uint32_t)(~0)) - x) < y); ++} ++ ++static struct grub_txt_acm_info_table* ++get_acmod_info_table (struct grub_txt_acm_header* hdr) ++{ ++ grub_uint32_t user_area_off; ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 (hdr->header_len, hdr->scratch_size) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM header length plus scratch size overflows")); ++ return NULL; ++ } ++ ++ if ( multiply_overflow_u32 ((hdr->header_len + hdr->scratch_size), 4) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM header length and scratch size in bytes overflows")); ++ return NULL; ++ } ++ ++ /* ++ * This fn assumes that the ACM has already passed at least the initial ++ * is_acmod() checks. ++ */ ++ ++ user_area_off = (hdr->header_len + hdr->scratch_size) * 4; ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 (user_area_off, sizeof(struct grub_txt_acm_info_table)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("user_area_off plus acm_info_table_t size overflows")); ++ return NULL; ++ } ++ ++ /* Check that table is within module. */ ++ if ( user_area_off + sizeof(struct grub_txt_acm_info_table) > hdr->size * 4 ) ++ { ++ /* TODO: Is (grub_uint32_t) correct??? */ ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM info table size too large: %x > %x"), ++ user_area_off + (grub_uint32_t)sizeof(struct grub_txt_acm_info_table), hdr->size * 4); ++ return NULL; ++ } ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 ((grub_uint32_t)(unsigned long)hdr, user_area_off) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("hdr plus user_area_off overflows")); ++ return NULL; ++ } ++ ++ return (struct grub_txt_acm_info_table *)((unsigned long)hdr + user_area_off); ++} ++ ++static struct grub_txt_acm_chipset_id_list* ++get_acmod_chipset_list (struct grub_txt_acm_header *hdr) ++{ ++ struct grub_txt_acm_info_table *info_table; ++ grub_uint32_t size, id_list_off; ++ struct grub_txt_acm_chipset_id_list *chipset_id_list; ++ ++ /* This fn assumes that the ACM has already passed the is_acmod() checks */ ++ ++ info_table = get_acmod_info_table (hdr); ++ if ( !info_table ) ++ return NULL; ++ id_list_off = info_table->chipset_id_list; ++ ++ size = hdr->size * 4; ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 (id_list_off, sizeof(struct grub_txt_acm_chipset_id)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("id_list_off plus acm_chipset_id_t size overflows")); ++ return NULL; ++ } ++ ++ /* Check that chipset id table is w/in ACM */ ++ if ( id_list_off + sizeof(struct grub_txt_acm_chipset_id) > size ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("chipset id list is too big: %x"), id_list_off); ++ return NULL; ++ } ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 ((grub_uint32_t)(unsigned long)hdr, id_list_off) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("hdr plus id_list_off overflows")); ++ return NULL; ++ } ++ ++ chipset_id_list = (struct grub_txt_acm_chipset_id_list*) ++ ((unsigned long)hdr + id_list_off); ++ ++ /* Overflows? */ ++ if ( multiply_overflow_u32 (chipset_id_list->count, ++ sizeof(struct grub_txt_acm_chipset_id)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of acm_chipset_id_list overflows")); ++ return NULL; ++ } ++ ++ if ( plus_overflow_u32 (id_list_off + sizeof(struct grub_txt_acm_chipset_id), ++ chipset_id_list->count * sizeof(struct grub_txt_acm_chipset_id)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of all entries overflows")); ++ return NULL; ++ } ++ ++ /* Check that all entries are w/in ACM */ ++ if ( id_list_off + sizeof(struct grub_txt_acm_chipset_id) + ++ chipset_id_list->count * sizeof(struct grub_txt_acm_chipset_id) > size ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset id entries are too big: %x"), ++ chipset_id_list->count); ++ return NULL; ++ } ++ ++ return chipset_id_list; ++} ++ ++static struct grub_txt_acm_processor_id_list* ++get_acmod_processor_list (struct grub_txt_acm_header* hdr) ++{ ++ struct grub_txt_acm_info_table *info_table; ++ grub_uint32_t size, id_list_off; ++ struct grub_txt_acm_processor_id_list *proc_id_list; ++ ++ /* This fn assumes that the ACM has already passed the is_acmod() checks */ ++ ++ info_table = get_acmod_info_table(hdr); ++ if ( info_table == NULL ) ++ return NULL; ++ id_list_off = info_table->processor_id_list; ++ ++ size = hdr->size * 4; ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 (id_list_off, sizeof(struct grub_txt_acm_processor_id)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("id_list_off plus acm_processor_id_t size overflows")); ++ return NULL; ++ } ++ ++ /* Check that processor id table is w/in ACM */ ++ if ( id_list_off + sizeof(struct grub_txt_acm_processor_id) > size ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor id list is too big: %x"), id_list_off); ++ return NULL; ++ } ++ ++ /* Overflow? */ ++ if ( plus_overflow_u32 ((unsigned long)hdr, id_list_off) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("hdr plus id_list_off overflows")); ++ return NULL; ++ } ++ ++ proc_id_list = (struct grub_txt_acm_processor_id_list *) ++ ((unsigned long)hdr + id_list_off); ++ ++ /* Overflows? */ ++ if ( multiply_overflow_u32 (proc_id_list->count, ++ sizeof(struct grub_txt_acm_processor_id)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of acm_processor_id_list overflows")); ++ return NULL; ++ } ++ ++ if ( plus_overflow_u32 (id_list_off + sizeof(struct grub_txt_acm_processor_id), ++ proc_id_list->count * sizeof(struct grub_txt_acm_processor_id)) ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of all entries overflows")); ++ return NULL; ++ } ++ ++ /* Check that all entries are w/in ACM */ ++ if ( id_list_off + sizeof(struct grub_txt_acm_processor_id) + ++ proc_id_list->count * sizeof(struct grub_txt_acm_processor_id) > size ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor id entries are too big: %x"), ++ proc_id_list->count); ++ return NULL; ++ } ++ ++ return proc_id_list; ++} ++ ++static int ++is_acmod (const void *acmod_base, grub_uint32_t acmod_size, ++ grub_uint8_t *type_out) ++{ ++ struct grub_txt_acm_header *acm_hdr = (struct grub_txt_acm_header *)acmod_base; ++ struct grub_txt_acm_info_table *info_table; ++ ++ /* First check size */ ++ if ( acmod_size < sizeof (struct grub_txt_acm_header) ) ++ return 0; ++ ++ /* Then check overflow */ ++ if ( multiply_overflow_u32 (acm_hdr->size, 4) ) ++ return 0; ++ ++ /* Then check size equivalency */ ++ if ( acmod_size != acm_hdr->size * 4 ) ++ return 0; ++ ++ /* Then check type and vendor */ ++ if ( (acm_hdr->module_type != GRUB_TXT_ACM_MODULE_TYPE) || ++ (acm_hdr->module_vendor != GRUB_TXT_ACM_MODULE_VENDOR_INTEL) ) ++ return 0; ++ ++ info_table = get_acmod_info_table (acm_hdr); ++ if ( !info_table ) ++ return 0; ++ ++ /* Check if ACM UUID is present */ ++ if ( grub_memcmp (&(info_table->uuid), GRUB_TXT_ACM_UUID, 16) ) ++ return 0; ++ ++ if ( type_out ) ++ *type_out = info_table->chipset_acm_type; ++ ++ return 1; ++} ++ ++static struct grub_txt_acm_header* ++get_bios_sinit (void *sinit_region_base) ++{ ++ grub_uint8_t *txt_heap = grub_txt_get_heap (); ++ struct grub_txt_bios_data *bios_data = grub_txt_bios_data_start (txt_heap); ++ struct grub_txt_acm_header *bios_sinit; ++ ++ if ( !sinit_region_base ) ++ return NULL; ++ ++ if ( bios_data->bios_sinit_size == 0 ) ++ return NULL; ++ ++ /* BIOS has loaded an SINIT module, so verify that it is valid */ ++ grub_dprintf ("slaunch", "BIOS has already loaded an SINIT module\n"); ++ ++ bios_sinit = (struct grub_txt_acm_header *)sinit_region_base; ++ ++ /* Is it a valid SINIT module? */ ++ if ( !grub_txt_is_sinit_acmod (sinit_region_base, bios_data->bios_sinit_size) || ++ !grub_txt_acmod_match_platform (bios_sinit) ) ++ return NULL; ++ ++ return bios_sinit; ++} ++ ++grub_uint32_t ++grub_txt_supported_os_sinit_data_ver (struct grub_txt_acm_header* hdr) ++{ ++ static struct grub_txt_acm_info_table *info_table; ++ ++ /* Assumes that it passed is_sinit_acmod() */ ++ info_table = get_acmod_info_table (hdr); ++ ++ if ( info_table == NULL ) ++ return 0; ++ ++ return info_table->os_sinit_data_ver; ++} ++ ++grub_uint32_t ++grub_txt_get_sinit_capabilities (struct grub_txt_acm_header* hdr) ++{ ++ static struct grub_txt_acm_info_table *info_table; ++ ++ /* Assumes that it passed is_sinit_acmod() */ ++ info_table = get_acmod_info_table (hdr); ++ ++ if ( info_table == NULL || info_table->version < 3 ) ++ return 0; ++ ++ return info_table->capabilities; ++} ++ ++int ++grub_txt_is_sinit_acmod (const void *acmod_base, grub_uint32_t acmod_size) ++{ ++ grub_uint8_t type; ++ ++ if ( !is_acmod (acmod_base, acmod_size, &type) ) ++ return 0; ++ ++ if ( type != GRUB_TXT_ACM_CHIPSET_TYPE_SINIT ) ++ return 0; ++ ++ return 1; ++} ++ ++/* Format of VER.FSBIF and VER.QPIIF registers. */ ++typedef union { ++ grub_uint64_t _raw; ++ struct { ++ grub_uint64_t reserved : 31; ++ grub_uint64_t prod_fused : 1; ++ }; ++} grub_txt_ver_fsbif_qpiif_t; ++ ++int ++grub_txt_acmod_match_platform (struct grub_txt_acm_header *hdr) ++{ ++ union grub_txt_didvid didvid; ++ grub_uint32_t fms, ign, i; ++ grub_uint64_t platform_id; ++ grub_txt_ver_fsbif_qpiif_t ver; ++ struct grub_txt_acm_chipset_id_list *chipset_id_list; ++ struct grub_txt_acm_chipset_id *chipset_id; ++ struct grub_txt_acm_processor_id_list *proc_id_list; ++ struct grub_txt_acm_processor_id *proc_id; ++ struct grub_txt_acm_info_table *info_table; ++ ++ /* This fn assumes that the ACM has already passed the is_acmod() checks */ ++ ++ /* Get chipset fusing, device, and vendor id info */ ++ didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); ++ ++ ver._raw = grub_txt_reg_pub_readq (GRUB_TXT_VER_FSBIF); ++ if ( (ver._raw & 0xffffffff) == 0xffffffff || ++ (ver._raw & 0xffffffff) == 0x00 ) /* Need to use VER.QPIIF */ ++ ver._raw = grub_txt_reg_pub_readq (GRUB_TXT_VER_QPIIF); ++ ++ grub_dprintf ("slaunch", "chipset production fused: %x, " ++ "chipset vendor: 0x%x, device: 0x%x, revision: 0x%x\n", ++ ver.prod_fused, didvid.vid, didvid.did, didvid.rid); ++ ++ grub_cpuid (1, fms, ign, ign, ign); ++ platform_id = grub_rdmsr (GRUB_MSR_X86_PLATFORM_ID); ++ ++ grub_dprintf ("slaunch", "processor family/model/stepping: 0x%x, " ++ "platform id: 0x%" PRIxGRUB_UINT64_T "\n", fms, platform_id); ++ ++ /* ++ * Check if chipset fusing is same. Note the DEBUG.FUSE bit in the version ++ * is 0 when debug fused so the logic below checking a mismatch is valid. ++ */ ++ if ( (ver._raw & GRUB_TXT_VERSION_DEBUG_FUSED) && ++ (hdr->flags & GRUB_TXT_ACM_FLAG_DEBUG_SIGNED) ) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("production/debug mismatch between chipset and ACM")); ++ return 0; ++ } ++ ++ /* Check if chipset vendor/device/revision IDs match */ ++ chipset_id_list = get_acmod_chipset_list (hdr); ++ if ( !chipset_id_list ) ++ return 0; ++ ++ grub_dprintf ("slaunch", "%d SINIT ACM chipset id entries:\n", chipset_id_list->count); ++ ++ chipset_id = (struct grub_txt_acm_chipset_id *) ((grub_addr_t)chipset_id_list + sizeof (chipset_id_list->count)); ++ for (i = 0; i < chipset_id_list->count; i++, chipset_id++) ++ { ++ grub_dprintf ("slaunch", " vendor: 0x%x, device: 0x%x, flags: 0x%x, " ++ "revision: 0x%x, extended: 0x%x\n", chipset_id->vendor_id, ++ chipset_id->device_id, chipset_id->flags, ++ chipset_id->revision_id, chipset_id->extended_id); ++ ++ if ( (didvid.vid == chipset_id->vendor_id ) && ++ (didvid.did == chipset_id->device_id ) && ++ ( ( ( (chipset_id->flags & GRUB_TXT_ACM_REVISION_ID_MASK) == 0) && ++ (didvid.rid == chipset_id->revision_id) ) || ++ ( ( (chipset_id->flags & GRUB_TXT_ACM_REVISION_ID_MASK) == 1) && ++ ( (didvid.rid & chipset_id->revision_id) != 0 ) ) ) ) ++ break; ++ } ++ ++ if ( i >= chipset_id_list->count ) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("chipset id mismatch")); ++ return 0; ++ } ++ ++ /* Check if processor family/model/stepping and platform IDs match */ ++ info_table = get_acmod_info_table (hdr); ++ if ( !info_table ) ++ return 0; ++ ++ /* ++ * Logic inverted from oringal to avoid the if block. Not sure what drives ++ * the logic of not checking processor infrmation for version 4 or less. ++ */ ++ if ( info_table->version < 4 ) ++ return 1; ++ ++ proc_id_list = get_acmod_processor_list(hdr); ++ if ( !proc_id_list ) ++ return 1; ++ ++ grub_dprintf ("slaunch", "%d SINIT ACM processor id entries:\n", proc_id_list->count); ++ ++ proc_id = (struct grub_txt_acm_processor_id *) ((grub_addr_t)proc_id_list + sizeof (proc_id_list->count)); ++ for (i = 0; i < proc_id_list->count; i++, proc_id++) ++ { ++ grub_dprintf ("slaunch", " fms: 0x%x, fms_mask: 0x%x, platform_id: 0x%" PRIxGRUB_UINT64_T ++ ", platform_mask: 0x%" PRIxGRUB_UINT64_T "\n", proc_id->fms, proc_id->fms_mask, ++ proc_id->platform_id, proc_id->platform_mask); ++ ++ if ( (proc_id->fms == (fms & proc_id->fms_mask)) && ++ (proc_id->platform_id == (platform_id & proc_id->platform_mask)) ) ++ break; ++ } ++ ++ if ( i >= proc_id_list->count ) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("chipset id mismatch")); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++struct grub_txt_acm_header * ++grub_txt_sinit_select (struct grub_txt_acm_header *sinit) ++{ ++ struct grub_txt_acm_header *bios_sinit; ++ void *sinit_region_base; ++ grub_uint32_t sinit_region_size; ++ ++ sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_readq (GRUB_TXT_SINIT_BASE); ++ sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_readq (GRUB_TXT_SINIT_SIZE); ++ ++ grub_dprintf ("slaunch", "TXT.SINIT.BASE: %p\nTXT.SINIT.SIZE: 0x%" ++ PRIxGRUB_UINT32_T "\n", sinit_region_base, sinit_region_size); ++ ++ if (sinit_region_base == NULL) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no SINIT ACM final resting place")); ++ return NULL; ++ } ++ ++ if (sinit != NULL) ++ grub_dprintf ("slaunch", "SINIT ACM date: %" PRIxGRUB_UINT32_T "\n", sinit->date); ++ ++ bios_sinit = get_bios_sinit (sinit_region_base); ++ ++ /* Does BIOS provide SINIT ACM? */ ++ if (bios_sinit != NULL) ++ { ++ grub_dprintf ("slaunch", "BIOS SINIT ACM date: %" PRIxGRUB_UINT32_T "\n", ++ bios_sinit->date); ++ ++ if (sinit == NULL) ++ { ++ grub_dprintf ("slaunch", "no SINIT ACM provided. Using BIOS SINIT ACM\n"); ++ return bios_sinit; ++ } ++ ++ if (bios_sinit->date >= sinit->date) ++ { ++ grub_dprintf ("slaunch", "BIOS provides newer or same SINIT ACM, so, using BIOS one\n"); ++ return bios_sinit; ++ } ++ ++ grub_dprintf ("slaunch", "BIOS provides older SINIT ACM, so, ignoring BIOS one\n"); ++ } ++ ++ /* Fail if there is no SINIT ACM. */ ++ if (sinit == NULL) ++ return NULL; ++ ++ /* Our SINIT ACM is newer than BIOS one or BIOS does not have one. */ ++ ++ if (multiply_overflow_u32 (sinit->size, 4)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("SINIT ACM size in bytes overflows")); ++ return NULL; ++ } ++ ++ if ((sinit->size * 4) > sinit_region_size) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("SINIT ACM does not fit into final resting place: 0x%" ++ PRIxGRUB_UINT32_T "\n"), sinit->size * 4); ++ return NULL; ++ } ++ ++ grub_memcpy (sinit_region_base, sinit, sinit->size * 4); ++ ++ return sinit_region_base; ++} +-- +2.17.1 + diff --git a/1113-i386-txt-Add-Intel-TXT-verification-routines.patch b/1113-i386-txt-Add-Intel-TXT-verification-routines.patch new file mode 100644 index 0000000..84d6c02 --- /dev/null +++ b/1113-i386-txt-Add-Intel-TXT-verification-routines.patch @@ -0,0 +1,318 @@ +From 8287663cc69f939f6abc14e39cb8de7a6d89a93d Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Wed, 7 Aug 2019 14:46:17 -0400 +Subject: [PATCH 1113/1118] i386/txt: Add Intel TXT verification routines + +Signed-off-by: Ross Philipson +Signed-off-by: Daniel Kiper +--- + grub-core/loader/i386/txt/verify.c | 297 +++++++++++++++++++++++++++++ + 1 file changed, 297 insertions(+) + create mode 100644 grub-core/loader/i386/txt/verify.c + +diff --git a/grub-core/loader/i386/txt/verify.c b/grub-core/loader/i386/txt/verify.c +new file mode 100644 +index 000000000000..16b898041f65 +--- /dev/null ++++ b/grub-core/loader/i386/txt/verify.c +@@ -0,0 +1,297 @@ ++/* ++ * verify.c: verify that platform and processor supports Intel(r) TXT ++ * ++ * Copyright (c) 2003-2010, Intel Corporation ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following ++ * disclaimer in the documentation and/or other materials provided ++ * with the distribution. ++ * * Neither the name of the Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Current max that the secure launch can handle */ ++#define TXT_MAX_CPUS 512 ++ ++static grub_err_t ++verify_bios_spec_ver_elt (struct grub_txt_heap_ext_data_element *elt) ++{ ++ grub_uint8_t *ptr = (grub_uint8_t *)elt; ++ struct grub_txt_heap_bios_spec_ver_element *bios_spec_ver_elt = ++ (struct grub_txt_heap_bios_spec_ver_element *)ptr; ++ ++ if ( elt->size != sizeof(*elt) + sizeof(*bios_spec_ver_elt) ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("HEAP_BIOS_SPEC_VER element has wrong size (%d)"), ++ elt->size); ++ ++ /* Any values are allowed */ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++verify_acm_elt (struct grub_txt_heap_ext_data_element *elt) ++{ ++ grub_uint8_t *ptr = ((grub_uint8_t *)elt + sizeof(*elt)); ++ struct grub_txt_heap_acm_element *acm_elt = ++ (struct grub_txt_heap_acm_element *)ptr; ++ grub_uint64_t *acm_addrs; ++ grub_uint32_t i; ++ ++ if ( elt->size != sizeof(*elt) + sizeof(*acm_elt) + ++ acm_elt->num_acms*sizeof(grub_uint64_t) ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("HEAP_ACM element has wrong size (%d)"), ++ elt->size); ++ ++ /* No addrs is not error, but print warning. */ ++ if ( acm_elt->num_acms == 0 ) ++ grub_printf ("WARNING: HEAP_ACM element has no ACM addrs\n"); ++ ++ acm_addrs = (grub_uint64_t *)(ptr + sizeof(*acm_elt)); ++ for ( i = 0; i < acm_elt->num_acms; i++ ) ++ { ++ if ( acm_addrs[i] == 0 ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("HEAP_ACM element ACM addr (%d) is NULL"), i); ++ ++ if ( acm_addrs[i] >= 0x100000000UL ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("HEAP_ACM element ACM addr (%d) is >4GB"), i); ++ ++ /* Not going to check if ACM addrs are valid ACMs */ ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++verify_custom_elt (struct grub_txt_heap_ext_data_element *elt) ++{ ++ grub_uint8_t *ptr = (grub_uint8_t *)elt; ++ struct grub_txt_heap_custom_element *custom_elt = ++ (struct grub_txt_heap_custom_element *)ptr; ++ ++ if ( elt->size < sizeof(*elt) + sizeof(*custom_elt) ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("HEAP_CUSTOM element has wrong size (%d)"), ++ elt->size); ++ ++ /* Any values are allowed */ ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++verify_evt_log_ptr_elt (struct grub_txt_heap_ext_data_element *elt) ++{ ++ grub_uint8_t *ptr = (grub_uint8_t *)elt; ++ struct grub_txt_heap_tpm_event_log_element *elog_elt = ++ (struct grub_txt_heap_tpm_event_log_element *)ptr; ++ ++ if ( elt->size != sizeof(*elt) + sizeof(*elog_elt) ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("HEAP_EVENT_LOG_POINTER element has wrong size (%d)"), ++ elt->size); ++ ++ /* TODO: Sort out how to do this verifier once the event log handling is in place ++ * ++ * return verify_evt_log((event_log_container_t *)(unsigned long) ++ * elog_elt->event_log_phys_addr); ++ */ ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++verify_ext_data_elts(struct grub_txt_heap_ext_data_element *elts, ++ grub_uint64_t elts_size) ++{ ++ struct grub_txt_heap_ext_data_element *elt = elts; ++ grub_err_t err; ++ ++ if ( elts_size < sizeof(*elt) ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("TXT heap ext data elements too small")); ++ ++ for ( ; ; ) ++ { ++ if ( elts_size < elt->size || elt->size == 0 ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("TXT heap invalid element size: type: %d, size: %d"), ++ elt->type, elt->size); ++ ++ switch ( elt->type ) ++ { ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_END: ++ return GRUB_ERR_NONE; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_BIOS_SPEC_VER: ++ err = verify_bios_spec_ver_elt (elt); ++ if ( err ) ++ return err; ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_ACM: ++ err = verify_acm_elt (elt); ++ if ( err ) ++ return err; ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_STM: ++ /* Nothing to check, platform specific */ ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_CUSTOM: ++ err = verify_custom_elt (elt); ++ if ( err ) ++ return err; ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR: ++ err = verify_evt_log_ptr_elt (elt); ++ if ( err ) ++ return err; ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_MADT: ++ /* Copy of ACPI MADT, not validating */ ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1: ++ /* TODO TBOOT did not verify this, not sure why or how to do it */ ++ break; ++ case GRUB_TXT_HEAP_EXTDATA_TYPE_MCFG: ++ /* Copy of ACPI MCFG, not validating */ ++ break; ++ default: ++ /* TODO: What kind of element??? Improve the message. */ ++ grub_printf ("WARNING: unknown element: type: %u, size: %u\n", elt->type, elt->size); ++ break; ++ } ++ ++ elts_size -= elt->size; ++ elt = (struct grub_txt_heap_ext_data_element *)((grub_uint8_t *)elt + elt->size); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_txt_verify_platform (void) ++{ ++ grub_uint8_t *txt_heap; ++ grub_uint32_t eax, ebx, ecx, edx; ++ grub_uint64_t bios_size, heap_base, heap_size, msr; ++ grub_err_t err = GRUB_ERR_NONE; ++ struct grub_txt_bios_data *bios_data; ++ struct grub_txt_heap_ext_data_element *elts; ++ ++ grub_cpuid (GRUB_X86_CPUID_FEATURES, eax, ebx, ecx, edx); ++ ++ if (!(ecx & GRUB_SMX_CPUID_FEATURE)) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("CPU does not support SMX")); ++ ++ msr = grub_rdmsr (GRUB_MSR_X86_FEATURE_CONTROL); ++ ++ if ((msr & (GRUB_MSR_X86_SENTER_FUNCTIONS | GRUB_MSR_X86_SENTER_ENABLE)) != ++ (GRUB_MSR_X86_SENTER_FUNCTIONS | GRUB_MSR_X86_SENTER_ENABLE)) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("GETSEC[SENTER] is not enabled")); ++ ++ /* ++ * TODO ++ * TXT Specification ++ * 4.5 SGX Requirement for TXT Platform ++ * Secure Launch currently does not support interop with SGX since it does ++ * not have TPM support to write the SE NVRAM index. ++ * Eventually need the verify_IA32_se_svn_status routine to be called here. ++ */ ++ ++ if (grub_txt_reg_pub_readq (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("TXT_RESET.STS is set and GETSEC[SENTER] is disabled")); ++ ++ /* ++ * Verify that the BIOS information in the TXT heap that was setup by the ++ * BIOS ACM is sane. ++ */ ++ ++ txt_heap = grub_txt_get_heap (); ++ heap_base = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE); ++ heap_size = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_SIZE); ++ ++ if ( txt_heap == NULL || heap_base == 0 || heap_size == 0 ) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("TXT heap is not configured correctly")); ++ ++ bios_size = grub_txt_bios_data_size (txt_heap); ++ if ( bios_size == 0 || bios_size > heap_size ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("invalid size of the TXT heap BIOS data table")); ++ ++ bios_data = grub_txt_bios_data_start (txt_heap); ++ ++ /* Check version */ ++ if ( bios_data->version < 3 ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("unsupported BIOS data version (%d)"), bios_data->version); ++ ++ if ( bios_data->num_logical_procs > TXT_MAX_CPUS ) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("BIOS reports too many CPUs for secure launch (%d)"), ++ bios_data->num_logical_procs); ++ ++ if ( bios_data->version >= 4 && bios_size > sizeof(*bios_data) + sizeof(bios_size) ) ++ { ++ elts = (struct grub_txt_heap_ext_data_element *) ((grub_uint8_t *)bios_data + sizeof(*bios_data)); ++ err = verify_ext_data_elts(elts, bios_size - sizeof(*bios_data)); ++ } ++ ++ return err; ++} +-- +2.17.1 + diff --git a/1114-i386-slaunch-Add-secure-launch-framework-and-command.patch b/1114-i386-slaunch-Add-secure-launch-framework-and-command.patch new file mode 100644 index 0000000..aec1ddb --- /dev/null +++ b/1114-i386-slaunch-Add-secure-launch-framework-and-command.patch @@ -0,0 +1,891 @@ +From 32f19a720565b16cea3b7356d7c39d6c1614dcbd Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Wed, 7 Aug 2019 15:01:00 -0400 +Subject: [PATCH 1114/1118] i386/slaunch: Add secure launch framework and + commands + +Signed-off-by: Ross Philipson +Signed-off-by: Daniel Kiper +--- + grub-core/Makefile.am | 3 + + grub-core/Makefile.core.def | 15 +++ + grub-core/lib/i386/relocator32.S | 8 ++ + grub-core/loader/i386/bsd.c | 7 + + grub-core/loader/i386/linux.c | 213 ++++++++++++++++++++++++++++--- + grub-core/loader/i386/slaunch.c | 194 ++++++++++++++++++++++++++++ + grub-core/loader/i386/xnu.c | 3 + + grub-core/loader/multiboot.c | 5 + + include/grub/file.h | 3 + + include/grub/i386/linux.h | 14 +- + include/grub/i386/slaunch.h | 57 +++++++++ + 11 files changed, 506 insertions(+), 16 deletions(-) + create mode 100644 grub-core/loader/i386/slaunch.c + create mode 100644 include/grub/i386/slaunch.h + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index ee88e44e97a0..769bf013d47b 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -103,6 +103,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h + endif + + if COND_i386_xen_pvh +@@ -122,6 +123,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h +@@ -183,6 +185,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index e6b41ede92c4..b606496b26ef 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1831,6 +1831,15 @@ module = { + enable = noemu; + }; + ++module = { ++ name = slaunch; ++ x86 = loader/i386/slaunch.c; ++ x86 = loader/i386/txt/txt.c; ++ x86 = loader/i386/txt/acmod.c; ++ x86 = loader/i386/txt/verify.c; ++ enable = x86; ++}; ++ + module = { + name = fdt; + efi = loader/efi/fdt.c; +@@ -2504,6 +2513,12 @@ module = { + common = commands/testspeed.c; + }; + ++module = { ++ name = tpm; ++ x86 = commands/i386/tpm.c; ++ enable = x86; ++}; ++ + module = { + name = tpm_verifier; + common = commands/tpm_verifier.c; +diff --git a/grub-core/lib/i386/relocator32.S b/grub-core/lib/i386/relocator32.S +index 09ce56ad0ae6..a2b377197b16 100644 +--- a/grub-core/lib/i386/relocator32.S ++++ b/grub-core/lib/i386/relocator32.S +@@ -24,6 +24,8 @@ + + #include "relocator_common.S" + ++#include ++ + .p2align 4 /* force 16-byte alignment */ + + VARIABLE(grub_relocator32_start) +@@ -110,11 +112,17 @@ VARIABLE(grub_relocator32_edx) + payload and makes this implementation easier. */ + cld + ++ cmpl $SLP_INTEL_TXT, %edi ++ je LOCAL(intel_txt) ++ + .byte 0xea + VARIABLE(grub_relocator32_eip) + .long 0 + .word CODE_SEGMENT + ++LOCAL(intel_txt): ++ getsec ++ + /* GDT. Copied from loader/i386/linux.c. */ + .p2align 4 + LOCAL(gdt): +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index 5f3290ce17bc..328b34635f78 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -21,6 +21,10 @@ + #include + #include + #include ++#if 0 ++#include ++#endif ++#define SLP_NONE 0 + #include + #include + #include +@@ -792,6 +796,7 @@ grub_freebsd_boot (void) + #endif + + grub_memcpy (&stack[9], &bi, sizeof (bi)); ++ state.edi = SLP_NONE; + state.eip = entry; + state.esp = stack_target; + state.ebp = stack_target; +@@ -907,6 +912,7 @@ grub_openbsd_boot (void) + return err; + #endif + ++ state.edi = SLP_NONE; + state.eip = entry; + state.ebp = state.esp + = ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target; +@@ -1229,6 +1235,7 @@ grub_netbsd_boot (void) + return err; + #endif + ++ state.edi = SLP_NONE; + state.eip = entry; + state.esp = stack_target; + state.ebp = stack_target; +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 9f74a96b19ae..ba050de2d1df 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -34,6 +34,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -63,18 +65,23 @@ GRUB_MOD_LICENSE ("GPLv3+"); + #define ACCEPTS_PURE_TEXT 1 + #endif + ++#define KERNEL_INFO_HEADER "LToP" ++#define KERNEL_INFO_MIN_SIZE_TOTAL 12 ++ + static grub_dl_t my_mod; + + static grub_size_t linux_mem_size; + static int loaded; + static void *prot_mode_mem; + static grub_addr_t prot_mode_target; ++static grub_size_t prot_file_size; + static void *initrd_mem; + static grub_addr_t initrd_mem_target; + static grub_size_t prot_init_space; + static struct grub_relocator *relocator = NULL; + static void *efi_mmap_buf; + static grub_size_t maximal_cmdline_size; ++static struct linux_kernel_info *linux_info; + static struct linux_kernel_params linux_params; + static char *linux_cmdline; + #ifdef GRUB_MACHINE_EFI +@@ -82,6 +89,7 @@ static grub_efi_uintn_t efi_mmap_size; + #else + static const grub_size_t efi_mmap_size = 0; + #endif ++static struct grub_slaunch_params slparams; + + /* FIXME */ + #if 0 +@@ -98,6 +106,8 @@ static struct idt_descriptor idt_desc = + }; + #endif + ++#define OFFSET_OF(x, y) ((grub_size_t)((grub_uint8_t *)(&(y)->x) - (grub_uint8_t *)(y))) ++ + static inline grub_size_t + page_align (grub_size_t size) + { +@@ -150,11 +160,35 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + grub_uint64_t preferred_address) + { + grub_err_t err; ++ grub_size_t total_size; + + if (prot_size == 0) + prot_size = 1; + +- prot_size = page_align (prot_size); ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ prot_size = ALIGN_UP (prot_size, GRUB_TXT_PMR_ALIGN); ++ ++ if (prot_size > GRUB_TXT_MLE_MAX_SIZE) ++ { ++ err = GRUB_ERR_OUT_OF_RANGE; ++ goto fail; ++ } ++ ++ slparams.mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); ++ slparams.mle_ptab_size = ALIGN_UP (slparams.mle_ptab_size, GRUB_TXT_PMR_ALIGN); ++ /* Do not go below GRUB_TXT_PMR_ALIGN. */ ++ preferred_address = (preferred_address > slparams.mle_ptab_size) ? ++ (preferred_address - slparams.mle_ptab_size) : GRUB_TXT_PMR_ALIGN; ++ preferred_address = ALIGN_UP (preferred_address, GRUB_TXT_PMR_ALIGN); ++ } ++ else ++ { ++ prot_size = page_align (prot_size); ++ slparams.mle_ptab_size = 0; ++ } ++ ++ total_size = prot_size + slparams.mle_ptab_size; + + /* Initialize the memory pointers with NULL for convenience. */ + free_pages (); +@@ -176,7 +210,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + err = grub_relocator_alloc_chunk_align (relocator, &ch, + preferred_address, + preferred_address, +- prot_size, 1, ++ total_size, 1, + GRUB_RELOCATOR_PREFERENCE_LOW, + 1); + for (; err && *align + 1 > min_align; (*align)--) +@@ -194,11 +228,45 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + else + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + preferred_address, +- prot_size); ++ total_size); + if (err) + goto fail; + prot_mode_mem = get_virtual_current_address (ch); + prot_mode_target = get_physical_target_address (ch); ++ ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ /* Zero out memory to get stable MLE measurements. */ ++ grub_memset (prot_mode_mem, 0, total_size); ++ ++ slparams.mle_ptab_mem = prot_mode_mem; ++ slparams.mle_ptab_target = prot_mode_target; ++ ++ prot_mode_mem = (char *)prot_mode_mem + slparams.mle_ptab_size; ++ prot_mode_target += slparams.mle_ptab_size; ++ ++ slparams.mle_start = prot_mode_target; ++ slparams.mle_size = prot_size; ++ ++ grub_dprintf ("linux", "mle_ptab_mem = %p, mle_ptab_target = %lx, mle_ptab_size = %x\n", ++ slparams.mle_ptab_mem, (unsigned long) slparams.mle_ptab_target, ++ (unsigned) slparams.mle_ptab_size); ++ ++ if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, ++ 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, ++ GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 1)) ++ goto fail; ++ ++ slparams.tpm_evt_log_base = get_physical_target_address (ch); ++ slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; ++ ++ grub_memset (get_virtual_current_address (ch), 0, slparams.tpm_evt_log_size); ++ ++ grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", ++ (unsigned long) slparams.tpm_evt_log_base, ++ (unsigned) slparams.tpm_evt_log_size); ++ } + } + + grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", +@@ -286,7 +354,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) + params->lfb_size >>= 16; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + break; +- ++ + case GRUB_VIDEO_DRIVER_EFI_UGA: + case GRUB_VIDEO_DRIVER_EFI_GOP: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; +@@ -411,6 +479,7 @@ grub_linux_boot (void) + }; + grub_size_t mmap_size; + grub_size_t cl_offset; ++ grub_size_t ap_wake_block_size = 0; + + #ifdef GRUB_MACHINE_IEEE1275 + { +@@ -543,6 +612,9 @@ grub_linux_boot (void) + (unsigned) ctx.real_size, + (unsigned) efi_mmap_size); + ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ ap_wake_block_size = GRUB_MLE_AP_WAKE_BLOCK_SIZE; ++ + if (! ctx.real_mode_target) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); + +@@ -550,7 +622,7 @@ grub_linux_boot (void) + grub_relocator_chunk_t ch; + grub_size_t sz; + +- if (grub_add (ctx.real_size, efi_mmap_size, &sz)) ++ if (grub_add (ctx.real_size, efi_mmap_size + ap_wake_block_size, &sz)) + return GRUB_ERR_OUT_OF_RANGE; + + err = grub_relocator_alloc_chunk_addr (relocator, &ch, +@@ -561,6 +633,17 @@ grub_linux_boot (void) + } + efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; + ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ slparams.ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; ++ slparams.ap_wake_block_size = ap_wake_block_size; ++ grub_memset ((void *) ((grub_addr_t) real_mode_mem + ctx.real_size + ++ efi_mmap_size), 0, ap_wake_block_size); ++ grub_dprintf ("linux", "ap_wake_block = %lx, ap_wake_block_size = %lx\n", ++ (unsigned long) slparams.ap_wake_block, ++ (unsigned long) ap_wake_block_size); ++ } ++ + grub_dprintf ("linux", "real_mode_mem = %p\n", + real_mode_mem); + +@@ -591,9 +674,9 @@ grub_linux_boot (void) + &efi_desc_size, &efi_desc_version); + if (err) + return err; +- ++ + /* Note that no boot services are available from here. */ +- efi_mmap_target = ctx.real_mode_target ++ efi_mmap_target = ctx.real_mode_target + + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); + /* Pass EFI parameters. */ + if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) +@@ -624,12 +707,33 @@ grub_linux_boot (void) + } + #endif + +- /* FIXME. */ +- /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ +- state.ebp = state.edi = state.ebx = 0; +- state.esi = ctx.real_mode_target; +- state.esp = ctx.real_mode_target; +- state.eip = ctx.params->code32_start; ++ state.edi = grub_slaunch_platform_type (); ++ ++ if (state.edi == SLP_INTEL_TXT) ++ { ++ slparams.boot_params_addr = (grub_uint32_t) ctx.real_mode_target; ++ ++ err = grub_txt_boot_prepare (&slparams); ++ ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ /* Configure relocator GETSEC[SENTER] call. */ ++ state.eax = GRUB_SMX_LEAF_SENTER; ++ state.ebx = slparams.sinit_acm_base; ++ state.ecx = slparams.sinit_acm_size; ++ state.edx = 0; ++ } ++ else ++ { ++ /* FIXME. */ ++ /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ ++ state.ebp = state.edi = state.ebx = 0; ++ state.esi = ctx.real_mode_target; ++ state.esp = ctx.real_mode_target; ++ state.eip = ctx.params->code32_start; ++ } ++ + return grub_relocator32_boot (relocator, state, 0); + } + +@@ -650,7 +754,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_file_t file = 0; + struct linux_i386_kernel_header lh; + grub_uint8_t setup_sects; +- grub_size_t real_size, prot_size, prot_file_size; ++ grub_size_t real_size, prot_size; + grub_ssize_t len; + int i; + grub_size_t align, min_align; +@@ -743,7 +847,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + align = 0; + relocatable = 0; + } +- ++ + if (grub_le_to_cpu16 (lh.version) >= 0x020a) + { + min_align = lh.min_alignment; +@@ -760,6 +864,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + prot_init_space = page_align (prot_size) * 3; + } + ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ /* PMRs require GRUB_TXT_PMR_ALIGN_SHIFT aligments. */ ++ min_align = grub_max (min_align, GRUB_TXT_PMR_ALIGN_SHIFT); ++ align = grub_max (align, GRUB_TXT_PMR_ALIGN_SHIFT); ++ } ++ + if (allocate_pages (prot_size, &align, + min_align, relocatable, + preferred_address)) +@@ -767,6 +878,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + + grub_memset (&linux_params, 0, sizeof (linux_params)); + ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ grub_txt_setup_mle_ptab (&slparams); ++ + /* + * The Linux 32-bit boot protocol defines the setup header end + * to be at 0x202 + the byte value at 0x201. +@@ -793,6 +907,75 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + ++ /* Read the kernel_info struct. */ ++ if (grub_le_to_cpu16 (lh.version) >= 0x020f) ++ { ++ if (grub_file_seek (file, grub_le_to_cpu32 (lh.kernel_info_offset) + ++ real_size + GRUB_DISK_SECTOR_SIZE) == ((grub_off_t) -1)) ++ goto fail; ++ ++ linux_info = grub_malloc (KERNEL_INFO_MIN_SIZE_TOTAL); ++ ++ if (!linux_info) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate memory for kernel_info")); ++ goto fail; ++ } ++ ++ /* Load minimal kernel_info struct. */ ++ if (grub_file_read (file, linux_info, ++ KERNEL_INFO_MIN_SIZE_TOTAL) != KERNEL_INFO_MIN_SIZE_TOTAL) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); ++ goto fail; ++ } ++ ++ if (grub_memcmp (&linux_info->header, KERNEL_INFO_HEADER, sizeof (linux_info->header))) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("incorrect kernel_info header")); ++ goto fail; ++ } ++ ++ linux_info->size_total = grub_le_to_cpu32 (linux_info->size_total); ++ ++ linux_info = grub_realloc (linux_info, linux_info->size_total); ++ ++ if (!linux_info) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot reallocate memory for kernel_info")); ++ goto fail; ++ } ++ ++ /* Load the rest of kernel_info struct. */ ++ if (grub_file_read (file, &linux_info->setup_type_max, ++ linux_info->size_total - KERNEL_INFO_MIN_SIZE_TOTAL) != ++ (grub_ssize_t)(linux_info->size_total - KERNEL_INFO_MIN_SIZE_TOTAL)) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); ++ goto fail; ++ } ++ ++ if (grub_slaunch_platform_type () != SLP_NONE) ++ { ++ if (OFFSET_OF (mle_header_offset, linux_info) >= ++ grub_le_to_cpu32 (linux_info->size)) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("not slaunch kernel: lack of mle_header_offset")); ++ goto fail; ++ } ++ ++ slparams.mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); ++ } ++ } ++ else if (grub_slaunch_platform_type () != SLP_NONE) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("not slaunch kernel: boot protocol too old")); ++ goto fail; ++ } ++ + linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; + linux_params.kernel_alignment = (1 << align); + linux_params.ps_mouse = linux_params.padding11 = 0; +diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c +new file mode 100644 +index 000000000000..72d09236b2ae +--- /dev/null ++++ b/grub-core/loader/i386/slaunch.c +@@ -0,0 +1,194 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_uint32_t slp = SLP_NONE; ++ ++static void *slaunch_module = NULL; ++ ++grub_uint32_t ++grub_slaunch_platform_type (void) ++{ ++ return slp; ++} ++ ++void * ++grub_slaunch_module (void) ++{ ++ return slaunch_module; ++} ++ ++static grub_err_t ++grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ grub_uint32_t manufacturer[3]; ++ grub_uint32_t eax; ++ grub_err_t err; ++ ++ if (!grub_cpu_is_cpuid_supported ()) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("CPUID is unsupported")); ++ ++ err = grub_cpu_is_msr_supported (); ++ ++ if (err != GRUB_ERR_NONE) ++ return grub_error (err, N_("MSRs are unsupported")); ++ ++ grub_cpuid (0, eax, manufacturer[0], manufacturer[2], manufacturer[1]); ++ ++ if (!grub_memcmp (manufacturer, "GenuineIntel", 12)) ++ { ++ err = grub_txt_init (); ++ ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ slp = SLP_INTEL_TXT; ++ } ++ else ++ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("CPU is unsupported")); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_slaunch_module (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_file_t file; ++ grub_ssize_t size; ++ ++ if (!argc) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ ++ if (slp == SLP_NONE) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("secure launch not enabled")); ++ ++ grub_errno = GRUB_ERR_NONE; ++ ++ file = grub_file_open (argv[0], GRUB_FILE_TYPE_SLAUNCH_MODULE); ++ ++ if (file == NULL) ++ return grub_errno; ++ ++ size = grub_file_size (file); ++ ++ if (!size) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("file size is zero")); ++ goto fail; ++ } ++ ++ slaunch_module = grub_malloc (size); ++ ++ if (slaunch_module == NULL) ++ goto fail; ++ ++ if (grub_file_read (file, slaunch_module, size) != size) ++ { ++ if (grub_errno == GRUB_ERR_NONE) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file: %s"), ++ argv[0]); ++ goto fail; ++ } ++ ++ if (slp == SLP_INTEL_TXT) ++ { ++ if (!grub_txt_is_sinit_acmod (slaunch_module, size)) ++ { ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("it does not look like SINIT ACM")); ++ goto fail; ++ } ++ ++ if (!grub_txt_acmod_match_platform (slaunch_module)) ++ { ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("SINIT ACM does not match platform")); ++ goto fail; ++ } ++ } ++ ++ grub_file_close (file); ++ ++ return GRUB_ERR_NONE; ++ ++ fail: ++ grub_error_push (); ++ ++ grub_free (slaunch_module); ++ grub_file_close (file); ++ ++ slaunch_module = NULL; ++ ++ grub_error_pop (); ++ ++ return grub_errno; ++} ++ ++static grub_err_t ++grub_cmd_slaunch_state (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ if (slp == SLP_NONE) ++ grub_printf ("Secure launcher: Disabled\n"); ++ else if (slp == SLP_INTEL_TXT) ++ { ++ grub_printf ("Secure launcher: Intel TXT\n"); ++ grub_txt_state_show (); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_command_t cmd_slaunch, cmd_slaunch_module, cmd_slaunch_state; ++ ++GRUB_MOD_INIT (slaunch) ++{ ++ cmd_slaunch = grub_register_command ("slaunch", grub_cmd_slaunch, ++ NULL, N_("Enable secure launcher")); ++ cmd_slaunch_module = grub_register_command ("slaunch_module", grub_cmd_slaunch_module, ++ NULL, N_("Secure launcher module command")); ++ cmd_slaunch_state = grub_register_command ("slaunch_state", grub_cmd_slaunch_state, ++ NULL, N_("Display secure launcher state")); ++} ++ ++GRUB_MOD_FINI (slaunch) ++{ ++ grub_unregister_command (cmd_slaunch_state); ++ grub_unregister_command (cmd_slaunch_module); ++ grub_unregister_command (cmd_slaunch); ++ ++ if (slp == SLP_INTEL_TXT) ++ grub_txt_shutdown (); ++} +diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c +index a7009360732a..4989227bdbf5 100644 +--- a/grub-core/loader/i386/xnu.c ++++ b/grub-core/loader/i386/xnu.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -807,6 +808,7 @@ grub_xnu_boot_resume (void) + { + struct grub_relocator32_state state; + ++ state.edi = SLP_NONE; + state.esp = grub_xnu_stack; + state.ebp = grub_xnu_stack; + state.eip = grub_xnu_entry_point; +@@ -1134,6 +1136,7 @@ grub_xnu_boot (void) + grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, + descriptor_version, memory_map); + ++ state.edi = SLP_NONE; + state.eip = grub_xnu_entry_point; + state.eax = grub_xnu_arg1; + state.esp = grub_xnu_stack; +diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c +index facb13f3d36e..3ab0c828c3ae 100644 +--- a/grub-core/loader/multiboot.c ++++ b/grub-core/loader/multiboot.c +@@ -50,6 +50,9 @@ + #include + #include + #include ++#if defined (__i386__) || defined (__x86_64__) ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -161,6 +164,8 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)), + static void + normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state) + { ++ state.edi = SLP_NONE; ++ + grub_relocator32_boot (rel, state, 0); + } + #else +diff --git a/include/grub/file.h b/include/grub/file.h +index 31567483ccfc..f08fcda74115 100644 +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -128,6 +128,9 @@ enum grub_file_type + + GRUB_FILE_TYPE_VERIFY_SIGNATURE, + ++ /* Secure Launch module. */ ++ GRUB_FILE_TYPE_SLAUNCH_MODULE, ++ + GRUB_FILE_TYPE_MASK = 0xffff, + + /* --skip-sig is specified. */ +diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h +index eddf9251d9a5..798188c85454 100644 +--- a/include/grub/i386/linux.h ++++ b/include/grub/i386/linux.h +@@ -148,6 +148,17 @@ struct linux_i386_kernel_header + grub_uint64_t pref_address; + grub_uint32_t init_size; + grub_uint32_t handover_offset; ++ grub_uint32_t kernel_info_offset; ++} GRUB_PACKED; ++ ++struct linux_kernel_info ++{ ++ grub_uint32_t header; ++ grub_uint32_t size; ++ grub_uint32_t size_total; ++ grub_uint32_t setup_type_max; ++ grub_uint32_t mle_header_offset; ++ grub_uint8_t var_len_data[0]; + } GRUB_PACKED; + + /* Boot parameters for Linux based on 2.6.12. This is used by the setup +@@ -325,9 +336,10 @@ struct linux_kernel_params + grub_uint64_t pref_address; + grub_uint32_t init_size; + grub_uint32_t handover_offset; ++ grub_uint32_t kernel_info_offset; + /* Linux setup header copy - END. */ + +- grub_uint8_t _pad7[40]; ++ grub_uint8_t _pad7[36]; + grub_uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 290 */ + struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */ + } GRUB_PACKED; +diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h +new file mode 100644 +index 000000000000..12cd341aae0c +--- /dev/null ++++ b/include/grub/i386/slaunch.h +@@ -0,0 +1,57 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * Main secure launch definitions header file. ++ */ ++ ++#ifndef GRUB_I386_SLAUNCH_H ++#define GRUB_I386_SLAUNCH_H 1 ++ ++/* Secure launch platform types. */ ++#define SLP_NONE 0 ++#define SLP_INTEL_TXT 1 ++ ++#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE) ++ ++#ifndef ASM_FILE ++ ++#include ++#include ++ ++struct grub_slaunch_params ++{ ++ grub_uint32_t boot_params_addr; ++ grub_uint32_t mle_start; ++ grub_uint32_t mle_size; ++ void *mle_ptab_mem; ++ grub_uint64_t mle_ptab_target; ++ grub_uint32_t mle_ptab_size; ++ grub_uint32_t mle_header_offset; ++ grub_uint32_t ap_wake_block; ++ grub_uint32_t ap_wake_block_size; ++ grub_uint32_t sinit_acm_base; ++ grub_uint32_t sinit_acm_size; ++ grub_uint64_t tpm_evt_log_base; ++ grub_uint32_t tpm_evt_log_size; ++}; ++ ++extern grub_uint32_t grub_slaunch_platform_type (void); ++extern void *grub_slaunch_module (void); ++ ++#endif /* ASM_FILE */ ++ ++#endif /* GRUB_I386_SLAUNCH_H */ +-- +2.17.1 + diff --git a/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch b/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch new file mode 100644 index 0000000..03e162c --- /dev/null +++ b/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch @@ -0,0 +1,163 @@ +From d9ba5e9769fb55b246bf76b3d812b85497610325 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= +Date: Wed, 31 Aug 2022 14:37:49 +0200 +Subject: [PATCH 1115/1118] i386/txt: Initialize TPM 1.2 event log in TXT heap +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michał Żygowski +Signed-off-by: Krystian Hebel +--- + grub-core/loader/i386/txt/txt.c | 61 +++++++++++++++++++++++++++++++-- + include/grub/i386/txt.h | 29 ++++++++++++++++ + 2 files changed, 88 insertions(+), 2 deletions(-) + +diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c +index 201167ce9a44..f3afb6ad1d92 100644 +--- a/grub-core/loader/i386/txt/txt.c ++++ b/grub-core/loader/i386/txt/txt.c +@@ -501,6 +501,24 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) + return GRUB_ERR_NONE; + } + ++static void init_tpm12_event_log(struct grub_slaunch_params *slparams) ++{ ++ struct event_log_container *elog; ++ elog = (struct event_log_container *)(grub_addr_t)slparams->tpm_evt_log_base; ++ ++ if (slparams->tpm_evt_log_base == 0 || slparams->tpm_evt_log_size == 0) ++ return; ++ ++ grub_memcpy((void *)elog->signature, EVTLOG_SIGNATURE, sizeof(elog->signature)); ++ elog->container_ver_major = EVTLOG_CNTNR_MAJOR_VER; ++ elog->container_ver_minor = EVTLOG_CNTNR_MINOR_VER; ++ elog->pcr_event_ver_major = EVTLOG_EVT_MAJOR_VER; ++ elog->pcr_event_ver_minor = EVTLOG_EVT_MINOR_VER; ++ elog->size = slparams->tpm_evt_log_size; ++ elog->pcr_events_offset = sizeof(*elog); ++ elog->next_event_offset = sizeof(*elog); ++} ++ + static grub_err_t + init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header *sinit) + { +@@ -510,6 +528,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + struct grub_txt_os_mle_data *os_mle_data; + struct grub_txt_os_sinit_data *os_sinit_data; + struct grub_txt_heap_end_element *heap_end_element; ++ struct grub_txt_heap_tpm_event_log_element *heap_tpm_event_log_element; + struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; + #ifdef GRUB_MACHINE_EFI + struct grub_acpi_rsdp_v20 *rsdp; +@@ -598,10 +617,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + + sinit_caps = grub_txt_get_sinit_capabilities (sinit); + +- /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ ++ grub_dprintf ("slaunch", "SINIT capabilities %08x\n", sinit_caps); ++ + os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE | + GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; + ++ if (grub_get_tpm_ver () == GRUB_TPM_20) ++ { ++ /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ ++ if ((sinit_caps & os_sinit_data->capabilities) != os_sinit_data->capabilities) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Details/authorities PCR usage is not supported")); ++ } ++ else ++ { ++ if (!(sinit_caps & GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE)) ++ { ++ grub_dprintf ("slaunch", "Details/authorities PCR usage is not supported. Trying legacy"); ++ if (sinit_caps & GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Not a single PCR usage available in SINIT capabilities")); ++ ++ os_sinit_data->capabilities = 0; ++ } ++ } ++ + /* Choose monitor RLP wakeup mechanism first. */ + if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) + os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; +@@ -614,9 +654,26 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; + + if (grub_get_tpm_ver () == GRUB_TPM_12) +- return grub_error (GRUB_ERR_BAD_DEVICE, N_("TPM 1.2 is not supported")); ++ { ++ os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; ++ os_sinit_data->version = OS_SINIT_DATA_TPM_12_VER; ++ ++ heap_tpm_event_log_element = (struct grub_txt_heap_tpm_event_log_element *) ++ os_sinit_data->ext_data_elts; ++ heap_tpm_event_log_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR; ++ heap_tpm_event_log_element->size = sizeof (*heap_tpm_event_log_element); ++ heap_tpm_event_log_element->event_log_phys_addr = slparams->tpm_evt_log_base; ++ init_tpm12_event_log (slparams); ++ ++ heap_end_element = (struct grub_txt_heap_end_element *) ++ ((grub_addr_t) heap_tpm_event_log_element + heap_tpm_event_log_element->size); ++ heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; ++ heap_end_element->size = sizeof (*heap_end_element); ++ } + else + { ++ grub_dprintf ("slaunch", "TPM 2.0 detected\n"); ++ grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); + if (!(sinit_caps & GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("original TXT TPM 2.0 event log format is not supported")); +diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h +index 7d57af68841f..a8ac569968c7 100644 +--- a/include/grub/i386/txt.h ++++ b/include/grub/i386/txt.h +@@ -22,6 +22,7 @@ + #define GRUB_TXT_H 1 + + #include ++#include + #include + #include + #include +@@ -465,6 +466,34 @@ struct grub_txt_heap_event_log_ptr_elt2_1 + grub_uint32_t next_record_offset; + } GRUB_PACKED; + ++struct tpm12_pcr_event { ++ grub_uint32_t pcr_index; ++ grub_uint32_t type; ++ grub_uint8_t digest[SHA1_DIGEST_SIZE]; ++ grub_uint32_t data_size; ++ grub_uint8_t data[]; ++} GRUB_PACKED; ++ ++#define EVTLOG_SIGNATURE "TXT Event Container\0" ++#define EVTLOG_CNTNR_MAJOR_VER 1 ++#define EVTLOG_CNTNR_MINOR_VER 0 ++#define EVTLOG_EVT_MAJOR_VER 1 ++#define EVTLOG_EVT_MINOR_VER 0 ++ ++struct event_log_container { ++ grub_uint8_t signature[20]; ++ grub_uint8_t reserved[12]; ++ grub_uint8_t container_ver_major; ++ grub_uint8_t container_ver_minor; ++ grub_uint8_t pcr_event_ver_major; ++ grub_uint8_t pcr_event_ver_minor; ++ grub_uint32_t size; ++ grub_uint32_t pcr_events_offset; ++ grub_uint32_t next_event_offset; ++ struct tpm12_pcr_event pcr_events[]; ++} GRUB_PACKED; ++ ++ + /* TXT register and heap access */ + + static inline grub_uint64_t +-- +2.17.1 + diff --git a/1116-slaunch-Make-slparams-accessible-by-other-modules.patch b/1116-slaunch-Make-slparams-accessible-by-other-modules.patch new file mode 100644 index 0000000..6046a1c --- /dev/null +++ b/1116-slaunch-Make-slparams-accessible-by-other-modules.patch @@ -0,0 +1,222 @@ +From cd5911293aabf5f8336bdf12088710b06e396a62 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= +Date: Thu, 1 Sep 2022 17:57:46 +0200 +Subject: [PATCH 1116/1118] slaunch: Make slparams accessible by other modules +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michał Żygowski +--- + grub-core/loader/i386/linux.c | 60 +++++++++++++++++---------------- + grub-core/loader/i386/slaunch.c | 8 +++++ + include/grub/i386/slaunch.h | 1 + + 3 files changed, 40 insertions(+), 29 deletions(-) + +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index ba050de2d1df..88c04b3fffd5 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -89,7 +89,6 @@ static grub_efi_uintn_t efi_mmap_size; + #else + static const grub_size_t efi_mmap_size = 0; + #endif +-static struct grub_slaunch_params slparams; + + /* FIXME */ + #if 0 +@@ -161,6 +160,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + { + grub_err_t err; + grub_size_t total_size; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); + + if (prot_size == 0) + prot_size = 1; +@@ -175,20 +175,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + goto fail; + } + +- slparams.mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); +- slparams.mle_ptab_size = ALIGN_UP (slparams.mle_ptab_size, GRUB_TXT_PMR_ALIGN); ++ slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); ++ slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN); + /* Do not go below GRUB_TXT_PMR_ALIGN. */ +- preferred_address = (preferred_address > slparams.mle_ptab_size) ? +- (preferred_address - slparams.mle_ptab_size) : GRUB_TXT_PMR_ALIGN; ++ preferred_address = (preferred_address > slparams->mle_ptab_size) ? ++ (preferred_address - slparams->mle_ptab_size) : GRUB_TXT_PMR_ALIGN; + preferred_address = ALIGN_UP (preferred_address, GRUB_TXT_PMR_ALIGN); + } + else + { + prot_size = page_align (prot_size); +- slparams.mle_ptab_size = 0; ++ slparams->mle_ptab_size = 0; + } + +- total_size = prot_size + slparams.mle_ptab_size; ++ total_size = prot_size + slparams->mle_ptab_size; + + /* Initialize the memory pointers with NULL for convenience. */ + free_pages (); +@@ -239,18 +239,18 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + /* Zero out memory to get stable MLE measurements. */ + grub_memset (prot_mode_mem, 0, total_size); + +- slparams.mle_ptab_mem = prot_mode_mem; +- slparams.mle_ptab_target = prot_mode_target; ++ slparams->mle_ptab_mem = prot_mode_mem; ++ slparams->mle_ptab_target = prot_mode_target; + +- prot_mode_mem = (char *)prot_mode_mem + slparams.mle_ptab_size; +- prot_mode_target += slparams.mle_ptab_size; ++ prot_mode_mem = (char *)prot_mode_mem + slparams->mle_ptab_size; ++ prot_mode_target += slparams->mle_ptab_size; + +- slparams.mle_start = prot_mode_target; +- slparams.mle_size = prot_size; ++ slparams->mle_start = prot_mode_target; ++ slparams->mle_size = prot_size; + + grub_dprintf ("linux", "mle_ptab_mem = %p, mle_ptab_target = %lx, mle_ptab_size = %x\n", +- slparams.mle_ptab_mem, (unsigned long) slparams.mle_ptab_target, +- (unsigned) slparams.mle_ptab_size); ++ slparams->mle_ptab_mem, (unsigned long) slparams->mle_ptab_target, ++ (unsigned) slparams->mle_ptab_size); + + if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, + 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, +@@ -258,14 +258,14 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + GRUB_RELOCATOR_PREFERENCE_NONE, 1)) + goto fail; + +- slparams.tpm_evt_log_base = get_physical_target_address (ch); +- slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; ++ slparams->tpm_evt_log_base = get_physical_target_address (ch); ++ slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; + +- grub_memset (get_virtual_current_address (ch), 0, slparams.tpm_evt_log_size); ++ grub_memset (get_virtual_current_address (ch), 0, slparams->tpm_evt_log_size); + + grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", +- (unsigned long) slparams.tpm_evt_log_base, +- (unsigned) slparams.tpm_evt_log_size); ++ (unsigned long) slparams->tpm_evt_log_base, ++ (unsigned) slparams->tpm_evt_log_size); + } + } + +@@ -480,6 +480,7 @@ grub_linux_boot (void) + grub_size_t mmap_size; + grub_size_t cl_offset; + grub_size_t ap_wake_block_size = 0; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); + + #ifdef GRUB_MACHINE_IEEE1275 + { +@@ -635,12 +636,12 @@ grub_linux_boot (void) + + if (grub_slaunch_platform_type () == SLP_INTEL_TXT) + { +- slparams.ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; +- slparams.ap_wake_block_size = ap_wake_block_size; ++ slparams->ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; ++ slparams->ap_wake_block_size = ap_wake_block_size; + grub_memset ((void *) ((grub_addr_t) real_mode_mem + ctx.real_size + + efi_mmap_size), 0, ap_wake_block_size); + grub_dprintf ("linux", "ap_wake_block = %lx, ap_wake_block_size = %lx\n", +- (unsigned long) slparams.ap_wake_block, ++ (unsigned long) slparams->ap_wake_block, + (unsigned long) ap_wake_block_size); + } + +@@ -711,17 +712,17 @@ grub_linux_boot (void) + + if (state.edi == SLP_INTEL_TXT) + { +- slparams.boot_params_addr = (grub_uint32_t) ctx.real_mode_target; ++ slparams->boot_params_addr = (grub_uint32_t) ctx.real_mode_target; + +- err = grub_txt_boot_prepare (&slparams); ++ err = grub_txt_boot_prepare (slparams); + + if (err != GRUB_ERR_NONE) + return err; + + /* Configure relocator GETSEC[SENTER] call. */ + state.eax = GRUB_SMX_LEAF_SENTER; +- state.ebx = slparams.sinit_acm_base; +- state.ecx = slparams.sinit_acm_size; ++ state.ebx = slparams->sinit_acm_base; ++ state.ecx = slparams->sinit_acm_size; + state.edx = 0; + } + else +@@ -760,6 +761,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_size_t align, min_align; + int relocatable; + grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); + + grub_dl_ref (my_mod); + +@@ -879,7 +881,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_memset (&linux_params, 0, sizeof (linux_params)); + + if (grub_slaunch_platform_type () == SLP_INTEL_TXT) +- grub_txt_setup_mle_ptab (&slparams); ++ grub_txt_setup_mle_ptab (grub_slaunch_params ()); + + /* + * The Linux 32-bit boot protocol defines the setup header end +@@ -967,7 +969,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- slparams.mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); ++ slparams->mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); + } + } + else if (grub_slaunch_platform_type () != SLP_NONE) +diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c +index 72d09236b2ae..f1a7b8704d45 100644 +--- a/grub-core/loader/i386/slaunch.c ++++ b/grub-core/loader/i386/slaunch.c +@@ -36,6 +36,8 @@ static grub_uint32_t slp = SLP_NONE; + + static void *slaunch_module = NULL; + ++static struct grub_slaunch_params slparams; ++ + grub_uint32_t + grub_slaunch_platform_type (void) + { +@@ -48,6 +50,12 @@ grub_slaunch_module (void) + return slaunch_module; + } + ++struct grub_slaunch_params * ++grub_slaunch_params (void) ++{ ++ return &slparams; ++} ++ + static grub_err_t + grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), +diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h +index 12cd341aae0c..ee1777d86759 100644 +--- a/include/grub/i386/slaunch.h ++++ b/include/grub/i386/slaunch.h +@@ -51,6 +51,7 @@ struct grub_slaunch_params + + extern grub_uint32_t grub_slaunch_platform_type (void); + extern void *grub_slaunch_module (void); ++extern struct grub_slaunch_params *grub_slaunch_params (void); + + #endif /* ASM_FILE */ + +-- +2.17.1 + diff --git a/1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch b/1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch new file mode 100644 index 0000000..ee7328f --- /dev/null +++ b/1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch @@ -0,0 +1,108 @@ +From 077aa6775468c2c5ac1d2eaabdabe5606974eac9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= +Date: Thu, 13 Oct 2022 12:36:18 +0200 +Subject: [PATCH 1117/1118] grub-core/loader/i386/txt/txt.c: add debug prints +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michał Żygowski +--- + grub-core/loader/i386/txt/txt.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c +index f3afb6ad1d92..620118edb7d5 100644 +--- a/grub-core/loader/i386/txt/txt.c ++++ b/grub-core/loader/i386/txt/txt.c +@@ -538,9 +538,12 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + + txt_heap = grub_txt_get_heap (); + ++ grub_dprintf ("slaunch", "TXT heap %p\n", txt_heap); ++ + /* OS/loader to MLE data. */ + + os_mle_data = grub_txt_os_mle_data_start (txt_heap); ++ grub_dprintf ("slaunch", "OS MLE data: %p\n", os_mle_data); + size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); + *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); + +@@ -556,10 +559,11 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + os_mle_data->evtlog_addr = slparams->tpm_evt_log_base; + os_mle_data->evtlog_size = slparams->tpm_evt_log_size; + ++ grub_dprintf ("slaunch", "Saving MTRRs to OS MLE data\n"); + save_mtrrs (os_mle_data); + + /* OS/loader to SINIT data. */ +- ++ grub_dprintf ("slaunch", "Get supported OS SINIT data version\n"); + os_sinit_data_ver = grub_txt_supported_os_sinit_data_ver (sinit); + + if (os_sinit_data_ver < OS_SINIT_DATA_MIN_VER) +@@ -568,6 +572,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + " expected >= %d"), os_sinit_data_ver, OS_SINIT_DATA_MIN_VER); + + os_sinit_data = grub_txt_os_sinit_data_start (txt_heap); ++ grub_dprintf ("slaunch", "OS SINIT data: %p\n", os_sinit_data); + size = (grub_uint64_t *) ((grub_addr_t) os_sinit_data - sizeof (grub_uint64_t)); + + *size = sizeof(grub_uint64_t) + sizeof (struct grub_txt_os_sinit_data) + +@@ -655,6 +660,8 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + + if (grub_get_tpm_ver () == GRUB_TPM_12) + { ++ grub_dprintf ("slaunch", "TPM 1.2 detected\n"); ++ grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); + os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; + os_sinit_data->version = OS_SINIT_DATA_TPM_12_VER; + +@@ -696,7 +703,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; + heap_end_element->size = sizeof (*heap_end_element); + } +- ++ grub_dprintf ("slaunch", "TXT HEAP init done\n"); + /* + * TODO: TXT spec: Note: BiosDataSize + OsMleDataSize + OsSinitDataSize + SinitMleDataSize + * must be less than or equal to TXT.HEAP.SIZE, TXT spec, p. 102. +@@ -918,11 +925,14 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) + if (sinit_base == NULL) + return grub_errno; + ++ grub_dprintf ("slaunch", "Init TXT heap\n"); + err = init_txt_heap (slparams, sinit_base); + + if (err != GRUB_ERR_NONE) + return err; + ++ grub_dprintf ("slaunch", "TXT heap successfully prepared\n"); ++ + /* Update the MLE header. */ + mle_header = (struct grub_txt_mle_header *)(grub_addr_t) (slparams->mle_start + slparams->mle_header_offset); + mle_header->first_valid_page = 0; +@@ -932,15 +942,20 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) + slparams->sinit_acm_size = sinit_base->size * 4; + + grub_tpm_relinquish_lcl (0); ++ grub_dprintf ("slaunch", "TPM locality reliquished\n"); + + err = set_mtrrs_for_acmod (sinit_base); + if (err) + return grub_error (err, N_("secure launch failed to set MTRRs for ACM")); + ++ grub_dprintf ("slaunch", "MTRRs set for ACMOD\n"); ++ + err = grub_txt_prepare_cpu (); + if ( err ) + return err; + ++ grub_dprintf ("slaunch", "CPU prepared for secure launch\n"); ++ + if (!(grub_rdmsr (GRUB_MSR_X86_APICBASE) & GRUB_MSR_X86_APICBASE_BSP)) + return grub_error (GRUB_ERR_BAD_DEVICE, N_("secure launch must run on BSP")); + +-- +2.17.1 + diff --git a/1118-multiboot2-Implement-TXT-slaunch-support.patch b/1118-multiboot2-Implement-TXT-slaunch-support.patch new file mode 100644 index 0000000..ec512d8 --- /dev/null +++ b/1118-multiboot2-Implement-TXT-slaunch-support.patch @@ -0,0 +1,303 @@ +From 385569aa9be925c96e8112c69437241831152dd5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= +Date: Thu, 1 Sep 2022 17:58:53 +0200 +Subject: [PATCH 1118/1118] multiboot2: Implement TXT slaunch support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michał Żygowski +Signed-off-by: Tomasz Żyjewski +Signed-off-by: Krystian Hebel +--- + grub-core/loader/multiboot.c | 19 +++++- + grub-core/loader/multiboot_elfxx.c | 102 ++++++++++++++++++++++++++--- + grub-core/loader/multiboot_mbi2.c | 55 ++++++++++++++++ + include/grub/i386/txt.h | 1 + + 4 files changed, 168 insertions(+), 9 deletions(-) + +diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c +index 3ab0c828c3ae..eb2da8546d9a 100644 +--- a/grub-core/loader/multiboot.c ++++ b/grub-core/loader/multiboot.c +@@ -52,6 +52,7 @@ + #include + #if defined (__i386__) || defined (__x86_64__) + #include ++#include + #endif + + GRUB_MOD_LICENSE ("GPLv3+"); +@@ -164,7 +165,23 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)), + static void + normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state) + { +- state.edi = SLP_NONE; ++ grub_err_t err; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); ++ state.edi = grub_slaunch_platform_type (); ++ ++ if (state.edi == SLP_INTEL_TXT) ++ { ++ err = grub_txt_boot_prepare (slparams); ++ ++ if (err != GRUB_ERR_NONE) ++ return; ++ ++ /* Configure relocator GETSEC[SENTER] call. */ ++ state.eax = GRUB_SMX_LEAF_SENTER; ++ state.ebx = slparams->sinit_acm_base; ++ state.ecx = slparams->sinit_acm_size; ++ state.edx = 0; ++ } + + grub_relocator32_boot (rel, state, 0); + } +diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c +index f2318e0d165d..47ba4c3f2746 100644 +--- a/grub-core/loader/multiboot_elfxx.c ++++ b/grub-core/loader/multiboot_elfxx.c +@@ -34,6 +34,8 @@ + #error "I'm confused" + #endif + ++#include ++#include + #include + + #define CONCAT(a,b) CONCAT_(a, b) +@@ -60,6 +62,9 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) + grub_uint32_t load_offset = 0, load_size; + int i; + void *source = NULL; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); ++ grub_size_t total_size; ++ grub_uint32_t mle_hdr_offset; + + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 + || ehdr->e_ident[EI_MAG1] != ELFMAG1 +@@ -106,25 +111,86 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) + (long) mld->align, mld->preference, load_size, + mld->avoid_efi_boot_services); + +- if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size) ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++#ifndef GRUB_USE_MULTIBOOT2 ++ return grub_error (GRUB_ERR_BAD_OS, "Only multiboot2 supported for slaunch"); ++#else ++ /* ++ * We allocate the the binary together with page tables to make one ++ * contiguous block for MLE. We have to align up to PMR (2MB). ++ */ ++ total_size = ALIGN_UP(load_size, GRUB_TXT_PMR_ALIGN); ++ ++ slparams->mle_size = total_size; ++ ++ slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (total_size); ++ slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN); ++ ++ /* Do not go below GRUB_TXT_PMR_ALIGN. */ ++ if (mld->align < GRUB_TXT_PMR_ALIGN) ++ mld->align = GRUB_TXT_PMR_ALIGN; ++#endif ++ } ++ else ++ { ++ total_size = load_size; ++ slparams->mle_ptab_size = 0; ++ } ++ ++ if (total_size > mld->max_addr || mld->min_addr > mld->max_addr - total_size) + return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); + + err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch, +- mld->min_addr, mld->max_addr, +- load_size, mld->align ? mld->align : 1, ++ mld->min_addr, mld->max_addr - total_size, ++ total_size, mld->align ? mld->align : 1, + mld->preference, mld->avoid_efi_boot_services); + + if (err) +- { +- grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); +- return err; +- } ++ { ++ grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); ++ return err; ++ } + + mld->load_base_addr = get_physical_target_address (ch); + source = get_virtual_current_address (ch); ++ grub_memset (get_virtual_current_address (ch), 0, total_size); ++ grub_dprintf ("multiboot_loader", "load_base_addr=0x%lx, source=0x%lx\n", ++ (long) mld->load_base_addr, (long) source); ++ ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++#ifndef GRUB_USE_MULTIBOOT2 ++ return grub_error (GRUB_ERR_BAD_OS, "Only multiboot2 supported for slaunch"); ++#else ++ slparams->mle_start = mld->load_base_addr; ++ ++ err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch, ++ GRUB_MEMORY_MACHINE_UPPER_START, ++ mld->load_base_addr - slparams->mle_ptab_size, ++ slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 1); ++ if (err) ++ { ++ grub_dprintf ("multiboot_loader", "Cannot allocate memory for MLE page tables\n"); ++ return err; ++ } ++ ++ slparams->mle_ptab_mem = get_virtual_current_address (ch); ++ slparams->mle_ptab_target = (grub_uint64_t) get_physical_target_address (ch); ++ grub_dprintf ("multiboot_loader", "mle_ptab_mem = %p, mle_ptab_target = %lx, mle_ptab_size = %x\n", ++ slparams->mle_ptab_mem, (unsigned long) slparams->mle_ptab_target, ++ (unsigned) slparams->mle_ptab_size); ++#endif ++ } + } + else +- mld->load_base_addr = mld->link_base_addr; ++ { ++ mld->load_base_addr = mld->link_base_addr; ++ /* TODO: support non-relocatable */ ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ return grub_error (GRUB_ERR_BAD_OS, "Non-relocatable ELF not supported with slaunch"); ++ } + + grub_dprintf ("multiboot_loader", "relocatable=%d, link_base_addr=0x%x, " + "load_base_addr=0x%x\n", mld->relocatable, +@@ -180,6 +246,26 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) + } + } + ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ slparams->mle_header_offset = 0xffffffff; ++ ++ for (mle_hdr_offset = 0; mle_hdr_offset < 0x1000; mle_hdr_offset += 16) ++ { ++ if ( !grub_memcmp ((void *)((grub_addr_t) source + mle_hdr_offset), GRUB_TXT_MLE_UUID, 16) ) ++ { ++ slparams->mle_header_offset = mle_hdr_offset; ++ break; ++ } ++ } ++ ++ if (slparams->mle_header_offset == 0xffffffff) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "MLE header not found"); ++ ++ grub_dprintf ("slaunch", "slparams->mle_header_offset: 0x%08x\n", ++ slparams->mle_header_offset); ++ } ++ + for (i = 0; i < ehdr->e_phnum; i++) + if (phdr(i)->p_vaddr <= ehdr->e_entry + && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) +diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c +index 9a943d7bdd7c..14ac7137cd09 100644 +--- a/grub-core/loader/multiboot_mbi2.c ++++ b/grub-core/loader/multiboot_mbi2.c +@@ -36,6 +36,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #if defined (GRUB_MACHINE_EFI) + #include +@@ -277,6 +280,9 @@ grub_multiboot2_load (grub_file_t file, const char *filename) + + if (addr_tag) + { ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ return grub_error (GRUB_ERR_BAD_OS, "Slaunch not supported with multiboot addr tag"); ++ + grub_uint64_t load_addr = (addr_tag->load_addr + 1) + ? addr_tag->load_addr : (addr_tag->header_addr + - ((char *) header - (char *) mld.buffer)); +@@ -390,6 +396,50 @@ grub_multiboot2_load (grub_file_t file, const char *filename) + err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT, + accepted_consoles, + 0, 0, 0, console_required); ++ ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ grub_relocator_chunk_t ch; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); ++ ++ if (grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch, 0x1000000, ++ UP_TO_TOP32 (GRUB_SLAUNCH_TPM_EVT_LOG_SIZE), ++ GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE, ++ GRUB_RELOCATOR_PREFERENCE_HIGH, 1)) ++ { ++ grub_free (mld.buffer); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not allocate TPM event log area"); ++ } ++ ++ slparams->tpm_evt_log_base = get_physical_target_address (ch); ++ slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; ++ ++ grub_memset (get_virtual_current_address (ch), 0, slparams->tpm_evt_log_size); ++ ++ grub_dprintf ("multiboot_loader", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", ++ (unsigned long) slparams->tpm_evt_log_base, ++ (unsigned) slparams->tpm_evt_log_size); ++ ++ if (grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch, 0x1000000, ++ UP_TO_TOP32 (GRUB_MLE_AP_WAKE_BLOCK_SIZE), ++ GRUB_MLE_AP_WAKE_BLOCK_SIZE, GRUB_PAGE_SIZE, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 1)) ++ { ++ grub_free (mld.buffer); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not allocate AP wakeup block"); ++ } ++ ++ slparams->ap_wake_block = get_physical_target_address (ch); ++ slparams->ap_wake_block_size = GRUB_MLE_AP_WAKE_BLOCK_SIZE; ++ ++ grub_memset ((void *) (grub_addr_t)slparams->ap_wake_block, 0, slparams->ap_wake_block_size); ++ grub_dprintf ("multiboot_loader", "ap_wake_block = %lx, ap_wake_block_size = %lx\n", ++ (unsigned long) slparams->ap_wake_block, ++ (unsigned long) slparams->ap_wake_block_size); ++ ++ grub_txt_setup_mle_ptab (slparams); ++ } ++ + return err; + } + +@@ -722,7 +772,12 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) + + ptrorig = get_virtual_current_address (ch); + #if defined (__i386__) || defined (__x86_64__) ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); ++ + *target = get_physical_target_address (ch); ++ /* Save MBI pointer in the TXT heap area */ ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ slparams->boot_params_addr = *target; + #elif defined (__mips) + *target = get_physical_target_address (ch) | 0x80000000; + #else +diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h +index a8ac569968c7..6166f17ff5ee 100644 +--- a/include/grub/i386/txt.h ++++ b/include/grub/i386/txt.h +@@ -101,6 +101,7 @@ struct grub_txt_acm_header + } GRUB_PACKED; + + #define GRUB_TXT_ACM_UUID "\xaa\x3a\xc0\x7f\xa7\x46\xdb\x18\x2e\xac\x69\x8f\x8d\x41\x7f\x5a" ++#define GRUB_TXT_MLE_UUID "\x5a\xac\x82\x90\x6f\x47\xa7\x74\x0f\x5c\x55\xa2\xcb\x51\xb6\x42" + + #define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS 0 + #define GRUB_TXT_ACM_CHIPSET_TYPE_SINIT 1 +-- +2.17.1 + diff --git a/grub2.spec.in b/grub2.spec.in index 570094e..118d57b 100644 --- a/grub2.spec.in +++ b/grub2.spec.in @@ -747,6 +747,26 @@ Patch0215: 0215-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch Patch1000: 1000-templates-linux_xen-fix-detecting-xsm-policy.patch Patch1001: 1001-Hide-os-prober-disabled-warning.patch +# Intel TXT support patches +Patch1101: 1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch +Patch1102: 1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch +Patch1103: 1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch +Patch1104: 1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch +Patch1105: 1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch +Patch1106: 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch +Patch1107: 1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch +Patch1108: 1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch +Patch1109: 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +Patch1110: 1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch +Patch1111: 1111-i386-txt-Add-Intel-TXT-core-implementation.patch +Patch1112: 1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch +Patch1113: 1113-i386-txt-Add-Intel-TXT-verification-routines.patch +Patch1114: 1114-i386-slaunch-Add-secure-launch-framework-and-command.patch +Patch1115: 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +Patch1116: 1116-slaunch-Make-slparams-accessible-by-other-modules.patch +Patch1117: 1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch +Patch1118: 1118-multiboot2-Implement-TXT-slaunch-support.patch + BuildRequires: autoconf BuildRequires: automake BuildRequires: bison From e1b51bbf4c604fa3529a3e3092e95040e6fe2d0c Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Thu, 13 Apr 2023 20:54:09 +0200 Subject: [PATCH 2/5] Add patches for Intel TXT support v2 Signed-off-by: Krystian Hebel --- ...Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch | 4 +- ...ame-grub_msr_read-and-grub_msr_write.patch | 5 +- ...-and-improve-MSR-support-detection-c.patch | 5 +- ...Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch | 4 +- ...me-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch | 6 +- ...ap_get_lowest-and-grub_mmap_get_high.patch | 19 +- ...-basic-platform-support-for-secure-l.patch | 156 ++----- ...pm-Rename-tpm-module-to-tpm_verifier.patch | 14 +- ...-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch | 41 +- ...dd-Intel-TXT-definitions-header-file.patch | 4 +- ...xt-Add-Intel-TXT-core-implementation.patch | 230 +++++++---- ...txt-Add-Intel-TXT-ACM-module-support.patch | 382 +++++++++--------- ...-Add-Intel-TXT-verification-routines.patch | 32 +- ...-secure-launch-framework-and-command.patch | 94 ++++- ...ialize-TPM-1.2-event-log-in-TXT-heap.patch | 67 ++- ...slparams-accessible-by-other-modules.patch | 27 +- ...iboot2-Implement-TXT-slaunch-support.patch | 36 +- ...ader-i386-txt-txt.c-add-debug-prints.patch | 108 ----- grub2.spec.in | 31 +- 19 files changed, 632 insertions(+), 633 deletions(-) rename 1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch => 1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch (96%) rename 1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch => 1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch (93%) rename 1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch => 1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch (96%) rename 1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch => 1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch (98%) rename 1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch => 1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch (97%) rename 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch => 1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch (76%) rename 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch => 1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch (76%) rename 1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch => 1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch (99%) rename 1111-i386-txt-Add-Intel-TXT-core-implementation.patch => 1110-i386-txt-Add-Intel-TXT-core-implementation.patch (81%) rename 1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch => 1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch (57%) rename 1113-i386-txt-Add-Intel-TXT-verification-routines.patch => 1112-i386-txt-Add-Intel-TXT-verification-routines.patch (91%) rename 1114-i386-slaunch-Add-secure-launch-framework-and-command.patch => 1113-i386-slaunch-Add-secure-launch-framework-and-command.patch (90%) rename 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch => 1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch (70%) rename 1116-slaunch-Make-slparams-accessible-by-other-modules.patch => 1115-slaunch-Make-slparams-accessible-by-other-modules.patch (90%) rename 1118-multiboot2-Implement-TXT-slaunch-support.patch => 1116-multiboot2-Implement-TXT-slaunch-support.patch (88%) delete mode 100644 1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch diff --git a/1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch similarity index 96% rename from 1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch rename to 1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch index 97bde5c..5cde09b 100644 --- a/1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch +++ b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch @@ -1,7 +1,7 @@ -From a78796a23a33f12934ad45169be57735b05cdd81 Mon Sep 17 00:00:00 2001 +From 1614664a12563b23b2efd3b0c7b59a9c4ad10484 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 17 Dec 2019 17:51:29 +0100 -Subject: [PATCH 1101/1118] i386/msr: Merge rdmsr.h and wrmsr.h into msr.h +Subject: [PATCH] i386/msr: Merge rdmsr.h and wrmsr.h into msr.h It does not make sense to have separate headers for separate static functions. Additionally, we have to add some constants with MSR addresses diff --git a/1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch b/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch similarity index 93% rename from 1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch rename to 1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch index 197e093..9dcd804 100644 --- a/1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch +++ b/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch @@ -1,8 +1,7 @@ -From 4529bfd79f5ba84a9fd11cef803bd8c8f8aa9f8f Mon Sep 17 00:00:00 2001 +From bb8fe14ea78fbd7ad92b3d53c69e3b961eb8ccdd Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 17 Dec 2019 20:02:37 +0100 -Subject: [PATCH 1102/1118] i386/msr: Rename grub_msr_read() and - grub_msr_write() +Subject: [PATCH] i386/msr: Rename grub_msr_read() and grub_msr_write() ... to grub_rdmsr() and grub_wrmsr() respectively. New names are more obvious than older ones. diff --git a/1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch b/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch similarity index 96% rename from 1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch rename to 1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch index 4e9f7f3..1da2b7e 100644 --- a/1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch +++ b/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch @@ -1,8 +1,7 @@ -From ccee3f6377ecf0fba2edda7518911b3167657838 Mon Sep 17 00:00:00 2001 +From e0f617c89e3a03cba4b5e48ffac8ef76cc7c0838 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Sat, 25 Apr 2020 16:43:52 +0200 -Subject: [PATCH 1103/1118] i386/msr: Extract and improve MSR support detection - code +Subject: [PATCH] i386/msr: Extract and improve MSR support detection code Currently rdmsr and wrmsr commands have own MSR support detection code. This code is the same. So, it is duplicated. Additionally, this code diff --git a/1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch b/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch similarity index 98% rename from 1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch rename to 1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch index bd28eef..0cb7e8f 100644 --- a/1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch +++ b/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch @@ -1,7 +1,7 @@ -From e6e4cf0b0e1f2ee45706203ba8f30a7954acc83d Mon Sep 17 00:00:00 2001 +From 938357ec4fd8a8522fc55d3d050eff1f2235407d Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 20 Nov 2019 12:40:42 +0100 -Subject: [PATCH 1104/1118] i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT +Subject: [PATCH] i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT ...to avoid potential conflicts and confusion. diff --git a/1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch b/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch similarity index 97% rename from 1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch rename to 1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch index 8167e82..163709e 100644 --- a/1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch +++ b/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch @@ -1,8 +1,8 @@ -From be6df1e0e6b5fcbf26389e27288c54675d7e1aa5 Mon Sep 17 00:00:00 2001 +From 4e9a66d61b076b01826af440f581bb0c26c58431 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 20 Nov 2019 12:52:16 +0100 -Subject: [PATCH 1105/1118] i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and - make it global +Subject: [PATCH] i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and make it + global Subsequent patches will use that constant. diff --git a/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch b/1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch similarity index 76% rename from 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch rename to 1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch index 0b663e2..5cb2225 100644 --- a/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch +++ b/1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch @@ -1,8 +1,7 @@ -From 534e9d569caa75c0e36a80134dea6bf0f9350bc7 Mon Sep 17 00:00:00 2001 +From 47c88e17987444c862dd83a5e5aeb2faa6b4afb1 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:34:59 +0200 -Subject: [PATCH 1106/1118] mmap: Add grub_mmap_get_lowest() and - grub_mmap_get_highest() +Subject: [PATCH] mmap: Add grub_mmap_get_lowest() and grub_mmap_get_highest() The functions calculate lowest and highest available RAM addresses respectively. @@ -12,15 +11,15 @@ Intel TXT secure launcher introduced by subsequent patches. Signed-off-by: Daniel Kiper --- - grub-core/mmap/mmap.c | 64 +++++++++++++++++++++++++++++++++++++++++++ + grub-core/mmap/mmap.c | 70 +++++++++++++++++++++++++++++++++++++++++++ include/grub/memory.h | 3 ++ - 2 files changed, 67 insertions(+) + 2 files changed, 73 insertions(+) diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c -index c8c8312c56f2..270730fc770f 100644 +index c8c8312c56f2..1e93b7e3cabb 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c -@@ -343,6 +343,70 @@ grub_mmap_unregister (int handle) +@@ -343,6 +343,76 @@ grub_mmap_unregister (int handle) #endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ @@ -49,6 +48,8 @@ index c8c8312c56f2..270730fc770f 100644 + return 0; +} + ++/* This function calculates lowest available RAM address that is at or above ++ the passed limit. If no RAM exists above the limit, ~0 is returned. */ +grub_uint64_t +grub_mmap_get_lowest (grub_uint64_t limit) +{ @@ -78,6 +79,10 @@ index c8c8312c56f2..270730fc770f 100644 + return 0; +} + ++/* This function calculates highest available RAM address that is below the ++ passed limit. Returned address is either one byte after last byte of RAM or ++ equal to limit, whichever is lower. If no RAM exists below limit, 0 is ++ returned. */ +grub_uint64_t +grub_mmap_get_highest (grub_uint64_t limit) +{ diff --git a/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch b/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch similarity index 76% rename from 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch rename to 1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch index 063513e..c6c5b27 100644 --- a/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +++ b/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch @@ -1,50 +1,49 @@ -From 92abb1b1c33a697d51d3c95ee0861f65c939e092 Mon Sep 17 00:00:00 2001 +From 33c31aa22cab2841aa9d4f9578f61a926c30eb8e Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:50:14 -0400 -Subject: [PATCH 1109/1118] i386/slaunch: Add basic platform support for secure - launch +Subject: [PATCH] i386/slaunch: Add basic platform support for secure launch Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper +Signed-off-by: Krystian Hebel --- - include/grub/i386/cpuid.h | 13 +++ - include/grub/i386/crfr.h | 186 ++++++++++++++++++++++++++++++++++++++ - include/grub/i386/mmio.h | 90 ++++++++++++++++++ - include/grub/i386/msr.h | 61 +++++++++++++ - 4 files changed, 350 insertions(+) + include/grub/i386/cpuid.h | 12 ++++ + include/grub/i386/crfr.h | 127 ++++++++++++++++++++++++++++++++++++++ + include/grub/i386/mmio.h | 72 +++++++++++++++++++++ + include/grub/i386/msr.h | 61 ++++++++++++++++++ + 4 files changed, 272 insertions(+) create mode 100644 include/grub/i386/crfr.h create mode 100644 include/grub/i386/mmio.h diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h -index f7ae4b0a4641..8176e5d113d8 100644 +index f7ae4b0a4641..0ddd87b1544e 100644 --- a/include/grub/i386/cpuid.h +++ b/include/grub/i386/cpuid.h -@@ -19,6 +19,19 @@ +@@ -19,6 +19,18 @@ #ifndef GRUB_CPU_CPUID_HEADER #define GRUB_CPU_CPUID_HEADER 1 +/* General */ -+#define GRUB_X86_CPUID_VENDOR 0x00000000 -+#define GRUB_X86_CPUID_FEATURES 0x00000001 -+ ++#define GRUB_X86_CPUID_VENDOR 0x00000000 ++#define GRUB_X86_CPUID_FEATURES 0x00000001 +/* Intel */ -+#define GRUB_VMX_CPUID_FEATURE (1<<5) -+#define GRUB_SMX_CPUID_FEATURE (1<<6) ++#define GRUB_X86_CPUID_FEATURES_ECX_VMX (1<<5) ++#define GRUB_X86_CPUID_FEATURES_ECX_SMX (1<<6) + +/* AMD */ -+#define GRUB_AMD_CPUID_FEATURES 0x80000001 -+#define GRUB_SVM_CPUID_FEATURE (1<<2) -+#define GRUB_AMD_CPUID_FUNC 0x8000000a ++#define GRUB_AMD_CPUID_FEATURES 0x80000001 ++#define GRUB_AMD_CPUID_FEATURES_ECX_SVM (1<<2) ++#define GRUB_AMD_CPUID_FUNC 0x8000000a + extern unsigned char grub_cpuid_has_longmode; extern unsigned char grub_cpuid_has_pae; diff --git a/include/grub/i386/crfr.h b/include/grub/i386/crfr.h new file mode 100644 -index 000000000000..284d6967be4b +index 000000000000..1dcae427dc8b --- /dev/null +++ b/include/grub/i386/crfr.h -@@ -0,0 +1,186 @@ +@@ -0,0 +1,127 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -98,94 +97,35 @@ index 000000000000..284d6967be4b +#define GRUB_CR4_X86_PCIDE 0x00020000 /* Enable PCID */ + +static inline unsigned long -+grub_read_cr4 (void) ++grub_read_cr0 (void) +{ + unsigned long val; + -+ asm volatile ("mov %%cr4, %0" : "=r" (val) : : "memory"); ++ asm volatile ("mov %%cr0, %0" : "=r" (val) : : "memory"); + + return val; +} + +static inline void -+grub_write_cr4 (unsigned long val) ++grub_write_cr0 (unsigned long val) +{ -+ asm volatile ("mov %0, %%cr4" : : "r" (val) : "memory"); ++ asm volatile ("mov %0, %%cr0" : : "r" (val) : "memory"); +} + -+#define GRUB_CR0 0 -+#define GRUB_CR1 1 -+#define GRUB_CR2 2 -+#define GRUB_CR3 3 -+#define GRUB_CR4 4 -+ -+#ifdef __x86_64__ -+#define read_cr(r, d) asm volatile ("movq %%cr" r ", %0" : "=r" (d)) -+#else -+#define read_cr(r, d) asm volatile ("movl %%cr" r ", %0" : "=r" (d)) -+#endif -+ +static inline unsigned long -+grub_read_control_register(grub_uint8_t reg) ++grub_read_cr4 (void) +{ -+ unsigned long data; -+ -+ switch (reg) -+ { -+ case GRUB_CR0: -+ read_cr("0", data); -+ break; -+ case GRUB_CR1: -+ read_cr("1", data); -+ break; -+ case GRUB_CR2: -+ read_cr("2", data); -+ break; -+ case GRUB_CR3: -+ read_cr("3", data); -+ break; -+ case GRUB_CR4: -+ read_cr("4", data); -+ break; -+ default: -+ /* TODO: Loudly complain if this is called. Even some kind of BUG() */ -+ data = ~0UL; -+ break; -+ } -+ -+ return data; -+} ++ unsigned long val; + -+#ifdef __x86_64__ -+#define write_cr(r, d) asm volatile ("movq %0, %%cr" r : : "r" (d)) -+#else -+#define write_cr(r, d) asm volatile ("movl %0, %%cr" r : : "r" (d)) -+#endif ++ asm volatile ("mov %%cr4, %0" : "=r" (val) : : "memory"); ++ ++ return val; ++} + +static inline void -+grub_write_control_register(grub_uint8_t reg, unsigned long data) ++grub_write_cr4 (unsigned long val) +{ -+ switch (reg) -+ { -+ case GRUB_CR0: -+ write_cr("0", data); -+ break; -+ case GRUB_CR1: -+ write_cr("1", data); -+ break; -+ case GRUB_CR2: -+ write_cr("2", data); -+ break; -+ case GRUB_CR3: -+ write_cr("3", data); -+ break; -+ case GRUB_CR4: -+ write_cr("4", data); -+ break; -+ default: -+ /* TODO: Loudly complain if this is called. Even some kind of BUG() */ -+ ; -+ } ++ asm volatile ("mov %0, %%cr4" : : "r" (val) : "memory"); +} + +#define GRUB_EFLAGS_X86_CF 0x00000001 /* Carry Flag */ @@ -233,10 +173,10 @@ index 000000000000..284d6967be4b +#endif diff --git a/include/grub/i386/mmio.h b/include/grub/i386/mmio.h new file mode 100644 -index 000000000000..6f5bf18ce3ac +index 000000000000..b5bce71ef8d6 --- /dev/null +++ b/include/grub/i386/mmio.h -@@ -0,0 +1,90 @@ +@@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -260,70 +200,52 @@ index 000000000000..6f5bf18ce3ac + +#include + -+/* TODO: Are these barirers really needed??? */ -+#define grub_mb() asm volatile ("mfence" : : : "memory") -+#define grub_rmb() asm volatile ("lfence" : : : "memory") -+#define grub_wmb() asm volatile ("sfence" : : : "memory") -+#define grub_barrier() asm volatile ("" : : : "memory") -+ +static inline grub_uint8_t -+grub_readb (const volatile void *addr) ++grub_readb (const grub_addr_t addr) +{ + grub_uint8_t val; + -+ grub_barrier (); + val = (*(volatile grub_uint8_t *) (addr)); -+ grub_rmb (); + + return val; +} + +static inline grub_uint32_t -+grub_readl (const volatile void *addr) ++grub_readl (const grub_addr_t addr) +{ + grub_uint32_t val; + -+ grub_barrier (); + val = (*(volatile grub_uint32_t *) (addr)); -+ grub_rmb (); + + return val; +} + +static inline grub_uint64_t -+grub_readq (const volatile void *addr) ++grub_readq (const grub_addr_t addr) +{ + grub_uint64_t val; + -+ grub_barrier (); + val = (*(volatile grub_uint64_t *) (addr)); -+ grub_rmb (); + + return val; +} + +static inline void -+grub_writeb (grub_uint8_t val, volatile void *addr) ++grub_writeb (grub_uint8_t val, grub_addr_t addr) +{ -+ grub_wmb (); + (*(volatile grub_uint8_t *) (addr)) = val; -+ grub_barrier (); +} + +static inline void -+grub_writel (grub_uint32_t val, volatile void *addr) ++grub_writel (grub_uint32_t val, grub_addr_t addr) +{ -+ grub_wmb (); + (*(volatile grub_uint32_t *) (addr)) = val; -+ grub_barrier (); +} + +static inline void -+grub_writeq (grub_uint64_t val, volatile void *addr) ++grub_writeq (grub_uint64_t val, grub_addr_t addr) +{ -+ grub_wmb (); + (*(volatile grub_uint64_t *) (addr)) = val; -+ grub_barrier (); +} + +#endif /* GRUB_I386_MMIO_H */ diff --git a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch index 948eb3e..fa4b1af 100644 --- a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch +++ b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch @@ -1,7 +1,7 @@ -From 6933cf0a6011f6c9eb951a2375c204c699b635ee Mon Sep 17 00:00:00 2001 +From 3b50cdd2ec6f1d94b126c510e8d2f20cc37bfaaa Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 22 Apr 2020 21:41:24 +0200 -Subject: [PATCH 1107/1118] i386/tpm: Rename tpm module to tpm_verifier +Subject: [PATCH] i386/tpm: Rename tpm module to tpm_verifier ...to avoid naming collision with TPM TIS and CRB driver introduced by subsequent patch. @@ -15,10 +15,10 @@ Signed-off-by: Daniel Kiper rename grub-core/commands/{tpm.c => tpm_verifier.c} (96%) diff --git a/docs/grub.texi b/docs/grub.texi -index 96c85927ad36..d0525023bbb8 100644 +index f8b4b3b21a7f..20cf82a813a7 100644 --- a/docs/grub.texi +++ b/docs/grub.texi -@@ -6008,10 +6008,10 @@ grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efine +@@ -5991,10 +5991,10 @@ grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efine @node Measured Boot @section Measuring boot components @@ -33,7 +33,7 @@ index 96c85927ad36..d0525023bbb8 100644 event description as described below. @multitable @columnfractions 0.3 0.1 0.6 -@@ -6036,9 +6036,10 @@ corresponding to the filename. +@@ -6019,9 +6019,10 @@ corresponding to the filename. GRUB will not measure its own @file{core.img} - it is expected that firmware will carry this out. GRUB will also not perform any measurements until the @@ -48,10 +48,10 @@ index 96c85927ad36..d0525023bbb8 100644 Measured boot is currently only supported on EFI platforms. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 452a30adab89..e6b41ede92c4 100644 +index 8022e1c0a794..f482cc01e36e 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -2505,8 +2505,8 @@ module = { +@@ -2490,8 +2490,8 @@ module = { }; module = { diff --git a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch index d9f014a..18523fb 100644 --- a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch +++ b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch @@ -1,25 +1,25 @@ -From 4b1ce3e251cc45963cb69fffdf8916e638f543f9 Mon Sep 17 00:00:00 2001 +From 0a9bf6cbbfac39052763f7a2ea19c50108eef35c Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:30:58 +0200 -Subject: [PATCH 1108/1118] i386/tpm: Add TPM TIS and CRB driver +Subject: [PATCH] i386/tpm: Add TPM TIS and CRB driver It will be used by Intel TXT secure launcher introduced by subsequent patches. Signed-off-by: Daniel Kiper --- - grub-core/commands/i386/tpm.c | 182 ++++++++++++++++++++++++++++++++++ + grub-core/commands/i386/tpm.c | 187 ++++++++++++++++++++++++++++++++++ include/grub/i386/tpm.h | 36 +++++++ - 2 files changed, 218 insertions(+) + 2 files changed, 223 insertions(+) create mode 100644 grub-core/commands/i386/tpm.c create mode 100644 include/grub/i386/tpm.h diff --git a/grub-core/commands/i386/tpm.c b/grub-core/commands/i386/tpm.c new file mode 100644 -index 000000000000..ff29c2e85070 +index 000000000000..232e8bbb946e --- /dev/null +++ b/grub-core/commands/i386/tpm.c -@@ -0,0 +1,182 @@ +@@ -0,0 +1,187 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Free Software Foundation, Inc. @@ -53,8 +53,12 @@ index 000000000000..ff29c2e85070 + +GRUB_MOD_LICENSE ("GPLv3+"); + ++/* Code based on TCG PC Client Platform TPM Profile Specification for TPM 2.0, ++ Version 1.05 Revision 14 released September 4, 2020. */ ++ +#define TPM_MMIO_BASE 0xfed40000 + ++/* 6.3.2 Register Space Addresses */ +/* TIS registers. */ +#define TPM_ACCESS 0x0000 +#define TPM_INTF_CAPABILITY 0x0014 @@ -63,16 +67,12 @@ index 000000000000..ff29c2e85070 +/* CRB registers. */ +#define TPM_LOC_CTRL 0x0008 + -+#define TPM_12_TIS_INTF_12 0x0 -+#define TPM_12_TIS_INTF_13 0x2 -+#define TPM_20_TIS_INTF_13 0x3 -+ -+#define TPM_CRB_INTF_ACTIVE 0x1 + +#define TIS_RELINQUISH_LCL 0x20 +#define CRB_RELINQUISH_LCL 0x0002 + -+/* TODO: Do we need GRUB_PACKED for unions below??? */ ++/* 6.4.2 Interface Identifier Register */ ++#define TPM_CRB_INTF_ACTIVE 0x1 + +union tpm_interface_id +{ @@ -91,9 +91,14 @@ index 000000000000..ff29c2e85070 + grub_uint32_t reserved_1:4; + grub_uint32_t reserved_2:8; + }; -+} GRUB_PACKED; ++}; +typedef union tpm_interface_id tpm_interface_id_t; + ++/* 6.5.2.7 Interface Capability */ ++#define TPM_12_TIS_INTF_12 0x0 ++#define TPM_12_TIS_INTF_13 0x2 ++#define TPM_20_TIS_INTF_13 0x3 ++ +union tpm_intf_capability +{ + grub_uint32_t raw; @@ -113,7 +118,7 @@ index 000000000000..ff29c2e85070 + grub_uint32_t interface_version:3; + grub_uint32_t reserved_1:1; + }; -+} GRUB_PACKED; ++}; +typedef union tpm_intf_capability tpm_intf_capability_t; + +typedef enum @@ -135,7 +140,7 @@ index 000000000000..ff29c2e85070 + +/* Localities 0-4 are supported only. */ +void -+grub_tpm_relinquish_lcl (grub_uint8_t lcl) ++grub_tpm_relinquish_locality (grub_uint8_t lcl) +{ + grub_addr_t addr = TPM_MMIO_BASE + lcl * GRUB_PAGE_SIZE; + @@ -163,7 +168,7 @@ index 000000000000..ff29c2e85070 + else if (tpm_intf == TPM_INTF_CRB) + tpm_intf_s = "CRB"; + -+ grub_printf ("TPM VER: %s\nTPM INTF: %s\n", tpm_ver_s, tpm_intf_s); ++ grub_printf ("TPM family: %s\nTPM interface: %s\n", tpm_ver_s, tpm_intf_s); + + return GRUB_ERR_NONE; +} @@ -204,7 +209,7 @@ index 000000000000..ff29c2e85070 +} diff --git a/include/grub/i386/tpm.h b/include/grub/i386/tpm.h new file mode 100644 -index 000000000000..ae8d4a27def7 +index 000000000000..d22a2507efa1 --- /dev/null +++ b/include/grub/i386/tpm.h @@ -0,0 +1,36 @@ @@ -241,7 +246,7 @@ index 000000000000..ae8d4a27def7 +grub_tpm_ver_t; + +extern grub_tpm_ver_t grub_get_tpm_ver (void); -+extern void grub_tpm_relinquish_lcl (grub_uint8_t lcl); ++extern void grub_tpm_relinquish_locality (grub_uint8_t lcl); + +#endif /* GRUB_I386_TPM_H */ -- diff --git a/1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch b/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch similarity index 99% rename from 1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch rename to 1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch index 2796385..dac364c 100644 --- a/1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch +++ b/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch @@ -1,7 +1,7 @@ -From 5f6b716437c7606e5505838ff824875954da23b1 Mon Sep 17 00:00:00 2001 +From 8e91862df3df4072b2f8ad7ef28884da6c4a5e6a Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:53:06 -0400 -Subject: [PATCH 1110/1118] i386/txt: Add Intel TXT definitions header file +Subject: [PATCH] i386/txt: Add Intel TXT definitions header file Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper diff --git a/1111-i386-txt-Add-Intel-TXT-core-implementation.patch b/1110-i386-txt-Add-Intel-TXT-core-implementation.patch similarity index 81% rename from 1111-i386-txt-Add-Intel-TXT-core-implementation.patch rename to 1110-i386-txt-Add-Intel-TXT-core-implementation.patch index 9dded95..1ac470d 100644 --- a/1111-i386-txt-Add-Intel-TXT-core-implementation.patch +++ b/1110-i386-txt-Add-Intel-TXT-core-implementation.patch @@ -1,22 +1,29 @@ -From 52435a735ec9807383adc1ac77209ad77057f00c Mon Sep 17 00:00:00 2001 +From 38bf9bedd60fff65aa8402432ed05d7ed27d07c0 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:57:33 -0400 -Subject: [PATCH 1111/1118] i386/txt: Add Intel TXT core implementation +Subject: [PATCH] i386/txt: Add Intel TXT core implementation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper +Signed-off-by: Michał Żygowski +Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/txt.c | 891 ++++++++++++++++++++++++++++++++ + grub-core/loader/i386/txt/txt.c | 914 ++++++++++++++++++++++++++++++++ include/grub/i386/memory.h | 5 + - 2 files changed, 896 insertions(+) + include/grub/i386/msr.h | 1 + + include/grub/i386/txt.h | 18 +- + 4 files changed, 935 insertions(+), 3 deletions(-) create mode 100644 grub-core/loader/i386/txt/txt.c diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c new file mode 100644 -index 000000000000..201167ce9a44 +index 000000000000..9540719990bd --- /dev/null +++ b/grub-core/loader/i386/txt/txt.c -@@ -0,0 +1,891 @@ +@@ -0,0 +1,914 @@ +/* + * txt.c: Intel(r) TXT support functions, including initiating measured + * launch, post-launch, AP wakeup, etc. @@ -97,6 +104,14 @@ index 000000000000..201167ce9a44 +enable_smx_mode (void) +{ + grub_uint32_t caps; ++ grub_uint64_t feat_ctrl = grub_rdmsr (GRUB_MSR_X86_FEATURE_CONTROL); ++ ++ if (!(feat_ctrl & GRUB_MSR_X86_FEATURE_CTRL_LOCK)) ++ { ++ grub_dprintf ("slaunch", "Firmware didn't lock FEATURE_CONTROL MSR," ++ "locking it now\n"); ++ feat_ctrl |= GRUB_MSR_X86_FEATURE_CTRL_LOCK; ++ } + + /* Enable SMX mode. */ + grub_write_cr4 (grub_read_cr4 () | GRUB_CR4_X86_SMXE); @@ -203,7 +218,7 @@ index 000000000000..201167ce9a44 + grub_uint64_t mcg_cap, mcg_stat; + unsigned long cr0; + -+ cr0 = grub_read_control_register (GRUB_CR0); ++ cr0 = grub_read_cr0 (); + + /* Cache must be enabled (CR0.CD = CR0.NW = 0). */ + cr0 &= ~(GRUB_CR0_X86_CD | GRUB_CR0_X86_NW); @@ -211,7 +226,7 @@ index 000000000000..201167ce9a44 + /* Native FPU error reporting must be enabled for proper interaction behavior. */ + cr0 |= GRUB_CR0_X86_NE; + -+ grub_write_control_register (GRUB_CR0, cr0); ++ grub_write_cr0 (cr0); + + /* Disable virtual-8086 mode (EFLAGS.VM = 0). */ + grub_write_flags_register (grub_read_flags_register () & ~GRUB_EFLAGS_X86_VM); @@ -480,16 +495,15 @@ index 000000000000..201167ce9a44 + grub_write_flags_register (eflags & ~GRUB_EFLAGS_X86_IF); + + /* Save CR0 then disable cache (CRO.CD=1, CR0.NW=0) */ -+ cr0 = grub_read_control_register (GRUB_CR0); -+ grub_write_control_register (GRUB_CR0, -+ (cr0 & ~GRUB_CR0_X86_NW) | GRUB_CR0_X86_CD); ++ cr0 = grub_read_cr0 (); ++ grub_write_cr0 ( (cr0 & ~GRUB_CR0_X86_NW) | GRUB_CR0_X86_CD ); + + /* Flush caches */ + asm volatile ("wbinvd"); + + /* Save CR4 and disable global pages (CR4.PGE=0) */ -+ cr4 = grub_read_control_register (GRUB_CR4); -+ grub_write_control_register (GRUB_CR4, cr4 & ~GRUB_CR4_X86_PGE); ++ cr4 = grub_read_cr4 (); ++ grub_write_cr4 (cr4 & ~GRUB_CR4_X86_PGE); + + /* Disable MTRRs */ + set_all_mtrrs (0); @@ -508,11 +522,11 @@ index 000000000000..201167ce9a44 + /* Enable MTRRs */ + set_all_mtrrs (1); + -+ /* Restore CR0 (cacheing) */ -+ grub_write_control_register (GRUB_CR0, cr0); ++ /* Restore CR0 (caching) */ ++ grub_write_cr0 (cr0); + + /* Restore CR4 (global pages) */ -+ grub_write_control_register (GRUB_CR4, cr4); ++ grub_write_cr4 (cr4); + + /* Restore flags */ + grub_write_flags_register (eflags); @@ -538,9 +552,12 @@ index 000000000000..201167ce9a44 + + txt_heap = grub_txt_get_heap (); + ++ grub_dprintf ("slaunch", "TXT heap %p\n", txt_heap); ++ + /* OS/loader to MLE data. */ + + os_mle_data = grub_txt_os_mle_data_start (txt_heap); ++ grub_dprintf ("slaunch", "OS MLE data: %p\n", os_mle_data); + size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); + *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); + @@ -556,10 +573,11 @@ index 000000000000..201167ce9a44 + os_mle_data->evtlog_addr = slparams->tpm_evt_log_base; + os_mle_data->evtlog_size = slparams->tpm_evt_log_size; + ++ grub_dprintf ("slaunch", "Saving MTRRs to OS MLE data\n"); + save_mtrrs (os_mle_data); + + /* OS/loader to SINIT data. */ -+ ++ grub_dprintf ("slaunch", "Get supported OS SINIT data version\n"); + os_sinit_data_ver = grub_txt_supported_os_sinit_data_ver (sinit); + + if (os_sinit_data_ver < OS_SINIT_DATA_MIN_VER) @@ -568,6 +586,7 @@ index 000000000000..201167ce9a44 + " expected >= %d"), os_sinit_data_ver, OS_SINIT_DATA_MIN_VER); + + os_sinit_data = grub_txt_os_sinit_data_start (txt_heap); ++ grub_dprintf ("slaunch", "OS SINIT data: %p\n", os_sinit_data); + size = (grub_uint64_t *) ((grub_addr_t) os_sinit_data - sizeof (grub_uint64_t)); + + *size = sizeof(grub_uint64_t) + sizeof (struct grub_txt_os_sinit_data) + @@ -658,7 +677,7 @@ index 000000000000..201167ce9a44 + heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; + heap_end_element->size = sizeof (*heap_end_element); + } -+ ++ grub_dprintf ("slaunch", "TXT HEAP init done\n"); + /* + * TODO: TXT spec: Note: BiosDataSize + OsMleDataSize + OsSinitDataSize + SinitMleDataSize + * must be less than or equal to TXT.HEAP.SIZE, TXT spec, p. 102. @@ -770,11 +789,16 @@ index 000000000000..201167ce9a44 +void +grub_txt_state_show (void) +{ -+ grub_uint64_t data; -+ grub_uint8_t *data8 = (grub_uint8_t *) &data; ++ union { ++ grub_uint64_t d64; ++ grub_uint32_t d32; ++ grub_uint8_t d8; ++ grub_uint8_t a8[8]; ++ } data; + int i; ++ union grub_txt_didvid didvid; + -+ data = grub_txt_reg_pub_readq (GRUB_TXT_STS); ++ data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_STS); + grub_printf (" TXT.STS: 0x%016" PRIxGRUB_UINT64_T "\n" + " SENTER.DONE.STS: %d\n" + " SEXIT.DONE.STS: %d\n" @@ -782,88 +806,86 @@ index 000000000000..201167ce9a44 + " PRIVATEOPEN.STS: %d\n" + " TXT.LOCALITY1.OPEN.STS: %d\n" + " TXT.LOCALITY2.OPEN.STS: %d\n", -+ data, !!(data & GRUB_TXT_STS_SENTER_DONE), -+ !!(data & GRUB_TXT_STS_SEXIT_DONE), -+ !!(data & GRUB_TXT_STS_MEM_CONFIG_LOCK), -+ !!(data & GRUB_TXT_STS_PRIVATE_OPEN), -+ !!(data & GRUB_TXT_STS_LOCALITY1_OPEN), -+ !!(data & GRUB_TXT_STS_LOCALITY2_OPEN)); ++ data.d64, !!(data.d64 & GRUB_TXT_STS_SENTER_DONE), ++ !!(data.d64 & GRUB_TXT_STS_SEXIT_DONE), ++ !!(data.d64 & GRUB_TXT_STS_MEM_CONFIG_LOCK), ++ !!(data.d64 & GRUB_TXT_STS_PRIVATE_OPEN), ++ !!(data.d64 & GRUB_TXT_STS_LOCALITY1_OPEN), ++ !!(data.d64 & GRUB_TXT_STS_LOCALITY2_OPEN)); + + /* Only least significant byte has a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_ESTS) & 0x00000000000000ff; -+ grub_printf (" TXT.ESTS: 0x%02" PRIxGRUB_UINT64_T "\n" -+ " TXT_RESET.STS: %d\n", data, -+ !!(data & GRUB_TXT_ESTS_TXT_RESET)); ++ data.d8 = grub_txt_reg_pub_readb (GRUB_TXT_ESTS); ++ grub_printf (" TXT.ESTS: 0x%02x\n" ++ " TXT_RESET.STS: %d\n", data.d8, ++ !!(data.d8 & GRUB_TXT_ESTS_TXT_RESET)); + -+ data = grub_txt_reg_pub_readq (GRUB_TXT_E2STS); ++ data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_E2STS); + grub_printf (" TXT.E2STS: 0x%016" PRIxGRUB_UINT64_T "\n" -+ " SECRETS.STS: %d\n", data, -+ !!(data & GRUB_TXT_E2STS_SECRETS)); ++ " SECRETS.STS: %d\n", data.d64, ++ !!(data.d64 & GRUB_TXT_E2STS_SECRETS)); + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_ERRORCODE) & 0x00000000ffffffff; -+ grub_printf (" TXT.ERRORCODE: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_ERRORCODE); ++ grub_printf (" TXT.ERRORCODE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + -+ data = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); ++ didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); + grub_printf (" TXT.DIDVID: 0x%016" PRIxGRUB_UINT64_T "\n" -+ " VID: 0x%04" PRIxGRUB_UINT64_T "\n" -+ " DID: 0x%04" PRIxGRUB_UINT64_T "\n" -+ " RID: 0x%04" PRIxGRUB_UINT64_T "\n" -+ " ID-EXT: 0x%04" PRIxGRUB_UINT64_T "\n", -+ data, data & 0x000000000000ffff, -+ (data & 0x00000000ffff0000) >> 16, -+ (data & 0x0000ffff00000000) >> 32, data >> 48); ++ " VID: 0x%04x\n" ++ " DID: 0x%04x\n" ++ " RID: 0x%04x\n" ++ " ID-EXT: 0x%04x\n", ++ didvid.value, didvid.vid, didvid.did, didvid.rid, didvid.id_ext); + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_VER_FSBIF) & 0x00000000ffffffff; -+ grub_printf (" TXT.VER.FSBIF: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF); ++ grub_printf (" TXT.VER.FSBIF: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + -+ if ((data != 0x00000000) && (data != 0xffffffff)) -+ grub_printf (" DEBUG.FUSE: %d\n", !!(data & GRUB_TXT_VER_FSBIF_DEBUG_FUSE)); ++ if ((data.d32 != 0x00000000) && (data.d32 != 0xffffffff)) ++ grub_printf (" DEBUG.FUSE: %d\n", !!(data.d32 & GRUB_TXT_VER_FSBIF_DEBUG_FUSE)); + else + { + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_VER_QPIIF) & 0x00000000ffffffff; -+ grub_printf (" TXT.VER.QPIIF: 0x%08" PRIxGRUB_UINT64_T "\n" -+ " DEBUG.FUSE: %d\n", data, -+ !!(data & GRUB_TXT_VER_QPIIF_DEBUG_FUSE)); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF); ++ grub_printf (" TXT.VER.QPIIF: 0x%08" PRIxGRUB_UINT32_T "\n" ++ " DEBUG.FUSE: %d\n", data.d32, ++ !!(data.d32 & GRUB_TXT_VER_QPIIF_DEBUG_FUSE)); + } + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_SINIT_BASE) & 0x00000000ffffffff; -+ grub_printf (" TXT.SINIT.BASE: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_SINIT_BASE); ++ grub_printf (" TXT.SINIT.BASE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_SINIT_SIZE) & 0x00000000ffffffff; -+ grub_printf (" TXT.SINIT.SIZE: %" PRIuGRUB_UINT64_T -+ " B (0x%" PRIxGRUB_UINT64_T ")\n", data, data); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_SINIT_SIZE); ++ grub_printf (" TXT.SINIT.SIZE: %" PRIuGRUB_UINT32_T ++ " B (0x%" PRIxGRUB_UINT32_T ")\n", data.d32, data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE) & 0x00000000ffffffff; -+ grub_printf (" TXT.HEAP.BASE: 0x%08" PRIxGRUB_UINT64_T "\n", data); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); ++ grub_printf (" TXT.HEAP.BASE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_SIZE) & 0x00000000ffffffff; -+ grub_printf (" TXT.HEAP.SIZE: %" PRIuGRUB_UINT64_T -+ " B (0x%" PRIxGRUB_UINT64_T ")\n", data, data); ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE); ++ grub_printf (" TXT.HEAP.SIZE: %" PRIuGRUB_UINT32_T ++ " B (0x%" PRIxGRUB_UINT32_T ")\n", data.d32, data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_DPR) & 0x00000000ffffffff; -+ grub_printf (" TXT.DPR: 0x%08" PRIxGRUB_UINT64_T "\n" ++ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_DPR); ++ grub_printf (" TXT.DPR: 0x%08" PRIxGRUB_UINT32_T "\n" + " LOCK: %d\n" -+ " TOP: 0x%08" PRIxGRUB_UINT64_T "\n" -+ " SIZE: %" PRIuGRUB_UINT64_T " MiB\n", -+ data, !!(data & (1 << 0)), (data & 0xfff00000), -+ (data & 0x00000ff0) >> 4); ++ " TOP: 0x%08" PRIxGRUB_UINT32_T "\n" ++ " SIZE: %" PRIuGRUB_UINT32_T " MiB\n", ++ data.d32, !!(data.d32 & (1 << 0)), (data.d32 & 0xfff00000), ++ (data.d32 & 0x00000ff0) >> 4); + + grub_printf (" TXT.PUBLIC.KEY:\n"); + + for (i = 0; i < 4; ++i) + { + /* TODO: Check relevant MSRs on SGX platforms. */ -+ data = grub_txt_reg_pub_readq (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t)); -+ grub_printf (" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x%s", data8[0], data8[1], -+ data8[2], data8[3], data8[4], data8[5], data8[6], data8[7], ++ data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t)); ++ grub_printf (" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x%s", data.a8[0], data.a8[1], ++ data.a8[2], data.a8[3], data.a8[4], data.a8[5], data.a8[6], data.a8[7], + (i < 3) ? ":\n" : "\n"); + } +} @@ -880,11 +902,14 @@ index 000000000000..201167ce9a44 + if (sinit_base == NULL) + return grub_errno; + ++ grub_dprintf ("slaunch", "Init TXT heap\n"); + err = init_txt_heap (slparams, sinit_base); + + if (err != GRUB_ERR_NONE) + return err; + ++ grub_dprintf ("slaunch", "TXT heap successfully prepared\n"); ++ + /* Update the MLE header. */ + mle_header = (struct grub_txt_mle_header *)(grub_addr_t) (slparams->mle_start + slparams->mle_header_offset); + mle_header->first_valid_page = 0; @@ -893,16 +918,21 @@ index 000000000000..201167ce9a44 + slparams->sinit_acm_base = (grub_uint32_t)(grub_addr_t) sinit_base; + slparams->sinit_acm_size = sinit_base->size * 4; + -+ grub_tpm_relinquish_lcl (0); ++ grub_tpm_relinquish_locality (0); ++ grub_dprintf ("slaunch", "TPM locality reliquished\n"); + + err = set_mtrrs_for_acmod (sinit_base); + if (err) + return grub_error (err, N_("secure launch failed to set MTRRs for ACM")); + ++ grub_dprintf ("slaunch", "MTRRs set for ACMOD\n"); ++ + err = grub_txt_prepare_cpu (); + if ( err ) + return err; + ++ grub_dprintf ("slaunch", "CPU prepared for secure launch\n"); ++ + if (!(grub_rdmsr (GRUB_MSR_X86_APICBASE) & GRUB_MSR_X86_APICBASE_BSP)) + return grub_error (GRUB_ERR_BAD_DEVICE, N_("secure launch must run on BSP")); + @@ -933,6 +963,62 @@ index c64529630f19..56f64855be7e 100644 struct grub_e820_mmap_entry { grub_uint64_t addr; +diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h +index f2552ecbc6d4..99e2c6f675b3 100644 +--- a/include/grub/i386/msr.h ++++ b/include/grub/i386/msr.h +@@ -31,6 +31,7 @@ + #define GRUB_MSR_X86_APICBASE_BASE (0xfffff<<12) + + #define GRUB_MSR_X86_FEATURE_CONTROL 0x0000003a ++#define GRUB_MSR_X86_FEATURE_CTRL_LOCK (1<<0) + #define GRUB_MSR_X86_ENABLE_VMX_IN_SMX (1<<1) + #define GRUB_MSR_X86_SENTER_FUNCTIONS (0x7f<<8) + #define GRUB_MSR_X86_SENTER_ENABLE (1<<15) +diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h +index 7d57af68841f..7a54632bede9 100644 +--- a/include/grub/i386/txt.h ++++ b/include/grub/i386/txt.h +@@ -235,7 +235,7 @@ union grub_txt_didvid + }; + } GRUB_PACKED; + +-#define GRUB_TXT_VERSION_DEBUG_FUSED (1<<31) ++#define GRUB_TXT_VERSION_PROD_FUSED (1<<31) + + /* Appendix C Intel TXT Heap Memory */ + +@@ -467,16 +467,28 @@ struct grub_txt_heap_event_log_ptr_elt2_1 + + /* TXT register and heap access */ + ++static inline grub_uint8_t ++grub_txt_reg_pub_readb (grub_uint32_t reg) ++{ ++ return grub_readb (GRUB_TXT_CFG_REGS_PUB + reg); ++} ++ ++static inline grub_uint32_t ++grub_txt_reg_pub_readl (grub_uint32_t reg) ++{ ++ return grub_readl (GRUB_TXT_CFG_REGS_PUB + reg); ++} ++ + static inline grub_uint64_t + grub_txt_reg_pub_readq (grub_uint32_t reg) + { +- return grub_readq ((void *) (GRUB_TXT_CFG_REGS_PUB + reg)); ++ return grub_readq (GRUB_TXT_CFG_REGS_PUB + reg); + } + + static inline grub_uint8_t * + grub_txt_get_heap (void) + { +- return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE); ++ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); + } + + static inline grub_uint64_t -- 2.17.1 diff --git a/1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch b/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch similarity index 57% rename from 1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch rename to 1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch index 9116c07..b6ee390 100644 --- a/1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch +++ b/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch @@ -1,21 +1,22 @@ -From 2ff5828c221797a0165f7f9fd1459457ee1b499f Mon Sep 17 00:00:00 2001 +From b04efb5f9dfd96bc290109ddb6170822bc55dd6b Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:59:18 -0400 -Subject: [PATCH 1112/1118] i386/txt: Add Intel TXT ACM module support +Subject: [PATCH] i386/txt: Add Intel TXT ACM module support Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper +Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/acmod.c | 575 ++++++++++++++++++++++++++++++ - 1 file changed, 575 insertions(+) + grub-core/loader/i386/txt/acmod.c | 590 ++++++++++++++++++++++++++++++ + 1 file changed, 590 insertions(+) create mode 100644 grub-core/loader/i386/txt/acmod.c diff --git a/grub-core/loader/i386/txt/acmod.c b/grub-core/loader/i386/txt/acmod.c new file mode 100644 -index 000000000000..ed2fbab7b0da +index 000000000000..1611b33d4c96 --- /dev/null +++ b/grub-core/loader/i386/txt/acmod.c -@@ -0,0 +1,575 @@ +@@ -0,0 +1,590 @@ +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules @@ -76,6 +77,7 @@ index 000000000000..ed2fbab7b0da +#include +#include +#include ++#include +#include +#include +#include @@ -83,211 +85,181 @@ index 000000000000..ed2fbab7b0da +#include + +/* -+ * This checks to see if two numbers multiplied together are larger -+ * than the type that they are. Returns TRUE if OVERFLOWING. -+ * If the first parameter "x" is greater than zero and -+ * if that is true, that the largest possible value 0xFFFFFFFF / "x" -+ * is less than the second parameter "y". If "y" is zero then -+ * it will also fail because no unsigned number is less than zero. ++ * Returns hdr + offset if [offset, offset + count * size) is within the bounds ++ * of the ACM, NULL otherwise. + */ -+static inline int -+multiply_overflow_u32 (grub_uint32_t x, grub_uint32_t y) ++static void* ++n_fit_in_acm (struct grub_txt_acm_header *hdr, grub_uint32_t offset, ++ grub_uint32_t size, grub_uint32_t count) +{ -+ /* Use x instead of (x > 0)? */ -+ return (x > 0) ? ((((grub_uint32_t)(~0))/x) < y) : 0; ++ grub_uint32_t total_size, ret_u32, elem_end; ++ /* ACM size overflow was checked in is_acmod() */ ++ grub_uint32_t acm_len = hdr->size * 4; ++ ++ /* To simplify rest of the code check if offset is non-0 here */ ++ if ( offset == 0 ) ++ return NULL; ++ ++ if ( grub_mul (size, count, &total_size) ) ++ return NULL; ++ ++ if ( grub_add (offset, total_size, &elem_end) ) ++ return NULL; ++ ++ if ( elem_end > acm_len ) ++ return NULL; ++ ++ if ( grub_add ((grub_uint32_t)(unsigned long)hdr, offset, &ret_u32) ) ++ return NULL; ++ ++ /* Not checking if (hdr + elem_end) overflows. We know that (hdr + acm_len) ++ * doesn't, and that elem_end <= acm_len. */ ++ ++ return (void *)(unsigned long)ret_u32; +} + -+/* -+ * These three "plus overflow" functions take a "x" value -+ * and add the "y" value to it and if the two values are -+ * greater than the size of the variable type, they will -+ * overflow the type and end up with a smaller value and -+ * return TRUE - that they did overflow. i.e. -+ */ -+static inline int plus_overflow_u32 (grub_uint32_t x, grub_uint32_t y) ++static void* ++fits_in_acm (struct grub_txt_acm_header *hdr, grub_uint32_t offset, ++ grub_uint32_t size) +{ -+ return ((((grub_uint32_t)(~0)) - x) < y); ++ return n_fit_in_acm(hdr, offset, size, 1); +} + ++/* ++ * Macro that returns value of it->field if it's inside info table, 0 otherwise. ++ * Fields at or below 'length' ('uuid', 'chipset_acm_type', 'version') don't ++ * benefit from this macro, because it requires that 'length' (and by extension ++ * fields below that) is valid. ++ */ ++#define info_table_offset(it, field) \ ++ (__builtin_offsetof(struct grub_txt_acm_info_table, field) + sizeof(it->field)\ ++ <= it->length ? it->field : 0) ++ ++/* ++ * Returns pointer to ACM information table. If the table is located outside of ++ * ACM or its reported size is too small to cover at least 'length' field, ++ * NULL is returned instead. ++ */ +static struct grub_txt_acm_info_table* +get_acmod_info_table (struct grub_txt_acm_header* hdr) +{ -+ grub_uint32_t user_area_off; ++ grub_uint32_t user_area_off, info_table_size; ++ struct grub_txt_acm_info_table *ptr = NULL; ++ /* Minimum size required to read full size of table */ ++ info_table_size = __builtin_offsetof (struct grub_txt_acm_info_table, length) ++ + sizeof(ptr->length); + + /* Overflow? */ -+ if ( plus_overflow_u32 (hdr->header_len, hdr->scratch_size) ) ++ if ( grub_add (hdr->header_len, hdr->scratch_size, &user_area_off) ) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM header length plus scratch size overflows")); + return NULL; + } + -+ if ( multiply_overflow_u32 ((hdr->header_len + hdr->scratch_size), 4) ) ++ if ( grub_mul (user_area_off, 4, &user_area_off) ) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM header length and scratch size in bytes overflows")); + return NULL; + } + -+ /* -+ * This fn assumes that the ACM has already passed at least the initial -+ * is_acmod() checks. -+ */ -+ -+ user_area_off = (hdr->header_len + hdr->scratch_size) * 4; -+ -+ /* Overflow? */ -+ if ( plus_overflow_u32 (user_area_off, sizeof(struct grub_txt_acm_info_table)) ) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("user_area_off plus acm_info_table_t size overflows")); -+ return NULL; -+ } ++ ptr = fits_in_acm(hdr, user_area_off, info_table_size); + -+ /* Check that table is within module. */ -+ if ( user_area_off + sizeof(struct grub_txt_acm_info_table) > hdr->size * 4 ) ++ if ( ptr != NULL ) + { -+ /* TODO: Is (grub_uint32_t) correct??? */ -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM info table size too large: %x > %x"), -+ user_area_off + (grub_uint32_t)sizeof(struct grub_txt_acm_info_table), hdr->size * 4); -+ return NULL; -+ } ++ if ( info_table_offset (ptr, length) < info_table_size ) ++ return NULL; + -+ /* Overflow? */ -+ if ( plus_overflow_u32 ((grub_uint32_t)(unsigned long)hdr, user_area_off) ) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("hdr plus user_area_off overflows")); -+ return NULL; ++ info_table_size = info_table_offset (ptr, length); ++ ptr = fits_in_acm(hdr, user_area_off, info_table_size); + } + -+ return (struct grub_txt_acm_info_table *)((unsigned long)hdr + user_area_off); ++ return ptr; +} + ++/* Function returns pointer to chipset ID list, after checking that ++ * grub_txt_acm_chipset_id_list and all grub_txt_acm_chipset_id structures are ++ * within ACM. Otherwise, NULL is returned. */ +static struct grub_txt_acm_chipset_id_list* +get_acmod_chipset_list (struct grub_txt_acm_header *hdr) +{ + struct grub_txt_acm_info_table *info_table; -+ grub_uint32_t size, id_list_off; ++ grub_uint32_t id_entries_off; + struct grub_txt_acm_chipset_id_list *chipset_id_list; + + /* This fn assumes that the ACM has already passed the is_acmod() checks */ + + info_table = get_acmod_info_table (hdr); -+ if ( !info_table ) -+ return NULL; -+ id_list_off = info_table->chipset_id_list; -+ -+ size = hdr->size * 4; -+ -+ /* Overflow? */ -+ if ( plus_overflow_u32 (id_list_off, sizeof(struct grub_txt_acm_chipset_id)) ) ++ if ( info_table == NULL ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("id_list_off plus acm_chipset_id_t size overflows")); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM info table out of bounds")); + return NULL; + } + -+ /* Check that chipset id table is w/in ACM */ -+ if ( id_list_off + sizeof(struct grub_txt_acm_chipset_id) > size ) ++ chipset_id_list = fits_in_acm(hdr, info_table_offset (info_table, chipset_id_list), ++ sizeof(struct grub_txt_acm_chipset_id_list)); ++ if ( chipset_id_list == NULL ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("chipset id list is too big: %x"), id_list_off); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID list out of bounds")); + return NULL; + } + -+ /* Overflow? */ -+ if ( plus_overflow_u32 ((grub_uint32_t)(unsigned long)hdr, id_list_off) ) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("hdr plus id_list_off overflows")); -+ return NULL; -+ } -+ -+ chipset_id_list = (struct grub_txt_acm_chipset_id_list*) -+ ((unsigned long)hdr + id_list_off); -+ + /* Overflows? */ -+ if ( multiply_overflow_u32 (chipset_id_list->count, -+ sizeof(struct grub_txt_acm_chipset_id)) ) ++ if ( grub_add (info_table->chipset_id_list, ++ sizeof(struct grub_txt_acm_chipset_id_list), &id_entries_off)) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of acm_chipset_id_list overflows")); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID entries out of bounds")); + return NULL; + } + -+ if ( plus_overflow_u32 (id_list_off + sizeof(struct grub_txt_acm_chipset_id), -+ chipset_id_list->count * sizeof(struct grub_txt_acm_chipset_id)) ) ++ if ( n_fit_in_acm( hdr, id_entries_off, sizeof(struct grub_txt_acm_chipset_id), ++ chipset_id_list->count ) == NULL ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of all entries overflows")); -+ return NULL; -+ } -+ -+ /* Check that all entries are w/in ACM */ -+ if ( id_list_off + sizeof(struct grub_txt_acm_chipset_id) + -+ chipset_id_list->count * sizeof(struct grub_txt_acm_chipset_id) > size ) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset id entries are too big: %x"), -+ chipset_id_list->count); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID entries out of bounds")); + return NULL; + } + + return chipset_id_list; +} + ++/* Function returns pointer to processor ID list, after checking that ++ * grub_txt_acm_processor_id_list and all grub_txt_acm_processor_id structures ++ * are within ACM. Otherwise, NULL is returned. */ +static struct grub_txt_acm_processor_id_list* +get_acmod_processor_list (struct grub_txt_acm_header* hdr) +{ + struct grub_txt_acm_info_table *info_table; -+ grub_uint32_t size, id_list_off; ++ grub_uint32_t id_entries_off; + struct grub_txt_acm_processor_id_list *proc_id_list; + + /* This fn assumes that the ACM has already passed the is_acmod() checks */ + + info_table = get_acmod_info_table(hdr); + if ( info_table == NULL ) -+ return NULL; -+ id_list_off = info_table->processor_id_list; -+ -+ size = hdr->size * 4; -+ -+ /* Overflow? */ -+ if ( plus_overflow_u32 (id_list_off, sizeof(struct grub_txt_acm_processor_id)) ) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("id_list_off plus acm_processor_id_t size overflows")); -+ return NULL; -+ } -+ -+ /* Check that processor id table is w/in ACM */ -+ if ( id_list_off + sizeof(struct grub_txt_acm_processor_id) > size ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor id list is too big: %x"), id_list_off); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM info table out of bounds")); + return NULL; + } + -+ /* Overflow? */ -+ if ( plus_overflow_u32 ((unsigned long)hdr, id_list_off) ) ++ proc_id_list = fits_in_acm(hdr, info_table_offset (info_table, processor_id_list), ++ sizeof(struct grub_txt_acm_processor_id_list)); ++ if ( proc_id_list == NULL ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("hdr plus id_list_off overflows")); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID list out of bounds")); + return NULL; + } + -+ proc_id_list = (struct grub_txt_acm_processor_id_list *) -+ ((unsigned long)hdr + id_list_off); -+ + /* Overflows? */ -+ if ( multiply_overflow_u32 (proc_id_list->count, -+ sizeof(struct grub_txt_acm_processor_id)) ) ++ if ( grub_add (info_table->processor_id_list, ++ sizeof(struct grub_txt_acm_processor_id_list), &id_entries_off)) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of acm_processor_id_list overflows")); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID entries out of bounds")); + return NULL; + } + -+ if ( plus_overflow_u32 (id_list_off + sizeof(struct grub_txt_acm_processor_id), -+ proc_id_list->count * sizeof(struct grub_txt_acm_processor_id)) ) ++ if ( n_fit_in_acm ( hdr, id_entries_off, sizeof(struct grub_txt_acm_processor_id), ++ proc_id_list->count ) == NULL ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size of all entries overflows")); -+ return NULL; -+ } -+ -+ /* Check that all entries are w/in ACM */ -+ if ( id_list_off + sizeof(struct grub_txt_acm_processor_id) + -+ proc_id_list->count * sizeof(struct grub_txt_acm_processor_id) > size ) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor id entries are too big: %x"), -+ proc_id_list->count); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID entries out of bounds")); + return NULL; + } + @@ -300,34 +272,46 @@ index 000000000000..ed2fbab7b0da +{ + struct grub_txt_acm_header *acm_hdr = (struct grub_txt_acm_header *)acmod_base; + struct grub_txt_acm_info_table *info_table; ++ grub_uint32_t size_from_hdr; + + /* First check size */ + if ( acmod_size < sizeof (struct grub_txt_acm_header) ) + return 0; + + /* Then check overflow */ -+ if ( multiply_overflow_u32 (acm_hdr->size, 4) ) ++ if ( grub_mul (acm_hdr->size, 4, &size_from_hdr) ) + return 0; + + /* Then check size equivalency */ -+ if ( acmod_size != acm_hdr->size * 4 ) ++ if ( acmod_size != size_from_hdr ) + return 0; + -+ /* Then check type and vendor */ ++ /* Then check type, sub-type and vendor */ + if ( (acm_hdr->module_type != GRUB_TXT_ACM_MODULE_TYPE) || ++ (acm_hdr->module_sub_type != GRUB_TXT_ACM_MODULE_SUB_TYPE_TXT_ACM) || + (acm_hdr->module_vendor != GRUB_TXT_ACM_MODULE_VENDOR_INTEL) ) + return 0; + + info_table = get_acmod_info_table (acm_hdr); -+ if ( !info_table ) ++ if ( info_table == NULL ) + return 0; + + /* Check if ACM UUID is present */ + if ( grub_memcmp (&(info_table->uuid), GRUB_TXT_ACM_UUID, 16) ) + return 0; + ++ /* ++ * TXT specification doesn't give clear mapping of info table size to version, ++ * so just warn if the size is different than expected but try to use it ++ * anyway. info_table_offset() macro does enough testing to not read outside ++ * of info table. ++ */ ++ if ( info_table->length < sizeof(struct grub_txt_acm_info_table) ) ++ grub_dprintf ("slaunch", "Info table size (%x) smaller than expected (%x)\n", ++ info_table->length, sizeof(struct grub_txt_acm_info_table)); ++ + if ( type_out ) -+ *type_out = info_table->chipset_acm_type; ++ *type_out = info_table_offset (info_table, chipset_acm_type); + + return 1; +} @@ -338,13 +322,19 @@ index 000000000000..ed2fbab7b0da + grub_uint8_t *txt_heap = grub_txt_get_heap (); + struct grub_txt_bios_data *bios_data = grub_txt_bios_data_start (txt_heap); + struct grub_txt_acm_header *bios_sinit; ++ grub_uint32_t tmp; + -+ if ( !sinit_region_base ) -+ return NULL; ++ if ( sinit_region_base == NULL ) ++ return NULL; + + if ( bios_data->bios_sinit_size == 0 ) + return NULL; + ++ /* Check if ACM crosses 4G */ ++ if ( grub_add ( (unsigned long)sinit_region_base, bios_data->bios_sinit_size, ++ &tmp) ) ++ return NULL; ++ + /* BIOS has loaded an SINIT module, so verify that it is valid */ + grub_dprintf ("slaunch", "BIOS has already loaded an SINIT module\n"); + @@ -363,13 +353,13 @@ index 000000000000..ed2fbab7b0da +{ + static struct grub_txt_acm_info_table *info_table; + -+ /* Assumes that it passed is_sinit_acmod() */ ++ /* Assumes that it passed grub_txt_is_sinit_acmod() */ + info_table = get_acmod_info_table (hdr); + + if ( info_table == NULL ) + return 0; + -+ return info_table->os_sinit_data_ver; ++ return info_table_offset (info_table, os_sinit_data_ver); +} + +grub_uint32_t @@ -383,7 +373,7 @@ index 000000000000..ed2fbab7b0da + if ( info_table == NULL || info_table->version < 3 ) + return 0; + -+ return info_table->capabilities; ++ return info_table_offset (info_table, capabilities); +} + +int @@ -400,22 +390,38 @@ index 000000000000..ed2fbab7b0da + return 1; +} + -+/* Format of VER.FSBIF and VER.QPIIF registers. */ -+typedef union { -+ grub_uint64_t _raw; -+ struct { -+ grub_uint64_t reserved : 31; -+ grub_uint64_t prod_fused : 1; -+ }; -+} grub_txt_ver_fsbif_qpiif_t; ++static int ++didvid_matches(union grub_txt_didvid didvid, ++ struct grub_txt_acm_chipset_id *chipset_id) ++{ ++ if ( didvid.vid != chipset_id->vendor_id ) ++ return 0; ++ ++ if ( didvid.did != chipset_id->device_id ) ++ return 0; ++ ++ /* If RevisionIdMask is 0, the RevisionId field must exactly match the ++ * TXT.DIDVID.RID field. */ ++ if ( (chipset_id->flags & GRUB_TXT_ACM_REVISION_ID_MASK) == 0 && ++ ( didvid.rid == chipset_id->revision_id ) ) ++ return 1; ++ ++ /* If RevisionIdMask is 1, the RevisionId field is a bitwise mask that can be ++ * used to test for any bits set in the TXT.DIDVID.RID field. If any bits are ++ * set, the RevisionId is a match. */ ++ if ( (chipset_id->flags & GRUB_TXT_ACM_REVISION_ID_MASK) != 0 && ++ ( didvid.rid & chipset_id->revision_id ) != 0 ) ++ return 1; ++ ++ return 0; ++} + +int +grub_txt_acmod_match_platform (struct grub_txt_acm_header *hdr) +{ + union grub_txt_didvid didvid; -+ grub_uint32_t fms, ign, i; ++ grub_uint32_t fms, ign, i, ver; + grub_uint64_t platform_id; -+ grub_txt_ver_fsbif_qpiif_t ver; + struct grub_txt_acm_chipset_id_list *chipset_id_list; + struct grub_txt_acm_chipset_id *chipset_id; + struct grub_txt_acm_processor_id_list *proc_id_list; @@ -423,18 +429,21 @@ index 000000000000..ed2fbab7b0da + struct grub_txt_acm_info_table *info_table; + + /* This fn assumes that the ACM has already passed the is_acmod() checks */ ++ info_table = get_acmod_info_table (hdr); ++ if ( info_table == NULL ) ++ return 0; + + /* Get chipset fusing, device, and vendor id info */ + didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); + -+ ver._raw = grub_txt_reg_pub_readq (GRUB_TXT_VER_FSBIF); -+ if ( (ver._raw & 0xffffffff) == 0xffffffff || -+ (ver._raw & 0xffffffff) == 0x00 ) /* Need to use VER.QPIIF */ -+ ver._raw = grub_txt_reg_pub_readq (GRUB_TXT_VER_QPIIF); ++ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF); ++ if ( ver == 0xffffffff || ver == 0x00 ) /* Need to use VER.QPIIF */ ++ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF); + -+ grub_dprintf ("slaunch", "chipset production fused: %x, " ++ grub_dprintf ("slaunch", "chipset production fused: %s, " + "chipset vendor: 0x%x, device: 0x%x, revision: 0x%x\n", -+ ver.prod_fused, didvid.vid, didvid.did, didvid.rid); ++ (ver & GRUB_TXT_VERSION_PROD_FUSED) ? "yes" : "no" , didvid.vid, ++ didvid.did, didvid.rid); + + grub_cpuid (1, fms, ign, ign, ign); + platform_id = grub_rdmsr (GRUB_MSR_X86_PLATFORM_ID); @@ -446,8 +455,8 @@ index 000000000000..ed2fbab7b0da + * Check if chipset fusing is same. Note the DEBUG.FUSE bit in the version + * is 0 when debug fused so the logic below checking a mismatch is valid. + */ -+ if ( (ver._raw & GRUB_TXT_VERSION_DEBUG_FUSED) && -+ (hdr->flags & GRUB_TXT_ACM_FLAG_DEBUG_SIGNED) ) ++ if ( !!(ver & GRUB_TXT_VERSION_PROD_FUSED) == ++ !!(hdr->flags & GRUB_TXT_ACM_FLAG_DEBUG_SIGNED) ) + { + grub_error (GRUB_ERR_BAD_DEVICE, N_("production/debug mismatch between chipset and ACM")); + return 0; @@ -455,7 +464,7 @@ index 000000000000..ed2fbab7b0da + + /* Check if chipset vendor/device/revision IDs match */ + chipset_id_list = get_acmod_chipset_list (hdr); -+ if ( !chipset_id_list ) ++ if ( chipset_id_list == NULL ) + return 0; + + grub_dprintf ("slaunch", "%d SINIT ACM chipset id entries:\n", chipset_id_list->count); @@ -468,36 +477,43 @@ index 000000000000..ed2fbab7b0da + chipset_id->device_id, chipset_id->flags, + chipset_id->revision_id, chipset_id->extended_id); + -+ if ( (didvid.vid == chipset_id->vendor_id ) && -+ (didvid.did == chipset_id->device_id ) && -+ ( ( ( (chipset_id->flags & GRUB_TXT_ACM_REVISION_ID_MASK) == 0) && -+ (didvid.rid == chipset_id->revision_id) ) || -+ ( ( (chipset_id->flags & GRUB_TXT_ACM_REVISION_ID_MASK) == 1) && -+ ( (didvid.rid & chipset_id->revision_id) != 0 ) ) ) ) -+ break; ++ if ( didvid_matches ( didvid, chipset_id) ) ++ break; + } + + if ( i >= chipset_id_list->count ) + { -+ grub_error (GRUB_ERR_BAD_DEVICE, N_("chipset id mismatch")); ++ /* ++ * Version 9 introduces flexible ACM information table format, not yet ++ * supported by this code. ++ * ++ * TXT spec says that 9 will be the final version and further changes will ++ * be reflected elsewhere, but check for higher values too in case they ++ * change their mind. ++ */ ++ if ( info_table->version >= 9 ) ++ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ N_("chipset id mismatch, flexible ACM info list may contain" ++ " matching entry but it isn't yet supported by code")); ++ else ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("chipset id mismatch")); ++ + return 0; + } + -+ /* Check if processor family/model/stepping and platform IDs match */ -+ info_table = get_acmod_info_table (hdr); -+ if ( !info_table ) -+ return 0; -+ + /* -+ * Logic inverted from oringal to avoid the if block. Not sure what drives -+ * the logic of not checking processor infrmation for version 4 or less. ++ * Unfortunately the spec isn't too clear on what the changes to the info ++ * table were, across the different versions, but an old version of the entire ++ * spec document shows that the processor table field didn't exist when the ++ * latest version of the info table was 3. + */ + if ( info_table->version < 4 ) + return 1; + ++ /* Check if processor family/model/stepping and platform IDs match */ + proc_id_list = get_acmod_processor_list(hdr); -+ if ( !proc_id_list ) -+ return 1; ++ if ( proc_id_list == NULL ) ++ return 0; + + grub_dprintf ("slaunch", "%d SINIT ACM processor id entries:\n", proc_id_list->count); + @@ -515,7 +531,7 @@ index 000000000000..ed2fbab7b0da + + if ( i >= proc_id_list->count ) + { -+ grub_error (GRUB_ERR_BAD_DEVICE, N_("chipset id mismatch")); ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("processor id mismatch")); + return 0; + } + @@ -527,10 +543,10 @@ index 000000000000..ed2fbab7b0da +{ + struct grub_txt_acm_header *bios_sinit; + void *sinit_region_base; -+ grub_uint32_t sinit_region_size; ++ grub_uint32_t sinit_size, sinit_region_size; + -+ sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_readq (GRUB_TXT_SINIT_BASE); -+ sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_readq (GRUB_TXT_SINIT_SIZE); ++ sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_SINIT_BASE); ++ sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_readl (GRUB_TXT_SINIT_SIZE); + + grub_dprintf ("slaunch", "TXT.SINIT.BASE: %p\nTXT.SINIT.SIZE: 0x%" + PRIxGRUB_UINT32_T "\n", sinit_region_base, sinit_region_size); @@ -573,21 +589,21 @@ index 000000000000..ed2fbab7b0da + + /* Our SINIT ACM is newer than BIOS one or BIOS does not have one. */ + -+ if (multiply_overflow_u32 (sinit->size, 4)) ++ if (grub_mul (sinit->size, 4, &sinit_size)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("SINIT ACM size in bytes overflows")); + return NULL; + } + -+ if ((sinit->size * 4) > sinit_region_size) ++ if (sinit_size > sinit_region_size) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + N_("SINIT ACM does not fit into final resting place: 0x%" -+ PRIxGRUB_UINT32_T "\n"), sinit->size * 4); ++ PRIxGRUB_UINT32_T "\n"), sinit_size); + return NULL; + } + -+ grub_memcpy (sinit_region_base, sinit, sinit->size * 4); ++ grub_memcpy (sinit_region_base, sinit, sinit_size); + + return sinit_region_base; +} diff --git a/1113-i386-txt-Add-Intel-TXT-verification-routines.patch b/1112-i386-txt-Add-Intel-TXT-verification-routines.patch similarity index 91% rename from 1113-i386-txt-Add-Intel-TXT-verification-routines.patch rename to 1112-i386-txt-Add-Intel-TXT-verification-routines.patch index 84d6c02..e47f17b 100644 --- a/1113-i386-txt-Add-Intel-TXT-verification-routines.patch +++ b/1112-i386-txt-Add-Intel-TXT-verification-routines.patch @@ -1,21 +1,22 @@ -From 8287663cc69f939f6abc14e39cb8de7a6d89a93d Mon Sep 17 00:00:00 2001 +From 7238e5c808dcf90ccf813eb8d35a7060fb95c03f Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 14:46:17 -0400 -Subject: [PATCH 1113/1118] i386/txt: Add Intel TXT verification routines +Subject: [PATCH] i386/txt: Add Intel TXT verification routines Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper +Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/verify.c | 297 +++++++++++++++++++++++++++++ - 1 file changed, 297 insertions(+) + grub-core/loader/i386/txt/verify.c | 304 +++++++++++++++++++++++++++++ + 1 file changed, 304 insertions(+) create mode 100644 grub-core/loader/i386/txt/verify.c diff --git a/grub-core/loader/i386/txt/verify.c b/grub-core/loader/i386/txt/verify.c new file mode 100644 -index 000000000000..16b898041f65 +index 000000000000..d0af8d8bc4e5 --- /dev/null +++ b/grub-core/loader/i386/txt/verify.c -@@ -0,0 +1,297 @@ +@@ -0,0 +1,304 @@ +/* + * verify.c: verify that platform and processor supports Intel(r) TXT + * @@ -245,15 +246,15 @@ index 000000000000..16b898041f65 +grub_txt_verify_platform (void) +{ + grub_uint8_t *txt_heap; -+ grub_uint32_t eax, ebx, ecx, edx; -+ grub_uint64_t bios_size, heap_base, heap_size, msr; ++ grub_uint32_t eax, ebx, ecx, edx, errorcode, heap_base, heap_size; ++ grub_uint64_t bios_size, msr; + grub_err_t err = GRUB_ERR_NONE; + struct grub_txt_bios_data *bios_data; + struct grub_txt_heap_ext_data_element *elts; + + grub_cpuid (GRUB_X86_CPUID_FEATURES, eax, ebx, ecx, edx); + -+ if (!(ecx & GRUB_SMX_CPUID_FEATURE)) ++ if (!(ecx & GRUB_X86_CPUID_FEATURES_ECX_SMX)) + return grub_error (GRUB_ERR_BAD_DEVICE, N_("CPU does not support SMX")); + + msr = grub_rdmsr (GRUB_MSR_X86_FEATURE_CONTROL); @@ -271,7 +272,14 @@ index 000000000000..16b898041f65 + * Eventually need the verify_IA32_se_svn_status routine to be called here. + */ + -+ if (grub_txt_reg_pub_readq (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET) ++ errorcode = grub_txt_reg_pub_readl (GRUB_TXT_ERRORCODE); ++ /* 0 - no previous SENTER, 0xC0000001 - previous SENTER succeeded */ ++ if ( errorcode != 0 && errorcode != 0xC0000001 ) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("TXT_ERRORCODE reports failure: 0x%08" PRIxGRUB_UINT32_T), ++ errorcode); ++ ++ if (grub_txt_reg_pub_readb (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET) + return grub_error (GRUB_ERR_BAD_DEVICE, + N_("TXT_RESET.STS is set and GETSEC[SENTER] is disabled")); + @@ -281,8 +289,8 @@ index 000000000000..16b898041f65 + */ + + txt_heap = grub_txt_get_heap (); -+ heap_base = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE); -+ heap_size = grub_txt_reg_pub_readq (GRUB_TXT_HEAP_SIZE); ++ heap_base = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); ++ heap_size = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE); + + if ( txt_heap == NULL || heap_base == 0 || heap_size == 0 ) + return grub_error (GRUB_ERR_BAD_DEVICE, diff --git a/1114-i386-slaunch-Add-secure-launch-framework-and-command.patch b/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch similarity index 90% rename from 1114-i386-slaunch-Add-secure-launch-framework-and-command.patch rename to 1113-i386-slaunch-Add-secure-launch-framework-and-command.patch index aec1ddb..6199e25 100644 --- a/1114-i386-slaunch-Add-secure-launch-framework-and-command.patch +++ b/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch @@ -1,24 +1,26 @@ -From 32f19a720565b16cea3b7356d7c39d6c1614dcbd Mon Sep 17 00:00:00 2001 +From a01e6982379c8f1850bf3c1877568442bc8d6c76 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 15:01:00 -0400 -Subject: [PATCH 1114/1118] i386/slaunch: Add secure launch framework and - commands +Subject: [PATCH] i386/slaunch: Add secure launch framework and commands Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper +Signed-off-by: Krystian Hebel --- - grub-core/Makefile.am | 3 + - grub-core/Makefile.core.def | 15 +++ - grub-core/lib/i386/relocator32.S | 8 ++ - grub-core/loader/i386/bsd.c | 7 + - grub-core/loader/i386/linux.c | 213 ++++++++++++++++++++++++++++--- - grub-core/loader/i386/slaunch.c | 194 ++++++++++++++++++++++++++++ - grub-core/loader/i386/xnu.c | 3 + - grub-core/loader/multiboot.c | 5 + - include/grub/file.h | 3 + - include/grub/i386/linux.h | 14 +- - include/grub/i386/slaunch.h | 57 +++++++++ - 11 files changed, 506 insertions(+), 16 deletions(-) + grub-core/Makefile.am | 3 + + grub-core/Makefile.core.def | 15 ++ + grub-core/lib/i386/relocator32.S | 8 + + grub-core/loader/i386/bsd.c | 7 + + grub-core/loader/i386/coreboot/chainloader.c | 2 + + grub-core/loader/i386/linux.c | 213 +++++++++++++++++-- + grub-core/loader/i386/pc/plan9.c | 3 +- + grub-core/loader/i386/slaunch.c | 201 +++++++++++++++++ + grub-core/loader/i386/xnu.c | 3 + + grub-core/loader/multiboot.c | 5 + + include/grub/file.h | 3 + + include/grub/i386/linux.h | 14 +- + include/grub/i386/slaunch.h | 57 +++++ + 13 files changed, 517 insertions(+), 17 deletions(-) create mode 100644 grub-core/loader/i386/slaunch.c create mode 100644 include/grub/i386/slaunch.h @@ -51,10 +53,10 @@ index ee88e44e97a0..769bf013d47b 100644 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index e6b41ede92c4..b606496b26ef 100644 +index f482cc01e36e..7ebacaa3cefe 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -1831,6 +1831,15 @@ module = { +@@ -1816,6 +1816,15 @@ module = { enable = noemu; }; @@ -70,7 +72,7 @@ index e6b41ede92c4..b606496b26ef 100644 module = { name = fdt; efi = loader/efi/fdt.c; -@@ -2504,6 +2513,12 @@ module = { +@@ -2489,6 +2498,12 @@ module = { common = commands/testspeed.c; }; @@ -153,6 +155,26 @@ index 5f3290ce17bc..328b34635f78 100644 state.eip = entry; state.esp = stack_target; state.ebp = stack_target; +diff --git a/grub-core/loader/i386/coreboot/chainloader.c b/grub-core/loader/i386/coreboot/chainloader.c +index 0a19ebb9c3e5..dccd86b07bde 100644 +--- a/grub-core/loader/i386/coreboot/chainloader.c ++++ b/grub-core/loader/i386/coreboot/chainloader.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -47,6 +48,7 @@ grub_chain_boot (void) + grub_video_set_mode ("text", 0, 0); + + state.eip = entry; ++ state.edi = SLP_NONE; + return grub_relocator32_boot (relocator, state, 0); + } + diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 9f74a96b19ae..ba050de2d1df 100644 --- a/grub-core/loader/i386/linux.c @@ -524,12 +546,33 @@ index 9f74a96b19ae..ba050de2d1df 100644 linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; linux_params.kernel_alignment = (1 << align); linux_params.ps_mouse = linux_params.padding11 = 0; +diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c +index 37550155df78..cd8213a05d31 100644 +--- a/grub-core/loader/i386/pc/plan9.c ++++ b/grub-core/loader/i386/pc/plan9.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -84,7 +85,7 @@ grub_plan9_boot (void) + .ebx = 0, + .ecx = 0, + .edx = 0, +- .edi = 0, ++ .edi = SLP_NONE, + .esp = 0, + .ebp = 0, + .esi = 0 diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c new file mode 100644 -index 000000000000..72d09236b2ae +index 000000000000..9b2efd755f89 --- /dev/null +++ b/grub-core/loader/i386/slaunch.c -@@ -0,0 +1,194 @@ +@@ -0,0 +1,201 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -627,6 +670,10 @@ index 000000000000..72d09236b2ae + if (slp == SLP_NONE) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("secure launch not enabled")); + ++ if (slp > SLP_INTEL_TXT) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("unknown secure launch platform type: %d"), slp); ++ + grub_errno = GRUB_ERR_NONE; + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_SLAUNCH_MODULE); @@ -674,7 +721,7 @@ index 000000000000..72d09236b2ae + + return GRUB_ERR_NONE; + -+ fail: ++fail: + grub_error_push (); + + grub_free (slaunch_module); @@ -699,6 +746,9 @@ index 000000000000..72d09236b2ae + grub_printf ("Secure launcher: Intel TXT\n"); + grub_txt_state_show (); + } ++ else ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Unknown secure launcher platform type: %d\n"), slp); + + return GRUB_ERR_NONE; +} @@ -710,7 +760,7 @@ index 000000000000..72d09236b2ae + cmd_slaunch = grub_register_command ("slaunch", grub_cmd_slaunch, + NULL, N_("Enable secure launcher")); + cmd_slaunch_module = grub_register_command ("slaunch_module", grub_cmd_slaunch_module, -+ NULL, N_("Secure launcher module command")); ++ NULL, N_("Load secure launcher module from file")); + cmd_slaunch_state = grub_register_command ("slaunch_state", grub_cmd_slaunch_state, + NULL, N_("Display secure launcher state")); +} diff --git a/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch b/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch similarity index 70% rename from 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch rename to 1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch index 03e162c..aa1c6a6 100644 --- a/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +++ b/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch @@ -1,7 +1,7 @@ -From d9ba5e9769fb55b246bf76b3d812b85497610325 Mon Sep 17 00:00:00 2001 +From bcb5b12c584773f292777d33e50f44187f8ca497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 31 Aug 2022 14:37:49 +0200 -Subject: [PATCH 1115/1118] i386/txt: Initialize TPM 1.2 event log in TXT heap +Subject: [PATCH] i386/txt: Initialize TPM 1.2 event log in TXT heap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -9,32 +9,55 @@ Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/txt.c | 61 +++++++++++++++++++++++++++++++-- - include/grub/i386/txt.h | 29 ++++++++++++++++ - 2 files changed, 88 insertions(+), 2 deletions(-) + grub-core/loader/i386/linux.c | 3 +- + grub-core/loader/i386/txt/txt.c | 70 ++++++++++++++++++++++++++++++++- + include/grub/i386/txt.h | 31 +++++++++++++++ + 3 files changed, 101 insertions(+), 3 deletions(-) +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index ba050de2d1df..bc8d511bd6dd 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -261,7 +261,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + slparams.tpm_evt_log_base = get_physical_target_address (ch); + slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; + +- grub_memset (get_virtual_current_address (ch), 0, slparams.tpm_evt_log_size); ++ grub_txt_init_tpm_event_log (get_virtual_current_address (ch), ++ slparams.tpm_evt_log_size); + + grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", + (unsigned long) slparams.tpm_evt_log_base, diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c -index 201167ce9a44..f3afb6ad1d92 100644 +index 9540719990bd..581cb166ac54 100644 --- a/grub-core/loader/i386/txt/txt.c +++ b/grub-core/loader/i386/txt/txt.c -@@ -501,6 +501,24 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) +@@ -508,6 +508,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) return GRUB_ERR_NONE; } -+static void init_tpm12_event_log(struct grub_slaunch_params *slparams) ++void ++grub_txt_init_tpm_event_log (void *buf, grub_size_t size) +{ + struct event_log_container *elog; -+ elog = (struct event_log_container *)(grub_addr_t)slparams->tpm_evt_log_base; + -+ if (slparams->tpm_evt_log_base == 0 || slparams->tpm_evt_log_size == 0) ++ if (buf == NULL || size == 0) ++ return; ++ ++ /* For TPM2 just clear the area, only TPM12 requires initialization. */ ++ grub_memset (buf, 0, size); ++ ++ if (grub_get_tpm_ver () != GRUB_TPM_12) + return; + ++ elog = (struct event_log_container *) buf; ++ + grub_memcpy((void *)elog->signature, EVTLOG_SIGNATURE, sizeof(elog->signature)); + elog->container_ver_major = EVTLOG_CNTNR_MAJOR_VER; + elog->container_ver_minor = EVTLOG_CNTNR_MINOR_VER; + elog->pcr_event_ver_major = EVTLOG_EVT_MAJOR_VER; + elog->pcr_event_ver_minor = EVTLOG_EVT_MINOR_VER; -+ elog->size = slparams->tpm_evt_log_size; ++ elog->size = size; + elog->pcr_events_offset = sizeof(*elog); + elog->next_event_offset = sizeof(*elog); +} @@ -42,7 +65,7 @@ index 201167ce9a44..f3afb6ad1d92 100644 static grub_err_t init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header *sinit) { -@@ -510,6 +528,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -517,6 +543,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header struct grub_txt_os_mle_data *os_mle_data; struct grub_txt_os_sinit_data *os_sinit_data; struct grub_txt_heap_end_element *heap_end_element; @@ -50,7 +73,7 @@ index 201167ce9a44..f3afb6ad1d92 100644 struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; #ifdef GRUB_MACHINE_EFI struct grub_acpi_rsdp_v20 *rsdp; -@@ -598,10 +617,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -610,10 +637,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header sinit_caps = grub_txt_get_sinit_capabilities (sinit); @@ -83,12 +106,14 @@ index 201167ce9a44..f3afb6ad1d92 100644 /* Choose monitor RLP wakeup mechanism first. */ if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; -@@ -614,9 +654,26 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -626,9 +674,27 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; if (grub_get_tpm_ver () == GRUB_TPM_12) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("TPM 1.2 is not supported")); + { ++ grub_dprintf ("slaunch", "TPM 1.2 detected\n"); ++ grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); + os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; + os_sinit_data->version = OS_SINIT_DATA_TPM_12_VER; + @@ -97,7 +122,6 @@ index 201167ce9a44..f3afb6ad1d92 100644 + heap_tpm_event_log_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR; + heap_tpm_event_log_element->size = sizeof (*heap_tpm_event_log_element); + heap_tpm_event_log_element->event_log_phys_addr = slparams->tpm_evt_log_base; -+ init_tpm12_event_log (slparams); + + heap_end_element = (struct grub_txt_heap_end_element *) + ((grub_addr_t) heap_tpm_event_log_element + heap_tpm_event_log_element->size); @@ -112,7 +136,7 @@ index 201167ce9a44..f3afb6ad1d92 100644 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("original TXT TPM 2.0 event log format is not supported")); diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index 7d57af68841f..a8ac569968c7 100644 +index 7a54632bede9..0d2ca5b298c1 100644 --- a/include/grub/i386/txt.h +++ b/include/grub/i386/txt.h @@ -22,6 +22,7 @@ @@ -157,7 +181,16 @@ index 7d57af68841f..a8ac569968c7 100644 + /* TXT register and heap access */ - static inline grub_uint64_t + static inline grub_uint8_t +@@ -692,6 +721,8 @@ extern struct grub_txt_acm_header* grub_txt_sinit_select (struct grub_txt_acm_he + extern grub_err_t grub_txt_verify_platform (void); + extern grub_err_t grub_txt_prepare_cpu (void); + ++extern void grub_txt_init_tpm_event_log(void *buf, grub_size_t size); ++ + extern grub_uint32_t grub_txt_get_mle_ptab_size (grub_uint32_t mle_size); + extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); + -- 2.17.1 diff --git a/1116-slaunch-Make-slparams-accessible-by-other-modules.patch b/1115-slaunch-Make-slparams-accessible-by-other-modules.patch similarity index 90% rename from 1116-slaunch-Make-slparams-accessible-by-other-modules.patch rename to 1115-slaunch-Make-slparams-accessible-by-other-modules.patch index 6046a1c..75a5ca4 100644 --- a/1116-slaunch-Make-slparams-accessible-by-other-modules.patch +++ b/1115-slaunch-Make-slparams-accessible-by-other-modules.patch @@ -1,7 +1,7 @@ -From cd5911293aabf5f8336bdf12088710b06e396a62 Mon Sep 17 00:00:00 2001 +From 340094ad2af892ef538baacf84dbd5d4256056de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 1 Sep 2022 17:57:46 +0200 -Subject: [PATCH 1116/1118] slaunch: Make slparams accessible by other modules +Subject: [PATCH] slaunch: Make slparams accessible by other modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -14,7 +14,7 @@ Signed-off-by: Michał Żygowski 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index ba050de2d1df..88c04b3fffd5 100644 +index bc8d511bd6dd..b8611e1adebb 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -89,7 +89,6 @@ static grub_efi_uintn_t efi_mmap_size; @@ -87,7 +87,7 @@ index ba050de2d1df..88c04b3fffd5 100644 if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, -@@ -258,14 +258,14 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -258,15 +258,15 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, GRUB_RELOCATOR_PREFERENCE_NONE, 1)) goto fail; @@ -96,8 +96,9 @@ index ba050de2d1df..88c04b3fffd5 100644 + slparams->tpm_evt_log_base = get_physical_target_address (ch); + slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; -- grub_memset (get_virtual_current_address (ch), 0, slparams.tpm_evt_log_size); -+ grub_memset (get_virtual_current_address (ch), 0, slparams->tpm_evt_log_size); + grub_txt_init_tpm_event_log (get_virtual_current_address (ch), +- slparams.tpm_evt_log_size); ++ slparams->tpm_evt_log_size); grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", - (unsigned long) slparams.tpm_evt_log_base, @@ -107,7 +108,7 @@ index ba050de2d1df..88c04b3fffd5 100644 } } -@@ -480,6 +480,7 @@ grub_linux_boot (void) +@@ -481,6 +481,7 @@ grub_linux_boot (void) grub_size_t mmap_size; grub_size_t cl_offset; grub_size_t ap_wake_block_size = 0; @@ -115,7 +116,7 @@ index ba050de2d1df..88c04b3fffd5 100644 #ifdef GRUB_MACHINE_IEEE1275 { -@@ -635,12 +636,12 @@ grub_linux_boot (void) +@@ -636,12 +637,12 @@ grub_linux_boot (void) if (grub_slaunch_platform_type () == SLP_INTEL_TXT) { @@ -131,7 +132,7 @@ index ba050de2d1df..88c04b3fffd5 100644 (unsigned long) ap_wake_block_size); } -@@ -711,17 +712,17 @@ grub_linux_boot (void) +@@ -712,17 +713,17 @@ grub_linux_boot (void) if (state.edi == SLP_INTEL_TXT) { @@ -153,7 +154,7 @@ index ba050de2d1df..88c04b3fffd5 100644 state.edx = 0; } else -@@ -760,6 +761,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -761,6 +762,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_size_t align, min_align; int relocatable; grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; @@ -161,7 +162,7 @@ index ba050de2d1df..88c04b3fffd5 100644 grub_dl_ref (my_mod); -@@ -879,7 +881,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -880,7 +882,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memset (&linux_params, 0, sizeof (linux_params)); if (grub_slaunch_platform_type () == SLP_INTEL_TXT) @@ -170,7 +171,7 @@ index ba050de2d1df..88c04b3fffd5 100644 /* * The Linux 32-bit boot protocol defines the setup header end -@@ -967,7 +969,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -968,7 +970,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } @@ -180,7 +181,7 @@ index ba050de2d1df..88c04b3fffd5 100644 } else if (grub_slaunch_platform_type () != SLP_NONE) diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c -index 72d09236b2ae..f1a7b8704d45 100644 +index 9b2efd755f89..093eddef8db1 100644 --- a/grub-core/loader/i386/slaunch.c +++ b/grub-core/loader/i386/slaunch.c @@ -36,6 +36,8 @@ static grub_uint32_t slp = SLP_NONE; diff --git a/1118-multiboot2-Implement-TXT-slaunch-support.patch b/1116-multiboot2-Implement-TXT-slaunch-support.patch similarity index 88% rename from 1118-multiboot2-Implement-TXT-slaunch-support.patch rename to 1116-multiboot2-Implement-TXT-slaunch-support.patch index ec512d8..fd733dc 100644 --- a/1118-multiboot2-Implement-TXT-slaunch-support.patch +++ b/1116-multiboot2-Implement-TXT-slaunch-support.patch @@ -1,7 +1,7 @@ -From 385569aa9be925c96e8112c69437241831152dd5 Mon Sep 17 00:00:00 2001 +From b85ff5887e756890011ed8c00ab56c3fefdbc224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 1 Sep 2022 17:58:53 +0200 -Subject: [PATCH 1118/1118] multiboot2: Implement TXT slaunch support +Subject: [PATCH] multiboot2: Implement TXT slaunch support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -12,9 +12,9 @@ Signed-off-by: Krystian Hebel --- grub-core/loader/multiboot.c | 19 +++++- grub-core/loader/multiboot_elfxx.c | 102 ++++++++++++++++++++++++++--- - grub-core/loader/multiboot_mbi2.c | 55 ++++++++++++++++ + grub-core/loader/multiboot_mbi2.c | 39 +++++++++++ include/grub/i386/txt.h | 1 + - 4 files changed, 168 insertions(+), 9 deletions(-) + 4 files changed, 152 insertions(+), 9 deletions(-) diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 3ab0c828c3ae..eb2da8546d9a 100644 @@ -199,7 +199,7 @@ index f2318e0d165d..47ba4c3f2746 100644 if (phdr(i)->p_vaddr <= ehdr->e_entry && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c -index 9a943d7bdd7c..14ac7137cd09 100644 +index 9a943d7bdd7c..eb617083f8e5 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -36,6 +36,9 @@ @@ -222,7 +222,7 @@ index 9a943d7bdd7c..14ac7137cd09 100644 grub_uint64_t load_addr = (addr_tag->load_addr + 1) ? addr_tag->load_addr : (addr_tag->header_addr - ((char *) header - (char *) mld.buffer)); -@@ -390,6 +396,50 @@ grub_multiboot2_load (grub_file_t file, const char *filename) +@@ -390,6 +396,34 @@ grub_multiboot2_load (grub_file_t file, const char *filename) err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT, accepted_consoles, 0, 0, 0, console_required); @@ -244,36 +244,20 @@ index 9a943d7bdd7c..14ac7137cd09 100644 + slparams->tpm_evt_log_base = get_physical_target_address (ch); + slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; + -+ grub_memset (get_virtual_current_address (ch), 0, slparams->tpm_evt_log_size); ++ grub_txt_init_tpm_event_log(get_virtual_current_address (ch), ++ slparams->tpm_evt_log_size); + + grub_dprintf ("multiboot_loader", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", + (unsigned long) slparams->tpm_evt_log_base, + (unsigned) slparams->tpm_evt_log_size); + -+ if (grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch, 0x1000000, -+ UP_TO_TOP32 (GRUB_MLE_AP_WAKE_BLOCK_SIZE), -+ GRUB_MLE_AP_WAKE_BLOCK_SIZE, GRUB_PAGE_SIZE, -+ GRUB_RELOCATOR_PREFERENCE_NONE, 1)) -+ { -+ grub_free (mld.buffer); -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not allocate AP wakeup block"); -+ } -+ -+ slparams->ap_wake_block = get_physical_target_address (ch); -+ slparams->ap_wake_block_size = GRUB_MLE_AP_WAKE_BLOCK_SIZE; -+ -+ grub_memset ((void *) (grub_addr_t)slparams->ap_wake_block, 0, slparams->ap_wake_block_size); -+ grub_dprintf ("multiboot_loader", "ap_wake_block = %lx, ap_wake_block_size = %lx\n", -+ (unsigned long) slparams->ap_wake_block, -+ (unsigned long) slparams->ap_wake_block_size); -+ + grub_txt_setup_mle_ptab (slparams); + } + return err; } -@@ -722,7 +772,12 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) +@@ -722,7 +756,12 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) ptrorig = get_virtual_current_address (ch); #if defined (__i386__) || defined (__x86_64__) @@ -287,7 +271,7 @@ index 9a943d7bdd7c..14ac7137cd09 100644 *target = get_physical_target_address (ch) | 0x80000000; #else diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index a8ac569968c7..6166f17ff5ee 100644 +index 0d2ca5b298c1..53355d511412 100644 --- a/include/grub/i386/txt.h +++ b/include/grub/i386/txt.h @@ -101,6 +101,7 @@ struct grub_txt_acm_header diff --git a/1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch b/1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch deleted file mode 100644 index ee7328f..0000000 --- a/1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 077aa6775468c2c5ac1d2eaabdabe5606974eac9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= -Date: Thu, 13 Oct 2022 12:36:18 +0200 -Subject: [PATCH 1117/1118] grub-core/loader/i386/txt/txt.c: add debug prints -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Michał Żygowski ---- - grub-core/loader/i386/txt/txt.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c -index f3afb6ad1d92..620118edb7d5 100644 ---- a/grub-core/loader/i386/txt/txt.c -+++ b/grub-core/loader/i386/txt/txt.c -@@ -538,9 +538,12 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header - - txt_heap = grub_txt_get_heap (); - -+ grub_dprintf ("slaunch", "TXT heap %p\n", txt_heap); -+ - /* OS/loader to MLE data. */ - - os_mle_data = grub_txt_os_mle_data_start (txt_heap); -+ grub_dprintf ("slaunch", "OS MLE data: %p\n", os_mle_data); - size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); - *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); - -@@ -556,10 +559,11 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header - os_mle_data->evtlog_addr = slparams->tpm_evt_log_base; - os_mle_data->evtlog_size = slparams->tpm_evt_log_size; - -+ grub_dprintf ("slaunch", "Saving MTRRs to OS MLE data\n"); - save_mtrrs (os_mle_data); - - /* OS/loader to SINIT data. */ -- -+ grub_dprintf ("slaunch", "Get supported OS SINIT data version\n"); - os_sinit_data_ver = grub_txt_supported_os_sinit_data_ver (sinit); - - if (os_sinit_data_ver < OS_SINIT_DATA_MIN_VER) -@@ -568,6 +572,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header - " expected >= %d"), os_sinit_data_ver, OS_SINIT_DATA_MIN_VER); - - os_sinit_data = grub_txt_os_sinit_data_start (txt_heap); -+ grub_dprintf ("slaunch", "OS SINIT data: %p\n", os_sinit_data); - size = (grub_uint64_t *) ((grub_addr_t) os_sinit_data - sizeof (grub_uint64_t)); - - *size = sizeof(grub_uint64_t) + sizeof (struct grub_txt_os_sinit_data) + -@@ -655,6 +660,8 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header - - if (grub_get_tpm_ver () == GRUB_TPM_12) - { -+ grub_dprintf ("slaunch", "TPM 1.2 detected\n"); -+ grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); - os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; - os_sinit_data->version = OS_SINIT_DATA_TPM_12_VER; - -@@ -696,7 +703,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header - heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; - heap_end_element->size = sizeof (*heap_end_element); - } -- -+ grub_dprintf ("slaunch", "TXT HEAP init done\n"); - /* - * TODO: TXT spec: Note: BiosDataSize + OsMleDataSize + OsSinitDataSize + SinitMleDataSize - * must be less than or equal to TXT.HEAP.SIZE, TXT spec, p. 102. -@@ -918,11 +925,14 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) - if (sinit_base == NULL) - return grub_errno; - -+ grub_dprintf ("slaunch", "Init TXT heap\n"); - err = init_txt_heap (slparams, sinit_base); - - if (err != GRUB_ERR_NONE) - return err; - -+ grub_dprintf ("slaunch", "TXT heap successfully prepared\n"); -+ - /* Update the MLE header. */ - mle_header = (struct grub_txt_mle_header *)(grub_addr_t) (slparams->mle_start + slparams->mle_header_offset); - mle_header->first_valid_page = 0; -@@ -932,15 +942,20 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) - slparams->sinit_acm_size = sinit_base->size * 4; - - grub_tpm_relinquish_lcl (0); -+ grub_dprintf ("slaunch", "TPM locality reliquished\n"); - - err = set_mtrrs_for_acmod (sinit_base); - if (err) - return grub_error (err, N_("secure launch failed to set MTRRs for ACM")); - -+ grub_dprintf ("slaunch", "MTRRs set for ACMOD\n"); -+ - err = grub_txt_prepare_cpu (); - if ( err ) - return err; - -+ grub_dprintf ("slaunch", "CPU prepared for secure launch\n"); -+ - if (!(grub_rdmsr (GRUB_MSR_X86_APICBASE) & GRUB_MSR_X86_APICBASE_BSP)) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("secure launch must run on BSP")); - --- -2.17.1 - diff --git a/grub2.spec.in b/grub2.spec.in index 118d57b..dafd7a2 100644 --- a/grub2.spec.in +++ b/grub2.spec.in @@ -748,24 +748,23 @@ Patch1000: 1000-templates-linux_xen-fix-detecting-xsm-policy.patch Patch1001: 1001-Hide-os-prober-disabled-warning.patch # Intel TXT support patches -Patch1101: 1101-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch -Patch1102: 1102-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch -Patch1103: 1103-i386-msr-Extract-and-improve-MSR-support-detection-c.patch -Patch1104: 1104-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch -Patch1105: 1105-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch -Patch1106: 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch +Patch1100: 1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch +Patch1101: 1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch +Patch1102: 1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch +Patch1103: 1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch +Patch1104: 1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch +Patch1105: 1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch +Patch1106: 1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch Patch1107: 1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch Patch1108: 1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch -Patch1109: 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch -Patch1110: 1110-i386-txt-Add-Intel-TXT-definitions-header-file.patch -Patch1111: 1111-i386-txt-Add-Intel-TXT-core-implementation.patch -Patch1112: 1112-i386-txt-Add-Intel-TXT-ACM-module-support.patch -Patch1113: 1113-i386-txt-Add-Intel-TXT-verification-routines.patch -Patch1114: 1114-i386-slaunch-Add-secure-launch-framework-and-command.patch -Patch1115: 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch -Patch1116: 1116-slaunch-Make-slparams-accessible-by-other-modules.patch -Patch1117: 1117-grub-core-loader-i386-txt-txt.c-add-debug-prints.patch -Patch1118: 1118-multiboot2-Implement-TXT-slaunch-support.patch +Patch1109: 1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch +Patch1110: 1110-i386-txt-Add-Intel-TXT-core-implementation.patch +Patch1111: 1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch +Patch1112: 1112-i386-txt-Add-Intel-TXT-verification-routines.patch +Patch1113: 1113-i386-slaunch-Add-secure-launch-framework-and-command.patch +Patch1114: 1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +Patch1115: 1115-slaunch-Make-slparams-accessible-by-other-modules.patch +Patch1116: 1116-multiboot2-Implement-TXT-slaunch-support.patch BuildRequires: autoconf BuildRequires: automake From 44e3e6792c87d5f9d86adc785dbc88a97ffe2e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BByjewski?= Date: Fri, 26 May 2023 11:40:16 +0200 Subject: [PATCH 3/5] Add patches for Intel TXT support v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomasz Żyjewski --- ...Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch | 2 + ...-basic-platform-support-for-secure-l.patch | 6 +- ...pm-Rename-tpm-module-to-tpm_verifier.patch | 2 +- ...-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch | 82 +++++------------ ...dd-Intel-TXT-definitions-header-file.patch | 2 +- ...xt-Add-Intel-TXT-core-implementation.patch | 36 +++++--- ...txt-Add-Intel-TXT-ACM-module-support.patch | 87 +++++++++++-------- ...-Add-Intel-TXT-verification-routines.patch | 2 +- ...-secure-launch-framework-and-command.patch | 45 +++++----- ...ialize-TPM-1.2-event-log-in-TXT-heap.patch | 25 +++--- ...slparams-accessible-by-other-modules.patch | 26 +++--- ...iboot2-Implement-TXT-slaunch-support.patch | 15 ++-- 12 files changed, 165 insertions(+), 165 deletions(-) diff --git a/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch index 5cde09b..9bf0509 100644 --- a/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch +++ b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch @@ -126,6 +126,8 @@ index c0a0c717a0e9..000000000000 -} - -#endif /* GRUB_RDMSR_H */ + +base-commit: ae94b97be2b81b625d6af6654d3ed79078b50ff6 -- 2.17.1 diff --git a/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch b/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch index c6c5b27..909a45b 100644 --- a/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +++ b/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch @@ -1,4 +1,4 @@ -From 33c31aa22cab2841aa9d4f9578f61a926c30eb8e Mon Sep 17 00:00:00 2001 +From 1d08644f2c341b472ea9db94de746b3030a5f1c3 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:50:14 -0400 Subject: [PATCH] i386/slaunch: Add basic platform support for secure launch @@ -250,7 +250,7 @@ index 000000000000..b5bce71ef8d6 + +#endif /* GRUB_I386_MMIO_H */ diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h -index 1e838c022f41..f2552ecbc6d4 100644 +index 1e838c022f41..b99c49f002ee 100644 --- a/include/grub/i386/msr.h +++ b/include/grub/i386/msr.h @@ -2,6 +2,9 @@ @@ -306,7 +306,7 @@ index 1e838c022f41..f2552ecbc6d4 100644 +#define GRUB_MSR_X86_EFER 0xc0000080 /* Extended features */ +#define GRUB_MSR_EFER_LME (1<<8) /* Enable Long Mode/IA-32e */ +#define GRUB_MSR_EFER_LMA (1<<10) /* Long Mode/IA-32e Actuve */ -+#define GRUB_MSR_EFER_SVME (1<<12) /* Enable virtualization */ ++#define GRUB_MSR_EFER_SVME (1<<12) /* Enable SVM (AMD-V) */ + +/* AMD Specific */ +#define GRUB_MSR_AMD64_PATCH_LEVEL 0x0000008b diff --git a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch index fa4b1af..f447456 100644 --- a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch +++ b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch @@ -1,4 +1,4 @@ -From 3b50cdd2ec6f1d94b126c510e8d2f20cc37bfaaa Mon Sep 17 00:00:00 2001 +From 979cabb7a0e1bb6119b32a7465a569d6ddd8ee84 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 22 Apr 2020 21:41:24 +0200 Subject: [PATCH] i386/tpm: Rename tpm module to tpm_verifier diff --git a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch index 18523fb..0343bf8 100644 --- a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch +++ b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch @@ -1,4 +1,4 @@ -From 0a9bf6cbbfac39052763f7a2ea19c50108eef35c Mon Sep 17 00:00:00 2001 +From 5eca1b0802b90b5c0c928809f8bb76f41fd0e589 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:30:58 +0200 Subject: [PATCH] i386/tpm: Add TPM TIS and CRB driver @@ -7,19 +7,20 @@ It will be used by Intel TXT secure launcher introduced by subsequent patches. Signed-off-by: Daniel Kiper +Signed-off-by: Krystian Hebel --- - grub-core/commands/i386/tpm.c | 187 ++++++++++++++++++++++++++++++++++ - include/grub/i386/tpm.h | 36 +++++++ - 2 files changed, 223 insertions(+) + grub-core/commands/i386/tpm.c | 152 ++++++++++++++++++++++++++++++++++ + include/grub/i386/tpm.h | 36 ++++++++ + 2 files changed, 188 insertions(+) create mode 100644 grub-core/commands/i386/tpm.c create mode 100644 include/grub/i386/tpm.h diff --git a/grub-core/commands/i386/tpm.c b/grub-core/commands/i386/tpm.c new file mode 100644 -index 000000000000..232e8bbb946e +index 000000000000..1c57e5e826f9 --- /dev/null +++ b/grub-core/commands/i386/tpm.c -@@ -0,0 +1,187 @@ +@@ -0,0 +1,152 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Free Software Foundation, Inc. @@ -62,7 +63,11 @@ index 000000000000..232e8bbb946e +/* TIS registers. */ +#define TPM_ACCESS 0x0000 +#define TPM_INTF_CAPABILITY 0x0014 ++#define INTF_CAP_INTERFACE_VERSION_SHIFT 28 ++#define INTF_CAP_INTERFACE_VERSION_MASK 7 +#define TPM_INTERFACE_ID 0x0030 ++#define INTERFACE_ID_INTERFACE_TYPE_SHIFT 0 ++#define INTERFACE_ID_INTERFACE_TYPE_MASK 0xF + +/* CRB registers. */ +#define TPM_LOC_CTRL 0x0008 @@ -74,53 +79,11 @@ index 000000000000..232e8bbb946e +/* 6.4.2 Interface Identifier Register */ +#define TPM_CRB_INTF_ACTIVE 0x1 + -+union tpm_interface_id -+{ -+ grub_uint32_t raw; -+ struct -+ { -+ grub_uint32_t interface_type:4; -+ grub_uint32_t interface_version:4; -+ grub_uint32_t cap_locality:1; -+ grub_uint32_t reserved_0:4; -+ grub_uint32_t cap_tis:1; -+ grub_uint32_t cap_crb:1; -+ grub_uint32_t cap_ifres:2; -+ grub_uint32_t interface_selector:2; -+ grub_uint32_t intf_sel_lock:1; -+ grub_uint32_t reserved_1:4; -+ grub_uint32_t reserved_2:8; -+ }; -+}; -+typedef union tpm_interface_id tpm_interface_id_t; -+ +/* 6.5.2.7 Interface Capability */ +#define TPM_12_TIS_INTF_12 0x0 +#define TPM_12_TIS_INTF_13 0x2 +#define TPM_20_TIS_INTF_13 0x3 + -+union tpm_intf_capability -+{ -+ grub_uint32_t raw; -+ struct -+ { -+ grub_uint32_t data_avail_int_support:1; -+ grub_uint32_t sts_valid_int_support:1; -+ grub_uint32_t locality_change_int_support:1; -+ grub_uint32_t interrupt_level_high:1; -+ grub_uint32_t interrupt_level_low:1; -+ grub_uint32_t interrupt_edge_rising:1; -+ grub_uint32_t interrupt_edge_falling:1; -+ grub_uint32_t command_ready_int_support:1; -+ grub_uint32_t burst_count_static:1; -+ grub_uint32_t data_transfer_size_support:2; -+ grub_uint32_t reserved_0:17; -+ grub_uint32_t interface_version:3; -+ grub_uint32_t reserved_1:1; -+ }; -+}; -+typedef union tpm_intf_capability tpm_intf_capability_t; -+ +typedef enum + { + TPM_INTF_NONE = 0, @@ -145,9 +108,9 @@ index 000000000000..232e8bbb946e + grub_addr_t addr = TPM_MMIO_BASE + lcl * GRUB_PAGE_SIZE; + + if (tpm_intf == TPM_INTF_TIS) -+ grub_writeb (TIS_RELINQUISH_LCL, (void *) (addr + TPM_ACCESS)); ++ grub_writeb (TIS_RELINQUISH_LCL, addr + TPM_ACCESS); + else if (tpm_intf == TPM_INTF_CRB) -+ grub_writel (CRB_RELINQUISH_LCL, (void *) (addr + TPM_LOC_CTRL)); ++ grub_writel (CRB_RELINQUISH_LCL, addr + TPM_LOC_CTRL); +} + +static grub_err_t @@ -177,30 +140,33 @@ index 000000000000..232e8bbb946e + +GRUB_MOD_INIT (tpm) +{ -+ tpm_interface_id_t intf_id; -+ tpm_intf_capability_t intf_cap; ++ grub_uint32_t intf_id; ++ grub_uint32_t intf_cap; + + cmd_tpm_type = grub_register_command ("tpm_type", grub_cmd_tpm_type, + NULL, N_("Show TPM version and interface type.")); + -+ intf_cap.raw = grub_readl ((void *)(grub_addr_t) (TPM_MMIO_BASE + TPM_INTF_CAPABILITY)); ++ intf_cap = grub_readl (TPM_MMIO_BASE + TPM_INTF_CAPABILITY); ++ intf_cap >>= INTF_CAP_INTERFACE_VERSION_SHIFT; ++ intf_cap &= INTF_CAP_INTERFACE_VERSION_MASK; + -+ if (intf_cap.interface_version == TPM_12_TIS_INTF_12 || -+ intf_cap.interface_version == TPM_12_TIS_INTF_13) ++ if (intf_cap == TPM_12_TIS_INTF_12 || intf_cap == TPM_12_TIS_INTF_13) + { + tpm_ver = GRUB_TPM_12; + tpm_intf = TPM_INTF_TIS; + return; + } + -+ if (intf_cap.interface_version != TPM_20_TIS_INTF_13) ++ if (intf_cap != TPM_20_TIS_INTF_13) + return; + + tpm_ver = GRUB_TPM_20; + -+ intf_id.raw = grub_readl ((void *)(grub_addr_t) (TPM_MMIO_BASE + TPM_INTERFACE_ID)); ++ intf_id = grub_readl (TPM_MMIO_BASE + TPM_INTERFACE_ID); ++ intf_id >>= INTERFACE_ID_INTERFACE_TYPE_SHIFT; ++ intf_id &= INTERFACE_ID_INTERFACE_TYPE_MASK; + -+ tpm_intf = (intf_id.interface_type == TPM_CRB_INTF_ACTIVE) ? TPM_INTF_CRB : TPM_INTF_TIS; ++ tpm_intf = (intf_id == TPM_CRB_INTF_ACTIVE) ? TPM_INTF_CRB : TPM_INTF_TIS; +} + +GRUB_MOD_FINI (tpm) diff --git a/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch b/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch index dac364c..6922370 100644 --- a/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch +++ b/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch @@ -1,4 +1,4 @@ -From 8e91862df3df4072b2f8ad7ef28884da6c4a5e6a Mon Sep 17 00:00:00 2001 +From 87a1423e0129ba92eb4ef8d626156067333cbed3 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:53:06 -0400 Subject: [PATCH] i386/txt: Add Intel TXT definitions header file diff --git a/1110-i386-txt-Add-Intel-TXT-core-implementation.patch b/1110-i386-txt-Add-Intel-TXT-core-implementation.patch index 1ac470d..ddce7b0 100644 --- a/1110-i386-txt-Add-Intel-TXT-core-implementation.patch +++ b/1110-i386-txt-Add-Intel-TXT-core-implementation.patch @@ -1,4 +1,4 @@ -From 38bf9bedd60fff65aa8402432ed05d7ed27d07c0 Mon Sep 17 00:00:00 2001 +From cd6bee1ce1385df0902a0e30b949a4e6dfc5f3c6 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:57:33 -0400 Subject: [PATCH] i386/txt: Add Intel TXT core implementation @@ -11,19 +11,19 @@ Signed-off-by: Daniel Kiper Signed-off-by: Michał Żygowski Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/txt.c | 914 ++++++++++++++++++++++++++++++++ + grub-core/loader/i386/txt/txt.c | 928 ++++++++++++++++++++++++++++++++ include/grub/i386/memory.h | 5 + include/grub/i386/msr.h | 1 + include/grub/i386/txt.h | 18 +- - 4 files changed, 935 insertions(+), 3 deletions(-) + 4 files changed, 949 insertions(+), 3 deletions(-) create mode 100644 grub-core/loader/i386/txt/txt.c diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c new file mode 100644 -index 000000000000..9540719990bd +index 000000000000..18eb4fd1bf15 --- /dev/null +++ b/grub-core/loader/i386/txt/txt.c -@@ -0,0 +1,914 @@ +@@ -0,0 +1,928 @@ +/* + * txt.c: Intel(r) TXT support functions, including initiating measured + * launch, post-launch, AP wakeup, etc. @@ -110,7 +110,10 @@ index 000000000000..9540719990bd + { + grub_dprintf ("slaunch", "Firmware didn't lock FEATURE_CONTROL MSR," + "locking it now\n"); -+ feat_ctrl |= GRUB_MSR_X86_FEATURE_CTRL_LOCK; ++ /* Not setting SENTER_FUNCTIONS and SENTER_ENABLE because they were tested ++ * in grub_txt_verify_platform() */ ++ feat_ctrl |= GRUB_MSR_X86_FEATURE_CTRL_LOCK | GRUB_MSR_X86_ENABLE_VMX_IN_SMX; ++ grub_wrmsr (GRUB_MSR_X86_FEATURE_CONTROL, feat_ctrl); + } + + /* Enable SMX mode. */ @@ -605,7 +608,7 @@ index 000000000000..9540719990bd + rsdp = grub_acpi_get_rsdpv2 (); + + if (rsdp == NULL) -+ return grub_printf ("WARNING: ACPI RSDP 2.0 missing\n"); ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("ACPI RSDP 2.0 missing\n")); + + os_sinit_data->efi_rsdt_ptr = (grub_uint64_t)(grub_addr_t) rsdp; +#endif @@ -652,7 +655,8 @@ index 000000000000..9540719990bd + os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; + + if (grub_get_tpm_ver () == GRUB_TPM_12) -+ return grub_error (GRUB_ERR_BAD_DEVICE, N_("TPM 1.2 is not supported")); ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ N_("TPM 1.2 detected, but not implemented yet")); + else + { + if (!(sinit_caps & GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT)) @@ -896,6 +900,7 @@ index 000000000000..9540719990bd + grub_err_t err; + struct grub_txt_mle_header *mle_header; + struct grub_txt_acm_header *sinit_base; ++ int i; + + sinit_base = grub_txt_sinit_select (grub_slaunch_module ()); + @@ -918,8 +923,17 @@ index 000000000000..9540719990bd + slparams->sinit_acm_base = (grub_uint32_t)(grub_addr_t) sinit_base; + slparams->sinit_acm_size = sinit_base->size * 4; + -+ grub_tpm_relinquish_locality (0); -+ grub_dprintf ("slaunch", "TPM locality reliquished\n"); ++ /* ++ * Access to locality 4 isn't available to software, skip it. Don't bother ++ * checking TPM status, we have no tools for recovering from bad state better ++ * than command abort, which is part of locality relinquish. Write performed ++ * by the following function is no-op if locality is neither active nor ++ * requested. ++ */ ++ for (i = 0; i < 4; ++i) ++ grub_tpm_relinquish_locality (i); ++ ++ grub_dprintf ("slaunch", "TPM localities relinquished\n"); + + err = set_mtrrs_for_acmod (sinit_base); + if (err) @@ -964,7 +978,7 @@ index c64529630f19..56f64855be7e 100644 { grub_uint64_t addr; diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h -index f2552ecbc6d4..99e2c6f675b3 100644 +index b99c49f002ee..8f3e2a894883 100644 --- a/include/grub/i386/msr.h +++ b/include/grub/i386/msr.h @@ -31,6 +31,7 @@ diff --git a/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch b/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch index b6ee390..ecbaa67 100644 --- a/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch +++ b/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch @@ -1,4 +1,4 @@ -From b04efb5f9dfd96bc290109ddb6170822bc55dd6b Mon Sep 17 00:00:00 2001 +From 59ba16b5bc65ff8b91f4ed627fc7286717fce6dc Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:59:18 -0400 Subject: [PATCH] i386/txt: Add Intel TXT ACM module support @@ -7,16 +7,16 @@ Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/acmod.c | 590 ++++++++++++++++++++++++++++++ - 1 file changed, 590 insertions(+) + grub-core/loader/i386/txt/acmod.c | 603 ++++++++++++++++++++++++++++++ + 1 file changed, 603 insertions(+) create mode 100644 grub-core/loader/i386/txt/acmod.c diff --git a/grub-core/loader/i386/txt/acmod.c b/grub-core/loader/i386/txt/acmod.c new file mode 100644 -index 000000000000..1611b33d4c96 +index 000000000000..ec61d277d9f7 --- /dev/null +++ b/grub-core/loader/i386/txt/acmod.c -@@ -0,0 +1,590 @@ +@@ -0,0 +1,603 @@ +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules @@ -85,6 +85,16 @@ index 000000000000..1611b33d4c96 +#include + +/* ++ * Macro that returns value of it->field if it's inside info table, 0 otherwise. ++ * Fields at or below 'length' ('uuid', 'chipset_acm_type', 'version') don't ++ * benefit from this macro, because it requires that 'length' (and by extension ++ * fields below that) is valid. ++ */ ++#define info_table_get(it, field) \ ++ (__builtin_offsetof(struct grub_txt_acm_info_table, field) + sizeof(it->field)\ ++ <= it->length ? it->field : 0) ++ ++/* + * Returns hdr + offset if [offset, offset + count * size) is within the bounds + * of the ACM, NULL otherwise. + */ @@ -92,11 +102,15 @@ index 000000000000..1611b33d4c96 +n_fit_in_acm (struct grub_txt_acm_header *hdr, grub_uint32_t offset, + grub_uint32_t size, grub_uint32_t count) +{ -+ grub_uint32_t total_size, ret_u32, elem_end; ++ grub_uint32_t total_size, elem_end; + /* ACM size overflow was checked in is_acmod() */ + grub_uint32_t acm_len = hdr->size * 4; + -+ /* To simplify rest of the code check if offset is non-0 here */ ++ /* ++ * `offset` will often come from `info_table_get`, and this is the most ++ * convenient place to check for the macro returning zero. This is fine, since ++ * there is no legitimate reason to access the zero offset in this manner. ++ */ + if ( offset == 0 ) + return NULL; + @@ -109,13 +123,11 @@ index 000000000000..1611b33d4c96 + if ( elem_end > acm_len ) + return NULL; + -+ if ( grub_add ((grub_uint32_t)(unsigned long)hdr, offset, &ret_u32) ) -+ return NULL; -+ + /* Not checking if (hdr + elem_end) overflows. We know that (hdr + acm_len) -+ * doesn't, and that elem_end <= acm_len. */ ++ * doesn't, and that elem_end <= acm_len. For the same reason we don't have to ++ * check if (hdr + offset) overflows. */ + -+ return (void *)(unsigned long)ret_u32; ++ return (void *)((unsigned long)hdr + offset); +} + +static void* @@ -126,16 +138,6 @@ index 000000000000..1611b33d4c96 +} + +/* -+ * Macro that returns value of it->field if it's inside info table, 0 otherwise. -+ * Fields at or below 'length' ('uuid', 'chipset_acm_type', 'version') don't -+ * benefit from this macro, because it requires that 'length' (and by extension -+ * fields below that) is valid. -+ */ -+#define info_table_offset(it, field) \ -+ (__builtin_offsetof(struct grub_txt_acm_info_table, field) + sizeof(it->field)\ -+ <= it->length ? it->field : 0) -+ -+/* + * Returns pointer to ACM information table. If the table is located outside of + * ACM or its reported size is too small to cover at least 'length' field, + * NULL is returned instead. @@ -166,19 +168,21 @@ index 000000000000..1611b33d4c96 + + if ( ptr != NULL ) + { -+ if ( info_table_offset (ptr, length) < info_table_size ) ++ if ( info_table_get (ptr, length) < info_table_size ) + return NULL; + -+ info_table_size = info_table_offset (ptr, length); ++ info_table_size = info_table_get (ptr, length); + ptr = fits_in_acm(hdr, user_area_off, info_table_size); + } + + return ptr; +} + -+/* Function returns pointer to chipset ID list, after checking that ++/* ++ * Function returns pointer to chipset ID list, after checking that + * grub_txt_acm_chipset_id_list and all grub_txt_acm_chipset_id structures are -+ * within ACM. Otherwise, NULL is returned. */ ++ * within ACM. Otherwise, NULL is returned. ++ */ +static struct grub_txt_acm_chipset_id_list* +get_acmod_chipset_list (struct grub_txt_acm_header *hdr) +{ @@ -195,7 +199,7 @@ index 000000000000..1611b33d4c96 + return NULL; + } + -+ chipset_id_list = fits_in_acm(hdr, info_table_offset (info_table, chipset_id_list), ++ chipset_id_list = fits_in_acm(hdr, info_table_get (info_table, chipset_id_list), + sizeof(struct grub_txt_acm_chipset_id_list)); + if ( chipset_id_list == NULL ) + { @@ -221,9 +225,11 @@ index 000000000000..1611b33d4c96 + return chipset_id_list; +} + -+/* Function returns pointer to processor ID list, after checking that ++/* ++ * Function returns pointer to processor ID list, after checking that + * grub_txt_acm_processor_id_list and all grub_txt_acm_processor_id structures -+ * are within ACM. Otherwise, NULL is returned. */ ++ * are within ACM. Otherwise, NULL is returned. ++ */ +static struct grub_txt_acm_processor_id_list* +get_acmod_processor_list (struct grub_txt_acm_header* hdr) +{ @@ -240,7 +246,7 @@ index 000000000000..1611b33d4c96 + return NULL; + } + -+ proc_id_list = fits_in_acm(hdr, info_table_offset (info_table, processor_id_list), ++ proc_id_list = fits_in_acm(hdr, info_table_get (info_table, processor_id_list), + sizeof(struct grub_txt_acm_processor_id_list)); + if ( proc_id_list == NULL ) + { @@ -259,7 +265,7 @@ index 000000000000..1611b33d4c96 + if ( n_fit_in_acm ( hdr, id_entries_off, sizeof(struct grub_txt_acm_processor_id), + proc_id_list->count ) == NULL ) + { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID entries out of bounds")); ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID entries out of bounds")); + return NULL; + } + @@ -303,7 +309,7 @@ index 000000000000..1611b33d4c96 + /* + * TXT specification doesn't give clear mapping of info table size to version, + * so just warn if the size is different than expected but try to use it -+ * anyway. info_table_offset() macro does enough testing to not read outside ++ * anyway. info_table_get() macro does enough testing to not read outside + * of info table. + */ + if ( info_table->length < sizeof(struct grub_txt_acm_info_table) ) @@ -311,7 +317,7 @@ index 000000000000..1611b33d4c96 + info_table->length, sizeof(struct grub_txt_acm_info_table)); + + if ( type_out ) -+ *type_out = info_table_offset (info_table, chipset_acm_type); ++ *type_out = info_table_get (info_table, chipset_acm_type); + + return 1; +} @@ -343,7 +349,10 @@ index 000000000000..1611b33d4c96 + /* Is it a valid SINIT module? */ + if ( !grub_txt_is_sinit_acmod (sinit_region_base, bios_data->bios_sinit_size) || + !grub_txt_acmod_match_platform (bios_sinit) ) -+ return NULL; ++ { ++ grub_dprintf("slaunch", "BIOS SINIT module did not pass sanity checks"); ++ return NULL; ++ } + + return bios_sinit; +} @@ -359,7 +368,7 @@ index 000000000000..1611b33d4c96 + if ( info_table == NULL ) + return 0; + -+ return info_table_offset (info_table, os_sinit_data_ver); ++ return info_table_get (info_table, os_sinit_data_ver); +} + +grub_uint32_t @@ -367,13 +376,13 @@ index 000000000000..1611b33d4c96 +{ + static struct grub_txt_acm_info_table *info_table; + -+ /* Assumes that it passed is_sinit_acmod() */ ++ /* Assumes that it passed grub_txt_is_sinit_acmod() */ + info_table = get_acmod_info_table (hdr); + + if ( info_table == NULL || info_table->version < 3 ) + return 0; + -+ return info_table_offset (info_table, capabilities); ++ return info_table_get (info_table, capabilities); +} + +int @@ -538,6 +547,10 @@ index 000000000000..1611b33d4c96 + return 1; +} + ++/* ++ * Choose between the BIOS-provided and user-provided SINIT ACMs, and copy the ++ * chosen module to the SINIT memory. ++ */ +struct grub_txt_acm_header * +grub_txt_sinit_select (struct grub_txt_acm_header *sinit) +{ diff --git a/1112-i386-txt-Add-Intel-TXT-verification-routines.patch b/1112-i386-txt-Add-Intel-TXT-verification-routines.patch index e47f17b..13fa45f 100644 --- a/1112-i386-txt-Add-Intel-TXT-verification-routines.patch +++ b/1112-i386-txt-Add-Intel-TXT-verification-routines.patch @@ -1,4 +1,4 @@ -From 7238e5c808dcf90ccf813eb8d35a7060fb95c03f Mon Sep 17 00:00:00 2001 +From aa504dddd62f792791a04986c3469b10808dd146 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 14:46:17 -0400 Subject: [PATCH] i386/txt: Add Intel TXT verification routines diff --git a/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch b/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch index 6199e25..816dc76 100644 --- a/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch +++ b/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch @@ -1,4 +1,4 @@ -From a01e6982379c8f1850bf3c1877568442bc8d6c76 Mon Sep 17 00:00:00 2001 +From 98069630b28f8345d791bb68102d4e28789e8670 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 15:01:00 -0400 Subject: [PATCH] i386/slaunch: Add secure launch framework and commands @@ -12,7 +12,7 @@ Signed-off-by: Krystian Hebel grub-core/lib/i386/relocator32.S | 8 + grub-core/loader/i386/bsd.c | 7 + grub-core/loader/i386/coreboot/chainloader.c | 2 + - grub-core/loader/i386/linux.c | 213 +++++++++++++++++-- + grub-core/loader/i386/linux.c | 214 +++++++++++++++++-- grub-core/loader/i386/pc/plan9.c | 3 +- grub-core/loader/i386/slaunch.c | 201 +++++++++++++++++ grub-core/loader/i386/xnu.c | 3 + @@ -20,7 +20,7 @@ Signed-off-by: Krystian Hebel include/grub/file.h | 3 + include/grub/i386/linux.h | 14 +- include/grub/i386/slaunch.h | 57 +++++ - 13 files changed, 517 insertions(+), 17 deletions(-) + 13 files changed, 518 insertions(+), 17 deletions(-) create mode 100644 grub-core/loader/i386/slaunch.c create mode 100644 include/grub/i386/slaunch.h @@ -176,7 +176,7 @@ index 0a19ebb9c3e5..dccd86b07bde 100644 } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 9f74a96b19ae..ba050de2d1df 100644 +index 9f74a96b19ae..0ab2899f6774 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -34,6 +34,8 @@ @@ -188,10 +188,11 @@ index 9f74a96b19ae..ba050de2d1df 100644 #include #include #include -@@ -63,18 +65,23 @@ GRUB_MOD_LICENSE ("GPLv3+"); +@@ -63,18 +65,24 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define ACCEPTS_PURE_TEXT 1 #endif ++/* See kernel_info in Documentation/arch/x86/boot.rst in the kernel tree */ +#define KERNEL_INFO_HEADER "LToP" +#define KERNEL_INFO_MIN_SIZE_TOTAL 12 + @@ -212,7 +213,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 static struct linux_kernel_params linux_params; static char *linux_cmdline; #ifdef GRUB_MACHINE_EFI -@@ -82,6 +89,7 @@ static grub_efi_uintn_t efi_mmap_size; +@@ -82,6 +90,7 @@ static grub_efi_uintn_t efi_mmap_size; #else static const grub_size_t efi_mmap_size = 0; #endif @@ -220,7 +221,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 /* FIXME */ #if 0 -@@ -98,6 +106,8 @@ static struct idt_descriptor idt_desc = +@@ -98,6 +107,8 @@ static struct idt_descriptor idt_desc = }; #endif @@ -229,7 +230,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 static inline grub_size_t page_align (grub_size_t size) { -@@ -150,11 +160,35 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -150,11 +161,35 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, grub_uint64_t preferred_address) { grub_err_t err; @@ -266,7 +267,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 /* Initialize the memory pointers with NULL for convenience. */ free_pages (); -@@ -176,7 +210,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -176,7 +211,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, err = grub_relocator_alloc_chunk_align (relocator, &ch, preferred_address, preferred_address, @@ -275,7 +276,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 GRUB_RELOCATOR_PREFERENCE_LOW, 1); for (; err && *align + 1 > min_align; (*align)--) -@@ -194,11 +228,45 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -194,11 +229,45 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, else err = grub_relocator_alloc_chunk_addr (relocator, &ch, preferred_address, @@ -322,7 +323,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 } grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", -@@ -286,7 +354,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) +@@ -286,7 +355,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->lfb_size >>= 16; params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; break; @@ -331,7 +332,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 case GRUB_VIDEO_DRIVER_EFI_UGA: case GRUB_VIDEO_DRIVER_EFI_GOP: params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; -@@ -411,6 +479,7 @@ grub_linux_boot (void) +@@ -411,6 +480,7 @@ grub_linux_boot (void) }; grub_size_t mmap_size; grub_size_t cl_offset; @@ -339,7 +340,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 #ifdef GRUB_MACHINE_IEEE1275 { -@@ -543,6 +612,9 @@ grub_linux_boot (void) +@@ -543,6 +613,9 @@ grub_linux_boot (void) (unsigned) ctx.real_size, (unsigned) efi_mmap_size); @@ -349,7 +350,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 if (! ctx.real_mode_target) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); -@@ -550,7 +622,7 @@ grub_linux_boot (void) +@@ -550,7 +623,7 @@ grub_linux_boot (void) grub_relocator_chunk_t ch; grub_size_t sz; @@ -358,7 +359,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 return GRUB_ERR_OUT_OF_RANGE; err = grub_relocator_alloc_chunk_addr (relocator, &ch, -@@ -561,6 +633,17 @@ grub_linux_boot (void) +@@ -561,6 +634,17 @@ grub_linux_boot (void) } efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; @@ -376,7 +377,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 grub_dprintf ("linux", "real_mode_mem = %p\n", real_mode_mem); -@@ -591,9 +674,9 @@ grub_linux_boot (void) +@@ -591,9 +675,9 @@ grub_linux_boot (void) &efi_desc_size, &efi_desc_version); if (err) return err; @@ -388,7 +389,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); /* Pass EFI parameters. */ if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) -@@ -624,12 +707,33 @@ grub_linux_boot (void) +@@ -624,12 +708,33 @@ grub_linux_boot (void) } #endif @@ -428,7 +429,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 return grub_relocator32_boot (relocator, state, 0); } -@@ -650,7 +754,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -650,7 +755,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; @@ -437,7 +438,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 grub_ssize_t len; int i; grub_size_t align, min_align; -@@ -743,7 +847,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -743,7 +848,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), align = 0; relocatable = 0; } @@ -446,7 +447,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 if (grub_le_to_cpu16 (lh.version) >= 0x020a) { min_align = lh.min_alignment; -@@ -760,6 +864,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -760,6 +865,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), prot_init_space = page_align (prot_size) * 3; } @@ -460,7 +461,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 if (allocate_pages (prot_size, &align, min_align, relocatable, preferred_address)) -@@ -767,6 +878,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -767,6 +879,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memset (&linux_params, 0, sizeof (linux_params)); @@ -470,7 +471,7 @@ index 9f74a96b19ae..ba050de2d1df 100644 /* * The Linux 32-bit boot protocol defines the setup header end * to be at 0x202 + the byte value at 0x201. -@@ -793,6 +907,75 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -793,6 +908,75 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } diff --git a/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch b/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch index aa1c6a6..23907d3 100644 --- a/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +++ b/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch @@ -1,4 +1,4 @@ -From bcb5b12c584773f292777d33e50f44187f8ca497 Mon Sep 17 00:00:00 2001 +From 0b968b38a15412e81e85d97dd1d042cf459a8527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 31 Aug 2022 14:37:49 +0200 Subject: [PATCH] i386/txt: Initialize TPM 1.2 event log in TXT heap @@ -10,15 +10,15 @@ Signed-off-by: Michał Żygowski Signed-off-by: Krystian Hebel --- grub-core/loader/i386/linux.c | 3 +- - grub-core/loader/i386/txt/txt.c | 70 ++++++++++++++++++++++++++++++++- - include/grub/i386/txt.h | 31 +++++++++++++++ - 3 files changed, 101 insertions(+), 3 deletions(-) + grub-core/loader/i386/txt/txt.c | 71 +++++++++++++++++++++++++++++++-- + include/grub/i386/txt.h | 31 ++++++++++++++ + 3 files changed, 101 insertions(+), 4 deletions(-) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index ba050de2d1df..bc8d511bd6dd 100644 +index 0ab2899f6774..7ef4b36fefc7 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c -@@ -261,7 +261,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -262,7 +262,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, slparams.tpm_evt_log_base = get_physical_target_address (ch); slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; @@ -29,10 +29,10 @@ index ba050de2d1df..bc8d511bd6dd 100644 grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", (unsigned long) slparams.tpm_evt_log_base, diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c -index 9540719990bd..581cb166ac54 100644 +index 18eb4fd1bf15..c17c2f29ae12 100644 --- a/grub-core/loader/i386/txt/txt.c +++ b/grub-core/loader/i386/txt/txt.c -@@ -508,6 +508,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) +@@ -511,6 +511,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) return GRUB_ERR_NONE; } @@ -65,7 +65,7 @@ index 9540719990bd..581cb166ac54 100644 static grub_err_t init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header *sinit) { -@@ -517,6 +543,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -520,6 +546,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header struct grub_txt_os_mle_data *os_mle_data; struct grub_txt_os_sinit_data *os_sinit_data; struct grub_txt_heap_end_element *heap_end_element; @@ -73,7 +73,7 @@ index 9540719990bd..581cb166ac54 100644 struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; #ifdef GRUB_MACHINE_EFI struct grub_acpi_rsdp_v20 *rsdp; -@@ -610,10 +637,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -613,10 +640,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header sinit_caps = grub_txt_get_sinit_capabilities (sinit); @@ -106,11 +106,12 @@ index 9540719990bd..581cb166ac54 100644 /* Choose monitor RLP wakeup mechanism first. */ if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; -@@ -626,9 +674,27 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -629,10 +677,27 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; if (grub_get_tpm_ver () == GRUB_TPM_12) -- return grub_error (GRUB_ERR_BAD_DEVICE, N_("TPM 1.2 is not supported")); +- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, +- N_("TPM 1.2 detected, but not implemented yet")); + { + grub_dprintf ("slaunch", "TPM 1.2 detected\n"); + grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); diff --git a/1115-slaunch-Make-slparams-accessible-by-other-modules.patch b/1115-slaunch-Make-slparams-accessible-by-other-modules.patch index 75a5ca4..e994d28 100644 --- a/1115-slaunch-Make-slparams-accessible-by-other-modules.patch +++ b/1115-slaunch-Make-slparams-accessible-by-other-modules.patch @@ -1,4 +1,4 @@ -From 340094ad2af892ef538baacf84dbd5d4256056de Mon Sep 17 00:00:00 2001 +From 2c11b659b5272369f93386c50fc23875c0b753d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 1 Sep 2022 17:57:46 +0200 Subject: [PATCH] slaunch: Make slparams accessible by other modules @@ -14,10 +14,10 @@ Signed-off-by: Michał Żygowski 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index bc8d511bd6dd..b8611e1adebb 100644 +index 7ef4b36fefc7..3c123b90a0ea 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c -@@ -89,7 +89,6 @@ static grub_efi_uintn_t efi_mmap_size; +@@ -90,7 +90,6 @@ static grub_efi_uintn_t efi_mmap_size; #else static const grub_size_t efi_mmap_size = 0; #endif @@ -25,7 +25,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 /* FIXME */ #if 0 -@@ -161,6 +160,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -162,6 +161,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, { grub_err_t err; grub_size_t total_size; @@ -33,7 +33,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 if (prot_size == 0) prot_size = 1; -@@ -175,20 +175,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -176,20 +176,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, goto fail; } @@ -60,7 +60,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 /* Initialize the memory pointers with NULL for convenience. */ free_pages (); -@@ -239,18 +239,18 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -240,18 +240,18 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, /* Zero out memory to get stable MLE measurements. */ grub_memset (prot_mode_mem, 0, total_size); @@ -87,7 +87,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, -@@ -258,15 +258,15 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -259,15 +259,15 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, GRUB_RELOCATOR_PREFERENCE_NONE, 1)) goto fail; @@ -108,7 +108,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 } } -@@ -481,6 +481,7 @@ grub_linux_boot (void) +@@ -482,6 +482,7 @@ grub_linux_boot (void) grub_size_t mmap_size; grub_size_t cl_offset; grub_size_t ap_wake_block_size = 0; @@ -116,7 +116,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 #ifdef GRUB_MACHINE_IEEE1275 { -@@ -636,12 +637,12 @@ grub_linux_boot (void) +@@ -637,12 +638,12 @@ grub_linux_boot (void) if (grub_slaunch_platform_type () == SLP_INTEL_TXT) { @@ -132,7 +132,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 (unsigned long) ap_wake_block_size); } -@@ -712,17 +713,17 @@ grub_linux_boot (void) +@@ -713,17 +714,17 @@ grub_linux_boot (void) if (state.edi == SLP_INTEL_TXT) { @@ -154,7 +154,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 state.edx = 0; } else -@@ -761,6 +762,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -762,6 +763,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_size_t align, min_align; int relocatable; grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; @@ -162,7 +162,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 grub_dl_ref (my_mod); -@@ -880,7 +882,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -881,7 +883,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memset (&linux_params, 0, sizeof (linux_params)); if (grub_slaunch_platform_type () == SLP_INTEL_TXT) @@ -171,7 +171,7 @@ index bc8d511bd6dd..b8611e1adebb 100644 /* * The Linux 32-bit boot protocol defines the setup header end -@@ -968,7 +970,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -969,7 +971,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } diff --git a/1116-multiboot2-Implement-TXT-slaunch-support.patch b/1116-multiboot2-Implement-TXT-slaunch-support.patch index fd733dc..d397959 100644 --- a/1116-multiboot2-Implement-TXT-slaunch-support.patch +++ b/1116-multiboot2-Implement-TXT-slaunch-support.patch @@ -1,4 +1,4 @@ -From b85ff5887e756890011ed8c00ab56c3fefdbc224 Mon Sep 17 00:00:00 2001 +From 4d48d3bc4fe7ac5dae6f32de2928a803c2dfb770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 1 Sep 2022 17:58:53 +0200 Subject: [PATCH] multiboot2: Implement TXT slaunch support @@ -10,14 +10,14 @@ Signed-off-by: Michał Żygowski Signed-off-by: Tomasz Żyjewski Signed-off-by: Krystian Hebel --- - grub-core/loader/multiboot.c | 19 +++++- + grub-core/loader/multiboot.c | 22 ++++++- grub-core/loader/multiboot_elfxx.c | 102 ++++++++++++++++++++++++++--- grub-core/loader/multiboot_mbi2.c | 39 +++++++++++ include/grub/i386/txt.h | 1 + - 4 files changed, 152 insertions(+), 9 deletions(-) + 4 files changed, 155 insertions(+), 9 deletions(-) diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c -index 3ab0c828c3ae..eb2da8546d9a 100644 +index 3ab0c828c3ae..049efd04c649 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -52,6 +52,7 @@ @@ -28,7 +28,7 @@ index 3ab0c828c3ae..eb2da8546d9a 100644 #endif GRUB_MOD_LICENSE ("GPLv3+"); -@@ -164,7 +165,23 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)), +@@ -164,7 +165,26 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)), static void normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state) { @@ -42,7 +42,10 @@ index 3ab0c828c3ae..eb2da8546d9a 100644 + err = grub_txt_boot_prepare (slparams); + + if (err != GRUB_ERR_NONE) -+ return; ++ { ++ grub_printf ("TXT boot preparation failed"); ++ return; ++ } + + /* Configure relocator GETSEC[SENTER] call. */ + state.eax = GRUB_SMX_LEAF_SENTER; From 2d05df964cc53092319f09868a5af672a9599727 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Mon, 29 Jan 2024 20:31:19 +0100 Subject: [PATCH 4/5] TXT support: update after review and phase 3 Signed-off-by: Krystian Hebel --- ...Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch | 2 +- ...ame-grub_msr_read-and-grub_msr_write.patch | 2 +- ...-and-improve-MSR-support-detection-c.patch | 2 +- ...Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch | 2 +- ...me-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch | 2 +- ...ne-GRUB_PAGE_MASK-constant-and-GRUB_.patch | 41 ++ ...ap_get_lowest-and-grub_mmap_get_high.patch | 36 +- ...pm-Rename-tpm-module-to-tpm_verifier.patch | 4 +- ...-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch | 43 +- ...-basic-platform-support-for-secure-l.patch | 139 ++++-- ...-commit-of-the-Secure-Launch-Resourc.patch | 323 +++++++++++++ ...dd-Intel-TXT-definitions-header-file.patch | 234 +++++---- ...xt-Add-Intel-TXT-core-implementation.patch | 281 ++++++----- ...txt-Add-Intel-TXT-ACM-module-support.patch | 43 +- ...-Add-Intel-TXT-verification-routines.patch | 93 ++-- ...ialize-TPM-1.2-event-log-in-TXT-heap.patch | 97 ++-- ...slparams-accessible-by-other-modules.patch | 223 --------- ...to-using-Secure-Launch-Resource-Tabl.patch | 331 +++++++++++++ ...-secure-launch-framework-and-command.patch | 446 ++++++++++++------ ...RUB_MULTIBOOT-make_mbi-return-MBI-s-.patch | 114 +++++ ...iboot2-Implement-TXT-slaunch-support.patch | 159 +++++-- grub2.spec.in | 23 +- 22 files changed, 1760 insertions(+), 880 deletions(-) create mode 100644 1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch rename 1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch => 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch (78%) rename 1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch => 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch (69%) create mode 100644 1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch rename 1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch => 1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch (76%) rename 1110-i386-txt-Add-Intel-TXT-core-implementation.patch => 1112-i386-txt-Add-Intel-TXT-core-implementation.patch (81%) rename 1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch => 1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch (94%) rename 1112-i386-txt-Add-Intel-TXT-verification-routines.patch => 1114-i386-txt-Add-Intel-TXT-verification-routines.patch (78%) rename 1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch => 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch (56%) delete mode 100644 1115-slaunch-Make-slparams-accessible-by-other-modules.patch create mode 100644 1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch rename 1113-i386-slaunch-Add-secure-launch-framework-and-command.patch => 1117-i386-slaunch-Add-secure-launch-framework-and-command.patch (64%) create mode 100644 1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch rename 1116-multiboot2-Implement-TXT-slaunch-support.patch => 1119-multiboot2-Implement-TXT-slaunch-support.patch (65%) diff --git a/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch index 9bf0509..abac6cf 100644 --- a/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch +++ b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch @@ -129,5 +129,5 @@ index c0a0c717a0e9..000000000000 base-commit: ae94b97be2b81b625d6af6654d3ed79078b50ff6 -- -2.17.1 +2.41.0 diff --git a/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch b/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch index 9dcd804..b21fb4d 100644 --- a/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch +++ b/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch @@ -62,5 +62,5 @@ index 7b52b5d61229..4fba1b8e0d04 100644 grub_uint32_t low = msr_value, high = msr_value >> 32; -- -2.17.1 +2.41.0 diff --git a/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch b/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch index 1da2b7e..ec1cd34 100644 --- a/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch +++ b/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch @@ -132,5 +132,5 @@ index 4fba1b8e0d04..1e838c022f41 100644 * TODO: Add a general protection exception handler. * Accessing a reserved or unimplemented MSR address results in a GP#. -- -2.17.1 +2.41.0 diff --git a/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch b/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch index 0cb7e8f..ab45048 100644 --- a/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch +++ b/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch @@ -172,5 +172,5 @@ index 5cb607fb4667..7be57d6d7ecc 100644 /* The flag for protected mode. */ #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 -- -2.17.1 +2.41.0 diff --git a/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch b/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch index 163709e..c32fa9a 100644 --- a/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch +++ b/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch @@ -166,5 +166,5 @@ index 7be57d6d7ecc..c64529630f19 100644 /* The flag for protected mode. */ #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 -- -2.17.1 +2.41.0 diff --git a/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch b/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch new file mode 100644 index 0000000..bc6f260 --- /dev/null +++ b/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch @@ -0,0 +1,41 @@ +From 868093de8910bd66abcde04ca928538e07366ad7 Mon Sep 17 00:00:00 2001 +From: Krystian Hebel +Date: Mon, 22 Jan 2024 13:14:39 +0100 +Subject: [PATCH] i386/memory: Define GRUB_PAGE_MASK constant and + GRUB_PAGE_{UP,DOWN} macros + +Subsequent patches will use those macros and constant. + +Signed-off-by: Krystian Hebel +--- + include/grub/i386/memory.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h +index c64529630f19..56f64855be7e 100644 +--- a/include/grub/i386/memory.h ++++ b/include/grub/i386/memory.h +@@ -22,6 +22,7 @@ + + #define GRUB_PAGE_SHIFT 12 + #define GRUB_PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) ++#define GRUB_PAGE_MASK (~(GRUB_PAGE_SIZE - 1)) + + /* The flag for protected mode. */ + #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +@@ -43,8 +44,12 @@ + + #define GRUB_MMAP_MALLOC_LOW 1 + ++#include + #include + ++#define GRUB_PAGE_UP(p) ALIGN_UP (p, GRUB_PAGE_SIZE) ++#define GRUB_PAGE_DOWN(p) ALIGN_DOWN (p, GRUB_PAGE_SIZE) ++ + struct grub_e820_mmap_entry + { + grub_uint64_t addr; +-- +2.41.0 + diff --git a/1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch b/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch similarity index 78% rename from 1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch rename to 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch index 5cb2225..94028b1 100644 --- a/1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch +++ b/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch @@ -1,4 +1,4 @@ -From 47c88e17987444c862dd83a5e5aeb2faa6b4afb1 Mon Sep 17 00:00:00 2001 +From 0cfc0a5385a0847f79c9225d9dd9522ef25efaad Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:34:59 +0200 Subject: [PATCH] mmap: Add grub_mmap_get_lowest() and grub_mmap_get_highest() @@ -11,15 +11,23 @@ Intel TXT secure launcher introduced by subsequent patches. Signed-off-by: Daniel Kiper --- - grub-core/mmap/mmap.c | 70 +++++++++++++++++++++++++++++++++++++++++++ + grub-core/mmap/mmap.c | 79 +++++++++++++++++++++++++++++++++++++++++++ include/grub/memory.h | 3 ++ - 2 files changed, 73 insertions(+) + 2 files changed, 82 insertions(+) diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c -index c8c8312c56f2..1e93b7e3cabb 100644 +index c8c8312c56f2..5b18b1a4c297 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c -@@ -343,6 +343,76 @@ grub_mmap_unregister (int handle) +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -343,6 +344,84 @@ grub_mmap_unregister (int handle) #endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ @@ -35,14 +43,18 @@ index c8c8312c56f2..1e93b7e3cabb 100644 + void *data) +{ + addr_limit_t *al = data; ++ grub_uint64_t end; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + ++ if (grub_add (addr, size, &end)) ++ return 0; ++ + if (addr >= al->limit) + al->addr = grub_min (al->addr, addr); + -+ if ((addr < al->limit) && ((addr + size) > al->limit)) ++ if ((addr < al->limit) && (end > al->limit)) + al->addr = al->limit; + + return 0; @@ -66,14 +78,18 @@ index c8c8312c56f2..1e93b7e3cabb 100644 + void *data) +{ + addr_limit_t *al = data; ++ grub_uint64_t end; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + -+ if ((addr + size) < al->limit) -+ al->addr = grub_max (al->addr, addr + size); ++ if (grub_add (addr, size, &end)) ++ return 0; ++ ++ if (end < al->limit) ++ al->addr = grub_max (al->addr, end); + -+ if ((addr < al->limit) && ((addr + size) >= al->limit)) ++ if ((addr < al->limit) && (end >= al->limit)) + al->addr = al->limit; + + return 0; @@ -111,5 +127,5 @@ index 6da114a1bdc1..8f22f752502b 100644 struct grub_mmap_region -- -2.17.1 +2.41.0 diff --git a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch index f447456..5c68ceb 100644 --- a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch +++ b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch @@ -1,4 +1,4 @@ -From 979cabb7a0e1bb6119b32a7465a569d6ddd8ee84 Mon Sep 17 00:00:00 2001 +From a14dcf40c6eddc23c90a2486eb2665433824a4e2 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 22 Apr 2020 21:41:24 +0200 Subject: [PATCH] i386/tpm: Rename tpm module to tpm_verifier @@ -92,5 +92,5 @@ index 2052c36eaba5..1d820a774b3b 100644 grub_verifier_unregister (&grub_tpm_verifier); } -- -2.17.1 +2.41.0 diff --git a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch index 0343bf8..d449d26 100644 --- a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch +++ b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch @@ -1,4 +1,4 @@ -From 5eca1b0802b90b5c0c928809f8bb76f41fd0e589 Mon Sep 17 00:00:00 2001 +From 8527ee439916f427443d0eb68b7eb9be031611ee Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:30:58 +0200 Subject: [PATCH] i386/tpm: Add TPM TIS and CRB driver @@ -9,18 +9,18 @@ by subsequent patches. Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/commands/i386/tpm.c | 152 ++++++++++++++++++++++++++++++++++ + grub-core/commands/i386/tpm.c | 149 ++++++++++++++++++++++++++++++++++ include/grub/i386/tpm.h | 36 ++++++++ - 2 files changed, 188 insertions(+) + 2 files changed, 185 insertions(+) create mode 100644 grub-core/commands/i386/tpm.c create mode 100644 include/grub/i386/tpm.h diff --git a/grub-core/commands/i386/tpm.c b/grub-core/commands/i386/tpm.c new file mode 100644 -index 000000000000..1c57e5e826f9 +index 000000000000..f3b6f51ecd05 --- /dev/null +++ b/grub-core/commands/i386/tpm.c -@@ -0,0 +1,152 @@ +@@ -0,0 +1,149 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Free Software Foundation, Inc. @@ -108,9 +108,9 @@ index 000000000000..1c57e5e826f9 + grub_addr_t addr = TPM_MMIO_BASE + lcl * GRUB_PAGE_SIZE; + + if (tpm_intf == TPM_INTF_TIS) -+ grub_writeb (TIS_RELINQUISH_LCL, addr + TPM_ACCESS); ++ grub_write8 (TIS_RELINQUISH_LCL, addr + TPM_ACCESS); + else if (tpm_intf == TPM_INTF_CRB) -+ grub_writel (CRB_RELINQUISH_LCL, addr + TPM_LOC_CTRL); ++ grub_write32 (CRB_RELINQUISH_LCL, addr + TPM_LOC_CTRL); +} + +static grub_err_t @@ -146,27 +146,24 @@ index 000000000000..1c57e5e826f9 + cmd_tpm_type = grub_register_command ("tpm_type", grub_cmd_tpm_type, + NULL, N_("Show TPM version and interface type.")); + -+ intf_cap = grub_readl (TPM_MMIO_BASE + TPM_INTF_CAPABILITY); -+ intf_cap >>= INTF_CAP_INTERFACE_VERSION_SHIFT; -+ intf_cap &= INTF_CAP_INTERFACE_VERSION_MASK; -+ -+ if (intf_cap == TPM_12_TIS_INTF_12 || intf_cap == TPM_12_TIS_INTF_13) -+ { -+ tpm_ver = GRUB_TPM_12; -+ tpm_intf = TPM_INTF_TIS; -+ return; -+ } -+ -+ if (intf_cap != TPM_20_TIS_INTF_13) -+ return; -+ + tpm_ver = GRUB_TPM_20; + -+ intf_id = grub_readl (TPM_MMIO_BASE + TPM_INTERFACE_ID); ++ intf_id = grub_read32 (TPM_MMIO_BASE + TPM_INTERFACE_ID); + intf_id >>= INTERFACE_ID_INTERFACE_TYPE_SHIFT; + intf_id &= INTERFACE_ID_INTERFACE_TYPE_MASK; + + tpm_intf = (intf_id == TPM_CRB_INTF_ACTIVE) ? TPM_INTF_CRB : TPM_INTF_TIS; ++ ++ /* CRB exists only in TPM 2.0 */ ++ if (tpm_intf == TPM_INTF_CRB) ++ return; ++ ++ intf_cap = grub_read32 (TPM_MMIO_BASE + TPM_INTF_CAPABILITY); ++ intf_cap >>= INTF_CAP_INTERFACE_VERSION_SHIFT; ++ intf_cap &= INTF_CAP_INTERFACE_VERSION_MASK; ++ ++ if (intf_cap == TPM_12_TIS_INTF_12 || intf_cap == TPM_12_TIS_INTF_13) ++ tpm_ver = GRUB_TPM_12; +} + +GRUB_MOD_FINI (tpm) @@ -216,5 +213,5 @@ index 000000000000..d22a2507efa1 + +#endif /* GRUB_I386_TPM_H */ -- -2.17.1 +2.41.0 diff --git a/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch b/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch similarity index 69% rename from 1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch rename to 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch index 909a45b..adb2c19 100644 --- a/1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +++ b/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch @@ -1,19 +1,24 @@ -From 1d08644f2c341b472ea9db94de746b3030a5f1c3 Mon Sep 17 00:00:00 2001 +From f6a4ec51420020d205add6a8a95d13cd1b5a2be5 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:50:14 -0400 Subject: [PATCH] i386/slaunch: Add basic platform support for secure launch +Some of the commands declared in header files will be implemented in +the follow-up commits. + Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - include/grub/i386/cpuid.h | 12 ++++ - include/grub/i386/crfr.h | 127 ++++++++++++++++++++++++++++++++++++++ - include/grub/i386/mmio.h | 72 +++++++++++++++++++++ - include/grub/i386/msr.h | 61 ++++++++++++++++++ - 4 files changed, 272 insertions(+) + include/grub/i386/cpuid.h | 12 ++++ + include/grub/i386/crfr.h | 127 ++++++++++++++++++++++++++++++++++++ + include/grub/i386/mmio.h | 72 ++++++++++++++++++++ + include/grub/i386/msr.h | 63 ++++++++++++++++++ + include/grub/i386/slaunch.h | 58 ++++++++++++++++ + 5 files changed, 332 insertions(+) create mode 100644 include/grub/i386/crfr.h create mode 100644 include/grub/i386/mmio.h + create mode 100644 include/grub/i386/slaunch.h diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h index f7ae4b0a4641..0ddd87b1544e 100644 @@ -40,7 +45,7 @@ index f7ae4b0a4641..0ddd87b1544e 100644 diff --git a/include/grub/i386/crfr.h b/include/grub/i386/crfr.h new file mode 100644 -index 000000000000..1dcae427dc8b +index 000000000000..2efd42a1767c --- /dev/null +++ b/include/grub/i386/crfr.h @@ -0,0 +1,127 @@ @@ -91,7 +96,7 @@ index 000000000000..1dcae427dc8b +#define GRUB_CR4_X86_PGE 0x00000080 /* Enable Page global */ +#define GRUB_CR4_X86_PCE 0x00000100 /* Enable Performance monitoring counter */ +#define GRUB_CR4_X86_FXSR 0x00000200 /* Fast FPU save/restore */ -+#define GRUB_CR4_X86_XMM 0x00000400 /* Enable SIMD/MMX2 to use except 16 */ ++#define GRUB_CR4_X86_XMM 0x00000400 /* Generate #XM instead of #UD for SIMD */ +#define GRUB_CR4_X86_VMXE 0x00002000 /* Enable VMX */ +#define GRUB_CR4_X86_SMXE 0x00004000 /* Enable SMX */ +#define GRUB_CR4_X86_PCIDE 0x00020000 /* Enable PCID */ @@ -173,7 +178,7 @@ index 000000000000..1dcae427dc8b +#endif diff --git a/include/grub/i386/mmio.h b/include/grub/i386/mmio.h new file mode 100644 -index 000000000000..b5bce71ef8d6 +index 000000000000..97a30f7d8af6 --- /dev/null +++ b/include/grub/i386/mmio.h @@ -0,0 +1,72 @@ @@ -201,7 +206,7 @@ index 000000000000..b5bce71ef8d6 +#include + +static inline grub_uint8_t -+grub_readb (const grub_addr_t addr) ++grub_read8 (const grub_addr_t addr) +{ + grub_uint8_t val; + @@ -211,7 +216,7 @@ index 000000000000..b5bce71ef8d6 +} + +static inline grub_uint32_t -+grub_readl (const grub_addr_t addr) ++grub_read32 (const grub_addr_t addr) +{ + grub_uint32_t val; + @@ -221,7 +226,7 @@ index 000000000000..b5bce71ef8d6 +} + +static inline grub_uint64_t -+grub_readq (const grub_addr_t addr) ++grub_read64 (const grub_addr_t addr) +{ + grub_uint64_t val; + @@ -231,26 +236,26 @@ index 000000000000..b5bce71ef8d6 +} + +static inline void -+grub_writeb (grub_uint8_t val, grub_addr_t addr) ++grub_write8 (grub_uint8_t val, grub_addr_t addr) +{ + (*(volatile grub_uint8_t *) (addr)) = val; +} + +static inline void -+grub_writel (grub_uint32_t val, grub_addr_t addr) ++grub_write32 (grub_uint32_t val, grub_addr_t addr) +{ + (*(volatile grub_uint32_t *) (addr)) = val; +} + +static inline void -+grub_writeq (grub_uint64_t val, grub_addr_t addr) ++grub_write64 (grub_uint64_t val, grub_addr_t addr) +{ + (*(volatile grub_uint64_t *) (addr)) = val; +} + +#endif /* GRUB_I386_MMIO_H */ diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h -index 1e838c022f41..b99c49f002ee 100644 +index 1e838c022f41..52c923ab94ac 100644 --- a/include/grub/i386/msr.h +++ b/include/grub/i386/msr.h @@ -2,6 +2,9 @@ @@ -263,7 +268,7 @@ index 1e838c022f41..b99c49f002ee 100644 * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or -@@ -19,6 +22,62 @@ +@@ -19,6 +22,64 @@ #ifndef GRUB_I386_MSR_H #define GRUB_I386_MSR_H 1 @@ -273,26 +278,30 @@ index 1e838c022f41..b99c49f002ee 100644 +#define GRUB_MSR_X86_APICBASE 0x0000001b +#define GRUB_MSR_X86_APICBASE_BSP (1<<8) +#define GRUB_MSR_X86_APICBASE_ENABLE (1<<11) -+#define GRUB_MSR_X86_APICBASE_BASE (0xfffff<<12) ++#define GRUB_MSR_X86_APICBASE_BASE (0xfffff<<12) /* Mask for APIC base address */ + +#define GRUB_MSR_X86_FEATURE_CONTROL 0x0000003a -+#define GRUB_MSR_X86_ENABLE_VMX_IN_SMX (1<<1) -+#define GRUB_MSR_X86_SENTER_FUNCTIONS (0x7f<<8) -+#define GRUB_MSR_X86_SENTER_ENABLE (1<<15) ++#define GRUB_MSR_X86_FEATURE_CTRL_LOCK (1<<0) /* Lock writes to this register */ ++#define GRUB_MSR_X86_ENABLE_VMX_IN_SMX (1<<1) /* Enable VMX inside SMX */ ++#define GRUB_MSR_X86_ENABLE_VMX_OUT_SMX (1<<2) /* Enable VMX outside SMX */ ++#define GRUB_MSR_X86_SENTER_FUNCTIONS (0x7f<<8) /* Bitmap of SENTER function enables */ ++#define GRUB_MSR_X86_SENTER_ENABLE (1<<15) /* SENTER global enable */ + +#define GRUB_MSR_X86_MTRRCAP 0x000000fe -+#define GRUB_MSR_X86_VCNT_MASK 0xff ++#define GRUB_MSR_X86_VCNT_MASK 0xff /* Number of variable MTRRs */ + +#define GRUB_MSR_X86_MCG_CAP 0x00000179 -+#define GRUB_MSR_MCG_BANKCNT_MASK 0xff /* Number of banks */ ++#define GRUB_MSR_MCG_BANKCNT_MASK 0xff /* Number of banks */ +#define GRUB_MSR_X86_MCG_STATUS 0x0000017a -+#define GRUB_MSR_MCG_STATUS_MCIP (1ULL<<2) /* MC in progress */ ++#define GRUB_MSR_MCG_STATUS_MCIP (1ULL<<2) /* MC in progress */ + +#define GRUB_MSR_X86_MISC_ENABLE 0x000001a0 +#define GRUB_MSR_X86_ENABLE_MONITOR_FSM (1<<18) + +#define GRUB_MSR_X86_MTRR_PHYSBASE0 0x00000200 +#define GRUB_MSR_X86_MTRR_PHYSMASK0 0x00000201 ++#define GRUB_MSR_X86_MTRR_PHYSBASE(n) (GRUB_MSR_X86_MTRR_PHYSBASE0 + 2 * (n)) ++#define GRUB_MSR_X86_MTRR_PHYSMASK(n) (GRUB_MSR_X86_MTRR_PHYSMASK0 + 2 * (n)) +#define GRUB_MSR_X86_BASE_DEF_TYPE_MASK 0xff +#define GRUB_MSR_X86_MASK_VALID (1<<11) + @@ -303,16 +312,14 @@ index 1e838c022f41..b99c49f002ee 100644 + +#define GRUB_MSR_X86_MC0_STATUS 0x00000401 + -+#define GRUB_MSR_X86_EFER 0xc0000080 /* Extended features */ -+#define GRUB_MSR_EFER_LME (1<<8) /* Enable Long Mode/IA-32e */ -+#define GRUB_MSR_EFER_LMA (1<<10) /* Long Mode/IA-32e Actuve */ -+#define GRUB_MSR_EFER_SVME (1<<12) /* Enable SVM (AMD-V) */ ++#define GRUB_MSR_X86_EFER 0xc0000080 /* Extended features */ ++#define GRUB_MSR_EFER_LME (1<<8) /* Enable Long Mode/IA-32e */ ++#define GRUB_MSR_EFER_LMA (1<<10) /* Long Mode/IA-32e Active */ ++#define GRUB_MSR_EFER_SVME (1<<12) /* Enable SVM (AMD-V) */ + +/* AMD Specific */ -+#define GRUB_MSR_AMD64_PATCH_LEVEL 0x0000008b -+#define GRUB_MSR_AMD64_PATCH_CLEAR 0xc0010021 /* AMD-specific microcode patch clear */ -+#define GRUB_MSR_AMD64_VM_CR 0xc0010114 -+#define GRUB_MSR_SVM_VM_CR_SVM_DISABLE 4 ++#define GRUB_MSR_AMD64_VM_CR 0xc0010114 /* SVM control register */ ++#define GRUB_MSR_SVM_VM_CR_SVM_DISABLE (1<<4) /* Disable writes to EFER.SVME */ + +/* MTRR Specific */ +#define GRUB_MTRR_MEMORY_TYPE_UC 0 @@ -326,13 +333,77 @@ index 1e838c022f41..b99c49f002ee 100644 #include #include #include -@@ -71,4 +130,6 @@ grub_wrmsr (grub_uint32_t msr_id, grub_uint64_t msr_value) +@@ -71,4 +132,6 @@ grub_wrmsr (grub_uint32_t msr_id, grub_uint64_t msr_value) asm volatile ("wrmsr" : : "c" (msr_id), "a" (low), "d" (high)); } +#endif /* ASM_FILE */ + #endif /* GRUB_I386_MSR_H */ +diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h +new file mode 100644 +index 000000000000..f7160d5fab0c +--- /dev/null ++++ b/include/grub/i386/slaunch.h +@@ -0,0 +1,58 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * Main secure launch definitions header file. ++ */ ++ ++#ifndef GRUB_I386_SLAUNCH_H ++#define GRUB_I386_SLAUNCH_H 1 ++ ++/* Secure launch platform types. */ ++#define SLP_NONE 0 ++#define SLP_INTEL_TXT 1 ++ ++#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE) ++ ++#ifndef ASM_FILE ++ ++#include ++#include ++ ++struct grub_slaunch_params ++{ ++ grub_uint32_t boot_params_addr; ++ grub_uint32_t mle_start; ++ grub_uint32_t mle_size; ++ void *mle_ptab_mem; ++ grub_uint64_t mle_ptab_target; ++ grub_uint32_t mle_ptab_size; ++ grub_uint32_t mle_header_offset; ++ grub_uint32_t ap_wake_block; ++ grub_uint32_t ap_wake_block_size; ++ grub_uint32_t dce_base; ++ grub_uint32_t dce_size; ++ grub_uint64_t tpm_evt_log_base; ++ grub_uint32_t tpm_evt_log_size; ++}; ++ ++extern grub_uint32_t grub_slaunch_platform_type (void); ++extern void *grub_slaunch_module (void); ++extern struct grub_slaunch_params *grub_slaunch_params (void); ++ ++#endif /* ASM_FILE */ ++ ++#endif /* GRUB_I386_SLAUNCH_H */ -- -2.17.1 +2.41.0 diff --git a/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch b/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch new file mode 100644 index 0000000..2757e1e --- /dev/null +++ b/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch @@ -0,0 +1,323 @@ +From ad10c1df6be8ea4ac9a6346f0719983e0e04f936 Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Mon, 9 Jan 2023 12:55:42 -0500 +Subject: [PATCH] i386/txt: Initial commit of the Secure Launch Resource Table + (SLRT) + +Provide definitions of structures and basic functions for constructing +and parsing of SLRT. + +Signed-off-by: Ross Philipson +Signed-off-by: Sergii Dmytruk +--- + include/grub/slr_table.h | 298 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 298 insertions(+) + create mode 100644 include/grub/slr_table.h + +diff --git a/include/grub/slr_table.h b/include/grub/slr_table.h +new file mode 100644 +index 000000000000..59074723b500 +--- /dev/null ++++ b/include/grub/slr_table.h +@@ -0,0 +1,298 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2023 Oracle and/or its affiliates. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * Secure Launch Resource Table definitions ++ */ ++ ++#ifndef GRUB_SLR_TABLE_H ++#define GRUB_SLR_TABLE_H 1 ++ ++#define GRUB_UEFI_SLR_TABLE_GUID \ ++ { 0x877a9b2a, 0x0385, 0x45d1, { 0xa0, 0x34, 0x9d, 0xac, 0x9c, 0x9e, 0x56, 0x5f }} ++ ++/* SLR table header values */ ++#define GRUB_SLR_TABLE_MAGIC 0x4452544d ++#define GRUB_SLR_TABLE_REVISION 1 ++ ++/* Current revisions for the policy and UEFI config */ ++#define GRUB_SLR_POLICY_REVISION 1 ++#define GRUB_SLR_UEFI_CONFIG_REVISION 1 ++ ++/* SLR defined architectures */ ++#define GRUB_SLR_INTEL_TXT 1 ++#define GRUB_SLR_AMD_SKINIT 2 ++ ++/* SLR defined bootloaders */ ++#define GRUB_SLR_BOOTLOADER_INVALID 0 ++#define GRUB_SLR_BOOTLOADER_GRUB 1 ++ ++/* Log formats */ ++#define GRUB_SLR_DRTM_TPM12_LOG 1 ++#define GRUB_SLR_DRTM_TPM20_LOG 2 ++ ++/* DRTM Policy Entry Flags */ ++#define GRUB_SLR_POLICY_FLAG_MEASURED 0x1 ++#define GRUB_SLR_POLICY_IMPLICIT_SIZE 0x2 ++ ++/* Array Lengths */ ++#define GRUB_TPM_EVENT_INFO_LENGTH 32 ++#define GRUB_TXT_VARIABLE_MTRRS_LENGTH 32 ++ ++/* Tags */ ++#define GRUB_SLR_ENTRY_INVALID 0x0000 ++#define GRUB_SLR_ENTRY_DL_INFO 0x0001 ++#define GRUB_SLR_ENTRY_LOG_INFO 0x0002 ++#define GRUB_SLR_ENTRY_DRTM_POLICY 0x0003 ++#define GRUB_SLR_ENTRY_INTEL_INFO 0x0004 ++#define GRUB_SLR_ENTRY_AMD_INFO 0x0005 ++#define GRUB_SLR_ENTRY_ARM_INFO 0x0006 ++#define GRUB_SLR_ENTRY_UEFI_INFO 0x0007 ++#define GRUB_SLR_ENTRY_UEFI_CONFIG 0x0008 ++#define GRUB_SLR_ENTRY_END 0xffff ++ ++/* Entity Types */ ++#define GRUB_SLR_ET_UNSPECIFIED 0x0000 ++#define GRUB_SLR_ET_SLRT 0x0001 ++#define GRUB_SLR_ET_BOOT_PARAMS 0x0002 ++#define GRUB_SLR_ET_SETUP_DATA 0x0003 ++#define GRUB_SLR_ET_CMDLINE 0x0004 ++#define GRUB_SLR_ET_UEFI_MEMMAP 0x0005 ++#define GRUB_SLR_ET_RAMDISK 0x0006 ++#define GRUB_SLR_ET_MULTIBOOT2_INFO 0x0007 ++#define GRUB_SLR_ET_MULTIBOOT2_MODULE 0x0008 ++#define GRUB_SLR_ET_TXT_OS2MLE 0x0010 ++#define GRUB_SLR_ET_UNUSED 0xffff ++ ++/* ++ * Primary SLR Table Header ++ */ ++struct grub_slr_table ++{ ++ grub_uint32_t magic; ++ grub_uint16_t revision; ++ grub_uint16_t architecture; ++ grub_uint32_t size; ++ grub_uint32_t max_size; ++ /* entries[] */ ++} GRUB_PACKED; ++ ++/* ++ * Common SLRT Table Header ++ */ ++struct grub_slr_entry_hdr ++{ ++ grub_uint16_t tag; ++ grub_uint16_t size; ++} GRUB_PACKED; ++ ++/* ++ * Boot loader context ++ */ ++struct grub_slr_bl_context ++{ ++ grub_uint16_t bootloader; ++ grub_uint16_t reserved; ++ grub_uint64_t context; ++} GRUB_PACKED; ++ ++/* ++ * DRTM Dynamic Launch Configuration ++ */ ++struct grub_slr_entry_dl_info ++{ ++ struct grub_slr_entry_hdr hdr; ++ struct grub_slr_bl_context bl_context; ++ grub_uint64_t dl_handler; ++ grub_uint64_t dce_base; ++ grub_uint32_t dce_size; ++ grub_uint64_t dlme_entry; ++} GRUB_PACKED; ++ ++/* ++ * TPM Log Information ++ */ ++struct grub_slr_entry_log_info ++{ ++ struct grub_slr_entry_hdr hdr; ++ grub_uint16_t format; ++ grub_uint16_t reserved; ++ grub_uint64_t addr; ++ grub_uint32_t size; ++} GRUB_PACKED; ++ ++/* ++ * DRTM Measurement Policy ++ */ ++struct grub_slr_entry_policy ++{ ++ struct grub_slr_entry_hdr hdr; ++ grub_uint16_t revision; ++ grub_uint16_t nr_entries; ++ /* policy_entries[] */ ++} GRUB_PACKED; ++ ++/* ++ * DRTM Measurement Entry ++ */ ++struct grub_slr_policy_entry ++{ ++ grub_uint16_t pcr; ++ grub_uint16_t entity_type; ++ grub_uint16_t flags; ++ grub_uint16_t reserved; ++ grub_uint64_t entity; ++ grub_uint64_t size; ++ char evt_info[GRUB_TPM_EVENT_INFO_LENGTH]; ++} GRUB_PACKED; ++ ++/* ++ * Secure Launch defined MTRR saving structures ++ */ ++struct grub_slr_txt_mtrr_pair ++{ ++ grub_uint64_t mtrr_physbase; ++ grub_uint64_t mtrr_physmask; ++} GRUB_PACKED; ++ ++struct grub_slr_txt_mtrr_state ++{ ++ grub_uint64_t default_mem_type; ++ grub_uint64_t mtrr_vcnt; ++ struct grub_slr_txt_mtrr_pair mtrr_pair[GRUB_TXT_VARIABLE_MTRRS_LENGTH]; ++} GRUB_PACKED; ++ ++/* ++ * Intel TXT Info table ++ */ ++struct grub_slr_entry_intel_info ++{ ++ struct grub_slr_entry_hdr hdr; ++ grub_uint64_t saved_misc_enable_msr; ++ struct grub_slr_txt_mtrr_state saved_bsp_mtrrs; ++} GRUB_PACKED; ++ ++/* ++ * AMD SKINIT Info table ++ */ ++struct grub_slr_entry_amd_info ++{ ++ struct grub_slr_entry_hdr hdr; ++} GRUB_PACKED; ++ ++/* ++ * ARM DRTM Info table ++ */ ++struct grub_slr_entry_arm_info ++{ ++ struct grub_slr_entry_hdr hdr; ++} GRUB_PACKED; ++ ++struct grub_slr_entry_uefi_config ++{ ++ struct grub_slr_entry_hdr hdr; ++ grub_uint16_t revision; ++ grub_uint16_t nr_entries; ++ /* uefi_cfg_entries[] */ ++} GRUB_PACKED; ++ ++struct grub_slr_uefi_cfg_entry ++{ ++ grub_uint16_t pcr; ++ grub_uint16_t reserved; ++ grub_uint64_t cfg; /* address or value */ ++ grub_uint32_t size; ++ char evt_info[GRUB_TPM_EVENT_INFO_LENGTH]; ++} GRUB_PACKED; ++ ++static inline void * ++grub_slr_end_of_entries (struct grub_slr_table *table) ++{ ++ return (grub_uint8_t *) table + table->size; ++} ++ ++static inline struct grub_slr_entry_hdr * ++grub_slr_next_entry (struct grub_slr_table *table, ++ struct grub_slr_entry_hdr *curr) ++{ ++ struct grub_slr_entry_hdr *next = (struct grub_slr_entry_hdr *) ++ ((grub_uint8_t *) curr + curr->size); ++ ++ if ((void *)next >= grub_slr_end_of_entries (table)) ++ return NULL; ++ if (next->tag == GRUB_SLR_ENTRY_END) ++ return NULL; ++ ++ return next; ++} ++ ++static inline struct grub_slr_entry_hdr * ++grub_slr_next_entry_by_tag (struct grub_slr_table *table, ++ struct grub_slr_entry_hdr *entry, ++ grub_uint16_t tag) ++{ ++ if (!entry) /* Start from the beginning */ ++ entry = (struct grub_slr_entry_hdr *)((grub_uint8_t *) table + sizeof(*table)); ++ ++ for ( ; ; ) ++ { ++ if (entry->tag == tag) ++ return entry; ++ ++ entry = grub_slr_next_entry (table, entry); ++ if (!entry) ++ return NULL; ++ } ++ ++ return NULL; ++} ++ ++static inline int ++grub_slr_add_entry (struct grub_slr_table *table, ++ struct grub_slr_entry_hdr *entry) ++{ ++ struct grub_slr_entry_hdr *end; ++ ++ if ((table->size + entry->size) > table->max_size) ++ return -1; ++ ++ grub_memcpy ((grub_uint8_t *) table + table->size - sizeof(*end), entry, entry->size); ++ table->size += entry->size; ++ ++ end = (struct grub_slr_entry_hdr *)((grub_uint8_t *) table + table->size - sizeof(*end)); ++ end->tag = GRUB_SLR_ENTRY_END; ++ end->size = sizeof(*end); ++ ++ return 0; ++} ++ ++static inline void ++grub_slr_init_table(struct grub_slr_table *slrt, grub_uint16_t architecture, ++ grub_uint32_t max_size) ++{ ++ struct grub_slr_entry_hdr *end; ++ ++ slrt->magic = GRUB_SLR_TABLE_MAGIC; ++ slrt->revision = GRUB_SLR_TABLE_REVISION; ++ slrt->architecture = architecture; ++ slrt->size = sizeof(*slrt) + sizeof(*end); ++ slrt->max_size = max_size; ++ end = (struct grub_slr_entry_hdr *)((grub_uint8_t *) slrt + sizeof(*slrt)); ++ end->tag = GRUB_SLR_ENTRY_END; ++ end->size = sizeof(*end); ++} ++ ++#endif /* GRUB_SLR_TABLE_H */ +-- +2.41.0 + diff --git a/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch b/1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch similarity index 76% rename from 1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch rename to 1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch index 6922370..da3d5ff 100644 --- a/1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch +++ b/1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch @@ -1,4 +1,4 @@ -From 87a1423e0129ba92eb4ef8d626156067333cbed3 Mon Sep 17 00:00:00 2001 +From a19dcf70a333c0de0e17ea1fa95c0b9ada3197ff Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:53:06 -0400 Subject: [PATCH] i386/txt: Add Intel TXT definitions header file @@ -6,16 +6,16 @@ Subject: [PATCH] i386/txt: Add Intel TXT definitions header file Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper --- - include/grub/i386/txt.h | 691 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 691 insertions(+) + include/grub/i386/txt.h | 725 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 725 insertions(+) create mode 100644 include/grub/i386/txt.h diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h new file mode 100644 -index 000000000000..7d57af68841f +index 000000000000..d8598e259a77 --- /dev/null +++ b/include/grub/i386/txt.h -@@ -0,0 +1,691 @@ +@@ -0,0 +1,725 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -45,44 +45,35 @@ index 000000000000..7d57af68841f +#include +#include + -+/* Intel TXT Software Developers Guide */ -+ -+/* Chapter 2, Table 2 MLE/SINIT Capabilities Field Bit Definitions */ -+ -+#define GRUB_TXT_PCR_EXT_MAX_AGILITY_POLICY 0 -+#define GRUB_TXT_PCR_EXT_MAX_PERF_POLICY 1 ++/* Intel TXT Software Developers Guide Revision 017.4 */ + ++/* Chapter 2, Table 4. MLE/SINIT Capabilities Field Bit Definitions */ +#define GRUB_TXT_PLATFORM_TYPE_LEGACY 0 +#define GRUB_TXT_PLATFORM_TYPE_CLIENT 1 +#define GRUB_TXT_PLATFORM_TYPE_SERVER 2 +#define GRUB_TXT_PLATFORM_TYPE_RESERVED 3 + -+#define GRUB_TXT_CAPS_GETSEC_WAKE_SUPPORT (1<<0) -+#define GRUB_TXT_CAPS_MONITOR_SUPPORT (1<<1) -+#define GRUB_TXT_CAPS_ECX_PT_SUPPORT (1<<2) -+#define GRUB_TXT_CAPS_STM_SUPPORT (1<<3) ++#define GRUB_TXT_CAPS_GETSEC_WAKE_SUPPORT (1<<0) ++#define GRUB_TXT_CAPS_MONITOR_SUPPORT (1<<1) ++#define GRUB_TXT_CAPS_ECX_PT_SUPPORT (1<<2) ++#define GRUB_TXT_CAPS_STM_SUPPORT (1<<3) +#define GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE (1<<4) -+#define GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE (1<<5) -+#define GRUB_TXT_CAPS_PLATFORM_TYPE (3<<6) -+#define GRUB_TXT_CAPS_MAXPHYSADDR_SUPPORT (1<<8) -+#define GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT (1<<9) -+#define GRUB_TXT_CAPS_CBNT_SUPPORT (1<<10) ++#define GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE (1<<5) /* Must be 1 for TPM 2.0 */ ++#define GRUB_TXT_CAPS_PLATFORM_TYPE (3<<6) ++#define GRUB_TXT_CAPS_MAXPHYSADDR_SUPPORT (1<<8) ++#define GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT (1<<9) ++#define GRUB_TXT_CAPS_CBNT_SUPPORT (1<<10) ++#define GRUB_TXT_CAPS_STARTUP_ACM_SUPPORT (7<<11) /* Reserved for MLE, must be 0 */ ++#define GRUB_TXT_CAPS_DMA_PROTECTION (1<<14) /* 0 = Legacy, 1 = TPR */ +/* Rest is reserved */ + +/* Appendix A TXT Execution Technology Authenticated Code Modules */ +/* A.1 Authenticated Code Module Format */ -+ +#define GRUB_TXT_ACM_MODULE_TYPE 2 + +#define GRUB_TXT_ACM_MODULE_SUB_TYPE_TXT_ACM 0 +#define GRUB_TXT_ACM_MODULE_SUB_TYPE_S_ACM 1 + -+#define GRUB_TXT_ACM_HEADER_LEN_0_0 161 -+#define GRUB_TXT_ACM_HEADER_LEN_3_0 224 -+ -+#define GRUB_TXT_ACM_HEADER_VERSION_0_0 0x0000 -+#define GRUB_TXT_ACM_HEADER_VERSION_3_0 0x0300 -+ +#define GRUB_TXT_ACM_FLAG_PREPRODUCTION (1<<14) +#define GRUB_TXT_ACM_FLAG_DEBUG_SIGNED (1<<15) + @@ -117,10 +108,12 @@ index 000000000000..7d57af68841f + /* RSA Pub Key and Signature */ +} GRUB_PACKED; + ++/* A.1.2 ACM Information Table */ +#define GRUB_TXT_ACM_UUID "\xaa\x3a\xc0\x7f\xa7\x46\xdb\x18\x2e\xac\x69\x8f\x8d\x41\x7f\x5a" + +#define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS 0 +#define GRUB_TXT_ACM_CHIPSET_TYPE_SINIT 1 ++/* Revocation ACMs */ +#define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS_RACM 8 +#define GRUB_TXT_ACM_CHIPSET_TYPE_SINIT_RACM 9 + @@ -172,18 +165,6 @@ index 000000000000..7d57af68841f + grub_uint64_t platform_mask; +} GRUB_PACKED; + -+#define GRUB_TXT_TPM_CAPS_EXTPOL_NONE 0 /* TPM 1.2 */ -+#define GRUB_TXT_TPM_CAPS_EXTPOL_MA 1 -+#define GRUB_TXT_TPM_CAPS_EXTPOL_MP 2 -+#define GRUB_TXT_TPM_CAPS_EXTPOL_BOTH 3 -+ -+#define GRUB_TXT_TPM_CAPS_FAMILY_DISCRETE_12 1 -+#define GRUB_TXT_TPM_CAPS_FAMILY_DISCRETE_20 2 -+#define GRUB_TXT_TPM_CAPS_FAMILY_FIRMWARE_20 8 -+ -+#define GRUB_TXT_TPM_CAPS_INITIAL_NV_INDICES 0 -+#define GRUB_TXT_TPM_CAPS_TCP_NV_INDICES 1 -+ +struct grub_txt_acm_tpm_info +{ + grub_uint32_t capabilities; @@ -205,6 +186,7 @@ index 000000000000..7d57af68841f +#define GRUB_TXT_ERRORCODE 0x0030 +#define GRUB_TXT_CMD_RESET 0x0038 +#define GRUB_TXT_CMD_CLOSE_PRIVATE 0x0048 ++/* VER_FSBIF is considered deprecated, but some CPUs still use it */ +#define GRUB_TXT_VER_FSBIF 0x0100 +#define GRUB_TXT_DIDVID 0x0110 +#define GRUB_TXT_VER_QPIIF 0x0200 @@ -214,8 +196,7 @@ index 000000000000..7d57af68841f +#define GRUB_TXT_MLE_JOIN 0x0290 +#define GRUB_TXT_HEAP_BASE 0x0300 +#define GRUB_TXT_HEAP_SIZE 0x0308 -+#define GRUB_TXT_MSEG_BASE 0x0310 -+#define GRUB_TXT_MSEG_SIZE 0x0318 ++/* DPR is considered deprecated, but some CPUs still use it */ +#define GRUB_TXT_DPR 0x0330 +#define GRUB_TXT_CMD_OPEN_LOCALITY1 0x0380 +#define GRUB_TXT_CMD_CLOSE_LOCALITY1 0x0388 @@ -253,7 +234,7 @@ index 000000000000..7d57af68841f + }; +} GRUB_PACKED; + -+#define GRUB_TXT_VERSION_DEBUG_FUSED (1<<31) ++#define GRUB_TXT_VERSION_PROD_FUSED (1<<31) + +/* Appendix C Intel TXT Heap Memory */ + @@ -268,19 +249,11 @@ index 000000000000..7d57af68841f + grub_uint8_t data5[6]; +} GRUB_PACKED; + -+struct grub_txt_heap_ext_data_element -+{ -+ grub_uint32_t type; -+ grub_uint32_t size; -+ grub_uint8_t data[]; -+} GRUB_PACKED; -+ +#define GRUB_TXT_HEAP_EXTDATA_TYPE_END 0 + +struct grub_txt_heap_end_element +{ -+ grub_uint32_t type; -+ grub_uint32_t size; ++ /* Empty, just the common header with type and size */ +} GRUB_PACKED; + +#define GRUB_TXT_HEAP_EXTDATA_TYPE_BIOS_SPEC_VER 1 @@ -298,6 +271,7 @@ index 000000000000..7d57af68841f +{ + grub_uint32_t num_acms; + /* Array of num_acms grub_uint64_t addresses */ ++ grub_uint64_t addr[]; +} GRUB_PACKED; + +#define GRUB_TXT_HEAP_EXTDATA_TYPE_STM 3 @@ -305,6 +279,9 @@ index 000000000000..7d57af68841f +struct grub_txt_heap_stm_element +{ + /* STM specific BIOS properties */ ++ /* GNU extension used to counteract "error: flexible array member in a struct ++ * with no named members". */ ++ grub_uint8_t data[0]; +} GRUB_PACKED; + +#define GRUB_TXT_HEAP_EXTDATA_TYPE_CUSTOM 4 @@ -313,14 +290,14 @@ index 000000000000..7d57af68841f +{ + struct grub_txt_heap_uuid uuid; + /* Vendor Data */ ++ grub_uint8_t data[]; +} GRUB_PACKED; + ++/* Deprecated, but still used for TPM 1.2 */ +#define GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR 5 + +struct grub_txt_heap_tpm_event_log_element +{ -+ grub_uint32_t type; -+ grub_uint32_t size; + grub_uint64_t event_log_phys_addr; +} GRUB_PACKED; + @@ -329,14 +306,15 @@ index 000000000000..7d57af68841f +struct grub_txt_heap_madt_element +{ + /* Copy of ACPI MADT table */ ++ /* GNU extension used to counteract "error: flexible array member in a struct ++ * with no named members". */ ++ grub_uint8_t madt[0]; +} GRUB_PACKED; + +#define GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1 8 + +struct grub_txt_heap_event_log_pointer2_1_element +{ -+ grub_uint32_t type; -+ grub_uint32_t size; + grub_uint64_t phys_addr; + grub_uint32_t allocated_event_container_size; + grub_uint32_t first_record_offset; @@ -348,6 +326,28 @@ index 000000000000..7d57af68841f +struct grub_txt_heap_mcfg_element +{ + /* Copy of ACPI MCFG table */ ++ /* GNU extension used to counteract "error: flexible array member in a struct ++ * with no named members". */ ++ grub_uint8_t data[0]; ++} GRUB_PACKED; ++ ++#define GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE (2 * sizeof(grub_uint32_t)) ++ ++struct grub_txt_heap_ext_data_element ++{ ++ grub_uint32_t type; ++ grub_uint32_t size; /* Must be at least 8 bytes, includes size of this struct */ ++ union { ++ struct grub_txt_heap_end_element end; ++ struct grub_txt_heap_bios_spec_ver_element bios_spec_ver; ++ struct grub_txt_heap_acm_element acm; ++ struct grub_txt_heap_stm_element stm; ++ struct grub_txt_heap_custom_element custom; ++ struct grub_txt_heap_tpm_event_log_element tpm_event_log; ++ struct grub_txt_heap_madt_element madt; ++ struct grub_txt_heap_event_log_pointer2_1_element event_log_pointer2_1; ++ struct grub_txt_heap_mcfg_element mcfg; ++ }; +} GRUB_PACKED; + +/* TXT Heap Tables */ @@ -357,7 +357,7 @@ index 000000000000..7d57af68841f + grub_uint32_t version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */ + grub_uint32_t bios_sinit_size; + grub_uint64_t reserved1; -+ grub_uint64_t reserved22; ++ grub_uint64_t reserved2; + grub_uint32_t num_logical_procs; + /* Versions >= 5 with updates in version 6 */ + grub_uint32_t sinit_flags; @@ -367,9 +367,6 @@ index 000000000000..7d57af68841f +} GRUB_PACKED; + +/* GRUB SLAUNCH specific definitions OS-MLE data */ -+#define GRUB_SL_BOOTPARAMS_OFFSET 0x12c -+#define GRUB_SL_MAX_EVENT_LOG_SIZE (5*4*1024) /* 4k*5 */ -+#define GRUB_SL_MAX_VARIABLE_MTRRS 32 +#define GRUB_SL_OS_MLE_STRUCT_VERSION 1 + +struct grub_slaunch_mtrr_pair @@ -398,10 +395,14 @@ index 000000000000..7d57af68841f + grub_uint8_t mle_scratch[64]; +} GRUB_PACKED; + ++/* Table 29. OS to SINIT Data Table */ ++#define GRUB_TXT_PCR_EXT_MAX_AGILITY_POLICY 0 ++#define GRUB_TXT_PCR_EXT_MAX_PERF_POLICY 1 ++ +struct grub_txt_os_sinit_data +{ + grub_uint32_t version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */ -+ grub_uint32_t flags; ++ grub_uint32_t flags; /* Version 7+ only, otherwise reserved */ + grub_uint64_t mle_ptab; + grub_uint64_t mle_size; + grub_uint64_t mle_hdr_base; @@ -412,8 +413,9 @@ index 000000000000..7d57af68841f + grub_uint64_t lcp_po_base; + grub_uint64_t lcp_po_size; + grub_uint32_t capabilities; -+ /* Version = 5 */ -+ grub_uint64_t efi_rsdt_ptr; ++ /* Versions >= 5 */ ++ /* Warning: version 5 has pointer to RSDT here, not RSDP */ ++ grub_uint64_t efi_rsdp_ptr; + /* Versions >= 6 */ + /* Ext Data Elements */ + grub_uint8_t ext_data_elts[]; @@ -422,7 +424,7 @@ index 000000000000..7d57af68841f +struct grub_txt_sinit_mle_data +{ + grub_uint32_t version; /* Current values are 6 through 9 */ -+ /* Versions <= 8 */ ++ /* Reserved for versions >= 9, must be 0 */ + grub_uint8_t bios_acm_id[20]; + grub_uint32_t edx_senter_flags; + grub_uint64_t mseg_valid; @@ -439,7 +441,7 @@ index 000000000000..7d57af68841f + grub_uint32_t sinit_vtd_dmar_table_size; + grub_uint32_t sinit_vtd_dmar_table_offset; + /* Versions >= 8 */ -+ grub_uint32_t processor_scrtm_status; ++ grub_uint32_t processor_scrtm_status; /* Reserved for version 9 */ + /* Versions >= 9 */ + /* Ext Data Elements */ +} GRUB_PACKED; @@ -454,7 +456,9 @@ index 000000000000..7d57af68841f + +/* Section 2 Measured Launch Environment */ +/* 2.1 MLE Architecture Overview */ -+/* Table 1. MLE Header structure */ ++/* Table 3. MLE Header structure */ ++ ++#define GRUB_TXT_MLE_UUID "\x5a\xac\x82\x90\x6f\x47\xa7\x74\x0f\x5c\x55\xa2\xcb\x51\xb6\x42" + +struct grub_txt_mle_header +{ @@ -485,18 +489,44 @@ index 000000000000..7d57af68841f + +/* TXT register and heap access */ + ++static inline grub_uint8_t ++grub_txt_reg_pub_readb (grub_uint16_t reg) ++{ ++ return grub_read8 (GRUB_TXT_CFG_REGS_PUB + reg); ++} ++ ++static inline grub_uint32_t ++grub_txt_reg_pub_readl (grub_uint16_t reg) ++{ ++ return grub_read32 (GRUB_TXT_CFG_REGS_PUB + reg); ++} ++ +static inline grub_uint64_t -+grub_txt_reg_pub_readq (grub_uint32_t reg) ++grub_txt_reg_pub_readq (grub_uint16_t reg) +{ -+ return grub_readq ((void *) (GRUB_TXT_CFG_REGS_PUB + reg)); ++ return grub_read64 (GRUB_TXT_CFG_REGS_PUB + reg); +} + +static inline grub_uint8_t * +grub_txt_get_heap (void) +{ -+ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE); ++ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); +} + ++static inline grub_uint32_t ++grub_txt_get_heap_size (void) ++{ ++ return grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE); ++} ++ ++/* ++ * Each block of data on heap begins with 64-bit size field, followed by proper ++ * data. Specified size includes size field, so the minimal value of that field ++ * is 8. TXT SDG mentions that all sizes must be multiples of 8 bytes, but even ++ * BiosData produced by code signed by Intel doesn't follow that requirement. ++ * This means that we can't just cast pointer to arbitrary location on TXT heap ++ * with (grub_uint64_t *), because unaligned pointer is UB. ++ */ +static inline grub_uint64_t +grub_txt_bios_data_size (grub_uint8_t *heap) +{ @@ -518,14 +548,16 @@ index 000000000000..7d57af68841f +static inline struct grub_txt_os_mle_data* +grub_txt_os_mle_data_start (grub_uint8_t *heap) +{ -+ return (struct grub_txt_os_mle_data*)(heap + grub_txt_bios_data_size (heap) + ++ return (struct grub_txt_os_mle_data*)(heap + ++ grub_txt_bios_data_size (heap) + + sizeof (grub_uint64_t)); +} + +static inline grub_uint64_t +grub_txt_os_sinit_data_size (grub_uint8_t *heap) +{ -+ return *(grub_uint64_t *)(heap + grub_txt_bios_data_size (heap) + ++ return *(grub_uint64_t *)(heap + ++ grub_txt_bios_data_size (heap) + + grub_txt_os_mle_data_size (heap)); +} + @@ -533,14 +565,16 @@ index 000000000000..7d57af68841f +grub_txt_os_sinit_data_start (grub_uint8_t *heap) +{ + return (struct grub_txt_os_sinit_data*)(heap + -+ grub_txt_bios_data_size (heap) + -+ grub_txt_os_mle_data_size (heap) + sizeof (grub_uint64_t)); ++ grub_txt_bios_data_size (heap) + ++ grub_txt_os_mle_data_size (heap) + ++ sizeof (grub_uint64_t)); +} + +static inline grub_uint64_t +grub_txt_sinit_mle_data_size (grub_uint8_t *heap) +{ -+ return *(grub_uint64_t *)(heap + grub_txt_bios_data_size (heap) + ++ return *(grub_uint64_t *)(heap + ++ grub_txt_bios_data_size (heap) + + grub_txt_os_mle_data_size (heap) + + grub_txt_os_sinit_data_size (heap)); +} @@ -549,10 +583,10 @@ index 000000000000..7d57af68841f +grub_txt_sinit_mle_data_start (grub_uint8_t *heap) +{ + return (struct grub_txt_sinit_mle_data*)(heap + -+ grub_txt_bios_data_size (heap) + -+ grub_txt_os_mle_data_size (heap) + -+ grub_txt_os_sinit_data_size (heap) + -+ sizeof (grub_uint64_t)); ++ grub_txt_bios_data_size (heap) + ++ grub_txt_os_mle_data_size (heap) + ++ grub_txt_os_sinit_data_size (heap) + ++ sizeof (grub_uint64_t)); +} + +/* Intel 64 and IA-32 Architectures Software Developer’s Manual */ @@ -586,7 +620,7 @@ index 000000000000..7d57af68841f +{ + grub_uint32_t caps; + -+ asm volatile (".byte 0x0f,0x37\n" ++ asm volatile ("getsec" + : "=a" (caps) + : "a" (GRUB_SMX_LEAF_CAPABILITIES), "b" (index)); + return caps; @@ -595,7 +629,7 @@ index 000000000000..7d57af68841f +static inline void +grub_txt_getsec_enteraccs (grub_uint32_t acm_phys_addr, grub_uint32_t acm_size) +{ -+ asm volatile (".byte 0x0f,0x37\n" : ++ asm volatile ("getsec" : + : "a" (GRUB_SMX_LEAF_ENTERACCS), + "b" (acm_phys_addr), "c" (acm_size)); +} @@ -603,22 +637,34 @@ index 000000000000..7d57af68841f +static inline void +grub_txt_getsec_exitac (grub_uint32_t near_jump) +{ -+ asm volatile (".byte 0x0f,0x37\n" : ++ asm volatile ("getsec" : + : "a" (GRUB_SMX_LEAF_EXITAC), "b" (near_jump)); +} + +static inline void +grub_txt_getsec_senter (grub_uint32_t acm_phys_addr, grub_uint32_t acm_size) +{ -+ asm volatile (".byte 0x0f,0x37\n" : ++ asm volatile ("getsec" : + : "a" (GRUB_SMX_LEAF_SENTER), -+ "b" (acm_phys_addr), "c" (acm_size)); ++ "b" (acm_phys_addr), "c" (acm_size), "d"(0)); +} + +static inline void +grub_txt_getsec_sexit (void) +{ -+ asm volatile (".byte 0x0f,0x37\n" : : "a" (GRUB_SMX_LEAF_SEXIT)); ++ asm volatile ("getsec" : : "a" (GRUB_SMX_LEAF_SEXIT)); ++} ++ ++static inline void ++grub_txt_getsec_parameters (grub_uint32_t index, grub_uint32_t *eax_out, ++ grub_uint32_t *ebx_out, grub_uint32_t *ecx_out) ++{ ++ if (!eax_out || !ebx_out || !ecx_out) ++ return; ++ ++ asm volatile ("getsec" ++ : "=a" (*eax_out), "=b" (*ebx_out), "=c" (*ecx_out) ++ : "a" (GRUB_SMX_LEAF_PARAMETERS), "b" (index)); +} + +#define GRUB_SMX_PARAMETER_TYPE_MASK 0x1f @@ -632,7 +678,7 @@ index 000000000000..7d57af68841f + +#define GRUB_SMX_PARAMETER_MAX_VERSIONS 0x20 + -+#define GRUB_SMX_GET_MAX_ACM_SIZE(v) ((v & ~GRUB_SMX_PARAMETER_TYPE_MASK)*0x20) ++#define GRUB_SMX_GET_MAX_ACM_SIZE(v) ((v) & ~(__typeof__(v))GRUB_SMX_PARAMETER_TYPE_MASK) + +#define GRUB_SMX_ACM_MEMORY_TYPE_UC 0x00000100 +#define GRUB_SMX_ACM_MEMORY_TYPE_WC 0x00000200 @@ -640,13 +686,13 @@ index 000000000000..7d57af68841f +#define GRUB_SMX_ACM_MEMORY_TYPE_WP 0x00002000 +#define GRUB_SMX_ACM_MEMORY_TYPE_WB 0x00004000 + -+#define GRUB_SMX_GET_ACM_MEMORY_TYPES(v) (v & ~GRUB_SMX_PARAMETER_TYPE_MASK) ++#define GRUB_SMX_GET_ACM_MEMORY_TYPES(v) ((v) & ~(__typeof__(v))GRUB_SMX_PARAMETER_TYPE_MASK) + +#define GRUB_SMX_GET_SENTER_CONTROLS(v) ((v & 0x7f00) >> 8) + +#define GRUB_SMX_PROCESSOR_BASE_SCRTM 0x00000020 -+#define GRUB_SMX_MACHINE_CHECK_HANLDING 0x00000040 -+#define GRUB_SMX_GET_TXT_EXT_FEATURES(v) (v & (GRUB_SMX_PROCESSOR_BASE_SCRTM|GRUB_SMX_MACHINE_CHECK_HANLDING)) ++#define GRUB_SMX_MACHINE_CHECK_HANDLING 0x00000040 ++#define GRUB_SMX_GET_TXT_EXT_FEATURES(v) (v & (__typeof__(v))(GRUB_SMX_PROCESSOR_BASE_SCRTM|GRUB_SMX_MACHINE_CHECK_HANDLING)) + +#define GRUB_SMX_DEFAULT_VERSION 0x0 +#define GRUB_SMX_DEFAULT_VERSION_MASK 0xffffffff @@ -673,18 +719,6 @@ index 000000000000..7d57af68841f + grub_uint32_t txt_feature_ext_flags; +} GRUB_PACKED; + -+static inline void -+grub_txt_getsec_parameters (grub_uint32_t index, grub_uint32_t *eax_out, -+ grub_uint32_t *ebx_out, grub_uint32_t *ecx_out) -+{ -+ if (!eax_out || !ebx_out || !ecx_out) -+ return; -+ -+ asm volatile (".byte 0x0f,0x37\n" -+ : "=a" (*eax_out), "=b" (*ebx_out), "=c" (*ecx_out) -+ : "0" (GRUB_SMX_LEAF_PARAMETERS), "1" (index)); -+} -+ +extern grub_uint32_t grub_txt_supported_os_sinit_data_ver (struct grub_txt_acm_header* hdr); + +extern grub_uint32_t grub_txt_get_sinit_capabilities (struct grub_txt_acm_header* hdr); @@ -708,5 +742,5 @@ index 000000000000..7d57af68841f + +#endif -- -2.17.1 +2.41.0 diff --git a/1110-i386-txt-Add-Intel-TXT-core-implementation.patch b/1112-i386-txt-Add-Intel-TXT-core-implementation.patch similarity index 81% rename from 1110-i386-txt-Add-Intel-TXT-core-implementation.patch rename to 1112-i386-txt-Add-Intel-TXT-core-implementation.patch index ddce7b0..7b7963d 100644 --- a/1110-i386-txt-Add-Intel-TXT-core-implementation.patch +++ b/1112-i386-txt-Add-Intel-TXT-core-implementation.patch @@ -1,4 +1,4 @@ -From cd6bee1ce1385df0902a0e30b949a4e6dfc5f3c6 Mon Sep 17 00:00:00 2001 +From 695d4295e0bdb68c4d1b9d2900f7808f37b43372 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:57:33 -0400 Subject: [PATCH] i386/txt: Add Intel TXT core implementation @@ -11,19 +11,17 @@ Signed-off-by: Daniel Kiper Signed-off-by: Michał Żygowski Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/txt.c | 928 ++++++++++++++++++++++++++++++++ - include/grub/i386/memory.h | 5 + - include/grub/i386/msr.h | 1 + - include/grub/i386/txt.h | 18 +- - 4 files changed, 949 insertions(+), 3 deletions(-) + grub-core/loader/i386/txt/txt.c | 998 ++++++++++++++++++++++++++++++++ + include/grub/i386/slaunch.h | 1 - + 2 files changed, 998 insertions(+), 1 deletion(-) create mode 100644 grub-core/loader/i386/txt/txt.c diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c new file mode 100644 -index 000000000000..18eb4fd1bf15 +index 000000000000..24311c0cf2bd --- /dev/null +++ b/grub-core/loader/i386/txt/txt.c -@@ -0,0 +1,928 @@ +@@ -0,0 +1,998 @@ +/* + * txt.c: Intel(r) TXT support functions, including initiating measured + * launch, post-launch, AP wakeup, etc. @@ -85,6 +83,7 @@ index 000000000000..18eb4fd1bf15 +#include +#include +#include ++#include +#include +#include +#include @@ -112,7 +111,9 @@ index 000000000000..18eb4fd1bf15 + "locking it now\n"); + /* Not setting SENTER_FUNCTIONS and SENTER_ENABLE because they were tested + * in grub_txt_verify_platform() */ -+ feat_ctrl |= GRUB_MSR_X86_FEATURE_CTRL_LOCK | GRUB_MSR_X86_ENABLE_VMX_IN_SMX; ++ feat_ctrl |= GRUB_MSR_X86_ENABLE_VMX_OUT_SMX | ++ GRUB_MSR_X86_ENABLE_VMX_IN_SMX | ++ GRUB_MSR_X86_FEATURE_CTRL_LOCK; + grub_wrmsr (GRUB_MSR_X86_FEATURE_CONTROL, feat_ctrl); + } + @@ -170,7 +171,7 @@ index 000000000000..18eb4fd1bf15 + break; /* This means done. */ + + case GRUB_SMX_PARAMETER_ACM_VERSIONS: -+ if (params->version_count == GRUB_SMX_PARAMETER_MAX_VERSIONS) ++ if (params->version_count >= GRUB_SMX_PARAMETER_MAX_VERSIONS) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Too many ACM versions")); + break; @@ -245,11 +246,13 @@ index 000000000000..18eb4fd1bf15 + N_("machine check in progress during secure launch")); + + grub_txt_smx_parameters (¶ms); ++ if (grub_errno != GRUB_ERR_NONE) ++ return grub_errno; + + if (params.txt_feature_ext_flags & GRUB_SMX_PROCESSOR_BASE_SCRTM) + grub_dprintf ("slaunch", "CPU supports processor-based S-CRTM\n"); + -+ if (params.txt_feature_ext_flags & GRUB_SMX_MACHINE_CHECK_HANLDING) ++ if (params.txt_feature_ext_flags & GRUB_SMX_MACHINE_CHECK_HANDLING) + grub_dprintf ("slaunch", "CPU supports preserving machine check errors\n"); + else + { @@ -262,7 +265,8 @@ index 000000000000..18eb4fd1bf15 + mcg_stat = grub_rdmsr (GRUB_MSR_X86_MC0_STATUS + i * 4); + if (mcg_stat & (1ULL << 63)) + return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("secure launch MCG[%u] = %Lx ERROR"), i, mcg_stat); ++ N_("secure launch MCG[%u] = %" PRIxGRUB_UINT64_T " ERROR"), i, ++ mcg_stat); + } + } + @@ -293,9 +297,9 @@ index 000000000000..18eb4fd1bf15 + for (i = 0; i < os_mle_data->saved_bsp_mtrrs.mtrr_vcnt; ++i) + { + os_mle_data->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physmask = -+ grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + i * 2); ++ grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK (i)); + os_mle_data->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physbase = -+ grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + i * 2); ++ grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE (i)); + } +} + @@ -316,6 +320,12 @@ index 000000000000..18eb4fd1bf15 + +#define SINIT_MTRR_MASK 0xFFFFFF /* SINIT requires 36b mask */ + ++/* ++ * Note: bitfields in following structures are assumed to work on x86 and ++ * nothing else. All compilers supported by GRUB agree when it comes to layout ++ * of bits that is consistent with hardware implementation. It was decided to ++ * use bitfields for better readability instead of manual shifting and masking. ++ */ +union mtrr_physbase_t +{ + grub_uint64_t raw; @@ -384,9 +394,9 @@ index 000000000000..18eb4fd1bf15 + + for ( ndx = 0; ndx < vcnt; ndx++ ) + { -+ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2); ++ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK (ndx)); + mtrr_physmask.v = 0; -+ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2, mtrr_physmask.raw); ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK (ndx), mtrr_physmask.raw); + } + + /* Map all AC module pages as mem_type */ @@ -395,7 +405,8 @@ index 000000000000..18eb4fd1bf15 + grub_dprintf ("slaunch", "setting MTRRs for acmod: base=%p, size=%x, num_pages=%d\n", + base, size, num_pages); + -+ /* Each VAR MTRR base must be a multiple if that MTRR's Size */ ++ /* Each VAR MTRR base must be a multiple of that MTRR's Size */ ++ /* grub_txt_sinit_select() made sure that base is at least 4K-aligned */ + base_v = (unsigned long)base; + /* MTRR size in pages */ + mtrr_s = 1; @@ -415,16 +426,16 @@ index 000000000000..18eb4fd1bf15 + + while ( num_pages >= mtrr_s ) + { -+ mtrr_physbase.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2); ++ mtrr_physbase.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE (ndx)); + mtrr_physbase.base = ((unsigned long)base >> GRUB_PAGE_SHIFT) & + SINIT_MTRR_MASK; + mtrr_physbase.type = mem_type; -+ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2, mtrr_physbase.raw); ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSBASE (ndx), mtrr_physbase.raw); + -+ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2); ++ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK (ndx)); + mtrr_physmask.mask = ~(mtrr_s - 1) & SINIT_MTRR_MASK; + mtrr_physmask.v = 1; -+ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2, mtrr_physmask.raw); ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK (ndx), mtrr_physmask.raw); + + base += (mtrr_s * GRUB_PAGE_SIZE); + num_pages -= mtrr_s; @@ -434,16 +445,14 @@ index 000000000000..18eb4fd1bf15 + N_("exceeded number of var MTRRs when mapping range")); + } + -+ ndx = 0; -+ + while ( num_pages > 0 ) + { + /* Set the base of the current MTRR */ -+ mtrr_physbase.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2); ++ mtrr_physbase.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE (ndx)); + mtrr_physbase.base = ((unsigned long)base >> GRUB_PAGE_SHIFT) & + SINIT_MTRR_MASK; + mtrr_physbase.type = mem_type; -+ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSBASE0 + ndx*2, mtrr_physbase.raw); ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSBASE (ndx), mtrr_physbase.raw); + + /* + * Calculate MTRR mask @@ -452,10 +461,10 @@ index 000000000000..18eb4fd1bf15 + */ + pages_in_range = 1 << (fls (num_pages) - 1); + -+ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2); ++ mtrr_physmask.raw = grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK (ndx)); + mtrr_physmask.mask = ~(pages_in_range - 1) & SINIT_MTRR_MASK; + mtrr_physmask.v = 1; -+ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK0 + ndx*2, mtrr_physmask.raw); ++ grub_wrmsr (GRUB_MSR_X86_MTRR_PHYSMASK (ndx), mtrr_physmask.raw); + + /* + * Prepare for the next loop depending on number of pages @@ -514,8 +523,6 @@ index 000000000000..18eb4fd1bf15 + /* Set MTRRs for AC mod and rest of memory */ + err = set_mtrr_mem_type ((grub_uint8_t*)hdr, hdr->size*4, + GRUB_MTRR_MEMORY_TYPE_WB); -+ if ( err ) -+ return err; + + /* Undo some of earlier changes and enable our new settings */ + @@ -534,7 +541,25 @@ index 000000000000..18eb4fd1bf15 + /* Restore flags */ + grub_write_flags_register (eflags); + -+ return GRUB_ERR_NONE; ++ return err; ++} ++ ++/* Adds new element to the end. `size` does not include common header. */ ++/* Assume that heap was cleared and there is enough space to add the element. */ ++static inline struct grub_txt_heap_ext_data_element * ++add_ext_data_elt (struct grub_txt_os_sinit_data *os_sinit_data, ++ grub_uint32_t type, grub_uint32_t size) ++{ ++ struct grub_txt_heap_ext_data_element *elt = ++ (struct grub_txt_heap_ext_data_element *) os_sinit_data->ext_data_elts; ++ ++ while (elt->type != GRUB_TXT_HEAP_EXTDATA_TYPE_END) ++ elt = (struct grub_txt_heap_ext_data_element *)((grub_uint8_t *)elt + elt->size); ++ ++ elt->type = type; ++ elt->size = size + GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE; ++ ++ return elt; +} + +static grub_err_t @@ -543,10 +568,10 @@ index 000000000000..18eb4fd1bf15 + grub_uint8_t *txt_heap; + grub_uint32_t os_sinit_data_ver, sinit_caps; + grub_uint64_t *size; ++ grub_uint64_t size_total; + struct grub_txt_os_mle_data *os_mle_data; + struct grub_txt_os_sinit_data *os_sinit_data; -+ struct grub_txt_heap_end_element *heap_end_element; -+ struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; ++ struct grub_txt_heap_ext_data_element *elt; +#ifdef GRUB_MACHINE_EFI + struct grub_acpi_rsdp_v20 *rsdp; +#endif @@ -564,6 +589,14 @@ index 000000000000..18eb4fd1bf15 + size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); + *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); + ++ if (grub_add (grub_txt_bios_data_size (txt_heap), *size, &size_total) || ++ (size_total > grub_txt_get_heap_size ())) ++ { ++ *size = 0; ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("not enough TXT HEAP space for OsMleData")); ++ } ++ + grub_memset (os_mle_data, 0, sizeof (*os_mle_data)); + + os_mle_data->version = GRUB_SL_OS_MLE_STRUCT_VERSION; @@ -593,15 +626,25 @@ index 000000000000..18eb4fd1bf15 + size = (grub_uint64_t *) ((grub_addr_t) os_sinit_data - sizeof (grub_uint64_t)); + + *size = sizeof(grub_uint64_t) + sizeof (struct grub_txt_os_sinit_data) + -+ sizeof (struct grub_txt_heap_end_element); ++ GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE /* End element */; + + if (grub_get_tpm_ver () == GRUB_TPM_12) -+ *size += sizeof (struct grub_txt_heap_tpm_event_log_element); ++ *size += GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + ++ sizeof (struct grub_txt_heap_tpm_event_log_element); + else if (grub_get_tpm_ver () == GRUB_TPM_20) -+ *size += sizeof (struct grub_txt_heap_event_log_pointer2_1_element); ++ *size += GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + ++ sizeof (struct grub_txt_heap_event_log_pointer2_1_element); + else + return grub_error (GRUB_ERR_BAD_DEVICE, N_("unsupported TPM version")); + ++ if (grub_add (size_total, *size, &size_total) || ++ (size_total > grub_txt_get_heap_size ())) ++ { ++ *size = 0; ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("not enough TXT HEAP space for OsSinitData")); ++ } ++ + grub_memset (os_sinit_data, 0, *size); + +#ifdef GRUB_MACHINE_EFI @@ -610,7 +653,7 @@ index 000000000000..18eb4fd1bf15 + if (rsdp == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, N_("ACPI RSDP 2.0 missing\n")); + -+ os_sinit_data->efi_rsdt_ptr = (grub_uint64_t)(grub_addr_t) rsdp; ++ os_sinit_data->efi_rsdp_ptr = (grub_uint64_t)(grub_addr_t) rsdp; +#endif + + os_sinit_data->mle_ptab = slparams->mle_ptab_target; @@ -639,11 +682,25 @@ index 000000000000..18eb4fd1bf15 + + sinit_caps = grub_txt_get_sinit_capabilities (sinit); + -+ /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ -+ os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE | -+ GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; ++ /* ++ * In the latest TXT Software Development Guide as of now (April 2023, ++ * Revision 017.4) bits 4 and 5 (used to be "no legacy PCR usage" and ++ * "auth PCR usage" respectively) of capabilities field bit are reserved. ++ * Bit 4 is ignored, but it is returned as 0 by SINIT[CAPABILITIES], ++ * while bit 5 is forced to 1 for compatibility reasons. This is related ++ * to support for TPM 1.2 devices, which always had this bit set. ++ * ++ * There are TPM 2.0 platforms that will have both bits set. TXT ++ * specification doesn't specify when this has changed, so we can't ++ * reliably test for those. ++ */ ++ os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; + -+ /* Choose monitor RLP wakeup mechanism first. */ ++ /* ++ * APs (application processors) can't be brought up by usual INIT-SIPI-SIPI ++ * sequence after Measured Launch, otherwise the MLE integrity is lost. ++ * Choose monitor RLP (responding logical processor, fancy name for AP) wakeup ++ * mechanism first, if that isn't supported fall back to GETSEC[WAKEUP]. */ + if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) + os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; + else if (sinit_caps & GRUB_TXT_CAPS_GETSEC_WAKE_SUPPORT) @@ -669,23 +726,28 @@ index 000000000000..18eb4fd1bf15 + + os_sinit_data->version = OS_SINIT_DATA_TPM_20_VER; + -+ heap_event_log_pointer2_1_element = -+ (struct grub_txt_heap_event_log_pointer2_1_element *) os_sinit_data->ext_data_elts; -+ heap_event_log_pointer2_1_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1; -+ heap_event_log_pointer2_1_element->size = sizeof (*heap_event_log_pointer2_1_element); -+ heap_event_log_pointer2_1_element->phys_addr = slparams->tpm_evt_log_base; -+ heap_event_log_pointer2_1_element->allocated_event_container_size = slparams->tpm_evt_log_size; -+ -+ heap_end_element = (struct grub_txt_heap_end_element *) -+ ((grub_addr_t) heap_event_log_pointer2_1_element + heap_event_log_pointer2_1_element->size); -+ heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; -+ heap_end_element->size = sizeof (*heap_end_element); ++ elt = add_ext_data_elt(os_sinit_data, ++ GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1, ++ sizeof (struct grub_txt_heap_event_log_pointer2_1_element)); ++ elt->event_log_pointer2_1.phys_addr = slparams->tpm_evt_log_base; ++ elt->event_log_pointer2_1.allocated_event_container_size = slparams->tpm_evt_log_size; + } ++ ++ elt = add_ext_data_elt(os_sinit_data, GRUB_TXT_HEAP_EXTDATA_TYPE_END, 0); ++ ++ if ((grub_uint8_t *)elt + elt->size > ++ (grub_uint8_t *)grub_txt_sinit_mle_data_start (txt_heap) - sizeof(grub_uint64_t)) ++ return grub_error (GRUB_ERR_BUG, ++ N_("error in OsSinitData size requirements calculation")); ++ ++ /* SinitMleDataSize isn't known at this point, it is crafted by SINIT ACM. ++ * We can only test if size field fits and hope that ACM checks the rest. */ ++ if (grub_add (size_total, sizeof (grub_uint64_t), &size_total) || ++ (size_total > grub_txt_get_heap_size ())) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("not enough TXT HEAP space for SinitMleDataSize")); ++ + grub_dprintf ("slaunch", "TXT HEAP init done\n"); -+ /* -+ * TODO: TXT spec: Note: BiosDataSize + OsMleDataSize + OsSinitDataSize + SinitMleDataSize -+ * must be less than or equal to TXT.HEAP.SIZE, TXT spec, p. 102. -+ */ + + return GRUB_ERR_NONE; +} @@ -704,11 +766,15 @@ index 000000000000..18eb4fd1bf15 + /* + * #PT + 1 PT + #PD + 1 PD + 1 PDT + * -+ * Why do we need 2 extra PTEs and PDEs? Yes, because MLE image may not ++ * Why do we need 2 extra PTEs and PDEs? Because MLE image may not + * start and end at PTE (page) and PDE (2 MiB) boundary... + */ -+ return ((((mle_size / GRUB_PAGE_SIZE) + 2) / 512) + 1 + -+ (((mle_size / (512 * GRUB_PAGE_SIZE)) + 2) / 512) + 1 + 1) * GRUB_PAGE_SIZE; ++ return ((((mle_size / GRUB_PAGE_SIZE) + 2) / 512) + /* Number of PTs */ ++// 1 + /* PT */ ++ (((mle_size / (512 * GRUB_PAGE_SIZE)) + 2) / 512) + /* Number of PDs */ ++// 1 + /* PD */ ++ 1) /* PDT */ ++ * GRUB_PAGE_SIZE; +} + +/* Page directory and table entries only need Present set */ @@ -721,10 +787,10 @@ index 000000000000..18eb4fd1bf15 + * pages that can cover up to 36M . + * can only contain 4k pages + * -+ * TODO: TXT Spec p.32; List section name and number with PT MLE requirments here. ++ * TODO: TXT Spec p.32; List section name and number with PT MLE requirements here. + * + * TODO: This function is not able to cover MLEs larger than 1 GiB. Fix it!!! -+ * After fixing inrease GRUB_TXT_MLE_MAX_SIZE too. ++ * After fixing increase GRUB_TXT_MLE_MAX_SIZE too. + */ +void +grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams) @@ -749,6 +815,7 @@ index 000000000000..18eb4fd1bf15 + + do + { ++ /* mle_start may be unaligned, handled by mask in MAKE_PT_MLE_ENTRY */ + *pte = MAKE_PT_MLE_ENTRY(slparams->mle_start + mle_off); + + pte++; @@ -762,7 +829,8 @@ index 000000000000..18eb4fd1bf15 + pde++; + *pde = MAKE_PT_MLE_ENTRY(pte); + } -+ } while (mle_off < slparams->mle_size); ++ /* Add one page in case mle_start isn't aligned */ ++ } while (mle_off - GRUB_PAGE_SIZE + 1 < slparams->mle_size); +} + +grub_err_t @@ -920,8 +988,8 @@ index 000000000000..18eb4fd1bf15 + mle_header->first_valid_page = 0; + mle_header->mle_end = slparams->mle_size; + -+ slparams->sinit_acm_base = (grub_uint32_t)(grub_addr_t) sinit_base; -+ slparams->sinit_acm_size = sinit_base->size * 4; ++ slparams->dce_base = (grub_uint32_t)(grub_addr_t) sinit_base; ++ slparams->dce_size = sinit_base->size * 4; + + /* + * Access to locality 4 isn't available to software, skip it. Don't bother @@ -952,87 +1020,18 @@ index 000000000000..18eb4fd1bf15 + + return GRUB_ERR_NONE; +} -diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h -index c64529630f19..56f64855be7e 100644 ---- a/include/grub/i386/memory.h -+++ b/include/grub/i386/memory.h -@@ -22,6 +22,7 @@ +diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h +index f7160d5fab0c..3ee5c9bc1750 100644 +--- a/include/grub/i386/slaunch.h ++++ b/include/grub/i386/slaunch.h +@@ -29,7 +29,6 @@ - #define GRUB_PAGE_SHIFT 12 - #define GRUB_PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) -+#define GRUB_PAGE_MASK (~(GRUB_PAGE_SIZE - 1)) + #ifndef ASM_FILE - /* The flag for protected mode. */ - #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 -@@ -43,8 +44,12 @@ - - #define GRUB_MMAP_MALLOC_LOW 1 - -+#include +-#include #include -+#define GRUB_PAGE_UP(p) ALIGN_UP (p, GRUB_PAGE_SIZE) -+#define GRUB_PAGE_DOWN(p) ALIGN_DOWN (p, GRUB_PAGE_SIZE) -+ - struct grub_e820_mmap_entry - { - grub_uint64_t addr; -diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h -index b99c49f002ee..8f3e2a894883 100644 ---- a/include/grub/i386/msr.h -+++ b/include/grub/i386/msr.h -@@ -31,6 +31,7 @@ - #define GRUB_MSR_X86_APICBASE_BASE (0xfffff<<12) - - #define GRUB_MSR_X86_FEATURE_CONTROL 0x0000003a -+#define GRUB_MSR_X86_FEATURE_CTRL_LOCK (1<<0) - #define GRUB_MSR_X86_ENABLE_VMX_IN_SMX (1<<1) - #define GRUB_MSR_X86_SENTER_FUNCTIONS (0x7f<<8) - #define GRUB_MSR_X86_SENTER_ENABLE (1<<15) -diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index 7d57af68841f..7a54632bede9 100644 ---- a/include/grub/i386/txt.h -+++ b/include/grub/i386/txt.h -@@ -235,7 +235,7 @@ union grub_txt_didvid - }; - } GRUB_PACKED; - --#define GRUB_TXT_VERSION_DEBUG_FUSED (1<<31) -+#define GRUB_TXT_VERSION_PROD_FUSED (1<<31) - - /* Appendix C Intel TXT Heap Memory */ - -@@ -467,16 +467,28 @@ struct grub_txt_heap_event_log_ptr_elt2_1 - - /* TXT register and heap access */ - -+static inline grub_uint8_t -+grub_txt_reg_pub_readb (grub_uint32_t reg) -+{ -+ return grub_readb (GRUB_TXT_CFG_REGS_PUB + reg); -+} -+ -+static inline grub_uint32_t -+grub_txt_reg_pub_readl (grub_uint32_t reg) -+{ -+ return grub_readl (GRUB_TXT_CFG_REGS_PUB + reg); -+} -+ - static inline grub_uint64_t - grub_txt_reg_pub_readq (grub_uint32_t reg) - { -- return grub_readq ((void *) (GRUB_TXT_CFG_REGS_PUB + reg)); -+ return grub_readq (GRUB_TXT_CFG_REGS_PUB + reg); - } - - static inline grub_uint8_t * - grub_txt_get_heap (void) - { -- return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readq (GRUB_TXT_HEAP_BASE); -+ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); - } - - static inline grub_uint64_t + struct grub_slaunch_params -- -2.17.1 +2.41.0 diff --git a/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch b/1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch similarity index 94% rename from 1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch rename to 1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch index ecbaa67..83cd60a 100644 --- a/1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch +++ b/1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch @@ -1,4 +1,4 @@ -From 59ba16b5bc65ff8b91f4ed627fc7286717fce6dc Mon Sep 17 00:00:00 2001 +From f19c86b0de973bac58296596d394f2daaea7b561 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:59:18 -0400 Subject: [PATCH] i386/txt: Add Intel TXT ACM module support @@ -7,16 +7,16 @@ Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/acmod.c | 603 ++++++++++++++++++++++++++++++ - 1 file changed, 603 insertions(+) + grub-core/loader/i386/txt/acmod.c | 610 ++++++++++++++++++++++++++++++ + 1 file changed, 610 insertions(+) create mode 100644 grub-core/loader/i386/txt/acmod.c diff --git a/grub-core/loader/i386/txt/acmod.c b/grub-core/loader/i386/txt/acmod.c new file mode 100644 -index 000000000000..ec61d277d9f7 +index 000000000000..2605570a6c4f --- /dev/null +++ b/grub-core/loader/i386/txt/acmod.c -@@ -0,0 +1,603 @@ +@@ -0,0 +1,610 @@ +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules @@ -247,7 +247,7 @@ index 000000000000..ec61d277d9f7 + } + + proc_id_list = fits_in_acm(hdr, info_table_get (info_table, processor_id_list), -+ sizeof(struct grub_txt_acm_processor_id_list)); ++ sizeof(*proc_id_list)); + if ( proc_id_list == NULL ) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID list out of bounds")); @@ -255,14 +255,14 @@ index 000000000000..ec61d277d9f7 + } + + /* Overflows? */ -+ if ( grub_add (info_table->processor_id_list, -+ sizeof(struct grub_txt_acm_processor_id_list), &id_entries_off)) ++ if ( grub_add (info_table->processor_id_list, sizeof(*proc_id_list), ++ &id_entries_off)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID entries out of bounds")); + return NULL; + } + -+ if ( n_fit_in_acm ( hdr, id_entries_off, sizeof(struct grub_txt_acm_processor_id), ++ if ( n_fit_in_acm ( hdr, id_entries_off, sizeof(*proc_id_list), + proc_id_list->count ) == NULL ) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID entries out of bounds")); @@ -281,7 +281,7 @@ index 000000000000..ec61d277d9f7 + grub_uint32_t size_from_hdr; + + /* First check size */ -+ if ( acmod_size < sizeof (struct grub_txt_acm_header) ) ++ if ( acmod_size < sizeof (*acm_hdr) ) + return 0; + + /* Then check overflow */ @@ -312,9 +312,10 @@ index 000000000000..ec61d277d9f7 + * anyway. info_table_get() macro does enough testing to not read outside + * of info table. + */ -+ if ( info_table->length < sizeof(struct grub_txt_acm_info_table) ) -+ grub_dprintf ("slaunch", "Info table size (%x) smaller than expected (%x)\n", -+ info_table->length, sizeof(struct grub_txt_acm_info_table)); ++ if ( info_table->length < sizeof(*info_table) ) ++ grub_dprintf ("slaunch", "Info table size (%x) smaller than expected (" ++ PRIxGRUB_SIZE ")\n", ++ info_table->length, sizeof(*info_table)); + + if ( type_out ) + *type_out = info_table_get (info_table, chipset_acm_type); @@ -350,7 +351,7 @@ index 000000000000..ec61d277d9f7 + if ( !grub_txt_is_sinit_acmod (sinit_region_base, bios_data->bios_sinit_size) || + !grub_txt_acmod_match_platform (bios_sinit) ) + { -+ grub_dprintf("slaunch", "BIOS SINIT module did not pass sanity checks"); ++ grub_dprintf("slaunch", "BIOS SINIT module did not pass reasonableness checks"); + return NULL; + } + @@ -445,9 +446,9 @@ index 000000000000..ec61d277d9f7 + /* Get chipset fusing, device, and vendor id info */ + didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); + -+ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF); -+ if ( ver == 0xffffffff || ver == 0x00 ) /* Need to use VER.QPIIF */ -+ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF); ++ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF); ++ if ( ver == 0xffffffff || ver == 0x00 ) /* Old CPU, need to use VER.FSBIF */ ++ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF); + + grub_dprintf ("slaunch", "chipset production fused: %s, " + "chipset vendor: 0x%x, device: 0x%x, revision: 0x%x\n", @@ -570,6 +571,12 @@ index 000000000000..ec61d277d9f7 + return NULL; + } + ++ if ( ((grub_addr_t) sinit_region_base & ((1 << GRUB_PAGE_SHIFT) - 1)) != 0 ) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("SINIT ACM base not properly aligned")); ++ return NULL; ++ } ++ + if (sinit != NULL) + grub_dprintf ("slaunch", "SINIT ACM date: %" PRIxGRUB_UINT32_T "\n", sinit->date); + @@ -621,5 +628,5 @@ index 000000000000..ec61d277d9f7 + return sinit_region_base; +} -- -2.17.1 +2.41.0 diff --git a/1112-i386-txt-Add-Intel-TXT-verification-routines.patch b/1114-i386-txt-Add-Intel-TXT-verification-routines.patch similarity index 78% rename from 1112-i386-txt-Add-Intel-TXT-verification-routines.patch rename to 1114-i386-txt-Add-Intel-TXT-verification-routines.patch index 13fa45f..29e3cc2 100644 --- a/1112-i386-txt-Add-Intel-TXT-verification-routines.patch +++ b/1114-i386-txt-Add-Intel-TXT-verification-routines.patch @@ -1,4 +1,4 @@ -From aa504dddd62f792791a04986c3469b10808dd146 Mon Sep 17 00:00:00 2001 +From d75283aa6950fea8ac579735fe4528083b3932bb Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 14:46:17 -0400 Subject: [PATCH] i386/txt: Add Intel TXT verification routines @@ -7,16 +7,16 @@ Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/verify.c | 304 +++++++++++++++++++++++++++++ - 1 file changed, 304 insertions(+) + grub-core/loader/i386/txt/verify.c | 269 +++++++++++++++++++++++++++++ + 1 file changed, 269 insertions(+) create mode 100644 grub-core/loader/i386/txt/verify.c diff --git a/grub-core/loader/i386/txt/verify.c b/grub-core/loader/i386/txt/verify.c new file mode 100644 -index 000000000000..d0af8d8bc4e5 +index 000000000000..e8acb7da022f --- /dev/null +++ b/grub-core/loader/i386/txt/verify.c -@@ -0,0 +1,304 @@ +@@ -0,0 +1,269 @@ +/* + * verify.c: verify that platform and processor supports Intel(r) TXT + * @@ -77,6 +77,7 @@ index 000000000000..d0af8d8bc4e5 +#include +#include +#include ++#include +#include +#include +#include @@ -88,11 +89,8 @@ index 000000000000..d0af8d8bc4e5 +static grub_err_t +verify_bios_spec_ver_elt (struct grub_txt_heap_ext_data_element *elt) +{ -+ grub_uint8_t *ptr = (grub_uint8_t *)elt; -+ struct grub_txt_heap_bios_spec_ver_element *bios_spec_ver_elt = -+ (struct grub_txt_heap_bios_spec_ver_element *)ptr; -+ -+ if ( elt->size != sizeof(*elt) + sizeof(*bios_spec_ver_elt) ) ++ if ( elt->size != GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + ++ sizeof(struct grub_txt_heap_bios_spec_ver_element) ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("HEAP_BIOS_SPEC_VER element has wrong size (%d)"), + elt->size); @@ -104,30 +102,29 @@ index 000000000000..d0af8d8bc4e5 +static grub_err_t +verify_acm_elt (struct grub_txt_heap_ext_data_element *elt) +{ -+ grub_uint8_t *ptr = ((grub_uint8_t *)elt + sizeof(*elt)); -+ struct grub_txt_heap_acm_element *acm_elt = -+ (struct grub_txt_heap_acm_element *)ptr; -+ grub_uint64_t *acm_addrs; ++ grub_uint64_t acm_addrs_size; + grub_uint32_t i; + -+ if ( elt->size != sizeof(*elt) + sizeof(*acm_elt) + -+ acm_elt->num_acms*sizeof(grub_uint64_t) ) ++ if ( elt->size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + ++ sizeof(struct grub_txt_heap_acm_element) || ++ grub_mul (elt->acm.num_acms, sizeof(grub_uint64_t), &acm_addrs_size) || ++ elt->size != GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + sizeof(elt->acm) + ++ acm_addrs_size ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("HEAP_ACM element has wrong size (%d)"), + elt->size); + + /* No addrs is not error, but print warning. */ -+ if ( acm_elt->num_acms == 0 ) ++ if ( elt->acm.num_acms == 0 ) + grub_printf ("WARNING: HEAP_ACM element has no ACM addrs\n"); + -+ acm_addrs = (grub_uint64_t *)(ptr + sizeof(*acm_elt)); -+ for ( i = 0; i < acm_elt->num_acms; i++ ) ++ for ( i = 0; i < elt->acm.num_acms; i++ ) + { -+ if ( acm_addrs[i] == 0 ) ++ if ( elt->acm.addr[i] == 0 ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("HEAP_ACM element ACM addr (%d) is NULL"), i); + -+ if ( acm_addrs[i] >= 0x100000000UL ) ++ if ( elt->acm.addr[i] >= 0x100000000UL ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("HEAP_ACM element ACM addr (%d) is >4GB"), i); + @@ -140,11 +137,8 @@ index 000000000000..d0af8d8bc4e5 +static grub_err_t +verify_custom_elt (struct grub_txt_heap_ext_data_element *elt) +{ -+ grub_uint8_t *ptr = (grub_uint8_t *)elt; -+ struct grub_txt_heap_custom_element *custom_elt = -+ (struct grub_txt_heap_custom_element *)ptr; -+ -+ if ( elt->size < sizeof(*elt) + sizeof(*custom_elt) ) ++ if ( elt->size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + ++ sizeof(struct grub_txt_heap_custom_element) ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("HEAP_CUSTOM element has wrong size (%d)"), + elt->size); @@ -155,40 +149,20 @@ index 000000000000..d0af8d8bc4e5 +} + +static grub_err_t -+verify_evt_log_ptr_elt (struct grub_txt_heap_ext_data_element *elt) -+{ -+ grub_uint8_t *ptr = (grub_uint8_t *)elt; -+ struct grub_txt_heap_tpm_event_log_element *elog_elt = -+ (struct grub_txt_heap_tpm_event_log_element *)ptr; -+ -+ if ( elt->size != sizeof(*elt) + sizeof(*elog_elt) ) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("HEAP_EVENT_LOG_POINTER element has wrong size (%d)"), -+ elt->size); -+ -+ /* TODO: Sort out how to do this verifier once the event log handling is in place -+ * -+ * return verify_evt_log((event_log_container_t *)(unsigned long) -+ * elog_elt->event_log_phys_addr); -+ */ -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t +verify_ext_data_elts(struct grub_txt_heap_ext_data_element *elts, + grub_uint64_t elts_size) +{ + struct grub_txt_heap_ext_data_element *elt = elts; + grub_err_t err; + -+ if ( elts_size < sizeof(*elt) ) ++ if ( elts_size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("TXT heap ext data elements too small")); + + for ( ; ; ) + { -+ if ( elts_size < elt->size || elt->size == 0 ) ++ if ( elts_size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE || ++ elts_size < elt->size || elt->size == 0 ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("TXT heap invalid element size: type: %d, size: %d"), + elt->type, elt->size); @@ -215,24 +189,15 @@ index 000000000000..d0af8d8bc4e5 + if ( err ) + return err; + break; ++ /* These shouldn't be present in BIOS data, treat them as errors */ + case GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR: -+ err = verify_evt_log_ptr_elt (elt); -+ if ( err ) -+ return err; -+ break; + case GRUB_TXT_HEAP_EXTDATA_TYPE_MADT: -+ /* Copy of ACPI MADT, not validating */ -+ break; + case GRUB_TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1: -+ /* TODO TBOOT did not verify this, not sure why or how to do it */ -+ break; + case GRUB_TXT_HEAP_EXTDATA_TYPE_MCFG: -+ /* Copy of ACPI MCFG, not validating */ -+ break; + default: -+ /* TODO: What kind of element??? Improve the message. */ -+ grub_printf ("WARNING: unknown element: type: %u, size: %u\n", elt->type, elt->size); -+ break; ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("unknown element: type: %u, size: %u\n"), ++ elt->type, elt->size); + } + + elts_size -= elt->size; @@ -297,7 +262,7 @@ index 000000000000..d0af8d8bc4e5 + N_("TXT heap is not configured correctly")); + + bios_size = grub_txt_bios_data_size (txt_heap); -+ if ( bios_size == 0 || bios_size > heap_size ) ++ if ( bios_size < sizeof (grub_uint64_t) || bios_size > heap_size ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("invalid size of the TXT heap BIOS data table")); + @@ -322,5 +287,5 @@ index 000000000000..d0af8d8bc4e5 + return err; +} -- -2.17.1 +2.41.0 diff --git a/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch b/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch similarity index 56% rename from 1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch rename to 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch index 23907d3..0806997 100644 --- a/1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +++ b/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch @@ -1,4 +1,4 @@ -From 0b968b38a15412e81e85d97dd1d042cf459a8527 Mon Sep 17 00:00:00 2001 +From 66f7719aeccd92a418533444afdf771b0d1df6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 31 Aug 2022 14:37:49 +0200 Subject: [PATCH] i386/txt: Initialize TPM 1.2 event log in TXT heap @@ -9,31 +9,16 @@ Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/linux.c | 3 +- - grub-core/loader/i386/txt/txt.c | 71 +++++++++++++++++++++++++++++++-- - include/grub/i386/txt.h | 31 ++++++++++++++ - 3 files changed, 101 insertions(+), 4 deletions(-) + grub-core/loader/i386/txt/txt.c | 62 +++++++++++++++++++++++++++++++-- + include/grub/i386/txt.h | 31 +++++++++++++++++ + 2 files changed, 91 insertions(+), 2 deletions(-) -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 0ab2899f6774..7ef4b36fefc7 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -262,7 +262,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, - slparams.tpm_evt_log_base = get_physical_target_address (ch); - slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; - -- grub_memset (get_virtual_current_address (ch), 0, slparams.tpm_evt_log_size); -+ grub_txt_init_tpm_event_log (get_virtual_current_address (ch), -+ slparams.tpm_evt_log_size); - - grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", - (unsigned long) slparams.tpm_evt_log_base, diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c -index 18eb4fd1bf15..c17c2f29ae12 100644 +index 24311c0cf2bd..ecc0c03580f6 100644 --- a/grub-core/loader/i386/txt/txt.c +++ b/grub-core/loader/i386/txt/txt.c -@@ -511,6 +511,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) - return GRUB_ERR_NONE; +@@ -520,6 +520,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) + return err; } +void @@ -44,7 +29,7 @@ index 18eb4fd1bf15..c17c2f29ae12 100644 + if (buf == NULL || size == 0) + return; + -+ /* For TPM2 just clear the area, only TPM12 requires initialization. */ ++ /* For TPM 2.0 just clear the area, only TPM 1.2 requires initialization. */ + grub_memset (buf, 0, size); + + if (grub_get_tpm_ver () != GRUB_TPM_12) @@ -62,30 +47,24 @@ index 18eb4fd1bf15..c17c2f29ae12 100644 + elog->next_event_offset = sizeof(*elog); +} + - static grub_err_t - init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header *sinit) - { -@@ -520,6 +546,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header - struct grub_txt_os_mle_data *os_mle_data; - struct grub_txt_os_sinit_data *os_sinit_data; - struct grub_txt_heap_end_element *heap_end_element; -+ struct grub_txt_heap_tpm_event_log_element *heap_tpm_event_log_element; - struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; - #ifdef GRUB_MACHINE_EFI - struct grub_acpi_rsdp_v20 *rsdp; -@@ -613,10 +640,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + /* Adds new element to the end. `size` does not include common header. */ + /* Assume that heap was cleared and there is enough space to add the element. */ + static inline struct grub_txt_heap_ext_data_element * +@@ -658,6 +684,8 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header sinit_caps = grub_txt_get_sinit_capabilities (sinit); -- /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ + grub_dprintf ("slaunch", "SINIT capabilities %08x\n", sinit_caps); + - os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE | - GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; + /* + * In the latest TXT Software Development Guide as of now (April 2023, + * Revision 017.4) bits 4 and 5 (used to be "no legacy PCR usage" and +@@ -672,6 +700,25 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + */ + os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; + if (grub_get_tpm_ver () == GRUB_TPM_20) + { -+ /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ + if ((sinit_caps & os_sinit_data->capabilities) != os_sinit_data->capabilities) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Details/authorities PCR usage is not supported")); @@ -103,10 +82,10 @@ index 18eb4fd1bf15..c17c2f29ae12 100644 + } + } + - /* Choose monitor RLP wakeup mechanism first. */ - if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) - os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; -@@ -629,10 +677,27 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + /* + * APs (application processors) can't be brought up by usual INIT-SIPI-SIPI + * sequence after Measured Launch, otherwise the MLE integrity is lost. +@@ -688,10 +735,21 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; if (grub_get_tpm_ver () == GRUB_TPM_12) @@ -118,16 +97,10 @@ index 18eb4fd1bf15..c17c2f29ae12 100644 + os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; + os_sinit_data->version = OS_SINIT_DATA_TPM_12_VER; + -+ heap_tpm_event_log_element = (struct grub_txt_heap_tpm_event_log_element *) -+ os_sinit_data->ext_data_elts; -+ heap_tpm_event_log_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR; -+ heap_tpm_event_log_element->size = sizeof (*heap_tpm_event_log_element); -+ heap_tpm_event_log_element->event_log_phys_addr = slparams->tpm_evt_log_base; -+ -+ heap_end_element = (struct grub_txt_heap_end_element *) -+ ((grub_addr_t) heap_tpm_event_log_element + heap_tpm_event_log_element->size); -+ heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; -+ heap_end_element->size = sizeof (*heap_end_element); ++ elt = add_ext_data_elt(os_sinit_data, ++ GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR, ++ sizeof (struct grub_txt_heap_tpm_event_log_element)); ++ elt->tpm_event_log.event_log_phys_addr = slparams->tpm_evt_log_base; + } else { @@ -137,7 +110,7 @@ index 18eb4fd1bf15..c17c2f29ae12 100644 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("original TXT TPM 2.0 event log format is not supported")); diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index 7a54632bede9..0d2ca5b298c1 100644 +index d8598e259a77..5e3e6086d0d7 100644 --- a/include/grub/i386/txt.h +++ b/include/grub/i386/txt.h @@ -22,6 +22,7 @@ @@ -148,10 +121,11 @@ index 7a54632bede9..0d2ca5b298c1 100644 #include #include #include -@@ -465,6 +466,34 @@ struct grub_txt_heap_event_log_ptr_elt2_1 - grub_uint32_t next_record_offset; +@@ -701,6 +702,34 @@ struct grub_smx_parameters + grub_uint32_t txt_feature_ext_flags; } GRUB_PACKED; ++/* Structures and constants used for TPM 1.2 event log initialization */ +struct tpm12_pcr_event { + grub_uint32_t pcr_index; + grub_uint32_t type; @@ -160,7 +134,7 @@ index 7a54632bede9..0d2ca5b298c1 100644 + grub_uint8_t data[]; +} GRUB_PACKED; + -+#define EVTLOG_SIGNATURE "TXT Event Container\0" ++#define EVTLOG_SIGNATURE "TXT Event Container" +#define EVTLOG_CNTNR_MAJOR_VER 1 +#define EVTLOG_CNTNR_MINOR_VER 0 +#define EVTLOG_EVT_MAJOR_VER 1 @@ -179,11 +153,10 @@ index 7a54632bede9..0d2ca5b298c1 100644 + struct tpm12_pcr_event pcr_events[]; +} GRUB_PACKED; + -+ - /* TXT register and heap access */ + extern grub_uint32_t grub_txt_supported_os_sinit_data_ver (struct grub_txt_acm_header* hdr); - static inline grub_uint8_t -@@ -692,6 +721,8 @@ extern struct grub_txt_acm_header* grub_txt_sinit_select (struct grub_txt_acm_he + extern grub_uint32_t grub_txt_get_sinit_capabilities (struct grub_txt_acm_header* hdr); +@@ -714,6 +743,8 @@ extern struct grub_txt_acm_header* grub_txt_sinit_select (struct grub_txt_acm_he extern grub_err_t grub_txt_verify_platform (void); extern grub_err_t grub_txt_prepare_cpu (void); @@ -193,5 +166,5 @@ index 7a54632bede9..0d2ca5b298c1 100644 extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); -- -2.17.1 +2.41.0 diff --git a/1115-slaunch-Make-slparams-accessible-by-other-modules.patch b/1115-slaunch-Make-slparams-accessible-by-other-modules.patch deleted file mode 100644 index e994d28..0000000 --- a/1115-slaunch-Make-slparams-accessible-by-other-modules.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 2c11b659b5272369f93386c50fc23875c0b753d8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= -Date: Thu, 1 Sep 2022 17:57:46 +0200 -Subject: [PATCH] slaunch: Make slparams accessible by other modules -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Michał Żygowski ---- - grub-core/loader/i386/linux.c | 60 +++++++++++++++++---------------- - grub-core/loader/i386/slaunch.c | 8 +++++ - include/grub/i386/slaunch.h | 1 + - 3 files changed, 40 insertions(+), 29 deletions(-) - -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 7ef4b36fefc7..3c123b90a0ea 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -90,7 +90,6 @@ static grub_efi_uintn_t efi_mmap_size; - #else - static const grub_size_t efi_mmap_size = 0; - #endif --static struct grub_slaunch_params slparams; - - /* FIXME */ - #if 0 -@@ -162,6 +161,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, - { - grub_err_t err; - grub_size_t total_size; -+ struct grub_slaunch_params *slparams = grub_slaunch_params(); - - if (prot_size == 0) - prot_size = 1; -@@ -176,20 +176,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, - goto fail; - } - -- slparams.mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); -- slparams.mle_ptab_size = ALIGN_UP (slparams.mle_ptab_size, GRUB_TXT_PMR_ALIGN); -+ slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); -+ slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN); - /* Do not go below GRUB_TXT_PMR_ALIGN. */ -- preferred_address = (preferred_address > slparams.mle_ptab_size) ? -- (preferred_address - slparams.mle_ptab_size) : GRUB_TXT_PMR_ALIGN; -+ preferred_address = (preferred_address > slparams->mle_ptab_size) ? -+ (preferred_address - slparams->mle_ptab_size) : GRUB_TXT_PMR_ALIGN; - preferred_address = ALIGN_UP (preferred_address, GRUB_TXT_PMR_ALIGN); - } - else - { - prot_size = page_align (prot_size); -- slparams.mle_ptab_size = 0; -+ slparams->mle_ptab_size = 0; - } - -- total_size = prot_size + slparams.mle_ptab_size; -+ total_size = prot_size + slparams->mle_ptab_size; - - /* Initialize the memory pointers with NULL for convenience. */ - free_pages (); -@@ -240,18 +240,18 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, - /* Zero out memory to get stable MLE measurements. */ - grub_memset (prot_mode_mem, 0, total_size); - -- slparams.mle_ptab_mem = prot_mode_mem; -- slparams.mle_ptab_target = prot_mode_target; -+ slparams->mle_ptab_mem = prot_mode_mem; -+ slparams->mle_ptab_target = prot_mode_target; - -- prot_mode_mem = (char *)prot_mode_mem + slparams.mle_ptab_size; -- prot_mode_target += slparams.mle_ptab_size; -+ prot_mode_mem = (char *)prot_mode_mem + slparams->mle_ptab_size; -+ prot_mode_target += slparams->mle_ptab_size; - -- slparams.mle_start = prot_mode_target; -- slparams.mle_size = prot_size; -+ slparams->mle_start = prot_mode_target; -+ slparams->mle_size = prot_size; - - grub_dprintf ("linux", "mle_ptab_mem = %p, mle_ptab_target = %lx, mle_ptab_size = %x\n", -- slparams.mle_ptab_mem, (unsigned long) slparams.mle_ptab_target, -- (unsigned) slparams.mle_ptab_size); -+ slparams->mle_ptab_mem, (unsigned long) slparams->mle_ptab_target, -+ (unsigned) slparams->mle_ptab_size); - - if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, - 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, -@@ -259,15 +259,15 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, - GRUB_RELOCATOR_PREFERENCE_NONE, 1)) - goto fail; - -- slparams.tpm_evt_log_base = get_physical_target_address (ch); -- slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; -+ slparams->tpm_evt_log_base = get_physical_target_address (ch); -+ slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; - - grub_txt_init_tpm_event_log (get_virtual_current_address (ch), -- slparams.tpm_evt_log_size); -+ slparams->tpm_evt_log_size); - - grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", -- (unsigned long) slparams.tpm_evt_log_base, -- (unsigned) slparams.tpm_evt_log_size); -+ (unsigned long) slparams->tpm_evt_log_base, -+ (unsigned) slparams->tpm_evt_log_size); - } - } - -@@ -482,6 +482,7 @@ grub_linux_boot (void) - grub_size_t mmap_size; - grub_size_t cl_offset; - grub_size_t ap_wake_block_size = 0; -+ struct grub_slaunch_params *slparams = grub_slaunch_params(); - - #ifdef GRUB_MACHINE_IEEE1275 - { -@@ -637,12 +638,12 @@ grub_linux_boot (void) - - if (grub_slaunch_platform_type () == SLP_INTEL_TXT) - { -- slparams.ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; -- slparams.ap_wake_block_size = ap_wake_block_size; -+ slparams->ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; -+ slparams->ap_wake_block_size = ap_wake_block_size; - grub_memset ((void *) ((grub_addr_t) real_mode_mem + ctx.real_size + - efi_mmap_size), 0, ap_wake_block_size); - grub_dprintf ("linux", "ap_wake_block = %lx, ap_wake_block_size = %lx\n", -- (unsigned long) slparams.ap_wake_block, -+ (unsigned long) slparams->ap_wake_block, - (unsigned long) ap_wake_block_size); - } - -@@ -713,17 +714,17 @@ grub_linux_boot (void) - - if (state.edi == SLP_INTEL_TXT) - { -- slparams.boot_params_addr = (grub_uint32_t) ctx.real_mode_target; -+ slparams->boot_params_addr = (grub_uint32_t) ctx.real_mode_target; - -- err = grub_txt_boot_prepare (&slparams); -+ err = grub_txt_boot_prepare (slparams); - - if (err != GRUB_ERR_NONE) - return err; - - /* Configure relocator GETSEC[SENTER] call. */ - state.eax = GRUB_SMX_LEAF_SENTER; -- state.ebx = slparams.sinit_acm_base; -- state.ecx = slparams.sinit_acm_size; -+ state.ebx = slparams->sinit_acm_base; -+ state.ecx = slparams->sinit_acm_size; - state.edx = 0; - } - else -@@ -762,6 +763,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_size_t align, min_align; - int relocatable; - grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; -+ struct grub_slaunch_params *slparams = grub_slaunch_params(); - - grub_dl_ref (my_mod); - -@@ -881,7 +883,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_memset (&linux_params, 0, sizeof (linux_params)); - - if (grub_slaunch_platform_type () == SLP_INTEL_TXT) -- grub_txt_setup_mle_ptab (&slparams); -+ grub_txt_setup_mle_ptab (grub_slaunch_params ()); - - /* - * The Linux 32-bit boot protocol defines the setup header end -@@ -969,7 +971,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- slparams.mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); -+ slparams->mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); - } - } - else if (grub_slaunch_platform_type () != SLP_NONE) -diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c -index 9b2efd755f89..093eddef8db1 100644 ---- a/grub-core/loader/i386/slaunch.c -+++ b/grub-core/loader/i386/slaunch.c -@@ -36,6 +36,8 @@ static grub_uint32_t slp = SLP_NONE; - - static void *slaunch_module = NULL; - -+static struct grub_slaunch_params slparams; -+ - grub_uint32_t - grub_slaunch_platform_type (void) - { -@@ -48,6 +50,12 @@ grub_slaunch_module (void) - return slaunch_module; - } - -+struct grub_slaunch_params * -+grub_slaunch_params (void) -+{ -+ return &slparams; -+} -+ - static grub_err_t - grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), -diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h -index 12cd341aae0c..ee1777d86759 100644 ---- a/include/grub/i386/slaunch.h -+++ b/include/grub/i386/slaunch.h -@@ -51,6 +51,7 @@ struct grub_slaunch_params - - extern grub_uint32_t grub_slaunch_platform_type (void); - extern void *grub_slaunch_module (void); -+extern struct grub_slaunch_params *grub_slaunch_params (void); - - #endif /* ASM_FILE */ - --- -2.17.1 - diff --git a/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch b/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch new file mode 100644 index 0000000..d77c26f --- /dev/null +++ b/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch @@ -0,0 +1,331 @@ +From 2974b3b9922043cedc6d8418eaeed2bcd1361ce1 Mon Sep 17 00:00:00 2001 +From: Ross Philipson +Date: Fri, 13 Jan 2023 15:11:26 -0500 +Subject: [PATCH] i386/txt: switch to using Secure Launch Resource Table + interface + +Signed-off-by: Ross Philipson +Signed-off-by: Sergii Dmytruk +--- + grub-core/loader/i386/txt/txt.c | 109 ++++++++++++++++++++++++-------- + include/grub/i386/slaunch.h | 30 ++++++++- + include/grub/i386/txt.h | 26 +++----- + 3 files changed, 121 insertions(+), 44 deletions(-) + +diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c +index ecc0c03580f6..03ba5130eaaa 100644 +--- a/grub-core/loader/i386/txt/txt.c ++++ b/grub-core/loader/i386/txt/txt.c +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -75,6 +76,8 @@ + + #define OS_SINIT_DATA_MIN_VER OS_SINIT_DATA_TPM_12_VER + ++static struct grub_slr_entry_intel_info slr_intel_info_staging = {0}; ++ + static grub_err_t + enable_smx_mode (void) + { +@@ -250,33 +253,39 @@ grub_txt_prepare_cpu (void) + } + + static void +-save_mtrrs (struct grub_txt_os_mle_data *os_mle_data) ++save_mtrrs (struct grub_slr_txt_mtrr_state *saved_bsp_mtrrs) + { + grub_uint64_t i; + +- os_mle_data->saved_bsp_mtrrs.default_mem_type = ++ saved_bsp_mtrrs->default_mem_type = + grub_rdmsr (GRUB_MSR_X86_MTRR_DEF_TYPE); + +- os_mle_data->saved_bsp_mtrrs.mtrr_vcnt = ++ saved_bsp_mtrrs->mtrr_vcnt = + grub_rdmsr (GRUB_MSR_X86_MTRRCAP) & GRUB_MSR_X86_VCNT_MASK; + +- if (os_mle_data->saved_bsp_mtrrs.mtrr_vcnt > GRUB_SL_MAX_VARIABLE_MTRRS) ++ if (saved_bsp_mtrrs->mtrr_vcnt > GRUB_TXT_VARIABLE_MTRRS_LENGTH) + { + /* Print warning but continue saving what we can... */ + grub_printf ("WARNING: Actual number of variable MTRRs (%" PRIuGRUB_UINT64_T + ") > GRUB_SL_MAX_VARIABLE_MTRRS (%d)\n", +- os_mle_data->saved_bsp_mtrrs.mtrr_vcnt, +- GRUB_SL_MAX_VARIABLE_MTRRS); +- os_mle_data->saved_bsp_mtrrs.mtrr_vcnt = GRUB_SL_MAX_VARIABLE_MTRRS; ++ saved_bsp_mtrrs->mtrr_vcnt, ++ GRUB_TXT_VARIABLE_MTRRS_LENGTH); ++ saved_bsp_mtrrs->mtrr_vcnt = GRUB_TXT_VARIABLE_MTRRS_LENGTH; + } + +- for (i = 0; i < os_mle_data->saved_bsp_mtrrs.mtrr_vcnt; ++i) ++ for (i = 0; i < saved_bsp_mtrrs->mtrr_vcnt; ++i) + { +- os_mle_data->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physmask = ++ saved_bsp_mtrrs->mtrr_pair[i].mtrr_physmask = + grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSMASK (i)); +- os_mle_data->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physbase = ++ saved_bsp_mtrrs->mtrr_pair[i].mtrr_physbase = + grub_rdmsr (GRUB_MSR_X86_MTRR_PHYSBASE (i)); + } ++ /* Zero unused array items. */ ++ for ( ; i < GRUB_TXT_VARIABLE_MTRRS_LENGTH; ++i) ++ { ++ saved_bsp_mtrrs->mtrr_pair[i].mtrr_physmask = 0; ++ saved_bsp_mtrrs->mtrr_pair[i].mtrr_physbase = 0; ++ } + } + + static void +@@ -546,6 +555,20 @@ grub_txt_init_tpm_event_log (void *buf, grub_size_t size) + elog->next_event_offset = sizeof(*elog); + } + ++static void ++setup_txt_slrt_entry (struct grub_slaunch_params *slparams, ++ struct grub_txt_os_mle_data *os_mle_data) ++{ ++ struct grub_slr_table *slr_table = slparams->slr_table_mem; ++ struct grub_slr_entry_hdr *txt_info; ++ ++ grub_slr_add_entry (slr_table, &slr_intel_info_staging.hdr); ++ ++ txt_info = grub_slr_next_entry_by_tag (slr_table, NULL, GRUB_SLR_ENTRY_INTEL_INFO); ++ os_mle_data->txt_info = (grub_addr_t) slparams->slr_table_base ++ + ((grub_addr_t) txt_info - (grub_addr_t) slparams->slr_table_mem); ++} ++ + /* Adds new element to the end. `size` does not include common header. */ + /* Assume that heap was cleared and there is enough space to add the element. */ + static inline struct grub_txt_heap_ext_data_element * +@@ -591,6 +614,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); + *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); + ++ if (slparams->slr_table_base == GRUB_SLAUNCH_STORE_IN_OS2MLE) ++ { ++ /* SLRT needs to be at least 4-byte aligned per specification. */ ++ slparams->slr_table_base = ++ ALIGN_UP ((grub_addr_t) os_mle_data + sizeof (*os_mle_data), 4); ++ ++ /* Recompute size including SLRT table in it. */ ++ *size = (slparams->slr_table_base + slparams->slr_table_size) ++ - ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); ++ ++ /* Size of heap sections should be a multiple of 8. */ ++ *size = ALIGN_UP (*size, 8); ++ } ++ + if (grub_add (grub_txt_bios_data_size (txt_heap), *size, &size_total) || + (size_total > grub_txt_get_heap_size ())) + { +@@ -603,16 +640,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header + + os_mle_data->version = GRUB_SL_OS_MLE_STRUCT_VERSION; + os_mle_data->boot_params_addr = slparams->boot_params_addr; +- os_mle_data->saved_misc_enable_msr = grub_rdmsr (GRUB_MSR_X86_MISC_ENABLE); ++ os_mle_data->slrt = slparams->slr_table_base; + + os_mle_data->ap_wake_block = slparams->ap_wake_block; + os_mle_data->ap_wake_block_size = slparams->ap_wake_block_size; + +- os_mle_data->evtlog_addr = slparams->tpm_evt_log_base; +- os_mle_data->evtlog_size = slparams->tpm_evt_log_size; ++ /* Setup the TXT specific SLR information */ ++ slr_intel_info_staging.hdr.tag = GRUB_SLR_ENTRY_INTEL_INFO; ++ slr_intel_info_staging.hdr.size = sizeof(struct grub_slr_entry_intel_info); ++ slr_intel_info_staging.saved_misc_enable_msr = ++ grub_rdmsr (GRUB_MSR_X86_MISC_ENABLE); + ++ /* Save the BSPs MTRR state so post launch can restore it. */ + grub_dprintf ("slaunch", "Saving MTRRs to OS MLE data\n"); +- save_mtrrs (os_mle_data); ++ save_mtrrs (&slr_intel_info_staging.saved_bsp_mtrrs); + + /* OS/loader to SINIT data. */ + grub_dprintf ("slaunch", "Get supported OS SINIT data version\n"); +@@ -1000,9 +1041,10 @@ grub_err_t + grub_txt_boot_prepare (struct grub_slaunch_params *slparams) + { + grub_err_t err; ++ grub_uint8_t *txt_heap; ++ struct grub_txt_os_mle_data *os_mle_data; + struct grub_txt_mle_header *mle_header; + struct grub_txt_acm_header *sinit_base; +- int i; + + sinit_base = grub_txt_sinit_select (grub_slaunch_module ()); + +@@ -1018,24 +1060,22 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) + grub_dprintf ("slaunch", "TXT heap successfully prepared\n"); + + /* Update the MLE header. */ +- mle_header = (struct grub_txt_mle_header *)(grub_addr_t) (slparams->mle_start + slparams->mle_header_offset); ++ mle_header = ++ (struct grub_txt_mle_header *) ((grub_uint8_t *) slparams->mle_mem + slparams->mle_header_offset); + mle_header->first_valid_page = 0; + mle_header->mle_end = slparams->mle_size; + + slparams->dce_base = (grub_uint32_t)(grub_addr_t) sinit_base; + slparams->dce_size = sinit_base->size * 4; + +- /* +- * Access to locality 4 isn't available to software, skip it. Don't bother +- * checking TPM status, we have no tools for recovering from bad state better +- * than command abort, which is part of locality relinquish. Write performed +- * by the following function is no-op if locality is neither active nor +- * requested. +- */ +- for (i = 0; i < 4; ++i) +- grub_tpm_relinquish_locality (i); ++ /* Setup of SLR table. */ ++ grub_slaunch_init_slrt_storage (GRUB_SLR_INTEL_TXT); ++ txt_heap = grub_txt_get_heap (); ++ os_mle_data = grub_txt_os_mle_data_start (txt_heap); ++ setup_txt_slrt_entry (slparams, os_mle_data); + +- grub_dprintf ("slaunch", "TPM localities relinquished\n"); ++ grub_tpm_relinquish_locality (0); ++ grub_dprintf ("slaunch", "Relinquished TPM locality 0\n"); + + err = set_mtrrs_for_acmod (sinit_base); + if (err) +@@ -1054,3 +1094,20 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) + + return GRUB_ERR_NONE; + } ++ ++void ++grub_txt_add_slrt_policy_entries (void) ++{ ++ struct grub_txt_os_mle_data *os_mle_data; ++ grub_uint8_t *txt_heap; ++ ++ txt_heap = grub_txt_get_heap (); ++ os_mle_data = grub_txt_os_mle_data_start (txt_heap); ++ ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_TXT_OS2MLE, ++ /*flags=*/0, ++ (grub_addr_t) os_mle_data, ++ sizeof(*os_mle_data), ++ "Measured TXT OS-MLE data"); ++} +diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h +index 3ee5c9bc1750..4b43662bea2f 100644 +--- a/include/grub/i386/slaunch.h ++++ b/include/grub/i386/slaunch.h +@@ -27,6 +27,19 @@ + + #define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE) + ++/* ++ * Special value for slr_table_base of struct grub_slaunch_params that indicates ++ * that the table should be stored near OS2MLE data (right after it). ++ * ++ * In this case: ++ * 1. Platform-specific code (e.g., TXT-code) is responsible for setting ++ * slr_table_base to its final value ++ * 2. SLRT should be copied from slr_table_mem to slr_table_base after invoking ++ * grub_slaunch_finish_slr_table () by the code which used this special ++ * value. ++ */ ++#define GRUB_SLAUNCH_STORE_IN_OS2MLE ((grub_uint64_t) 0xFFFFFFFFFFFFFFFF) ++ + #ifndef ASM_FILE + + #include +@@ -34,11 +47,16 @@ + struct grub_slaunch_params + { + grub_uint32_t boot_params_addr; ++ grub_uint64_t slr_table_base; ++ /* This is size of SLRT buffer, so maximum size of the table. */ ++ grub_uint32_t slr_table_size; ++ void *slr_table_mem; + grub_uint32_t mle_start; + grub_uint32_t mle_size; +- void *mle_ptab_mem; ++ void *mle_mem; + grub_uint64_t mle_ptab_target; + grub_uint32_t mle_ptab_size; ++ void *mle_ptab_mem; + grub_uint32_t mle_header_offset; + grub_uint32_t ap_wake_block; + grub_uint32_t ap_wake_block_size; +@@ -52,6 +70,16 @@ extern grub_uint32_t grub_slaunch_platform_type (void); + extern void *grub_slaunch_module (void); + extern struct grub_slaunch_params *grub_slaunch_params (void); + ++extern void grub_slaunch_init_slrt_storage (int arch); ++extern void grub_slaunch_add_slrt_policy_entries (void); ++extern void grub_slaunch_add_slrt_policy_entry (grub_uint16_t pcr, ++ grub_uint16_t entity_type, ++ grub_uint16_t flags, ++ grub_uint64_t entity, ++ grub_uint64_t size, ++ const char *evt_info); ++extern void grub_slaunch_finish_slr_table (void); ++ + #endif /* ASM_FILE */ + + #endif /* GRUB_I386_SLAUNCH_H */ +diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h +index 5e3e6086d0d7..ba98043a1735 100644 +--- a/include/grub/i386/txt.h ++++ b/include/grub/i386/txt.h +@@ -352,29 +352,14 @@ struct grub_txt_bios_data + /* GRUB SLAUNCH specific definitions OS-MLE data */ + #define GRUB_SL_OS_MLE_STRUCT_VERSION 1 + +-struct grub_slaunch_mtrr_pair +-{ +- grub_uint64_t mtrr_physbase; +- grub_uint64_t mtrr_physmask; +-} GRUB_PACKED; +- +-struct grub_slaunch_mtrr_state +-{ +- grub_uint64_t default_mem_type; +- grub_uint64_t mtrr_vcnt; +- struct grub_slaunch_mtrr_pair mtrr_pair[GRUB_SL_MAX_VARIABLE_MTRRS]; +-} GRUB_PACKED; +- + struct grub_txt_os_mle_data + { + grub_uint32_t version; + grub_uint32_t boot_params_addr; +- grub_uint64_t saved_misc_enable_msr; +- struct grub_slaunch_mtrr_state saved_bsp_mtrrs; ++ grub_uint32_t slrt; ++ grub_uint32_t txt_info; + grub_uint32_t ap_wake_block; + grub_uint32_t ap_wake_block_size; +- grub_uint64_t evtlog_addr; +- grub_uint32_t evtlog_size; + grub_uint8_t mle_scratch[64]; + } GRUB_PACKED; + +@@ -751,6 +736,13 @@ extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); + extern grub_err_t grub_txt_init (void); + extern void grub_txt_shutdown (void); + extern void grub_txt_state_show (void); ++/* ++ * This function doesn't finish building of SLRT. It's caller's responsibility ++ * to call grub_slaunch_finish_slr_table() after making any necessary ++ * grub_slr_add_entry() and grub_slaunch_add_slrt_policy_entry() calls including ++ * grub_txt_add_slrt_polic_entries() and grub_slaunch_add_slrt_policy_entries(). ++ */ + extern grub_err_t grub_txt_boot_prepare (struct grub_slaunch_params *slparams); ++extern void grub_txt_add_slrt_policy_entries (void); + + #endif +-- +2.41.0 + diff --git a/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch b/1117-i386-slaunch-Add-secure-launch-framework-and-command.patch similarity index 64% rename from 1113-i386-slaunch-Add-secure-launch-framework-and-command.patch rename to 1117-i386-slaunch-Add-secure-launch-framework-and-command.patch index 816dc76..5c120a4 100644 --- a/1113-i386-slaunch-Add-secure-launch-framework-and-command.patch +++ b/1117-i386-slaunch-Add-secure-launch-framework-and-command.patch @@ -1,4 +1,4 @@ -From 98069630b28f8345d791bb68102d4e28789e8670 Mon Sep 17 00:00:00 2001 +From 916454efb00b14fa85bf529fa0575e99b9d484fb Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 15:01:00 -0400 Subject: [PATCH] i386/slaunch: Add secure launch framework and commands @@ -7,48 +7,49 @@ Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/Makefile.am | 3 + - grub-core/Makefile.core.def | 15 ++ + grub-core/Makefile.am | 6 + + grub-core/Makefile.core.def | 15 + grub-core/lib/i386/relocator32.S | 8 + - grub-core/loader/i386/bsd.c | 7 + + grub-core/loader/i386/bsd.c | 4 + grub-core/loader/i386/coreboot/chainloader.c | 2 + - grub-core/loader/i386/linux.c | 214 +++++++++++++++++-- + grub-core/loader/i386/linux.c | 315 ++++++++++++++++++- grub-core/loader/i386/pc/plan9.c | 3 +- - grub-core/loader/i386/slaunch.c | 201 +++++++++++++++++ + grub-core/loader/i386/slaunch.c | 299 ++++++++++++++++++ grub-core/loader/i386/xnu.c | 3 + grub-core/loader/multiboot.c | 5 + include/grub/file.h | 3 + include/grub/i386/linux.h | 14 +- - include/grub/i386/slaunch.h | 57 +++++ - 13 files changed, 518 insertions(+), 17 deletions(-) + 12 files changed, 660 insertions(+), 17 deletions(-) create mode 100644 grub-core/loader/i386/slaunch.c - create mode 100644 include/grub/i386/slaunch.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index ee88e44e97a0..769bf013d47b 100644 +index ee88e44e97a0..44ba9ac40538 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am -@@ -103,6 +103,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +@@ -103,6 +103,8 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/slr_table.h endif if COND_i386_xen_pvh -@@ -122,6 +123,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +@@ -122,6 +124,8 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/slr_table.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h -@@ -183,6 +185,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +@@ -183,6 +187,8 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/slr_table.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h @@ -117,21 +118,18 @@ index 09ce56ad0ae6..a2b377197b16 100644 .p2align 4 LOCAL(gdt): diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c -index 5f3290ce17bc..328b34635f78 100644 +index 5f3290ce17bc..d9832328d307 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c -@@ -21,6 +21,10 @@ +@@ -21,6 +21,7 @@ #include #include #include -+#if 0 +#include -+#endif -+#define SLP_NONE 0 #include #include #include -@@ -792,6 +796,7 @@ grub_freebsd_boot (void) +@@ -792,6 +793,7 @@ grub_freebsd_boot (void) #endif grub_memcpy (&stack[9], &bi, sizeof (bi)); @@ -139,7 +137,7 @@ index 5f3290ce17bc..328b34635f78 100644 state.eip = entry; state.esp = stack_target; state.ebp = stack_target; -@@ -907,6 +912,7 @@ grub_openbsd_boot (void) +@@ -907,6 +909,7 @@ grub_openbsd_boot (void) return err; #endif @@ -147,7 +145,7 @@ index 5f3290ce17bc..328b34635f78 100644 state.eip = entry; state.ebp = state.esp = ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target; -@@ -1229,6 +1235,7 @@ grub_netbsd_boot (void) +@@ -1229,6 +1232,7 @@ grub_netbsd_boot (void) return err; #endif @@ -176,10 +174,10 @@ index 0a19ebb9c3e5..dccd86b07bde 100644 } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 9f74a96b19ae..0ab2899f6774 100644 +index 9f74a96b19ae..18485e9b1766 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c -@@ -34,6 +34,8 @@ +@@ -34,9 +34,12 @@ #include #include #include @@ -188,13 +186,29 @@ index 9f74a96b19ae..0ab2899f6774 100644 #include #include #include -@@ -63,18 +65,24 @@ GRUB_MOD_LICENSE ("GPLv3+"); ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -63,18 +66,36 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define ACCEPTS_PURE_TEXT 1 #endif +/* See kernel_info in Documentation/arch/x86/boot.rst in the kernel tree */ +#define KERNEL_INFO_HEADER "LToP" +#define KERNEL_INFO_MIN_SIZE_TOTAL 12 ++ ++struct linux_params_efi_info ++{ ++ grub_uint32_t efi_signature; ++ grub_uint32_t efi_system_table; ++ grub_uint32_t efi_mem_desc_size; ++ grub_uint32_t efi_mem_desc_version; ++ grub_uint32_t efi_mmap; ++ grub_uint32_t efi_mmap_size; ++ grub_uint32_t efi_system_table_hi; ++ grub_uint32_t efi_mmap_hi; ++}; + static grub_dl_t my_mod; @@ -213,15 +227,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 static struct linux_kernel_params linux_params; static char *linux_cmdline; #ifdef GRUB_MACHINE_EFI -@@ -82,6 +90,7 @@ static grub_efi_uintn_t efi_mmap_size; - #else - static const grub_size_t efi_mmap_size = 0; - #endif -+static struct grub_slaunch_params slparams; - - /* FIXME */ - #if 0 -@@ -98,6 +107,8 @@ static struct idt_descriptor idt_desc = +@@ -98,6 +119,8 @@ static struct idt_descriptor idt_desc = }; #endif @@ -230,11 +236,12 @@ index 9f74a96b19ae..0ab2899f6774 100644 static inline grub_size_t page_align (grub_size_t size) { -@@ -150,11 +161,35 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -150,11 +173,36 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, grub_uint64_t preferred_address) { grub_err_t err; + grub_size_t total_size; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); if (prot_size == 0) prot_size = 1; @@ -250,24 +257,24 @@ index 9f74a96b19ae..0ab2899f6774 100644 + goto fail; + } + -+ slparams.mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); -+ slparams.mle_ptab_size = ALIGN_UP (slparams.mle_ptab_size, GRUB_TXT_PMR_ALIGN); ++ slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); ++ slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN); + /* Do not go below GRUB_TXT_PMR_ALIGN. */ -+ preferred_address = (preferred_address > slparams.mle_ptab_size) ? -+ (preferred_address - slparams.mle_ptab_size) : GRUB_TXT_PMR_ALIGN; ++ preferred_address = (preferred_address > slparams->mle_ptab_size) ? ++ (preferred_address - slparams->mle_ptab_size) : GRUB_TXT_PMR_ALIGN; + preferred_address = ALIGN_UP (preferred_address, GRUB_TXT_PMR_ALIGN); + } + else + { + prot_size = page_align (prot_size); -+ slparams.mle_ptab_size = 0; ++ slparams->mle_ptab_size = 0; + } + -+ total_size = prot_size + slparams.mle_ptab_size; ++ total_size = prot_size + slparams->mle_ptab_size; /* Initialize the memory pointers with NULL for convenience. */ free_pages (); -@@ -176,7 +211,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -176,7 +224,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, err = grub_relocator_alloc_chunk_align (relocator, &ch, preferred_address, preferred_address, @@ -276,7 +283,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 GRUB_RELOCATOR_PREFERENCE_LOW, 1); for (; err && *align + 1 > min_align; (*align)--) -@@ -194,11 +229,45 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -194,11 +242,65 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, else err = grub_relocator_alloc_chunk_addr (relocator, &ch, preferred_address, @@ -292,38 +299,58 @@ index 9f74a96b19ae..0ab2899f6774 100644 + /* Zero out memory to get stable MLE measurements. */ + grub_memset (prot_mode_mem, 0, total_size); + -+ slparams.mle_ptab_mem = prot_mode_mem; -+ slparams.mle_ptab_target = prot_mode_target; ++ slparams->mle_ptab_mem = prot_mode_mem; ++ slparams->mle_ptab_target = prot_mode_target; + -+ prot_mode_mem = (char *)prot_mode_mem + slparams.mle_ptab_size; -+ prot_mode_target += slparams.mle_ptab_size; ++ prot_mode_mem = (char *)prot_mode_mem + slparams->mle_ptab_size; ++ prot_mode_target += slparams->mle_ptab_size; + -+ slparams.mle_start = prot_mode_target; -+ slparams.mle_size = prot_size; ++ slparams->mle_start = prot_mode_target; ++ slparams->mle_size = prot_size; ++ slparams->mle_mem = prot_mode_mem; + + grub_dprintf ("linux", "mle_ptab_mem = %p, mle_ptab_target = %lx, mle_ptab_size = %x\n", -+ slparams.mle_ptab_mem, (unsigned long) slparams.mle_ptab_target, -+ (unsigned) slparams.mle_ptab_size); ++ slparams->mle_ptab_mem, (unsigned long) slparams->mle_ptab_target, ++ (unsigned) slparams->mle_ptab_size); + -+ if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, -+ 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, -+ GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE, -+ GRUB_RELOCATOR_PREFERENCE_NONE, 1)) -+ goto fail; ++ err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, ++ 0xffffffff - GRUB_PAGE_SIZE, ++ GRUB_PAGE_SIZE, GRUB_PAGE_SIZE, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 1); ++ if (err) ++ goto fail; ++ ++ slparams->slr_table_base = get_physical_target_address (ch); ++ slparams->slr_table_size = GRUB_PAGE_SIZE; ++ slparams->slr_table_mem = get_virtual_current_address (ch); ++ ++ grub_memset (slparams->slr_table_mem, 0, slparams->slr_table_size); + -+ slparams.tpm_evt_log_base = get_physical_target_address (ch); -+ slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; ++ grub_dprintf ("linux", "slr_table_base = %lx, slr_table_size = %x\n", ++ (unsigned long) slparams->slr_table_base, ++ (unsigned) slparams->slr_table_size); + -+ grub_memset (get_virtual_current_address (ch), 0, slparams.tpm_evt_log_size); ++ err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, ++ 0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, ++ GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 1); ++ if (err) ++ goto fail; ++ ++ slparams->tpm_evt_log_base = get_physical_target_address (ch); ++ slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE; ++ ++ grub_txt_init_tpm_event_log (get_virtual_current_address (ch), ++ slparams->tpm_evt_log_size); + + grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n", -+ (unsigned long) slparams.tpm_evt_log_base, -+ (unsigned) slparams.tpm_evt_log_size); ++ (unsigned long) slparams->tpm_evt_log_base, ++ (unsigned) slparams->tpm_evt_log_size); + } } grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", -@@ -286,7 +355,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) +@@ -286,7 +388,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->lfb_size >>= 16; params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; break; @@ -332,15 +359,77 @@ index 9f74a96b19ae..0ab2899f6774 100644 case GRUB_VIDEO_DRIVER_EFI_UGA: case GRUB_VIDEO_DRIVER_EFI_GOP: params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; -@@ -411,6 +480,7 @@ grub_linux_boot (void) +@@ -398,6 +500,60 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, + return 0; + } + ++static void ++grub_linux_setup_slr_table (struct grub_slaunch_params *slparams) ++{ ++ struct linux_kernel_params *boot_params = (void *) (grub_addr_t) slparams->boot_params_addr; ++ struct linux_params_efi_info *efi_info; ++ ++ /* A bit of work to extract the v2.08 EFI info from the linux params */ ++ efi_info = (void *)((grub_uint8_t *)&boot_params->v0208 + 2*sizeof(grub_uint32_t)); ++ ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_BOOT_PARAMS, ++ /*flags=*/0, ++ (grub_addr_t) boot_params, ++ GRUB_PAGE_SIZE, ++ "Measured boot parameters"); ++ ++ if (boot_params->setup_data) ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_SETUP_DATA, ++ GRUB_SLR_POLICY_IMPLICIT_SIZE, ++ boot_params->setup_data, ++ /*size=*/0, ++ "Measured Kernel setup_data"); ++ ++ /* TODO the cmdline ptr can have hi bits but for now assume always < 4G */ ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_CMDLINE, ++ /*flags=*/0, ++ boot_params->cmd_line_ptr, ++ boot_params->cmdline_size, ++ "Measured Kernel command line"); ++ ++ if (!grub_memcmp(&efi_info->efi_signature, "EL64", sizeof(grub_uint32_t))) ++ { ++ grub_uint64_t mmap_addr = ++ ((grub_uint64_t) efi_info->efi_mmap_hi << 32) | efi_info->efi_mmap; ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_UEFI_MEMMAP, ++ /*flags=*/0, ++ mmap_addr, ++ efi_info->efi_mmap_size, ++ "Measured EFI memory map"); ++ } ++ ++ if (boot_params->ramdisk_image) ++ /* TODO the initrd image and size can have hi bits but for now assume always < 4G */ ++ grub_slaunch_add_slrt_policy_entry (17, ++ GRUB_SLR_ET_RAMDISK, ++ /*flags=*/0, ++ boot_params->ramdisk_image, ++ boot_params->ramdisk_size, ++ "Measured Kernel initrd"); ++} ++ + static grub_err_t + grub_linux_boot (void) + { +@@ -411,6 +567,8 @@ grub_linux_boot (void) }; grub_size_t mmap_size; grub_size_t cl_offset; + grub_size_t ap_wake_block_size = 0; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); #ifdef GRUB_MACHINE_IEEE1275 { -@@ -543,6 +613,9 @@ grub_linux_boot (void) +@@ -543,6 +701,9 @@ grub_linux_boot (void) (unsigned) ctx.real_size, (unsigned) efi_mmap_size); @@ -350,7 +439,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 if (! ctx.real_mode_target) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); -@@ -550,7 +623,7 @@ grub_linux_boot (void) +@@ -550,7 +711,7 @@ grub_linux_boot (void) grub_relocator_chunk_t ch; grub_size_t sz; @@ -359,25 +448,34 @@ index 9f74a96b19ae..0ab2899f6774 100644 return GRUB_ERR_OUT_OF_RANGE; err = grub_relocator_alloc_chunk_addr (relocator, &ch, -@@ -561,6 +634,17 @@ grub_linux_boot (void) +@@ -561,6 +722,20 @@ grub_linux_boot (void) } efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; + if (grub_slaunch_platform_type () == SLP_INTEL_TXT) + { -+ slparams.ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; -+ slparams.ap_wake_block_size = ap_wake_block_size; ++ slparams->ap_wake_block = ctx.real_mode_target + ctx.real_size + efi_mmap_size; ++ slparams->ap_wake_block_size = ap_wake_block_size; + grub_memset ((void *) ((grub_addr_t) real_mode_mem + ctx.real_size + + efi_mmap_size), 0, ap_wake_block_size); + grub_dprintf ("linux", "ap_wake_block = %lx, ap_wake_block_size = %lx\n", -+ (unsigned long) slparams.ap_wake_block, ++ (unsigned long) slparams->ap_wake_block, + (unsigned long) ap_wake_block_size); ++ ++ /* Grab the real mode target address, this is the boot params page. */ ++ slparams->boot_params_addr = ctx.real_mode_target; + } + grub_dprintf ("linux", "real_mode_mem = %p\n", real_mode_mem); -@@ -591,9 +675,9 @@ grub_linux_boot (void) +@@ -587,13 +762,15 @@ grub_linux_boot (void) + + ctx.params->secure_boot = grub_efi_get_secureboot (); + ++ grub_dprintf ("linux", "EFI exit boot services\n"); ++ + err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, &efi_desc_size, &efi_desc_version); if (err) return err; @@ -389,7 +487,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); /* Pass EFI parameters. */ if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) -@@ -624,12 +708,33 @@ grub_linux_boot (void) +@@ -624,12 +801,36 @@ grub_linux_boot (void) } #endif @@ -403,17 +501,20 @@ index 9f74a96b19ae..0ab2899f6774 100644 + + if (state.edi == SLP_INTEL_TXT) + { -+ slparams.boot_params_addr = (grub_uint32_t) ctx.real_mode_target; -+ -+ err = grub_txt_boot_prepare (&slparams); ++ err = grub_txt_boot_prepare (slparams); + + if (err != GRUB_ERR_NONE) + return err; + ++ grub_slaunch_add_slrt_policy_entries (); ++ grub_txt_add_slrt_policy_entries (); ++ grub_linux_setup_slr_table (slparams); ++ grub_slaunch_finish_slr_table (); ++ + /* Configure relocator GETSEC[SENTER] call. */ + state.eax = GRUB_SMX_LEAF_SENTER; -+ state.ebx = slparams.sinit_acm_base; -+ state.ecx = slparams.sinit_acm_size; ++ state.ebx = slparams->dce_base; ++ state.ecx = slparams->dce_size; + state.edx = 0; + } + else @@ -429,7 +530,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 return grub_relocator32_boot (relocator, state, 0); } -@@ -650,7 +755,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -650,12 +851,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; @@ -438,7 +539,13 @@ index 9f74a96b19ae..0ab2899f6774 100644 grub_ssize_t len; int i; grub_size_t align, min_align; -@@ -743,7 +848,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int relocatable; + grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; ++ struct grub_slaunch_params *slparams = grub_slaunch_params(); + + grub_dl_ref (my_mod); + +@@ -743,7 +945,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), align = 0; relocatable = 0; } @@ -447,7 +554,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 if (grub_le_to_cpu16 (lh.version) >= 0x020a) { min_align = lh.min_alignment; -@@ -760,6 +865,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -760,6 +962,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), prot_init_space = page_align (prot_size) * 3; } @@ -461,17 +568,17 @@ index 9f74a96b19ae..0ab2899f6774 100644 if (allocate_pages (prot_size, &align, min_align, relocatable, preferred_address)) -@@ -767,6 +879,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -767,6 +976,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memset (&linux_params, 0, sizeof (linux_params)); + if (grub_slaunch_platform_type () == SLP_INTEL_TXT) -+ grub_txt_setup_mle_ptab (&slparams); ++ grub_txt_setup_mle_ptab (grub_slaunch_params ()); + /* * The Linux 32-bit boot protocol defines the setup header end * to be at 0x202 + the byte value at 0x201. -@@ -793,6 +908,75 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -793,6 +1005,79 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } @@ -505,7 +612,11 @@ index 9f74a96b19ae..0ab2899f6774 100644 + goto fail; + } + -+ linux_info->size_total = grub_le_to_cpu32 (linux_info->size_total); ++ if (linux_info->size_total < KERNEL_INFO_MIN_SIZE_TOTAL) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("incorrect kernel_info size")); ++ goto fail; ++ } + + linux_info = grub_realloc (linux_info, linux_info->size_total); + @@ -535,7 +646,7 @@ index 9f74a96b19ae..0ab2899f6774 100644 + goto fail; + } + -+ slparams.mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); ++ slparams->mle_header_offset = grub_le_to_cpu32 (linux_info->mle_header_offset); + } + } + else if (grub_slaunch_platform_type () != SLP_NONE) @@ -570,10 +681,10 @@ index 37550155df78..cd8213a05d31 100644 .esi = 0 diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c new file mode 100644 -index 000000000000..9b2efd755f89 +index 000000000000..606152edb14d --- /dev/null +++ b/grub-core/loader/i386/slaunch.c -@@ -0,0 +1,201 @@ +@@ -0,0 +1,299 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -599,11 +710,13 @@ index 000000000000..9b2efd755f89 +#include +#include +#include ++#include +#include +#include +#include +#include +#include ++#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); @@ -612,6 +725,15 @@ index 000000000000..9b2efd755f89 + +static void *slaunch_module = NULL; + ++static struct grub_slaunch_params slparams; ++ ++/* Area to collect and build SLR Table information. */ ++static struct grub_slr_entry_dl_info slr_dl_info_staging; ++static struct grub_slr_entry_log_info slr_log_info_staging; ++static grub_uint8_t slr_policy_buf[GRUB_PAGE_SIZE]; ++static struct grub_slr_entry_policy *slr_policy_staging = ++ (struct grub_slr_entry_policy *)slr_policy_buf; ++ +grub_uint32_t +grub_slaunch_platform_type (void) +{ @@ -624,6 +746,93 @@ index 000000000000..9b2efd755f89 + return slaunch_module; +} + ++struct grub_slaunch_params * ++grub_slaunch_params (void) ++{ ++ return &slparams; ++} ++ ++void ++grub_slaunch_init_slrt_storage (int arch) ++{ ++ struct grub_txt_mle_header *mle_header = ++ (void *) ((grub_uint8_t *) slparams.mle_mem + slparams.mle_header_offset); ++ ++ /* Setup the generic bits of the SLRT. */ ++ grub_slr_init_table(slparams.slr_table_mem, arch, slparams.slr_table_size); ++ ++ /* Setup DCE and DLME information. */ ++ slr_dl_info_staging.hdr.tag = GRUB_SLR_ENTRY_DL_INFO; ++ slr_dl_info_staging.hdr.size = sizeof(struct grub_slr_entry_dl_info); ++ slr_dl_info_staging.dce_base = slparams.dce_base; ++ slr_dl_info_staging.dce_size = slparams.dce_size; ++ slr_dl_info_staging.dlme_entry = mle_header->entry_point; ++ ++ slr_log_info_staging.hdr.tag = GRUB_SLR_ENTRY_LOG_INFO; ++ slr_log_info_staging.hdr.size = sizeof(struct grub_slr_entry_log_info); ++ slr_log_info_staging.addr = slparams.tpm_evt_log_base; ++ slr_log_info_staging.size = slparams.tpm_evt_log_size; ++ slr_log_info_staging.format = ++ (grub_get_tpm_ver () == GRUB_TPM_20) ? ++ GRUB_SLR_DRTM_TPM20_LOG : GRUB_SLR_DRTM_TPM12_LOG; ++ ++ slr_policy_staging->hdr.tag = GRUB_SLR_ENTRY_DRTM_POLICY; ++ slr_policy_staging->hdr.size = sizeof(struct grub_slr_entry_policy); ++ slr_policy_staging->revision = GRUB_SLR_TABLE_REVISION; ++ slr_policy_staging->nr_entries = 0; ++} ++ ++void grub_slaunch_add_slrt_policy_entries (void) ++{ ++ /* The SLR table should be measured too, at least parts of it. */ ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_SLRT, ++ GRUB_SLR_POLICY_IMPLICIT_SIZE, ++ slparams.slr_table_base, ++ /*size=*/0, ++ "Measured SLR Table"); ++} ++ ++void ++grub_slaunch_add_slrt_policy_entry (grub_uint16_t pcr, ++ grub_uint16_t entity_type, ++ grub_uint16_t flags, ++ grub_uint64_t entity, ++ grub_uint64_t size, ++ const char *evt_info) ++{ ++ struct grub_slr_policy_entry *entry = ++ (void *)((grub_uint8_t *)slr_policy_staging + ++ sizeof(struct grub_slr_entry_policy) + ++ slr_policy_staging->nr_entries*sizeof(*entry)); ++ ++ if (slr_policy_staging->hdr.size + sizeof(*entry) > sizeof(slr_policy_buf)) ++ grub_fatal("Not enough space for adding policy entry: %s! The buffer is full.", ++ evt_info); ++ ++ entry->pcr = pcr; ++ entry->entity_type = entity_type; ++ entry->flags = flags; ++ entry->entity = entity; ++ entry->size = size; ++ ++ grub_strncpy(entry->evt_info, evt_info, sizeof(entry->evt_info) - 1); ++ entry->evt_info[sizeof(entry->evt_info) - 1] = '\0'; ++ ++ slr_policy_staging->hdr.size += sizeof(*entry); ++ ++slr_policy_staging->nr_entries; ++} ++ ++void ++grub_slaunch_finish_slr_table (void) ++{ ++ struct grub_slr_table *slr_table = slparams.slr_table_mem; ++ ++ grub_slr_add_entry (slr_table, &slr_dl_info_staging.hdr); ++ grub_slr_add_entry (slr_table, &slr_log_info_staging.hdr); ++ grub_slr_add_entry (slr_table, &slr_policy_staging->hdr); ++} ++ +static grub_err_t +grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), @@ -671,7 +880,7 @@ index 000000000000..9b2efd755f89 + if (slp == SLP_NONE) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("secure launch not enabled")); + -+ if (slp > SLP_INTEL_TXT) ++ if (slp != SLP_INTEL_TXT) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unknown secure launch platform type: %d"), slp); + @@ -874,69 +1083,6 @@ index eddf9251d9a5..798188c85454 100644 grub_uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 290 */ struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */ } GRUB_PACKED; -diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h -new file mode 100644 -index 000000000000..12cd341aae0c ---- /dev/null -+++ b/include/grub/i386/slaunch.h -@@ -0,0 +1,57 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 Oracle and/or its affiliates. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ * -+ * Main secure launch definitions header file. -+ */ -+ -+#ifndef GRUB_I386_SLAUNCH_H -+#define GRUB_I386_SLAUNCH_H 1 -+ -+/* Secure launch platform types. */ -+#define SLP_NONE 0 -+#define SLP_INTEL_TXT 1 -+ -+#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE) -+ -+#ifndef ASM_FILE -+ -+#include -+#include -+ -+struct grub_slaunch_params -+{ -+ grub_uint32_t boot_params_addr; -+ grub_uint32_t mle_start; -+ grub_uint32_t mle_size; -+ void *mle_ptab_mem; -+ grub_uint64_t mle_ptab_target; -+ grub_uint32_t mle_ptab_size; -+ grub_uint32_t mle_header_offset; -+ grub_uint32_t ap_wake_block; -+ grub_uint32_t ap_wake_block_size; -+ grub_uint32_t sinit_acm_base; -+ grub_uint32_t sinit_acm_size; -+ grub_uint64_t tpm_evt_log_base; -+ grub_uint32_t tpm_evt_log_size; -+}; -+ -+extern grub_uint32_t grub_slaunch_platform_type (void); -+extern void *grub_slaunch_module (void); -+ -+#endif /* ASM_FILE */ -+ -+#endif /* GRUB_I386_SLAUNCH_H */ -- -2.17.1 +2.41.0 diff --git a/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch b/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch new file mode 100644 index 0000000..18a52e1 --- /dev/null +++ b/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch @@ -0,0 +1,114 @@ +From c483385a164d0b7e950dd85a6dfd73f84fe05a4c Mon Sep 17 00:00:00 2001 +From: Sergii Dmytruk +Date: Wed, 22 Nov 2023 21:08:35 +0200 +Subject: [PATCH] multiboot: make GRUB_MULTIBOOT(make_mbi) return MBI's size + +GRUB_MULTIBOOT(get_mbi_size) doesn't look like an accurate source of the +final size, more like a minimal memory buffer size. + +Signed-off-by: Sergii Dmytruk +--- + grub-core/loader/i386/multiboot_mbi.c | 4 +++- + grub-core/loader/multiboot.c | 3 ++- + grub-core/loader/multiboot_mbi2.c | 6 ++++-- + include/grub/multiboot.h | 2 +- + include/grub/multiboot2.h | 3 ++- + 5 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c +index a67d9d0a8088..29dd9cbb7c25 100644 +--- a/grub-core/loader/i386/multiboot_mbi.c ++++ b/grub-core/loader/i386/multiboot_mbi.c +@@ -450,7 +450,7 @@ retrieve_video_parameters (struct multiboot_info *mbi, + } + + grub_err_t +-grub_multiboot_make_mbi (grub_uint32_t *target) ++grub_multiboot_make_mbi (grub_uint32_t *target, grub_uint32_t *size) + { + struct multiboot_info *mbi; + struct multiboot_mod_list *modlist; +@@ -618,6 +618,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) + return err; + #endif + ++ *size = (char *) ptrorig - (char *) mbi; ++ + return GRUB_ERR_NONE; + } + +diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c +index 3ab0c828c3ae..07173f60e7c4 100644 +--- a/grub-core/loader/multiboot.c ++++ b/grub-core/loader/multiboot.c +@@ -180,6 +180,7 @@ static grub_err_t + grub_multiboot_boot (void) + { + grub_err_t err; ++ grub_uint32_t mbi_size; + + #ifdef GRUB_USE_MULTIBOOT2 + struct grub_relocator32_state state = MULTIBOOT2_INITIAL_STATE; +@@ -188,7 +189,7 @@ grub_multiboot_boot (void) + #endif + state.MULTIBOOT_ENTRY_REGISTER = GRUB_MULTIBOOT (payload_eip); + +- err = GRUB_MULTIBOOT (make_mbi) (&state.MULTIBOOT_MBI_REGISTER); ++ err = GRUB_MULTIBOOT (make_mbi) (&state.MULTIBOOT_MBI_REGISTER, &mbi_size); + + if (err) + return err; +diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c +index 9a943d7bdd7c..197afd1b1809 100644 +--- a/grub-core/loader/multiboot_mbi2.c ++++ b/grub-core/loader/multiboot_mbi2.c +@@ -701,7 +701,7 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig) + } + + grub_err_t +-grub_multiboot2_make_mbi (grub_uint32_t *target) ++grub_multiboot2_make_mbi (grub_uint32_t *target, grub_uint32_t *size) + { + grub_properly_aligned_t *ptrorig; + grub_properly_aligned_t *mbistart; +@@ -1002,7 +1002,9 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) + / sizeof (grub_properly_aligned_t); + } + +- ((grub_uint32_t *) mbistart)[0] = (char *) ptrorig - (char *) mbistart; ++ *size = (char *) ptrorig - (char *) mbistart; ++ ++ ((grub_uint32_t *) mbistart)[0] = *size; + ((grub_uint32_t *) mbistart)[1] = 0; + + return GRUB_ERR_NONE; +diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h +index bd0a9873e6c1..f9fa74471326 100644 +--- a/include/grub/multiboot.h ++++ b/include/grub/multiboot.h +@@ -41,7 +41,7 @@ void grub_multiboot (int argc, char *argv[]); + void grub_module (int argc, char *argv[]); + + void grub_multiboot_set_accepts_video (int val); +-grub_err_t grub_multiboot_make_mbi (grub_uint32_t *target); ++grub_err_t grub_multiboot_make_mbi (grub_uint32_t *target, grub_uint32_t *size); + void grub_multiboot_free_mbi (void); + grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]); + grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size, +diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h +index 502d34ef1804..d1e3b3a8b4f6 100644 +--- a/include/grub/multiboot2.h ++++ b/include/grub/multiboot2.h +@@ -33,7 +33,8 @@ void grub_multiboot2 (int argc, char *argv[]); + void grub_module2 (int argc, char *argv[]); + + void grub_multiboot2_set_accepts_video (int val); +-grub_err_t grub_multiboot2_make_mbi (grub_uint32_t *target); ++grub_err_t grub_multiboot2_make_mbi (grub_uint32_t *target, ++ grub_uint32_t *size); + void grub_multiboot2_free_mbi (void); + grub_err_t grub_multiboot2_init_mbi (int argc, char *argv[]); + grub_err_t grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, +-- +2.41.0 + diff --git a/1116-multiboot2-Implement-TXT-slaunch-support.patch b/1119-multiboot2-Implement-TXT-slaunch-support.patch similarity index 65% rename from 1116-multiboot2-Implement-TXT-slaunch-support.patch rename to 1119-multiboot2-Implement-TXT-slaunch-support.patch index d397959..e67fdbb 100644 --- a/1116-multiboot2-Implement-TXT-slaunch-support.patch +++ b/1119-multiboot2-Implement-TXT-slaunch-support.patch @@ -1,4 +1,4 @@ -From 4d48d3bc4fe7ac5dae6f32de2928a803c2dfb770 Mon Sep 17 00:00:00 2001 +From 66b9d72c3119ab93b7529074010aefb3ad3d8bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 1 Sep 2022 17:58:53 +0200 Subject: [PATCH] multiboot2: Implement TXT slaunch support @@ -6,18 +6,26 @@ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +The code makes sure that MBI entry goes first in DRTM, so the payload +can measure it first on launch. + +SLRT table is allocated on the heap first, size for it is reserved +inside TXT heap by TXT code and data is later copied into its final +place. + +Signed-off-by: Sergii Dmytruk Signed-off-by: Michał Żygowski Signed-off-by: Tomasz Żyjewski Signed-off-by: Krystian Hebel --- - grub-core/loader/multiboot.c | 22 ++++++- - grub-core/loader/multiboot_elfxx.c | 102 ++++++++++++++++++++++++++--- - grub-core/loader/multiboot_mbi2.c | 39 +++++++++++ - include/grub/i386/txt.h | 1 + - 4 files changed, 155 insertions(+), 9 deletions(-) + grub-core/loader/multiboot.c | 23 ++++++- + grub-core/loader/multiboot_elfxx.c | 104 ++++++++++++++++++++++++++--- + grub-core/loader/multiboot_mbi2.c | 99 +++++++++++++++++++++++++++ + include/grub/multiboot2.h | 2 + + 4 files changed, 219 insertions(+), 9 deletions(-) diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c -index 3ab0c828c3ae..049efd04c649 100644 +index 07173f60e7c4..17a922be2a16 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -52,6 +52,7 @@ @@ -28,36 +36,44 @@ index 3ab0c828c3ae..049efd04c649 100644 #endif GRUB_MOD_LICENSE ("GPLv3+"); -@@ -164,7 +165,26 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)), +@@ -164,7 +165,17 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)), static void normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state) { - state.edi = SLP_NONE; -+ grub_err_t err; + struct grub_slaunch_params *slparams = grub_slaunch_params(); + state.edi = grub_slaunch_platform_type (); + + if (state.edi == SLP_INTEL_TXT) + { -+ err = grub_txt_boot_prepare (slparams); -+ -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_printf ("TXT boot preparation failed"); -+ return; -+ } -+ + /* Configure relocator GETSEC[SENTER] call. */ + state.eax = GRUB_SMX_LEAF_SENTER; -+ state.ebx = slparams->sinit_acm_base; -+ state.ecx = slparams->sinit_acm_size; ++ state.ebx = slparams->dce_base; ++ state.ecx = slparams->dce_size; + state.edx = 0; + } grub_relocator32_boot (rel, state, 0); } +@@ -194,6 +205,16 @@ grub_multiboot_boot (void) + if (err) + return err; + ++#ifdef GRUB_USE_MULTIBOOT2 ++ if (grub_slaunch_platform_type () == SLP_INTEL_TXT) ++ { ++ err = grub_multiboot2_prepare_slaunch_txt (state.MULTIBOOT_MBI_REGISTER, ++ mbi_size); ++ if (err) ++ return err; ++ } ++#endif ++ + if (grub_efi_is_finished) + normal_boot (GRUB_MULTIBOOT (relocator), state); + else diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c -index f2318e0d165d..47ba4c3f2746 100644 +index f2318e0d165d..438cedc2c096 100644 --- a/grub-core/loader/multiboot_elfxx.c +++ b/grub-core/loader/multiboot_elfxx.c @@ -34,6 +34,8 @@ @@ -79,7 +95,7 @@ index f2318e0d165d..47ba4c3f2746 100644 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 -@@ -106,25 +111,86 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) +@@ -106,25 +111,87 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) (long) mld->align, mld->preference, load_size, mld->avoid_efi_boot_services); @@ -143,6 +159,7 @@ index f2318e0d165d..47ba4c3f2746 100644 + return grub_error (GRUB_ERR_BAD_OS, "Only multiboot2 supported for slaunch"); +#else + slparams->mle_start = mld->load_base_addr; ++ slparams->mle_mem = source; + + err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch, + GRUB_MEMORY_MACHINE_UPPER_START, @@ -174,7 +191,7 @@ index f2318e0d165d..47ba4c3f2746 100644 grub_dprintf ("multiboot_loader", "relocatable=%d, link_base_addr=0x%x, " "load_base_addr=0x%x\n", mld->relocatable, -@@ -180,6 +246,26 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) +@@ -180,6 +247,27 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) } } @@ -182,6 +199,7 @@ index f2318e0d165d..47ba4c3f2746 100644 + { + slparams->mle_header_offset = 0xffffffff; + ++ /* TODO: decide on universal way of conveying location of MLE header */ + for (mle_hdr_offset = 0; mle_hdr_offset < 0x1000; mle_hdr_offset += 16) + { + if ( !grub_memcmp ((void *)((grub_addr_t) source + mle_hdr_offset), GRUB_TXT_MLE_UUID, 16) ) @@ -202,20 +220,21 @@ index f2318e0d165d..47ba4c3f2746 100644 if (phdr(i)->p_vaddr <= ehdr->e_entry && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c -index 9a943d7bdd7c..eb617083f8e5 100644 +index 197afd1b1809..fd93bc0e4237 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c -@@ -36,6 +36,9 @@ +@@ -36,6 +36,10 @@ #include #include #include +#include +#include +#include ++#include #if defined (GRUB_MACHINE_EFI) #include -@@ -277,6 +280,9 @@ grub_multiboot2_load (grub_file_t file, const char *filename) +@@ -277,6 +281,9 @@ grub_multiboot2_load (grub_file_t file, const char *filename) if (addr_tag) { @@ -225,7 +244,7 @@ index 9a943d7bdd7c..eb617083f8e5 100644 grub_uint64_t load_addr = (addr_tag->load_addr + 1) ? addr_tag->load_addr : (addr_tag->header_addr - ((char *) header - (char *) mld.buffer)); -@@ -390,6 +396,34 @@ grub_multiboot2_load (grub_file_t file, const char *filename) +@@ -390,6 +397,34 @@ grub_multiboot2_load (grub_file_t file, const char *filename) err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT, accepted_consoles, 0, 0, 0, console_required); @@ -260,7 +279,7 @@ index 9a943d7bdd7c..eb617083f8e5 100644 return err; } -@@ -722,7 +756,12 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) +@@ -722,7 +757,12 @@ grub_multiboot2_make_mbi (grub_uint32_t *target, grub_uint32_t *size) ptrorig = get_virtual_current_address (ch); #if defined (__i386__) || defined (__x86_64__) @@ -273,18 +292,82 @@ index 9a943d7bdd7c..eb617083f8e5 100644 #elif defined (__mips) *target = get_physical_target_address (ch) | 0x80000000; #else -diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index 0d2ca5b298c1..53355d511412 100644 ---- a/include/grub/i386/txt.h -+++ b/include/grub/i386/txt.h -@@ -101,6 +101,7 @@ struct grub_txt_acm_header - } GRUB_PACKED; +@@ -1128,3 +1168,62 @@ grub_multiboot2_set_bootdev (void) - #define GRUB_TXT_ACM_UUID "\xaa\x3a\xc0\x7f\xa7\x46\xdb\x18\x2e\xac\x69\x8f\x8d\x41\x7f\x5a" -+#define GRUB_TXT_MLE_UUID "\x5a\xac\x82\x90\x6f\x47\xa7\x74\x0f\x5c\x55\xa2\xcb\x51\xb6\x42" + bootdev_set = 1; + } ++ ++static void ++add_multiboot2_slrt_policy_entries (void) ++{ ++ unsigned i; ++ struct module *cur; ++ ++ for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next) ++ { ++ grub_slaunch_add_slrt_policy_entry (17, ++ GRUB_SLR_ET_MULTIBOOT2_MODULE, ++ /*flags=*/0, ++ cur->start, ++ cur->size, ++ "Measured MB2 module"); ++ } ++} ++ ++grub_err_t ++grub_multiboot2_prepare_slaunch_txt (grub_uint32_t mbi_target, ++ grub_uint32_t mbi_size) ++{ ++ grub_err_t err; ++ struct grub_slaunch_params *slparams = grub_slaunch_params (); ++ ++ slparams->slr_table_base = GRUB_SLAUNCH_STORE_IN_OS2MLE; ++ slparams->slr_table_size = GRUB_PAGE_SIZE; ++ ++ slparams->slr_table_mem = grub_zalloc (slparams->slr_table_size); ++ if (slparams->slr_table_mem == NULL) ++ return GRUB_ERR_OUT_OF_MEMORY; ++ ++ err = grub_txt_boot_prepare (slparams); ++ if (err != GRUB_ERR_NONE) ++ { ++ grub_printf ("TXT boot preparation failed"); ++ return err; ++ } ++ ++ grub_slaunch_add_slrt_policy_entry (18, ++ GRUB_SLR_ET_MULTIBOOT2_INFO, ++ /*flags=*/0, ++ mbi_target, ++ mbi_size, ++ "Measured MB2 information"); ++ grub_slaunch_add_slrt_policy_entries (); ++ grub_txt_add_slrt_policy_entries (); ++ add_multiboot2_slrt_policy_entries (); ++ grub_slaunch_finish_slr_table (); ++ ++ grub_dprintf ("multiboot_loader", "slr_table_base = %lx, slr_table_size = %x\n", ++ (unsigned long) slparams->slr_table_base, ++ (unsigned) slparams->slr_table_size); ++ grub_memcpy ((void *)(grub_addr_t) slparams->slr_table_base, ++ slparams->slr_table_mem, ++ slparams->slr_table_size); ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h +index d1e3b3a8b4f6..0ca577e7395f 100644 +--- a/include/grub/multiboot2.h ++++ b/include/grub/multiboot2.h +@@ -43,6 +43,8 @@ void grub_multiboot2_set_bootdev (void); + void + grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize, + unsigned shndx, void *data); ++grub_err_t grub_multiboot2_prepare_slaunch_txt (grub_uint32_t mbi_target, ++ grub_uint32_t mbi_size); - #define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS 0 - #define GRUB_TXT_ACM_CHIPSET_TYPE_SINIT 1 + grub_uint32_t grub_multiboot2_get_mmap_count (void); + grub_err_t grub_multiboot2_set_video_mode (void); -- -2.17.1 +2.41.0 diff --git a/grub2.spec.in b/grub2.spec.in index dafd7a2..6b24435 100644 --- a/grub2.spec.in +++ b/grub2.spec.in @@ -753,18 +753,21 @@ Patch1101: 1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch Patch1102: 1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch Patch1103: 1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch Patch1104: 1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch -Patch1105: 1105-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch -Patch1106: 1106-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +Patch1105: 1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch +Patch1106: 1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch Patch1107: 1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch Patch1108: 1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch -Patch1109: 1109-i386-txt-Add-Intel-TXT-definitions-header-file.patch -Patch1110: 1110-i386-txt-Add-Intel-TXT-core-implementation.patch -Patch1111: 1111-i386-txt-Add-Intel-TXT-ACM-module-support.patch -Patch1112: 1112-i386-txt-Add-Intel-TXT-verification-routines.patch -Patch1113: 1113-i386-slaunch-Add-secure-launch-framework-and-command.patch -Patch1114: 1114-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch -Patch1115: 1115-slaunch-Make-slparams-accessible-by-other-modules.patch -Patch1116: 1116-multiboot2-Implement-TXT-slaunch-support.patch +Patch1109: 1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +Patch1110: 1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch +Patch1111: 1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch +Patch1112: 1112-i386-txt-Add-Intel-TXT-core-implementation.patch +Patch1113: 1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch +Patch1114: 1114-i386-txt-Add-Intel-TXT-verification-routines.patch +Patch1115: 1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +Patch1116: 1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch +Patch1117: 1117-i386-slaunch-Add-secure-launch-framework-and-command.patch +Patch1118: 1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch +Patch1119: 1119-multiboot2-Implement-TXT-slaunch-support.patch BuildRequires: autoconf BuildRequires: automake From 98414dea6a22f44ec0efd911ce4a0a6496061170 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Wed, 21 Feb 2024 14:41:21 +0100 Subject: [PATCH 5/5] TXT support: update after review Reviewed on https://github.com/TrenchBoot/grub/pull/16 Signed-off-by: Krystian Hebel --- ...Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch | 2 +- ...ame-grub_msr_read-and-grub_msr_write.patch | 2 +- ...-and-improve-MSR-support-detection-c.patch | 2 +- ...Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch | 2 +- ...me-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch | 2 +- ...ne-GRUB_PAGE_MASK-constant-and-GRUB_.patch | 2 +- ...ap_get_lowest-and-grub_mmap_get_high.patch | 2 +- ...pm-Rename-tpm-module-to-tpm_verifier.patch | 2 +- ...-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch | 2 +- ...-basic-platform-support-for-secure-l.patch | 14 ++- ...-commit-of-the-Secure-Launch-Resourc.patch | 70 ++++++++---- ...dd-Intel-TXT-definitions-header-file.patch | 62 ++++------- ...xt-Add-Intel-TXT-core-implementation.patch | 61 ++++++----- ...txt-Add-Intel-TXT-ACM-module-support.patch | 40 +++---- ...-Add-Intel-TXT-verification-routines.patch | 37 ++++--- ...ialize-TPM-1.2-event-log-in-TXT-heap.patch | 18 ++-- ...to-using-Secure-Launch-Resource-Tabl.patch | 34 +++--- ...-secure-launch-framework-and-command.patch | 100 ++++++++++-------- ...RUB_MULTIBOOT-make_mbi-return-MBI-s-.patch | 2 +- ...iboot2-Implement-TXT-slaunch-support.patch | 2 +- 20 files changed, 240 insertions(+), 218 deletions(-) diff --git a/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch index abac6cf..a2ae71c 100644 --- a/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch +++ b/1100-i386-msr-Merge-rdmsr.h-and-wrmsr.h-into-msr.h.patch @@ -1,4 +1,4 @@ -From 1614664a12563b23b2efd3b0c7b59a9c4ad10484 Mon Sep 17 00:00:00 2001 +From b965e567652ec8eb8bde2cd6f79b4ef02fdb0fa4 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 17 Dec 2019 17:51:29 +0100 Subject: [PATCH] i386/msr: Merge rdmsr.h and wrmsr.h into msr.h diff --git a/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch b/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch index b21fb4d..0bf4178 100644 --- a/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch +++ b/1101-i386-msr-Rename-grub_msr_read-and-grub_msr_write.patch @@ -1,4 +1,4 @@ -From bb8fe14ea78fbd7ad92b3d53c69e3b961eb8ccdd Mon Sep 17 00:00:00 2001 +From 462af28050122f87412237abd8000f3667a5d3be Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 17 Dec 2019 20:02:37 +0100 Subject: [PATCH] i386/msr: Rename grub_msr_read() and grub_msr_write() diff --git a/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch b/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch index ec1cd34..73efb6a 100644 --- a/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch +++ b/1102-i386-msr-Extract-and-improve-MSR-support-detection-c.patch @@ -1,4 +1,4 @@ -From e0f617c89e3a03cba4b5e48ffac8ef76cc7c0838 Mon Sep 17 00:00:00 2001 +From 52d63e5e45eaf8df9a81a453459fd89fbf898969 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Sat, 25 Apr 2020 16:43:52 +0200 Subject: [PATCH] i386/msr: Extract and improve MSR support detection code diff --git a/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch b/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch index ab45048..0f0a500 100644 --- a/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch +++ b/1103-i386-memory-Rename-PAGE_SHIFT-to-GRUB_PAGE_SHIFT.patch @@ -1,4 +1,4 @@ -From 938357ec4fd8a8522fc55d3d050eff1f2235407d Mon Sep 17 00:00:00 2001 +From 7d5c059815a34eb170f4e8912cb742a9e69b6e45 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 20 Nov 2019 12:40:42 +0100 Subject: [PATCH] i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT diff --git a/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch b/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch index c32fa9a..1db0aab 100644 --- a/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch +++ b/1104-i386-memory-Rename-PAGE_SIZE-to-GRUB_PAGE_SIZE-and-m.patch @@ -1,4 +1,4 @@ -From 4e9a66d61b076b01826af440f581bb0c26c58431 Mon Sep 17 00:00:00 2001 +From 881d5870cbf72f7b35282de1addb107ac3b8100b Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 20 Nov 2019 12:52:16 +0100 Subject: [PATCH] i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and make it diff --git a/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch b/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch index bc6f260..d00e9ec 100644 --- a/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch +++ b/1105-i386-memory-Define-GRUB_PAGE_MASK-constant-and-GRUB_.patch @@ -1,4 +1,4 @@ -From 868093de8910bd66abcde04ca928538e07366ad7 Mon Sep 17 00:00:00 2001 +From d9f97aa57e7cb90a0ed3947daba727b2f619b17b Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Mon, 22 Jan 2024 13:14:39 +0100 Subject: [PATCH] i386/memory: Define GRUB_PAGE_MASK constant and diff --git a/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch b/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch index 94028b1..98ec1f6 100644 --- a/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch +++ b/1106-mmap-Add-grub_mmap_get_lowest-and-grub_mmap_get_high.patch @@ -1,4 +1,4 @@ -From 0cfc0a5385a0847f79c9225d9dd9522ef25efaad Mon Sep 17 00:00:00 2001 +From d0570055a9451163220d28e79ba3cf89fb2c1dfa Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:34:59 +0200 Subject: [PATCH] mmap: Add grub_mmap_get_lowest() and grub_mmap_get_highest() diff --git a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch index 5c68ceb..06343dc 100644 --- a/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch +++ b/1107-i386-tpm-Rename-tpm-module-to-tpm_verifier.patch @@ -1,4 +1,4 @@ -From a14dcf40c6eddc23c90a2486eb2665433824a4e2 Mon Sep 17 00:00:00 2001 +From 01e5b0008d4031ef8612cfc387c7a66d2d4331c6 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Wed, 22 Apr 2020 21:41:24 +0200 Subject: [PATCH] i386/tpm: Rename tpm module to tpm_verifier diff --git a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch index d449d26..37da1e2 100644 --- a/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch +++ b/1108-i386-tpm-Add-TPM-TIS-and-CRB-driver.patch @@ -1,4 +1,4 @@ -From 8527ee439916f427443d0eb68b7eb9be031611ee Mon Sep 17 00:00:00 2001 +From c51d2529ed6bbddcc08edd74ca9e855b4ad397ff Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 4 May 2020 22:30:58 +0200 Subject: [PATCH] i386/tpm: Add TPM TIS and CRB driver diff --git a/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch b/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch index adb2c19..3a43540 100644 --- a/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch +++ b/1109-i386-slaunch-Add-basic-platform-support-for-secure-l.patch @@ -1,4 +1,4 @@ -From f6a4ec51420020d205add6a8a95d13cd1b5a2be5 Mon Sep 17 00:00:00 2001 +From 615f29aac919a2fdaa6f9187569c8854ca1acf03 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:50:14 -0400 Subject: [PATCH] i386/slaunch: Add basic platform support for secure launch @@ -14,8 +14,8 @@ Signed-off-by: Krystian Hebel include/grub/i386/crfr.h | 127 ++++++++++++++++++++++++++++++++++++ include/grub/i386/mmio.h | 72 ++++++++++++++++++++ include/grub/i386/msr.h | 63 ++++++++++++++++++ - include/grub/i386/slaunch.h | 58 ++++++++++++++++ - 5 files changed, 332 insertions(+) + include/grub/i386/slaunch.h | 62 ++++++++++++++++++ + 5 files changed, 336 insertions(+) create mode 100644 include/grub/i386/crfr.h create mode 100644 include/grub/i386/mmio.h create mode 100644 include/grub/i386/slaunch.h @@ -342,10 +342,10 @@ index 1e838c022f41..52c923ab94ac 100644 #endif /* GRUB_I386_MSR_H */ diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h new file mode 100644 -index 000000000000..f7160d5fab0c +index 000000000000..7f7709cda75e --- /dev/null +++ b/include/grub/i386/slaunch.h -@@ -0,0 +1,58 @@ +@@ -0,0 +1,62 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -373,6 +373,10 @@ index 000000000000..f7160d5fab0c +#define SLP_NONE 0 +#define SLP_INTEL_TXT 1 + ++/* PCRs used by Secure launch. */ ++#define GRUB_SLAUNCH_CODE_PCR 17 ++#define GRUB_SLAUNCH_DATA_PCR 18 ++ +#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE) + +#ifndef ASM_FILE diff --git a/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch b/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch index 2757e1e..14480c8 100644 --- a/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch +++ b/1110-i386-txt-Initial-commit-of-the-Secure-Launch-Resourc.patch @@ -1,4 +1,4 @@ -From ad10c1df6be8ea4ac9a6346f0719983e0e04f936 Mon Sep 17 00:00:00 2001 +From 6833012da36ed4017abfe483cd09db9418490860 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Mon, 9 Jan 2023 12:55:42 -0500 Subject: [PATCH] i386/txt: Initial commit of the Secure Launch Resource Table @@ -10,16 +10,16 @@ and parsing of SLRT. Signed-off-by: Ross Philipson Signed-off-by: Sergii Dmytruk --- - include/grub/slr_table.h | 298 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 298 insertions(+) + include/grub/slr_table.h | 330 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 330 insertions(+) create mode 100644 include/grub/slr_table.h diff --git a/include/grub/slr_table.h b/include/grub/slr_table.h new file mode 100644 -index 000000000000..59074723b500 +index 000000000000..b6bbb0d546ff --- /dev/null +++ b/include/grub/slr_table.h -@@ -0,0 +1,298 @@ +@@ -0,0 +1,330 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2023 Oracle and/or its affiliates. @@ -43,6 +43,8 @@ index 000000000000..59074723b500 +#ifndef GRUB_SLR_TABLE_H +#define GRUB_SLR_TABLE_H 1 + ++#include ++ +#define GRUB_UEFI_SLR_TABLE_GUID \ + { 0x877a9b2a, 0x0385, 0x45d1, { 0xa0, 0x34, 0x9d, 0xac, 0x9c, 0x9e, 0x56, 0x5f }} + @@ -213,6 +215,7 @@ index 000000000000..59074723b500 +struct grub_slr_entry_amd_info +{ + struct grub_slr_entry_hdr hdr; ++ char reserved[]; /* Reserved for future use */ +} GRUB_PACKED; + +/* @@ -221,14 +224,7 @@ index 000000000000..59074723b500 +struct grub_slr_entry_arm_info +{ + struct grub_slr_entry_hdr hdr; -+} GRUB_PACKED; -+ -+struct grub_slr_entry_uefi_config -+{ -+ struct grub_slr_entry_hdr hdr; -+ grub_uint16_t revision; -+ grub_uint16_t nr_entries; -+ /* uefi_cfg_entries[] */ ++ char reserved[]; /* Reserved for future use */ +} GRUB_PACKED; + +struct grub_slr_uefi_cfg_entry @@ -240,21 +236,50 @@ index 000000000000..59074723b500 + char evt_info[GRUB_TPM_EVENT_INFO_LENGTH]; +} GRUB_PACKED; + -+static inline void * ++struct grub_slr_entry_uefi_config ++{ ++ struct grub_slr_entry_hdr hdr; ++ grub_uint16_t revision; ++ grub_uint16_t nr_entries; ++ struct grub_slr_uefi_cfg_entry uefi_cfg_entries[]; ++} GRUB_PACKED; ++ ++static inline grub_addr_t +grub_slr_end_of_entries (struct grub_slr_table *table) +{ -+ return (grub_uint8_t *) table + table->size; ++ return (grub_addr_t) table + table->size; +} + +static inline struct grub_slr_entry_hdr * +grub_slr_next_entry (struct grub_slr_table *table, + struct grub_slr_entry_hdr *curr) +{ -+ struct grub_slr_entry_hdr *next = (struct grub_slr_entry_hdr *) -+ ((grub_uint8_t *) curr + curr->size); ++ grub_addr_t addr; ++ struct grub_slr_entry_hdr *next; ++ ++ /* Can read the size field of current entry? */ ++ if ( grub_add ((grub_addr_t) curr, sizeof(*curr), &addr) ) ++ return NULL; + -+ if ((void *)next >= grub_slr_end_of_entries (table)) ++ /* Does current size overflow? */ ++ if ( grub_add ((grub_addr_t) curr, curr->size, &addr) ) + return NULL; ++ ++ /* Can read the size field of next entry? */ ++ if ( grub_add (addr, sizeof(*next), &addr) ) ++ return NULL; ++ ++ /* Does next element's header fit within the table? */ ++ if (addr >= grub_slr_end_of_entries (table)) ++ return NULL; ++ ++ next = (struct grub_slr_entry_hdr *) (addr - sizeof(*next)); ++ ++ /* Does next element fit within the table? */ ++ if (grub_slr_end_of_entries (table) - (addr - sizeof(*next)) < next->size) ++ return NULL; ++ ++ /* Is this the last element? */ + if (next->tag == GRUB_SLR_ENTRY_END) + return NULL; + @@ -287,8 +312,11 @@ index 000000000000..59074723b500 + struct grub_slr_entry_hdr *entry) +{ + struct grub_slr_entry_hdr *end; ++ grub_uint32_t new_size; + -+ if ((table->size + entry->size) > table->max_size) ++ if (entry->size < sizeof(*end) || ++ grub_add (table->size, entry->size, &new_size) || ++ new_size > table->max_size) + return -1; + + grub_memcpy ((grub_uint8_t *) table + table->size - sizeof(*end), entry, entry->size); @@ -307,6 +335,10 @@ index 000000000000..59074723b500 +{ + struct grub_slr_entry_hdr *end; + ++ if (max_size < sizeof(*slrt) + sizeof(*end)) ++ grub_fatal ("Requested SLRT max size (%" PRIuGRUB_UINT32_T ++ " B) is too small\n", max_size); ++ + slrt->magic = GRUB_SLR_TABLE_MAGIC; + slrt->revision = GRUB_SLR_TABLE_REVISION; + slrt->architecture = architecture; diff --git a/1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch b/1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch index da3d5ff..5946831 100644 --- a/1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch +++ b/1111-i386-txt-Add-Intel-TXT-definitions-header-file.patch @@ -1,4 +1,4 @@ -From a19dcf70a333c0de0e17ea1fa95c0b9ada3197ff Mon Sep 17 00:00:00 2001 +From e49d73b3f8d95c341f591f1b0f08843ed14aa1e1 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:53:06 -0400 Subject: [PATCH] i386/txt: Add Intel TXT definitions header file @@ -6,16 +6,16 @@ Subject: [PATCH] i386/txt: Add Intel TXT definitions header file Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper --- - include/grub/i386/txt.h | 725 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 725 insertions(+) + include/grub/i386/txt.h | 703 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 703 insertions(+) create mode 100644 include/grub/i386/txt.h diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h new file mode 100644 -index 000000000000..d8598e259a77 +index 000000000000..a7ddd3a66702 --- /dev/null +++ b/include/grub/i386/txt.h -@@ -0,0 +1,725 @@ +@@ -0,0 +1,703 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -359,8 +359,9 @@ index 000000000000..d8598e259a77 + grub_uint64_t reserved1; + grub_uint64_t reserved2; + grub_uint32_t num_logical_procs; -+ /* Versions >= 5 with updates in version 6 */ ++ /* Versions >= 3 */ + grub_uint32_t sinit_flags; ++ /* Versions >= 5 with updates in version 6 */ + grub_uint32_t mle_flags; + /* Versions >= 4 */ + /* Ext Data Elements */ @@ -490,19 +491,19 @@ index 000000000000..d8598e259a77 +/* TXT register and heap access */ + +static inline grub_uint8_t -+grub_txt_reg_pub_readb (grub_uint16_t reg) ++grub_txt_reg_pub_read8 (grub_uint16_t reg) +{ + return grub_read8 (GRUB_TXT_CFG_REGS_PUB + reg); +} + +static inline grub_uint32_t -+grub_txt_reg_pub_readl (grub_uint16_t reg) ++grub_txt_reg_pub_read32 (grub_uint16_t reg) +{ + return grub_read32 (GRUB_TXT_CFG_REGS_PUB + reg); +} + +static inline grub_uint64_t -+grub_txt_reg_pub_readq (grub_uint16_t reg) ++grub_txt_reg_pub_read64 (grub_uint16_t reg) +{ + return grub_read64 (GRUB_TXT_CFG_REGS_PUB + reg); +} @@ -510,13 +511,13 @@ index 000000000000..d8598e259a77 +static inline grub_uint8_t * +grub_txt_get_heap (void) +{ -+ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); ++ return (grub_uint8_t *)(grub_addr_t) grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_BASE); +} + +static inline grub_uint32_t +grub_txt_get_heap_size (void) +{ -+ return grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE); ++ return grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_SIZE); +} + +/* @@ -591,9 +592,11 @@ index 000000000000..d8598e259a77 + +/* Intel 64 and IA-32 Architectures Software Developer’s Manual */ +/* Volume 2 (2A, 2B, 2C & 2D): Instruction Set Reference, A-Z */ ++/* Order Number: 325383-082US December 2023 */ + -+/* CHAPTER 6 SAFER MODE EXTENSIONS REFERENCE */ ++/* CHAPTER 7 SAFER MODE EXTENSIONS REFERENCE */ + ++/* Table 7-2. GETSEC Leaf Functions */ +#define GRUB_SMX_LEAF_CAPABILITIES 0 +#define GRUB_SMX_LEAF_UNDEFINED 1 +#define GRUB_SMX_LEAF_ENTERACCS 2 @@ -604,6 +607,7 @@ index 000000000000..d8598e259a77 +#define GRUB_SMX_LEAF_SMCTRL 7 +#define GRUB_SMX_LEAF_WAKEUP 8 + ++/* Table 7-3. GETSEC Capability Result Encoding */ +#define GRUB_SMX_CAPABILITY_CHIPSET_PRESENT (1<<0) +#define GRUB_SMX_CAPABILITY_UNDEFINED (1<<1) +#define GRUB_SMX_CAPABILITY_ENTERACCS (1<<2) @@ -627,35 +631,6 @@ index 000000000000..d8598e259a77 +} + +static inline void -+grub_txt_getsec_enteraccs (grub_uint32_t acm_phys_addr, grub_uint32_t acm_size) -+{ -+ asm volatile ("getsec" : -+ : "a" (GRUB_SMX_LEAF_ENTERACCS), -+ "b" (acm_phys_addr), "c" (acm_size)); -+} -+ -+static inline void -+grub_txt_getsec_exitac (grub_uint32_t near_jump) -+{ -+ asm volatile ("getsec" : -+ : "a" (GRUB_SMX_LEAF_EXITAC), "b" (near_jump)); -+} -+ -+static inline void -+grub_txt_getsec_senter (grub_uint32_t acm_phys_addr, grub_uint32_t acm_size) -+{ -+ asm volatile ("getsec" : -+ : "a" (GRUB_SMX_LEAF_SENTER), -+ "b" (acm_phys_addr), "c" (acm_size), "d"(0)); -+} -+ -+static inline void -+grub_txt_getsec_sexit (void) -+{ -+ asm volatile ("getsec" : : "a" (GRUB_SMX_LEAF_SEXIT)); -+} -+ -+static inline void +grub_txt_getsec_parameters (grub_uint32_t index, grub_uint32_t *eax_out, + grub_uint32_t *ebx_out, grub_uint32_t *ecx_out) +{ @@ -675,7 +650,6 @@ index 000000000000..d8598e259a77 +#define GRUB_SMX_PARAMETER_SENTER_CONTROLS 4 +#define GRUB_SMX_PARAMETER_TXT_EXTENSIONS 5 + -+ +#define GRUB_SMX_PARAMETER_MAX_VERSIONS 0x20 + +#define GRUB_SMX_GET_MAX_ACM_SIZE(v) ((v) & ~(__typeof__(v))GRUB_SMX_PARAMETER_TYPE_MASK) @@ -700,6 +674,10 @@ index 000000000000..d8598e259a77 +#define GRUB_SMX_DEFAULT_ACM_MEMORY_TYPE GRUB_SMX_ACM_MEMORY_TYPE_UC +#define GRUB_SMX_DEFAULT_SENTER_CONTROLS 0x0 + ++/* ++ * Measured Launch Environment Developer’s Guide, ++ * Table 29. OS to SINIT Data Table ++ */ +#define GRUB_TXT_PMR_ALIGN_SHIFT 21 +#define GRUB_TXT_PMR_ALIGN (1 << GRUB_TXT_PMR_ALIGN_SHIFT) + diff --git a/1112-i386-txt-Add-Intel-TXT-core-implementation.patch b/1112-i386-txt-Add-Intel-TXT-core-implementation.patch index 7b7963d..b17be77 100644 --- a/1112-i386-txt-Add-Intel-TXT-core-implementation.patch +++ b/1112-i386-txt-Add-Intel-TXT-core-implementation.patch @@ -1,4 +1,4 @@ -From 695d4295e0bdb68c4d1b9d2900f7808f37b43372 Mon Sep 17 00:00:00 2001 +From 459766701425d1cab5bbd33071734424a95a2e3a Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:57:33 -0400 Subject: [PATCH] i386/txt: Add Intel TXT core implementation @@ -11,17 +11,17 @@ Signed-off-by: Daniel Kiper Signed-off-by: Michał Żygowski Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/txt.c | 998 ++++++++++++++++++++++++++++++++ + grub-core/loader/i386/txt/txt.c | 997 ++++++++++++++++++++++++++++++++ include/grub/i386/slaunch.h | 1 - - 2 files changed, 998 insertions(+), 1 deletion(-) + 2 files changed, 997 insertions(+), 1 deletion(-) create mode 100644 grub-core/loader/i386/txt/txt.c diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c new file mode 100644 -index 000000000000..24311c0cf2bd +index 000000000000..b92107d50ea3 --- /dev/null +++ b/grub-core/loader/i386/txt/txt.c -@@ -0,0 +1,998 @@ +@@ -0,0 +1,997 @@ +/* + * txt.c: Intel(r) TXT support functions, including initiating measured + * launch, post-launch, AP wakeup, etc. @@ -149,12 +149,12 @@ index 000000000000..24311c0cf2bd + return grub_errno; +} + -+static void ++static grub_err_t +grub_txt_smx_parameters (struct grub_smx_parameters *params) +{ + grub_uint32_t index = 0, eax, ebx, ecx, param_type; + -+ grub_memset (params, 0, sizeof(struct grub_smx_supported_versions)); ++ grub_memset (params, 0, sizeof(*params)); + + params->max_acm_size = GRUB_SMX_DEFAULT_MAX_ACM_SIZE; + params->acm_memory_types = GRUB_SMX_DEFAULT_ACM_MEMORY_TYPE; @@ -172,10 +172,7 @@ index 000000000000..24311c0cf2bd + + case GRUB_SMX_PARAMETER_ACM_VERSIONS: + if (params->version_count >= GRUB_SMX_PARAMETER_MAX_VERSIONS) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Too many ACM versions")); -+ break; -+ } ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Too many ACM versions")); + params->versions[params->version_count].mask = ebx; + params->versions[params->version_count++].version = ecx; + break; @@ -197,8 +194,7 @@ index 000000000000..24311c0cf2bd + break; + + default: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown SMX parameter")); -+ param_type = GRUB_SMX_PARAMETER_NULL; ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown SMX parameter")); + } + + ++index; @@ -212,6 +208,8 @@ index 000000000000..24311c0cf2bd + params->versions[0].version = GRUB_SMX_DEFAULT_VERSION; + params->version_count++; + } ++ ++ return GRUB_ERR_NONE; +} + +grub_err_t @@ -221,6 +219,7 @@ index 000000000000..24311c0cf2bd + grub_uint32_t i; + grub_uint64_t mcg_cap, mcg_stat; + unsigned long cr0; ++ grub_err_t err; + + cr0 = grub_read_cr0 (); + @@ -245,9 +244,9 @@ index 000000000000..24311c0cf2bd + return grub_error (GRUB_ERR_BAD_DEVICE, + N_("machine check in progress during secure launch")); + -+ grub_txt_smx_parameters (¶ms); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; ++ err = grub_txt_smx_parameters (¶ms); ++ if (err != GRUB_ERR_NONE) ++ return err; + + if (params.txt_feature_ext_flags & GRUB_SMX_PROCESSOR_BASE_SCRTM) + grub_dprintf ("slaunch", "CPU supports processor-based S-CRTM\n"); @@ -870,7 +869,7 @@ index 000000000000..24311c0cf2bd + int i; + union grub_txt_didvid didvid; + -+ data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_STS); ++ data.d64 = grub_txt_reg_pub_read64 (GRUB_TXT_STS); + grub_printf (" TXT.STS: 0x%016" PRIxGRUB_UINT64_T "\n" + " SENTER.DONE.STS: %d\n" + " SEXIT.DONE.STS: %d\n" @@ -886,21 +885,21 @@ index 000000000000..24311c0cf2bd + !!(data.d64 & GRUB_TXT_STS_LOCALITY2_OPEN)); + + /* Only least significant byte has a meaning. */ -+ data.d8 = grub_txt_reg_pub_readb (GRUB_TXT_ESTS); ++ data.d8 = grub_txt_reg_pub_read8 (GRUB_TXT_ESTS); + grub_printf (" TXT.ESTS: 0x%02x\n" + " TXT_RESET.STS: %d\n", data.d8, + !!(data.d8 & GRUB_TXT_ESTS_TXT_RESET)); + -+ data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_E2STS); ++ data.d64 = grub_txt_reg_pub_read64 (GRUB_TXT_E2STS); + grub_printf (" TXT.E2STS: 0x%016" PRIxGRUB_UINT64_T "\n" + " SECRETS.STS: %d\n", data.d64, + !!(data.d64 & GRUB_TXT_E2STS_SECRETS)); + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_ERRORCODE); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_ERRORCODE); + grub_printf (" TXT.ERRORCODE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + -+ didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); ++ didvid.value = grub_txt_reg_pub_read64 (GRUB_TXT_DIDVID); + grub_printf (" TXT.DIDVID: 0x%016" PRIxGRUB_UINT64_T "\n" + " VID: 0x%04x\n" + " DID: 0x%04x\n" @@ -909,7 +908,7 @@ index 000000000000..24311c0cf2bd + didvid.value, didvid.vid, didvid.did, didvid.rid, didvid.id_ext); + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_VER_FSBIF); + grub_printf (" TXT.VER.FSBIF: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + + if ((data.d32 != 0x00000000) && (data.d32 != 0xffffffff)) @@ -917,32 +916,32 @@ index 000000000000..24311c0cf2bd + else + { + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_VER_QPIIF); + grub_printf (" TXT.VER.QPIIF: 0x%08" PRIxGRUB_UINT32_T "\n" + " DEBUG.FUSE: %d\n", data.d32, + !!(data.d32 & GRUB_TXT_VER_QPIIF_DEBUG_FUSE)); + } + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_SINIT_BASE); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_BASE); + grub_printf (" TXT.SINIT.BASE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_SINIT_SIZE); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_SIZE); + grub_printf (" TXT.SINIT.SIZE: %" PRIuGRUB_UINT32_T + " B (0x%" PRIxGRUB_UINT32_T ")\n", data.d32, data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_BASE); + grub_printf (" TXT.HEAP.BASE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_SIZE); + grub_printf (" TXT.HEAP.SIZE: %" PRIuGRUB_UINT32_T + " B (0x%" PRIxGRUB_UINT32_T ")\n", data.d32, data.d32); + + /* Only least significant 4 bytes have a meaning. */ -+ data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_DPR); ++ data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_DPR); + grub_printf (" TXT.DPR: 0x%08" PRIxGRUB_UINT32_T "\n" + " LOCK: %d\n" + " TOP: 0x%08" PRIxGRUB_UINT32_T "\n" @@ -955,7 +954,7 @@ index 000000000000..24311c0cf2bd + for (i = 0; i < 4; ++i) + { + /* TODO: Check relevant MSRs on SGX platforms. */ -+ data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t)); ++ data.d64 = grub_txt_reg_pub_read64 (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t)); + grub_printf (" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x%s", data.a8[0], data.a8[1], + data.a8[2], data.a8[3], data.a8[4], data.a8[5], data.a8[6], data.a8[7], + (i < 3) ? ":\n" : "\n"); @@ -1021,10 +1020,10 @@ index 000000000000..24311c0cf2bd + return GRUB_ERR_NONE; +} diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h -index f7160d5fab0c..3ee5c9bc1750 100644 +index 7f7709cda75e..93a491e4fc9e 100644 --- a/include/grub/i386/slaunch.h +++ b/include/grub/i386/slaunch.h -@@ -29,7 +29,6 @@ +@@ -33,7 +33,6 @@ #ifndef ASM_FILE diff --git a/1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch b/1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch index 83cd60a..1725cef 100644 --- a/1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch +++ b/1113-i386-txt-Add-Intel-TXT-ACM-module-support.patch @@ -1,4 +1,4 @@ -From f19c86b0de973bac58296596d394f2daaea7b561 Mon Sep 17 00:00:00 2001 +From 0ce784f00a21af6b379ece3e2c681fa47b945a5d Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 13:59:18 -0400 Subject: [PATCH] i386/txt: Add Intel TXT ACM module support @@ -7,16 +7,16 @@ Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/acmod.c | 610 ++++++++++++++++++++++++++++++ - 1 file changed, 610 insertions(+) + grub-core/loader/i386/txt/acmod.c | 600 ++++++++++++++++++++++++++++++ + 1 file changed, 600 insertions(+) create mode 100644 grub-core/loader/i386/txt/acmod.c diff --git a/grub-core/loader/i386/txt/acmod.c b/grub-core/loader/i386/txt/acmod.c new file mode 100644 -index 000000000000..2605570a6c4f +index 000000000000..6a8338abfde5 --- /dev/null +++ b/grub-core/loader/i386/txt/acmod.c -@@ -0,0 +1,610 @@ +@@ -0,0 +1,600 @@ +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules @@ -207,13 +207,8 @@ index 000000000000..2605570a6c4f + return NULL; + } + -+ /* Overflows? */ -+ if ( grub_add (info_table->chipset_id_list, -+ sizeof(struct grub_txt_acm_chipset_id_list), &id_entries_off)) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID entries out of bounds")); -+ return NULL; -+ } ++ /* Overflows were checked by fits_in_acm() */ ++ id_entries_off = info_table->chipset_id_list + sizeof(*chipset_id_list); + + if ( n_fit_in_acm( hdr, id_entries_off, sizeof(struct grub_txt_acm_chipset_id), + chipset_id_list->count ) == NULL ) @@ -254,13 +249,8 @@ index 000000000000..2605570a6c4f + return NULL; + } + -+ /* Overflows? */ -+ if ( grub_add (info_table->processor_id_list, sizeof(*proc_id_list), -+ &id_entries_off)) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID entries out of bounds")); -+ return NULL; -+ } ++ /* Overflows were checked by fits_in_acm() */ ++ id_entries_off = info_table->processor_id_list + sizeof(*proc_id_list); + + if ( n_fit_in_acm ( hdr, id_entries_off, sizeof(*proc_id_list), + proc_id_list->count ) == NULL ) @@ -313,7 +303,7 @@ index 000000000000..2605570a6c4f + * of info table. + */ + if ( info_table->length < sizeof(*info_table) ) -+ grub_dprintf ("slaunch", "Info table size (%x) smaller than expected (" ++ grub_dprintf ("slaunch", "Info table size (%x) smaller than expected (%" + PRIxGRUB_SIZE ")\n", + info_table->length, sizeof(*info_table)); + @@ -444,11 +434,11 @@ index 000000000000..2605570a6c4f + return 0; + + /* Get chipset fusing, device, and vendor id info */ -+ didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID); ++ didvid.value = grub_txt_reg_pub_read64 (GRUB_TXT_DIDVID); + -+ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF); ++ ver = grub_txt_reg_pub_read32 (GRUB_TXT_VER_QPIIF); + if ( ver == 0xffffffff || ver == 0x00 ) /* Old CPU, need to use VER.FSBIF */ -+ ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF); ++ ver = grub_txt_reg_pub_read32 (GRUB_TXT_VER_FSBIF); + + grub_dprintf ("slaunch", "chipset production fused: %s, " + "chipset vendor: 0x%x, device: 0x%x, revision: 0x%x\n", @@ -559,8 +549,8 @@ index 000000000000..2605570a6c4f + void *sinit_region_base; + grub_uint32_t sinit_size, sinit_region_size; + -+ sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_SINIT_BASE); -+ sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_readl (GRUB_TXT_SINIT_SIZE); ++ sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_BASE); ++ sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_SIZE); + + grub_dprintf ("slaunch", "TXT.SINIT.BASE: %p\nTXT.SINIT.SIZE: 0x%" + PRIxGRUB_UINT32_T "\n", sinit_region_base, sinit_region_size); diff --git a/1114-i386-txt-Add-Intel-TXT-verification-routines.patch b/1114-i386-txt-Add-Intel-TXT-verification-routines.patch index 29e3cc2..11d8698 100644 --- a/1114-i386-txt-Add-Intel-TXT-verification-routines.patch +++ b/1114-i386-txt-Add-Intel-TXT-verification-routines.patch @@ -1,4 +1,4 @@ -From d75283aa6950fea8ac579735fe4528083b3932bb Mon Sep 17 00:00:00 2001 +From b3a5c6f2f404ecd814a938fa643a114d71fdd752 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 14:46:17 -0400 Subject: [PATCH] i386/txt: Add Intel TXT verification routines @@ -7,16 +7,16 @@ Signed-off-by: Ross Philipson Signed-off-by: Daniel Kiper Signed-off-by: Krystian Hebel --- - grub-core/loader/i386/txt/verify.c | 269 +++++++++++++++++++++++++++++ - 1 file changed, 269 insertions(+) + grub-core/loader/i386/txt/verify.c | 278 +++++++++++++++++++++++++++++ + 1 file changed, 278 insertions(+) create mode 100644 grub-core/loader/i386/txt/verify.c diff --git a/grub-core/loader/i386/txt/verify.c b/grub-core/loader/i386/txt/verify.c new file mode 100644 -index 000000000000..e8acb7da022f +index 000000000000..5205c931c35b --- /dev/null +++ b/grub-core/loader/i386/txt/verify.c -@@ -0,0 +1,269 @@ +@@ -0,0 +1,278 @@ +/* + * verify.c: verify that platform and processor supports Intel(r) TXT + * @@ -108,7 +108,7 @@ index 000000000000..e8acb7da022f + if ( elt->size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + + sizeof(struct grub_txt_heap_acm_element) || + grub_mul (elt->acm.num_acms, sizeof(grub_uint64_t), &acm_addrs_size) || -+ elt->size != GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + sizeof(elt->acm) + ++ elt->size - (GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + sizeof(elt->acm)) != + acm_addrs_size ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("HEAP_ACM element has wrong size (%d)"), @@ -162,7 +162,8 @@ index 000000000000..e8acb7da022f + for ( ; ; ) + { + if ( elts_size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE || -+ elts_size < elt->size || elt->size == 0 ) ++ elt->size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE || ++ elts_size < elt->size ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("TXT heap invalid element size: type: %d, size: %d"), + elt->type, elt->size); @@ -237,32 +238,33 @@ index 000000000000..e8acb7da022f + * Eventually need the verify_IA32_se_svn_status routine to be called here. + */ + -+ errorcode = grub_txt_reg_pub_readl (GRUB_TXT_ERRORCODE); ++ errorcode = grub_txt_reg_pub_read32 (GRUB_TXT_ERRORCODE); + /* 0 - no previous SENTER, 0xC0000001 - previous SENTER succeeded */ + if ( errorcode != 0 && errorcode != 0xC0000001 ) + return grub_error (GRUB_ERR_BAD_DEVICE, + N_("TXT_ERRORCODE reports failure: 0x%08" PRIxGRUB_UINT32_T), + errorcode); + -+ if (grub_txt_reg_pub_readb (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET) ++ if (grub_txt_reg_pub_read8 (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET) + return grub_error (GRUB_ERR_BAD_DEVICE, + N_("TXT_RESET.STS is set and GETSEC[SENTER] is disabled")); + + /* + * Verify that the BIOS information in the TXT heap that was setup by the -+ * BIOS ACM is sane. ++ * BIOS ACM is reasonable. + */ + + txt_heap = grub_txt_get_heap (); -+ heap_base = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE); -+ heap_size = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE); ++ heap_base = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_BASE); ++ heap_size = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_SIZE); + + if ( txt_heap == NULL || heap_base == 0 || heap_size == 0 ) + return grub_error (GRUB_ERR_BAD_DEVICE, + N_("TXT heap is not configured correctly")); + + bios_size = grub_txt_bios_data_size (txt_heap); -+ if ( bios_size < sizeof (grub_uint64_t) || bios_size > heap_size ) ++ if ( bios_size < sizeof (grub_uint64_t) + sizeof (*bios_data) || ++ bios_size > heap_size ) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("invalid size of the TXT heap BIOS data table")); + @@ -278,9 +280,16 @@ index 000000000000..e8acb7da022f + N_("BIOS reports too many CPUs for secure launch (%d)"), + bios_data->num_logical_procs); + ++ /* ++ * grub_uint32_t mle_flags is supposed to be added in version 5, however, the ++ * only ACM in 630744_003 package that is version 4 (Sandy Bridge & Ivy Bridge ++ * SNB_IVB_SINIT_20190708_PW.bin) seems to also have this field, or at least ++ * a placeholder for it. ++ */ + if ( bios_data->version >= 4 && bios_size > sizeof(*bios_data) + sizeof(bios_size) ) + { -+ elts = (struct grub_txt_heap_ext_data_element *) ((grub_uint8_t *)bios_data + sizeof(*bios_data)); ++ elts = (struct grub_txt_heap_ext_data_element *) ((grub_uint8_t *)bios_data + ++ sizeof(*bios_data)); + err = verify_ext_data_elts(elts, bios_size - sizeof(*bios_data)); + } + diff --git a/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch b/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch index 0806997..9ed7463 100644 --- a/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch +++ b/1115-i386-txt-Initialize-TPM-1.2-event-log-in-TXT-heap.patch @@ -1,4 +1,4 @@ -From 66f7719aeccd92a418533444afdf771b0d1df6a4 Mon Sep 17 00:00:00 2001 +From f13b0f94d0ffc26bd936d25233ecbd20d5e5b866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 31 Aug 2022 14:37:49 +0200 Subject: [PATCH] i386/txt: Initialize TPM 1.2 event log in TXT heap @@ -14,10 +14,10 @@ Signed-off-by: Krystian Hebel 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c -index 24311c0cf2bd..ecc0c03580f6 100644 +index b92107d50ea3..44a0b5c01bf3 100644 --- a/grub-core/loader/i386/txt/txt.c +++ b/grub-core/loader/i386/txt/txt.c -@@ -520,6 +520,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) +@@ -519,6 +519,32 @@ set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) return err; } @@ -50,7 +50,7 @@ index 24311c0cf2bd..ecc0c03580f6 100644 /* Adds new element to the end. `size` does not include common header. */ /* Assume that heap was cleared and there is enough space to add the element. */ static inline struct grub_txt_heap_ext_data_element * -@@ -658,6 +684,8 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -657,6 +683,8 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header sinit_caps = grub_txt_get_sinit_capabilities (sinit); @@ -59,7 +59,7 @@ index 24311c0cf2bd..ecc0c03580f6 100644 /* * In the latest TXT Software Development Guide as of now (April 2023, * Revision 017.4) bits 4 and 5 (used to be "no legacy PCR usage" and -@@ -672,6 +700,25 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -671,6 +699,25 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header */ os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; @@ -85,7 +85,7 @@ index 24311c0cf2bd..ecc0c03580f6 100644 /* * APs (application processors) can't be brought up by usual INIT-SIPI-SIPI * sequence after Measured Launch, otherwise the MLE integrity is lost. -@@ -688,10 +735,21 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -687,10 +734,21 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; if (grub_get_tpm_ver () == GRUB_TPM_12) @@ -110,7 +110,7 @@ index 24311c0cf2bd..ecc0c03580f6 100644 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("original TXT TPM 2.0 event log format is not supported")); diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index d8598e259a77..5e3e6086d0d7 100644 +index a7ddd3a66702..155ebab0ff6a 100644 --- a/include/grub/i386/txt.h +++ b/include/grub/i386/txt.h @@ -22,6 +22,7 @@ @@ -121,7 +121,7 @@ index d8598e259a77..5e3e6086d0d7 100644 #include #include #include -@@ -701,6 +702,34 @@ struct grub_smx_parameters +@@ -679,6 +680,34 @@ struct grub_smx_parameters grub_uint32_t txt_feature_ext_flags; } GRUB_PACKED; @@ -156,7 +156,7 @@ index d8598e259a77..5e3e6086d0d7 100644 extern grub_uint32_t grub_txt_supported_os_sinit_data_ver (struct grub_txt_acm_header* hdr); extern grub_uint32_t grub_txt_get_sinit_capabilities (struct grub_txt_acm_header* hdr); -@@ -714,6 +743,8 @@ extern struct grub_txt_acm_header* grub_txt_sinit_select (struct grub_txt_acm_he +@@ -692,6 +721,8 @@ extern struct grub_txt_acm_header* grub_txt_sinit_select (struct grub_txt_acm_he extern grub_err_t grub_txt_verify_platform (void); extern grub_err_t grub_txt_prepare_cpu (void); diff --git a/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch b/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch index d77c26f..c8699cf 100644 --- a/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch +++ b/1116-i386-txt-switch-to-using-Secure-Launch-Resource-Tabl.patch @@ -1,4 +1,4 @@ -From 2974b3b9922043cedc6d8418eaeed2bcd1361ce1 Mon Sep 17 00:00:00 2001 +From f5ce8a71089c4cd2899e4f191aa0fc7ca3c79d79 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Fri, 13 Jan 2023 15:11:26 -0500 Subject: [PATCH] i386/txt: switch to using Secure Launch Resource Table @@ -13,7 +13,7 @@ Signed-off-by: Sergii Dmytruk 3 files changed, 121 insertions(+), 44 deletions(-) diff --git a/grub-core/loader/i386/txt/txt.c b/grub-core/loader/i386/txt/txt.c -index ecc0c03580f6..03ba5130eaaa 100644 +index 44a0b5c01bf3..cc4db716d205 100644 --- a/grub-core/loader/i386/txt/txt.c +++ b/grub-core/loader/i386/txt/txt.c @@ -60,6 +60,7 @@ @@ -33,7 +33,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 static grub_err_t enable_smx_mode (void) { -@@ -250,33 +253,39 @@ grub_txt_prepare_cpu (void) +@@ -249,33 +252,39 @@ grub_txt_prepare_cpu (void) } static void @@ -83,7 +83,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 } static void -@@ -546,6 +555,20 @@ grub_txt_init_tpm_event_log (void *buf, grub_size_t size) +@@ -545,6 +554,20 @@ grub_txt_init_tpm_event_log (void *buf, grub_size_t size) elog->next_event_offset = sizeof(*elog); } @@ -104,7 +104,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 /* Adds new element to the end. `size` does not include common header. */ /* Assume that heap was cleared and there is enough space to add the element. */ static inline struct grub_txt_heap_ext_data_element * -@@ -591,6 +614,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -590,6 +613,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t)); *size = sizeof (*os_mle_data) + sizeof (grub_uint64_t); @@ -125,7 +125,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 if (grub_add (grub_txt_bios_data_size (txt_heap), *size, &size_total) || (size_total > grub_txt_get_heap_size ())) { -@@ -603,16 +640,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header +@@ -602,16 +639,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header os_mle_data->version = GRUB_SL_OS_MLE_STRUCT_VERSION; os_mle_data->boot_params_addr = slparams->boot_params_addr; @@ -150,7 +150,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 /* OS/loader to SINIT data. */ grub_dprintf ("slaunch", "Get supported OS SINIT data version\n"); -@@ -1000,9 +1041,10 @@ grub_err_t +@@ -999,9 +1040,10 @@ grub_err_t grub_txt_boot_prepare (struct grub_slaunch_params *slparams) { grub_err_t err; @@ -162,7 +162,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 sinit_base = grub_txt_sinit_select (grub_slaunch_module ()); -@@ -1018,24 +1060,22 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) +@@ -1017,24 +1059,22 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) grub_dprintf ("slaunch", "TXT heap successfully prepared\n"); /* Update the MLE header. */ @@ -196,7 +196,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 err = set_mtrrs_for_acmod (sinit_base); if (err) -@@ -1054,3 +1094,20 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) +@@ -1053,3 +1093,20 @@ grub_txt_boot_prepare (struct grub_slaunch_params *slparams) return GRUB_ERR_NONE; } @@ -210,7 +210,7 @@ index ecc0c03580f6..03ba5130eaaa 100644 + txt_heap = grub_txt_get_heap (); + os_mle_data = grub_txt_os_mle_data_start (txt_heap); + -+ grub_slaunch_add_slrt_policy_entry (18, ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR, + GRUB_SLR_ET_TXT_OS2MLE, + /*flags=*/0, + (grub_addr_t) os_mle_data, @@ -218,10 +218,10 @@ index ecc0c03580f6..03ba5130eaaa 100644 + "Measured TXT OS-MLE data"); +} diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h -index 3ee5c9bc1750..4b43662bea2f 100644 +index 93a491e4fc9e..a694260cbeea 100644 --- a/include/grub/i386/slaunch.h +++ b/include/grub/i386/slaunch.h -@@ -27,6 +27,19 @@ +@@ -31,6 +31,19 @@ #define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE) @@ -241,7 +241,7 @@ index 3ee5c9bc1750..4b43662bea2f 100644 #ifndef ASM_FILE #include -@@ -34,11 +47,16 @@ +@@ -38,11 +51,16 @@ struct grub_slaunch_params { grub_uint32_t boot_params_addr; @@ -259,7 +259,7 @@ index 3ee5c9bc1750..4b43662bea2f 100644 grub_uint32_t mle_header_offset; grub_uint32_t ap_wake_block; grub_uint32_t ap_wake_block_size; -@@ -52,6 +70,16 @@ extern grub_uint32_t grub_slaunch_platform_type (void); +@@ -56,6 +74,16 @@ extern grub_uint32_t grub_slaunch_platform_type (void); extern void *grub_slaunch_module (void); extern struct grub_slaunch_params *grub_slaunch_params (void); @@ -277,10 +277,10 @@ index 3ee5c9bc1750..4b43662bea2f 100644 #endif /* GRUB_I386_SLAUNCH_H */ diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h -index 5e3e6086d0d7..ba98043a1735 100644 +index 155ebab0ff6a..c3dde57ea849 100644 --- a/include/grub/i386/txt.h +++ b/include/grub/i386/txt.h -@@ -352,29 +352,14 @@ struct grub_txt_bios_data +@@ -353,29 +353,14 @@ struct grub_txt_bios_data /* GRUB SLAUNCH specific definitions OS-MLE data */ #define GRUB_SL_OS_MLE_STRUCT_VERSION 1 @@ -312,7 +312,7 @@ index 5e3e6086d0d7..ba98043a1735 100644 grub_uint8_t mle_scratch[64]; } GRUB_PACKED; -@@ -751,6 +736,13 @@ extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); +@@ -729,6 +714,13 @@ extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); extern grub_err_t grub_txt_init (void); extern void grub_txt_shutdown (void); extern void grub_txt_state_show (void); diff --git a/1117-i386-slaunch-Add-secure-launch-framework-and-command.patch b/1117-i386-slaunch-Add-secure-launch-framework-and-command.patch index 5c120a4..6b32e26 100644 --- a/1117-i386-slaunch-Add-secure-launch-framework-and-command.patch +++ b/1117-i386-slaunch-Add-secure-launch-framework-and-command.patch @@ -1,4 +1,4 @@ -From 916454efb00b14fa85bf529fa0575e99b9d484fb Mon Sep 17 00:00:00 2001 +From cf61e4e0ca2f76b6b306bf3e88faac028e427b12 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Wed, 7 Aug 2019 15:01:00 -0400 Subject: [PATCH] i386/slaunch: Add secure launch framework and commands @@ -12,14 +12,14 @@ Signed-off-by: Krystian Hebel grub-core/lib/i386/relocator32.S | 8 + grub-core/loader/i386/bsd.c | 4 + grub-core/loader/i386/coreboot/chainloader.c | 2 + - grub-core/loader/i386/linux.c | 315 ++++++++++++++++++- + grub-core/loader/i386/linux.c | 320 ++++++++++++++++++- grub-core/loader/i386/pc/plan9.c | 3 +- - grub-core/loader/i386/slaunch.c | 299 ++++++++++++++++++ + grub-core/loader/i386/slaunch.c | 304 ++++++++++++++++++ grub-core/loader/i386/xnu.c | 3 + grub-core/loader/multiboot.c | 5 + include/grub/file.h | 3 + include/grub/i386/linux.h | 14 +- - 12 files changed, 660 insertions(+), 17 deletions(-) + 12 files changed, 670 insertions(+), 17 deletions(-) create mode 100644 grub-core/loader/i386/slaunch.c diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am @@ -174,7 +174,7 @@ index 0a19ebb9c3e5..dccd86b07bde 100644 } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 9f74a96b19ae..18485e9b1766 100644 +index 9f74a96b19ae..bf3878ab91e2 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -34,9 +34,12 @@ @@ -236,7 +236,7 @@ index 9f74a96b19ae..18485e9b1766 100644 static inline grub_size_t page_align (grub_size_t size) { -@@ -150,11 +173,36 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -150,11 +173,37 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, grub_uint64_t preferred_address) { grub_err_t err; @@ -249,14 +249,15 @@ index 9f74a96b19ae..18485e9b1766 100644 - prot_size = page_align (prot_size); + if (grub_slaunch_platform_type () == SLP_INTEL_TXT) + { -+ prot_size = ALIGN_UP (prot_size, GRUB_TXT_PMR_ALIGN); -+ + if (prot_size > GRUB_TXT_MLE_MAX_SIZE) + { + err = GRUB_ERR_OUT_OF_RANGE; + goto fail; + } + ++ /* Check performed above makes sure that this doesn't overflow. */ ++ prot_size = ALIGN_UP (prot_size, GRUB_TXT_PMR_ALIGN); ++ + slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size); + slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN); + /* Do not go below GRUB_TXT_PMR_ALIGN. */ @@ -274,7 +275,7 @@ index 9f74a96b19ae..18485e9b1766 100644 /* Initialize the memory pointers with NULL for convenience. */ free_pages (); -@@ -176,7 +224,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -176,7 +225,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, err = grub_relocator_alloc_chunk_align (relocator, &ch, preferred_address, preferred_address, @@ -283,7 +284,7 @@ index 9f74a96b19ae..18485e9b1766 100644 GRUB_RELOCATOR_PREFERENCE_LOW, 1); for (; err && *align + 1 > min_align; (*align)--) -@@ -194,11 +242,65 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, +@@ -194,11 +243,65 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, else err = grub_relocator_alloc_chunk_addr (relocator, &ch, preferred_address, @@ -350,7 +351,7 @@ index 9f74a96b19ae..18485e9b1766 100644 } grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", -@@ -286,7 +388,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) +@@ -286,7 +389,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->lfb_size >>= 16; params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; break; @@ -359,7 +360,7 @@ index 9f74a96b19ae..18485e9b1766 100644 case GRUB_VIDEO_DRIVER_EFI_UGA: case GRUB_VIDEO_DRIVER_EFI_GOP: params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; -@@ -398,6 +500,60 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, +@@ -398,6 +501,63 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, return 0; } @@ -372,7 +373,7 @@ index 9f74a96b19ae..18485e9b1766 100644 + /* A bit of work to extract the v2.08 EFI info from the linux params */ + efi_info = (void *)((grub_uint8_t *)&boot_params->v0208 + 2*sizeof(grub_uint32_t)); + -+ grub_slaunch_add_slrt_policy_entry (18, ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR, + GRUB_SLR_ET_BOOT_PARAMS, + /*flags=*/0, + (grub_addr_t) boot_params, @@ -380,15 +381,15 @@ index 9f74a96b19ae..18485e9b1766 100644 + "Measured boot parameters"); + + if (boot_params->setup_data) -+ grub_slaunch_add_slrt_policy_entry (18, ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR, + GRUB_SLR_ET_SETUP_DATA, + GRUB_SLR_POLICY_IMPLICIT_SIZE, + boot_params->setup_data, + /*size=*/0, + "Measured Kernel setup_data"); + -+ /* TODO the cmdline ptr can have hi bits but for now assume always < 4G */ -+ grub_slaunch_add_slrt_policy_entry (18, ++ /* The cmdline ptr can have hi bits but GRUB puts it always < 4G */ ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR, + GRUB_SLR_ET_CMDLINE, + /*flags=*/0, + boot_params->cmd_line_ptr, @@ -399,7 +400,7 @@ index 9f74a96b19ae..18485e9b1766 100644 + { + grub_uint64_t mmap_addr = + ((grub_uint64_t) efi_info->efi_mmap_hi << 32) | efi_info->efi_mmap; -+ grub_slaunch_add_slrt_policy_entry (18, ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR, + GRUB_SLR_ET_UEFI_MEMMAP, + /*flags=*/0, + mmap_addr, @@ -408,8 +409,11 @@ index 9f74a96b19ae..18485e9b1766 100644 + } + + if (boot_params->ramdisk_image) -+ /* TODO the initrd image and size can have hi bits but for now assume always < 4G */ -+ grub_slaunch_add_slrt_policy_entry (17, ++ /* ++ * The initrd image and size can have hi bits but in GRUB it is always ++ * < 4G, see GRUB_LINUX_INITRD_MAX_ADDRESS in grub_cmd_initrd(). ++ */ ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_CODE_PCR, + GRUB_SLR_ET_RAMDISK, + /*flags=*/0, + boot_params->ramdisk_image, @@ -420,7 +424,7 @@ index 9f74a96b19ae..18485e9b1766 100644 static grub_err_t grub_linux_boot (void) { -@@ -411,6 +567,8 @@ grub_linux_boot (void) +@@ -411,6 +571,8 @@ grub_linux_boot (void) }; grub_size_t mmap_size; grub_size_t cl_offset; @@ -429,7 +433,7 @@ index 9f74a96b19ae..18485e9b1766 100644 #ifdef GRUB_MACHINE_IEEE1275 { -@@ -543,6 +701,9 @@ grub_linux_boot (void) +@@ -543,6 +705,9 @@ grub_linux_boot (void) (unsigned) ctx.real_size, (unsigned) efi_mmap_size); @@ -439,16 +443,17 @@ index 9f74a96b19ae..18485e9b1766 100644 if (! ctx.real_mode_target) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); -@@ -550,7 +711,7 @@ grub_linux_boot (void) +@@ -550,7 +715,8 @@ grub_linux_boot (void) grub_relocator_chunk_t ch; grub_size_t sz; - if (grub_add (ctx.real_size, efi_mmap_size, &sz)) -+ if (grub_add (ctx.real_size, efi_mmap_size + ap_wake_block_size, &sz)) ++ if (grub_add (efi_mmap_size, ap_wake_block_size, &sz) || ++ grub_add (ctx.real_size, sz, &sz)) return GRUB_ERR_OUT_OF_RANGE; err = grub_relocator_alloc_chunk_addr (relocator, &ch, -@@ -561,6 +722,20 @@ grub_linux_boot (void) +@@ -561,6 +727,20 @@ grub_linux_boot (void) } efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; @@ -469,7 +474,7 @@ index 9f74a96b19ae..18485e9b1766 100644 grub_dprintf ("linux", "real_mode_mem = %p\n", real_mode_mem); -@@ -587,13 +762,15 @@ grub_linux_boot (void) +@@ -587,13 +767,15 @@ grub_linux_boot (void) ctx.params->secure_boot = grub_efi_get_secureboot (); @@ -487,7 +492,7 @@ index 9f74a96b19ae..18485e9b1766 100644 + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); /* Pass EFI parameters. */ if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) -@@ -624,12 +801,36 @@ grub_linux_boot (void) +@@ -624,12 +806,36 @@ grub_linux_boot (void) } #endif @@ -530,7 +535,7 @@ index 9f74a96b19ae..18485e9b1766 100644 return grub_relocator32_boot (relocator, state, 0); } -@@ -650,12 +851,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -650,12 +856,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; @@ -545,7 +550,7 @@ index 9f74a96b19ae..18485e9b1766 100644 grub_dl_ref (my_mod); -@@ -743,7 +945,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -743,7 +950,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), align = 0; relocatable = 0; } @@ -554,7 +559,7 @@ index 9f74a96b19ae..18485e9b1766 100644 if (grub_le_to_cpu16 (lh.version) >= 0x020a) { min_align = lh.min_alignment; -@@ -760,6 +962,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -760,6 +967,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), prot_init_space = page_align (prot_size) * 3; } @@ -568,7 +573,7 @@ index 9f74a96b19ae..18485e9b1766 100644 if (allocate_pages (prot_size, &align, min_align, relocatable, preferred_address)) -@@ -767,6 +976,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -767,6 +981,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memset (&linux_params, 0, sizeof (linux_params)); @@ -578,14 +583,14 @@ index 9f74a96b19ae..18485e9b1766 100644 /* * The Linux 32-bit boot protocol defines the setup header end * to be at 0x202 + the byte value at 0x201. -@@ -793,6 +1005,79 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -793,6 +1010,79 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } + /* Read the kernel_info struct. */ + if (grub_le_to_cpu16 (lh.version) >= 0x020f) + { -+ if (grub_file_seek (file, grub_le_to_cpu32 (lh.kernel_info_offset) + ++ if (grub_file_seek (file, (grub_off_t) grub_le_to_cpu32 (lh.kernel_info_offset) + + real_size + GRUB_DISK_SECTOR_SIZE) == ((grub_off_t) -1)) + goto fail; + @@ -681,10 +686,10 @@ index 37550155df78..cd8213a05d31 100644 .esi = 0 diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c new file mode 100644 -index 000000000000..606152edb14d +index 000000000000..b15194c78b61 --- /dev/null +++ b/grub-core/loader/i386/slaunch.c -@@ -0,0 +1,299 @@ +@@ -0,0 +1,304 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Oracle and/or its affiliates. @@ -785,7 +790,7 @@ index 000000000000..606152edb14d +void grub_slaunch_add_slrt_policy_entries (void) +{ + /* The SLR table should be measured too, at least parts of it. */ -+ grub_slaunch_add_slrt_policy_entry (18, ++ grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR, + GRUB_SLR_ET_SLRT, + GRUB_SLR_POLICY_IMPLICIT_SIZE, + slparams.slr_table_base, @@ -806,7 +811,7 @@ index 000000000000..606152edb14d + sizeof(struct grub_slr_entry_policy) + + slr_policy_staging->nr_entries*sizeof(*entry)); + -+ if (slr_policy_staging->hdr.size + sizeof(*entry) > sizeof(slr_policy_buf)) ++ if (slr_policy_staging->hdr.size > sizeof(slr_policy_buf) - sizeof(*entry)) + grub_fatal("Not enough space for adding policy entry: %s! The buffer is full.", + evt_info); + @@ -874,8 +879,8 @@ index 000000000000..606152edb14d + grub_file_t file; + grub_ssize_t size; + -+ if (!argc) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ if (argc != 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected: filename")); + + if (slp == SLP_NONE) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("secure launch not enabled")); @@ -977,9 +982,14 @@ index 000000000000..606152edb14d + +GRUB_MOD_FINI (slaunch) +{ -+ grub_unregister_command (cmd_slaunch_state); -+ grub_unregister_command (cmd_slaunch_module); -+ grub_unregister_command (cmd_slaunch); ++ if (cmd_slaunch_state) ++ grub_unregister_command (cmd_slaunch_state); ++ ++ if (cmd_slaunch_module) ++ grub_unregister_command (cmd_slaunch_module); ++ ++ if (cmd_slaunch) ++ grub_unregister_command (cmd_slaunch); + + if (slp == SLP_INTEL_TXT) + grub_txt_shutdown (); @@ -1050,7 +1060,7 @@ index 31567483ccfc..f08fcda74115 100644 /* --skip-sig is specified. */ diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h -index eddf9251d9a5..798188c85454 100644 +index eddf9251d9a5..18c860e6b759 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -148,6 +148,17 @@ struct linux_i386_kernel_header @@ -1063,11 +1073,11 @@ index eddf9251d9a5..798188c85454 100644 +struct linux_kernel_info +{ + grub_uint32_t header; -+ grub_uint32_t size; -+ grub_uint32_t size_total; ++ grub_uint32_t size; /* In bytes, excluding var_len_data[] */ ++ grub_uint32_t size_total; /* In bytes, including var_len_data[] */ + grub_uint32_t setup_type_max; + grub_uint32_t mle_header_offset; -+ grub_uint8_t var_len_data[0]; ++ grub_uint8_t var_len_data[]; } GRUB_PACKED; /* Boot parameters for Linux based on 2.6.12. This is used by the setup diff --git a/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch b/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch index 18a52e1..8b9b3eb 100644 --- a/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch +++ b/1118-multiboot-make-GRUB_MULTIBOOT-make_mbi-return-MBI-s-.patch @@ -1,4 +1,4 @@ -From c483385a164d0b7e950dd85a6dfd73f84fe05a4c Mon Sep 17 00:00:00 2001 +From 4e6cb41ee5606159c9ec0f4b8239749645808901 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Wed, 22 Nov 2023 21:08:35 +0200 Subject: [PATCH] multiboot: make GRUB_MULTIBOOT(make_mbi) return MBI's size diff --git a/1119-multiboot2-Implement-TXT-slaunch-support.patch b/1119-multiboot2-Implement-TXT-slaunch-support.patch index e67fdbb..a3c8751 100644 --- a/1119-multiboot2-Implement-TXT-slaunch-support.patch +++ b/1119-multiboot2-Implement-TXT-slaunch-support.patch @@ -1,4 +1,4 @@ -From 66b9d72c3119ab93b7529074010aefb3ad3d8bb4 Mon Sep 17 00:00:00 2001 +From 58c9a06983cb68f04548713208b25c0b579b4043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 1 Sep 2022 17:58:53 +0200 Subject: [PATCH] multiboot2: Implement TXT slaunch support