Re: multiboot2 and module2 boot issues via GRUB2

2021-04-01 Thread Krystian Hebel

On 01.04.2021 10:44, Roger Pau Monné via Grub-devel wrote:

On Thu, Apr 01, 2021 at 09:31:07AM +0200, Jan Beulich wrote:

On 01.04.2021 03:06, Roman Shaposhnik wrote:

And the obvious next question: is my EVE usecase esoteric enough that
I should just go ahead and do a custom GRUB patch or is there a more
general interest in this?

Not sure if it ought to be a grub patch - the issue could as well
be dealt with in Xen, by concatenating modules to form a monolithic
initrd.

I would rather have it done in the loader than Xen, mostly because
it's a Linux boot specific format, and hence I don't think Xen should
have any knowledge about it.

Keep in mind that loader is loading Xen, using multiboot2 which is kind of
generic boot protocol, not Linux with its specific protocol. There may be
other multiboot2 kernels that depend on modules being _not_ concatenated,
such change would most likely break those.

Best regards,

--
Krystian Hebel
Firmware Engineer
https://3mdeb.com | @3mdeb_com


If it turns out to be impossible to implement on the loader side we
should consider doing it in Xen, but that's not my first option.

Thanks, Roger.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 22/22] i386/slaunch: Add support for AMD SKINIT

2020-11-10 Thread Krystian Hebel
Signed-off-by: Krystian Hebel 
---
 grub-core/Makefile.core.def  |  1 +
 grub-core/lib/i386/relocator32.S |  6 ++
 grub-core/loader/i386/linux.c| 30 +-
 grub-core/loader/i386/slaunch.c  | 21 -
 include/grub/i386/slaunch.h  | 11 +--
 5 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 204f9794dbce..68de5c07c060 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1829,6 +1829,7 @@ module = {
   x86 = loader/i386/txt/txt.c;
   x86 = loader/i386/txt/acmod.c;
   x86 = loader/i386/txt/verify.c;
+  x86 = loader/i386/skinit.c;
   enable = x86;
 };
 
diff --git a/grub-core/lib/i386/relocator32.S b/grub-core/lib/i386/relocator32.S
index a2b377197b16..2bdc07018a78 100644
--- a/grub-core/lib/i386/relocator32.S
+++ b/grub-core/lib/i386/relocator32.S
@@ -115,6 +115,9 @@ VARIABLE(grub_relocator32_edx)
cmpl$SLP_INTEL_TXT, %edi
je  LOCAL(intel_txt)
 
+   cmpl$SLP_AMD_SKINIT, %edi
+   je  LOCAL(amd_skinit)
+
.byte   0xea
 VARIABLE(grub_relocator32_eip)
.long   0
@@ -123,6 +126,9 @@ VARIABLE(grub_relocator32_eip)
 LOCAL(intel_txt):
getsec
 
+LOCAL(amd_skinit):
+   skinit
+
/* GDT. Copied from loader/i386/linux.c. */
.p2align4
 LOCAL(gdt):
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index d83912c17aad..dc4dcaa0a2ef 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -233,7 +234,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
 prot_mode_mem = get_virtual_current_address (ch);
 prot_mode_target = get_physical_target_address (ch);
 
-if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+if (grub_slaunch_platform_type () != SLP_NONE)
   {
slparams.mle_ptab_mem = prot_mode_mem;
slparams.mle_ptab_target = prot_mode_target;
@@ -803,6 +804,33 @@ grub_linux_boot (void)
   state.ecx = slparams.sinit_acm_size;
   state.edx = 0;
 }
+  else if (state.edi == SLP_AMD_SKINIT)
+{
+  grub_relocator_chunk_t ch;
+
+  slparams.params = ctx.real_mode_target;
+
+  /* Contrary to the TXT, on AMD we do not have vendor-provided blobs in
+   * reserved memory, we are using normal RAM */
+  err = grub_relocator_alloc_chunk_align (relocator, ,
+   0, (0x - GRUB_SKINIT_SLB_SIZE),
+   GRUB_SKINIT_SLB_SIZE,
+   GRUB_SKINIT_SLB_ALIGN,
+   GRUB_RELOCATOR_PREFERENCE_LOW, 1);
+
+  if (err != GRUB_ERR_NONE)
+   return err;
+
+  slparams.lz_base = (grub_uint32_t) get_virtual_current_address (ch);
+  slparams.lz_size = grub_skinit_get_sl_size ();
+
+  err = grub_skinit_boot_prepare ();
+
+  if (err != GRUB_ERR_NONE)
+   return err;
+
+  state.eax = get_physical_target_address (ch);
+}
   else
 {
   /* FIXME.  */
diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c
index 3acd177afd3b..9df04ff96538 100644
--- a/grub-core/loader/i386/slaunch.c
+++ b/grub-core/loader/i386/slaunch.c
@@ -57,7 +57,8 @@ grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)),
  char *argv[] __attribute__ ((unused)))
 {
   grub_uint32_t manufacturer[3];
-  grub_uint32_t eax;
+  grub_uint32_t eax, ebx, ecx, edx;
+  grub_uint64_t msr_value;
   grub_err_t err;
 
   if (!grub_cpu_is_cpuid_supported ())
@@ -79,6 +80,20 @@ grub_cmd_slaunch (grub_command_t cmd __attribute__ 
((unused)),
 
   slp = SLP_INTEL_TXT;
 }
+  else if (!grub_memcmp (manufacturer, "AuthenticAMD", 12))
+{
+
+  grub_cpuid (GRUB_AMD_CPUID_FEATURES, eax, ebx, ecx, edx);
+  if (! (ecx & GRUB_SVM_CPUID_FEATURE) )
+return grub_error (GRUB_ERR_BAD_DEVICE, N_("CPU does not support AMD 
SVM"));
+
+  /* Check whether SVM feature is disabled in BIOS */
+  msr_value = grub_rdmsr (GRUB_MSR_AMD64_VM_CR);
+  if (msr_value & GRUB_MSR_SVM_VM_CR_SVM_DISABLE)
+return grub_error (GRUB_ERR_BAD_DEVICE, N_("BIOS has AMD SVM 
disabled"));
+
+  slp = SLP_AMD_SKINIT;
+}
   else
 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("CPU is unsupported"));
 
@@ -170,6 +185,10 @@ grub_cmd_slaunch_state (grub_command_t cmd __attribute__ 
((unused)),
   grub_printf ("Secure launcher: Intel TXT\n");
   grub_txt_state_show ();
 }
+  else if (slp == SLP_AMD_SKINIT)
+{
+  grub_printf ("Secure launcher: AMD SKINIT\n");
+}
 
   return GRUB_ERR_NONE;
 }
diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h
index e5c32152d285..18e10d82ffc7 100644
--- a/include/

[GRUB PATCH RFC 20/22] i386/skinit: Add AMD SKINIT definitions header file

2020-11-10 Thread Krystian Hebel
Signed-off-by: Krystian Hebel 
---
 include/grub/i386/skinit.h | 46 ++
 1 file changed, 46 insertions(+)
 create mode 100644 include/grub/i386/skinit.h

diff --git a/include/grub/i386/skinit.h b/include/grub/i386/skinit.h
new file mode 100644
index ..3232d4c543cd
--- /dev/null
+++ b/include/grub/i386/skinit.h
@@ -0,0 +1,46 @@
+/*
+ *  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 <http://www.gnu.org/licenses/>.
+ *
+ *  Main secure launch definitions header file.
+ */
+
+#ifndef GRUB_I386_SKINIT_H
+#define GRUB_I386_SKINIT_H 1
+
+// SLB is 64k, 64k-aligned
+#define GRUB_SKINIT_SLB_SIZE  0x1
+#define GRUB_SKINIT_SLB_ALIGN 0x1
+
+#ifndef ASM_FILE
+
+#include 
+
+grub_err_t grub_skinit_boot_prepare (struct grub_slaunch_params *slparams);
+
+static inline grub_uint16_t grub_skinit_get_sl_size (void)
+{
+  grub_uint16_t *ptr = (grub_uint16_t *)grub_slaunch_module ();
+
+  if (ptr == NULL)
+return 0;
+
+  return ptr[1];
+}
+
+#endif /* ASM_FILE */
+
+#endif /* GRUB_I386_SKINIT_H */
-- 
2.17.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 11/22] efi: Add a function to read EFI variables with attributes

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

It will be used to properly detect and report UEFI Secure Boot status to
the x86 Linux kernel. The functionality will be added by subsequent patches.

Signed-off-by: Ignat Korchagin 
Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 grub-core/kern/efi/efi.c | 16 +---
 include/grub/efi/efi.h   |  5 +
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index 9403b12cd780..2942b8e355de 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -224,8 +224,11 @@ grub_efi_set_variable(const char *var, const 
grub_efi_guid_t *guid,
 }
 
 grub_efi_status_t
-grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-  grub_size_t *datasize_out, void **data_out)
+grub_efi_get_variable_with_attributes (const char *var,
+  const grub_efi_guid_t *guid,
+  grub_size_t *datasize_out,
+  void **data_out,
+  grub_efi_uint32_t *attributes)
 {
   grub_efi_status_t status;
   grub_efi_uintn_t datasize = 0;
@@ -262,7 +265,7 @@ grub_efi_get_variable (const char *var, const 
grub_efi_guid_t *guid,
   return GRUB_EFI_OUT_OF_RESOURCES;
 }
 
-  status = efi_call_5 (r->get_variable, var16, guid, NULL, , data);
+  status = efi_call_5 (r->get_variable, var16, guid, attributes, , 
data);
   grub_free (var16);
 
   if (status == GRUB_EFI_SUCCESS)
@@ -276,6 +279,13 @@ grub_efi_get_variable (const char *var, const 
grub_efi_guid_t *guid,
   return status;
 }
 
+grub_efi_status_t
+grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+  grub_size_t *datasize_out, void **data_out)
+{
+  return grub_efi_get_variable_with_attributes (var, guid, datasize_out, 
data_out, NULL);
+}
+
 #pragma GCC diagnostic ignored "-Wcast-align"
 
 /* Search the mods section from the PE32/PE32+ image. This code uses
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index 8b2a0f1f5907..83d958f9945e 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -74,6 +74,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) 
(grub_efi_uintn_t memo
   grub_efi_uintn_t 
descriptor_size,
   grub_efi_uint32_t 
descriptor_version,
   
grub_efi_memory_descriptor_t *virtual_map);
+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable_with_attributes) (const 
char *variable,
+  const 
grub_efi_guid_t *guid,
+  
grub_size_t *datasize_out,
+  void 
**data_out,
+  
grub_efi_uint32_t *attributes);
 grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
   const grub_efi_guid_t 
*guid,
   grub_size_t 
*datasize_out,
-- 
2.17.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 16/22] i386/txt: Add Intel TXT ACM module support

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

Signed-off-by: Ross Philipson 
Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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 ..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 0x / "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 PATCH RFC 05/22] i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and make it global

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

Subsequent patches will use that constant.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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..078795467290 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, ))
@@ -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) 

[GRUB PATCH RFC 17/22] i386/txt: Add Intel TXT verification routines

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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 ..97f3b325de03
--- /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] >= 0x1UL )
+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 PATCH RFC 21/22] i386/skinit: Add AMD SKINIT core implementation

2020-11-10 Thread Krystian Hebel
Signed-off-by: Krystian Hebel 
---
 grub-core/loader/i386/skinit.c | 162 +
 1 file changed, 162 insertions(+)
 create mode 100644 grub-core/loader/i386/skinit.c

diff --git a/grub-core/loader/i386/skinit.c b/grub-core/loader/i386/skinit.c
new file mode 100644
index ..0090102aae40
--- /dev/null
+++ b/grub-core/loader/i386/skinit.c
@@ -0,0 +1,162 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LZ_TAG_CLASS_MASK   0xF0
+
+/* Tags with no particular class */
+#define LZ_TAG_NO_CLASS 0x00
+#define LZ_TAG_END  0x00
+#define LZ_TAG_UNAWARE_OS   0x01
+#define LZ_TAG_TAGS_SIZE0x0F  /* Always first */
+
+/* Tags specifying kernel type */
+#define LZ_TAG_BOOT_CLASS   0x10
+#define LZ_TAG_BOOT_LINUX   0x10
+#define LZ_TAG_BOOT_MB2 0x11
+
+/* Tags specific to TPM event log */
+#define LZ_TAG_EVENT_LOG_CLASS  0x20
+#define LZ_TAG_EVENT_LOG0x20
+#define LZ_TAG_LZ_HASH  0x21
+
+struct lz_tag_hdr {
+  grub_uint8_t type;
+  grub_uint8_t len;
+} __attribute__ (( packed ));
+
+struct lz_tag_tags_size {
+  struct lz_tag_hdr hdr;
+  grub_uint16_t size;
+} __attribute__ (( packed ));
+
+struct lz_tag_boot_linux {
+  struct lz_tag_hdr hdr;
+  grub_uint32_t zero_page;
+} __attribute__ (( packed ));
+
+struct lz_tag_boot_mb2 {
+  struct lz_tag_hdr hdr;
+  grub_uint32_t mbi;
+   grub_uint32_t kernel_entry;
+  grub_uint32_t kernel_size;
+} __attribute__ (( packed ));
+
+struct lz_tag_evtlog {
+  struct lz_tag_hdr hdr;
+  grub_uint32_t address;
+  grub_uint32_t size;
+} __attribute__ (( packed ));
+
+struct lz_tag_hash {
+  struct lz_tag_hdr hdr;
+  grub_uint16_t algo_id;
+  grub_uint8_t digest[];
+} __attribute__ (( packed ));
+
+static inline struct lz_tag_tags_size *get_bootloader_data_addr (
+  struct grub_slaunch_params *slparams)
+{
+  return (struct lz_tag_tags_size *)(slparams->lz_base + slparams->lz_size);
+}
+
+static inline void *next_tag(struct lz_tag_tags_size *tags)
+{
+  return (void *)(((grub_uint8_t *)tags) + tags->size);
+}
+
+grub_err_t
+grub_skinit_boot_prepare (struct grub_slaunch_params *slparams)
+{
+  void *lz_base = (void *)(grub_addr_t) slparams->lz_base;
+  grub_memset (lz_base, 0, GRUB_SKINIT_SLB_SIZE);
+  grub_memcpy (lz_base, grub_slaunch_module(), slparams->lz_size);
+
+  struct lz_tag_tags_size *tags = get_bootloader_data_addr (slparams);
+  grub_uint32_t *apic = (grub_uint32_t *)0xfee00300ULL;
+
+  /* Tags header */
+  tags->hdr.type = LZ_TAG_TAGS_SIZE;
+  tags->hdr.len = sizeof(struct lz_tag_tags_size);
+  tags->size = sizeof(struct lz_tag_tags_size);
+
+  /* Hashes of LZ */
+  {
+grub_uint8_t buff[GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE];  /* SHA1 ctx is 
smaller */
+struct lz_tag_hash *h = next_tag(tags);
+h->hdr.type = LZ_TAG_LZ_HASH;
+h->hdr.len = sizeof(struct lz_tag_hash) + GRUB_MD_SHA256->mdlen;
+h->algo_id = 0x000B;
+GRUB_MD_SHA256->init(buff);
+GRUB_MD_SHA256->write(buff, lz_base, slparams->lz_size);
+GRUB_MD_SHA256->final(buff);
+grub_memcpy(h->digest, GRUB_MD_SHA256->read(buff), GRUB_MD_SHA256->mdlen);
+tags->size += h->hdr.len;
+
+h = next_tag(tags);
+h->hdr.type = LZ_TAG_LZ_HASH;
+h->hdr.len = sizeof(struct lz_tag_hash) + GRUB_MD_SHA1->mdlen;
+h->algo_id = 0x0004;
+GRUB_MD_SHA1->init(buff);
+GRUB_MD_SHA1->write(buff, lz_base, slparams->lz_size);
+GRUB_MD_SHA1->final(buff);
+grub_memcpy(h->digest, GRUB_MD_SHA1->read(buff), GRUB_MD_SHA1->mdlen);
+tags->size += h->hdr.len;
+  }
+
+  /* Boot protocol data */
+  struct lz_tag_boot_linux *b = next_tag(tags);
+  b->hdr.type = LZ_TAG_BOOT_LINUX;
+  b->hdr.len = sizeof(struct lz_tag_boot_linux);
+  b->zero_page = (grub_uint32_t)slparams->params;
+  tags->size += b->hdr.len;
+
+  if (slparams->tpm_evt_log_size != 0) {
+struct lz_tag_evtlog *e = next_tag(tags);
+e->hdr.type = LZ_TAG_EVENT_LOG;
+e->hdr.len = sizeof(struct lz_tag_evtlog);
+e->address = slparams->tpm_evt_l

[GRUB PATCH RFC 14/22] i386/txt: Add Intel TXT definitions header file

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 include/grub/i386/txt.h | 690 
 1 file changed, 690 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 ..4ec801db5900
--- /dev/null
+++ b/include/grub/i386/txt.h
@@ -0,0 +1,690 @@
+/*
+ *  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_POLICY0
+#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_RESERVED3
+
+#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_0161
+#define GRUB_TXT_ACM_HEADER_LEN_3_0224
+
+#define GRUB_TXT_ACM_HEADER_VERSION_0_00x
+#define GRUB_TXT_ACM_HEADER_VERSION_3_00x0300
+
+#define GRUB_TXT_ACM_FLAG_PREPRODUCTION(1<<14)
+#define GRUB_TXT_ACM_FLAG_DEBUG_SIGNED (1<<15)
+
+#define GRUB_TXT_ACM_MODULE_VENDOR_INTEL   0x8086
+
+#define GRUB_TXT_MLE_MAX_SIZE  0x4000
+
+#define GRUB_MLE_AP_WAKE_BLOCK_SIZEGRUB_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_SINIT1
+#define GRUB_TXT_ACM_CHIPSET_TYPE_BIOS_RACM8
+#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 PATCH RFC 03/22] i386/msr: Extract and improve MSR support detection code

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

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 
Signed-off-by: Norbert Kaminski 
---
 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 e3e9f2ee3244..d14bb3176ef2 100644
--- a/grub-core/commands/i386/wrmsr.c
+++ b/grub-core/commands/i386/wrmsr.c
@@ -35,26 +35,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


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 15/22] i386/txt: Add Intel TXT core implementation

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 grub-core/loader/i386/txt/txt.c | 886 
 include/grub/i386/memory.h  |   5 +
 2 files changed, 891 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 ..aea534003c6d
--- /dev/null
+++ b/grub-core/loader/i386/txt/txt.c
@@ -0,0 +1,886 @@
+/*
+ * 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, , , );
+  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 PATCH RFC 02/22] i386/msr: Rename grub_msr_read() and grub_msr_write()

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

to grub_rdmsr() and grub_wrmsr() respectively. New names are more
obvious than older ones.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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 9b7abba7cf27..e3e9f2ee3244 100644
--- a/grub-core/commands/i386/wrmsr.c
+++ b/grub-core/commands/i386/wrmsr.c
@@ -76,7 +76,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


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 10/22] efi: Return grub_efi_status_t from grub_efi_get_variable()

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

This is needed to properly detect and report UEFI Secure Boot status
to the x86 Linux kernel. The functionality will be added by subsequent
patches.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 grub-core/commands/efi/efifwsetup.c |  8 
 grub-core/kern/efi/efi.c| 16 +---
 grub-core/video/efi_gop.c   |  2 +-
 include/grub/efi/efi.h  |  7 ---
 4 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/grub-core/commands/efi/efifwsetup.c 
b/grub-core/commands/efi/efifwsetup.c
index 7a137a72a2fd..eaca03283886 100644
--- a/grub-core/commands/efi/efifwsetup.c
+++ b/grub-core/commands/efi/efifwsetup.c
@@ -38,8 +38,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)),
   grub_size_t oi_size;
   grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
 
-  old_os_indications = grub_efi_get_variable ("OsIndications", ,
- _size);
+  grub_efi_get_variable ("OsIndications", , _size,
+(void **) _os_indications);
 
   if (old_os_indications != NULL && oi_size == sizeof (os_indications))
 os_indications |= *old_os_indications;
@@ -63,8 +63,8 @@ efifwsetup_is_supported (void)
   grub_size_t oi_size = 0;
   grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
 
-  os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported",
-   , _size);
+  grub_efi_get_variable ("OsIndicationsSupported", , _size,
+(void **) _indications_supported);
 
   if (!os_indications_supported)
 return 0;
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index e0165e74c587..9403b12cd780 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -223,9 +223,9 @@ grub_efi_set_variable(const char *var, const 
grub_efi_guid_t *guid,
   return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
 }
 
-void *
+grub_efi_status_t
 grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-  grub_size_t *datasize_out)
+  grub_size_t *datasize_out, void **data_out)
 {
   grub_efi_status_t status;
   grub_efi_uintn_t datasize = 0;
@@ -234,13 +234,14 @@ grub_efi_get_variable (const char *var, const 
grub_efi_guid_t *guid,
   void *data;
   grub_size_t len, len16;
 
+  *data_out = NULL;
   *datasize_out = 0;
 
   len = grub_strlen (var);
   len16 = len * GRUB_MAX_UTF16_PER_UTF8;
   var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
   if (!var16)
-return NULL;
+return GRUB_EFI_OUT_OF_RESOURCES;
   len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
   var16[len16] = 0;
 
@@ -251,14 +252,14 @@ grub_efi_get_variable (const char *var, const 
grub_efi_guid_t *guid,
   if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
 {
   grub_free (var16);
-  return NULL;
+  return status;
 }
 
   data = grub_malloc (datasize);
   if (!data)
 {
   grub_free (var16);
-  return NULL;
+  return GRUB_EFI_OUT_OF_RESOURCES;
 }
 
   status = efi_call_5 (r->get_variable, var16, guid, NULL, , data);
@@ -266,12 +267,13 @@ grub_efi_get_variable (const char *var, const 
grub_efi_guid_t *guid,
 
   if (status == GRUB_EFI_SUCCESS)
 {
+  *data_out = data;
   *datasize_out = datasize;
-  return data;
+  return status;
 }
 
   grub_free (data);
-  return NULL;
+  return status;
 }
 
 #pragma GCC diagnostic ignored "-Wcast-align"
diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
index be446f8d2915..7fe0cdabf50b 100644
--- a/grub-core/video/efi_gop.c
+++ b/grub-core/video/efi_gop.c
@@ -316,7 +316,7 @@ grub_video_gop_get_edid (struct grub_video_edid_info 
*edid_info)
   char edidname[] = "agp-internal-edid";
   grub_size_t datasize;
   grub_uint8_t *data;
-  data = grub_efi_get_variable (edidname, _var_guid, );
+  grub_efi_get_variable (edidname, _var_guid, , (void **) 
);
   if (data && datasize > 16)
{
  copy_size = datasize - 16;
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index e90e00dc431b..8b2a0f1f5907 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -74,9 +74,10 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) 
(grub_efi_uintn_t memo
   grub_efi_uintn_t 
descriptor_size,
   grub_efi_uint32_t 
descriptor_version,
   
grub_efi_memory_descriptor_t *virtual_map);
-void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
-  const grub_efi_guid_t *guid,
-  grub_size_t *datasize_out);
+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
+ 

[GRUB PATCH RFC 12/22] i386/efi: Report UEFI Secure Boot status to the Linux kernel

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

Otherwise the kernel does not know its state and cannot enable various
security features depending on UEFI Secure Boot.

Signed-off-by: Ignat Korchagin 
Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 grub-core/loader/i386/linux.c | 86 ++-
 include/grub/i386/linux.h | 14 +-
 2 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 976af3fae873..940ce0f98bca 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -397,6 +397,87 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, 
grub_uint64_t size,
   return 0;
 }
 
+#ifdef GRUB_MACHINE_EFI
+/*
+ * Determine whether we're in secure boot mode.
+ *
+ * Please keep the logic in sync with the Linux kernel,
+ * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
+ */
+static grub_uint8_t
+grub_efi_get_secureboot (void)
+{
+  grub_efi_guid_t efi_variable_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+  grub_efi_guid_t efi_shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
+  grub_efi_status_t status;
+  grub_efi_uint32_t attr = 0;
+  grub_size_t size = 0;
+  grub_uint8_t *secboot = NULL;
+  grub_uint8_t *setupmode = NULL;
+  grub_uint8_t *moksbstate = NULL;
+  grub_uint8_t secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_UNKNOWN;
+  const char *secureboot_str = "UNKNOWN";
+
+  status = grub_efi_get_variable ("SecureBoot", _variable_guid,
+ , (void **) );
+
+  if (status == GRUB_EFI_NOT_FOUND)
+{
+  secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED;
+  goto out;
+}
+
+  if (status != GRUB_EFI_SUCCESS)
+goto out;
+
+  status = grub_efi_get_variable ("SetupMode", _variable_guid,
+ , (void **) );
+
+  if (status != GRUB_EFI_SUCCESS)
+goto out;
+
+  if ((*secboot == 0) || (*setupmode == 1))
+{
+  secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED;
+  goto out;
+}
+
+  /*
+   * See if a user has put the shim into insecure mode. If so, and if the
+   * variable doesn't have the runtime attribute set, we might as well
+   * honor that.
+   */
+  status = grub_efi_get_variable_with_attributes ("MokSBState", 
_shim_lock_guid,
+ , (void **) , 
);
+
+  /* If it fails, we don't care why. Default to secure. */
+  if (status != GRUB_EFI_SUCCESS)
+{
+  secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED;
+  goto out;
+}
+
+  if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1)
+secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED;
+
+  secureboot = GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED;
+
+ out:
+  grub_free (moksbstate);
+  grub_free (setupmode);
+  grub_free (secboot);
+
+  if (secureboot == GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED)
+secureboot_str = "Disabled";
+  else if (secureboot == GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED)
+secureboot_str = "Enabled";
+
+  grub_dprintf ("linux", "UEFI Secure Boot state: %s\n", secureboot_str);
+
+  return secureboot;
+}
+#endif
+
 static grub_err_t
 grub_linux_boot (void)
 {
@@ -583,6 +664,9 @@ grub_linux_boot (void)
 grub_efi_uintn_t efi_desc_size;
 grub_size_t efi_mmap_target;
 grub_efi_uint32_t efi_desc_version;
+
+ctx.params->secure_boot = grub_efi_get_secureboot ();
+
 err = grub_efi_finish_boot_services (_mmap_size, efi_mmap_buf, NULL,
 _desc_size, _desc_version);
 if (err)
@@ -794,7 +878,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   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.padding10 = 0;
+  linux_params.ps_mouse = linux_params.padding11 = 0;
   linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
 
   /* These two are used (instead of cmd_line_ptr) by older versions of Linux,
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index ce30e7fb01b9..6aea73ddb145 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -49,6 +49,12 @@
 /* Maximum number of MBR signatures to store. */
 #define EDD_MBR_SIG_MAX16
 
+/* Possible values for Linux secure_boot kernel parameter. */
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_UNSET   0
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_UNKNOWN 1
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_DISABLED2
+#define GRUB_LINUX_EFI_SECUREBOOT_MODE_ENABLED 3
+
 #ifdef __x86_64__
 
 #define GRUB_LINUX_EFI_SIGNATURE   \
@@ -275,7 +281,11 @@ struct linux_kernel_params
 
   grub_uint8_t mmap_size;  /* 1e8 */
 
-  grub_uint8_t padding9[0x1f1 - 0x1e9];
+  grub_uint8_t padding9[0x1ec - 0x1e9];
+
+  grub_uint8_t secure_boot; /* 1ec */
+
+  grub_uint8_t padding10[0x1f1 - 0x1ed];
 
   /* Linux setup header copy - BEGIN. */
   grub_uint8_t 

[GRUB PATCH RFC 07/22] i386/tpm: Rename tpm module to tpm_verifier

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

..to avoid naming collision with TPM TIS and CRB driver introduced
by subsequent patch.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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 37f7ce7da5fc..cb9fa6ac6522 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5915,10 +5915,10 @@ it cannot be unloaded if it was loaded into the memory.
 @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
@@ -5943,9 +5943,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 b5f47fc41b54..5485c87f3b16 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2497,8 +2497,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 (_tpm_verifier);
 }
 
-GRUB_MOD_FINI (tpm)
+GRUB_MOD_FINI (tpm_verifier)
 {
   grub_verifier_unregister (_tpm_verifier);
 }
-- 
2.17.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 09/22] efi: Make shim_lock GUID and protocol type public

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

The GUID will be used to properly detect and report UEFI Secure Boot
status to the x86 Linux kernel. The functionality will be added by
subsequent patches. The shim_lock protocol type is made public for
completeness.

Additionally, fix formatting of four preceding GUIDs.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 grub-core/commands/efi/shim_lock.c | 12 
 include/grub/efi/api.h | 19 +++
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/grub-core/commands/efi/shim_lock.c 
b/grub-core/commands/efi/shim_lock.c
index 764098cfc83e..d8f52d721c30 100644
--- a/grub-core/commands/efi/shim_lock.c
+++ b/grub-core/commands/efi/shim_lock.c
@@ -27,18 +27,6 @@
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
-#define GRUB_EFI_SHIM_LOCK_GUID \
-  { 0x605dab50, 0xe046, 0x4300, \
-{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
-  }
-
-struct grub_efi_shim_lock_protocol
-{
-  grub_efi_status_t
-  (*verify) (void *buffer, grub_uint32_t size);
-};
-typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
-
 static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
 static grub_efi_shim_lock_protocol_t *sl;
 
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 1dcaa12f59e8..39733585b580 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -321,22 +321,27 @@
 
 #define GRUB_EFI_SAL_TABLE_GUID \
   { 0xeb9d2d32, 0x2d88, 0x11d3, \
-  { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
   }
 
 #define GRUB_EFI_HCDP_TABLE_GUID \
   { 0xf951938d, 0x620b, 0x42ef, \
-  { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
+{ 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
   }
 
 #define GRUB_EFI_DEVICE_TREE_GUID \
   { 0xb1b621d5, 0xf19c, 0x41a5, \
-  { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
+{ 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
   }
 
 #define GRUB_EFI_VENDOR_APPLE_GUID \
   { 0x2B0585EB, 0xD8B8, 0x49A9,\
-  { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+{ 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+  }
+
+#define GRUB_EFI_SHIM_LOCK_GUID \
+  { 0x605dab50, 0xe046, 0x4300, \
+{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
   }
 
 struct grub_efi_sal_system_table
@@ -1694,6 +1699,12 @@ struct grub_efi_block_io
 };
 typedef struct grub_efi_block_io grub_efi_block_io_t;
 
+struct grub_efi_shim_lock_protocol
+{
+  grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
+};
+typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
+
 #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
   || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
   || defined(__riscv)
-- 
2.17.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 06/22] mmap: Add grub_mmap_get_lowest() and grub_mmap_get_highest()

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

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 
Signed-off-by: Norbert Kaminski 
---
 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 64684c23d0d9..5ba20833484b 100644
--- a/grub-core/mmap/mmap.c
+++ b/grub-core/mmap/mmap.c
@@ -340,6 +340,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, );
+
+  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, );
+
+  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


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB PATCH RFC 08/22] i386/tpm: Add TPM TIS and CRB driver

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

It will be used by Intel TXT secure launcher introduced
by subsequent patches.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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 ..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  0xfed4
+
+/* TIS registers. */
+#define TPM_ACCESS 0x
+#define TPM_INTF_CAPABILITY0x0014
+#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_ACTIVE0x1
+
+#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 + 

[GRUB PATCH RFC 04/22] i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

..to avoid potential conflicts and confusion.

Signed-off-by: Daniel Kiper 
Signed-off-by: Norbert Kaminski 
---
 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
movl0(%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;
-  

[GRUB PATCH RFC 01/22] i386/msr: Merge rdmsr.h and wrmsr.h into msr.h

2020-11-10 Thread Krystian Hebel
From: Norbert Kaminski 

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 
Signed-off-by: Norbert Kaminski 
---
 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 fa76f5aed117..9b7abba7cf27 100644
--- a/grub-core/commands/i386/wrmsr.c
+++ b/grub-core/commands/i386/wrmsr.c
@@ -26,7 +26,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..
--- 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


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[GRUB RFC PATCH 00/22] i386: Intel TXT and AMD SKINIT secure launcher

2020-11-10 Thread Krystian Hebel
Hi,

This is an addition to the RFC patchset which introduced TrenchBoot support for
Intel TXT.

It includes all original patches sent by Daniel Kiper back in May, rebased on
the top of current master so the AMD-specific changes can be applied cleanly.
Additionally, a small bug fix to patch 18 was added - original patch erroneously
passed pre-relocated address of Linux's zero_page instead of the target one. No
other changes were made to the TXT code.

Support for AMD SKINIT was added on top of those patches. Apart from SKINIT
preparations it includes small modification to the relocator and Linux boot
command, in similar matter as was done for TXT.

Original cover letter by Daniel:

  Hi,

  This is an RFC patchset for the GRUB introducing the Intel TXT secure 
launcher.
  This is a part of larger work known as the TrenchBoot. Patchset can be split
  into two distinct parts:
- 01-12: preparatory patches,
- 13-18: the Intel TXT secure launcher itself.

  The initial implementation of the Intel TXT secure launcher works. However,
  there are still some missing bits and pieces, e.g.:
- SINIT ACM auto loader,
- lack of RMRR support,
- lack of support for MLEs larger than 1 GiB,
- lack of TPM 1.2 support.
- various fixes and cleanups.

  Commands introduced by this patchset: tpm_type, slaunch, slaunch_module (not
  required on server platforms) and slaunch_state (useful for checking platform
  configuration and state; based on tboot's txt-stat).

  Daniel

Krystian Hebel (4):
  i386/slaunch: Add code for searching for DRTM event log in ACPI
  i386/skinit: Add AMD SKINIT definitions header file
  i386/skinit: Add AMD SKINIT core implementation
  i386/slaunch: Add support for AMD SKINIT

Norbert Kaminski (18):
  i386/msr: Merge rdmsr.h and wrmsr.h into msr.h
  i386/msr: Rename grub_msr_read() and grub_msr_write()
  i386/msr: Extract and improve MSR support detection code
  i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT
  i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and make it global
  mmap: Add grub_mmap_get_lowest() and grub_mmap_get_highest()
  i386/tpm: Rename tpm module to tpm_verifier
  i386/tpm: Add TPM TIS and CRB driver
  efi: Make shim_lock GUID and protocol type public
  efi: Return grub_efi_status_t from grub_efi_get_variable()
  efi: Add a function to read EFI variables with attributes
  i386/efi: Report UEFI Secure Boot status to the Linux kernel
  i386/slaunch: Add basic platform support for secure launch
  i386/txt: Add Intel TXT definitions header file
  i386/txt: Add Intel TXT core implementation
  i386/txt: Add Intel TXT ACM module support
  i386/txt: Add Intel TXT verification routines
  i386/slaunch: Add secure launch framework and commands

 docs/grub.texi   |  15 +-
 grub-core/Makefile.am|   3 +
 grub-core/Makefile.core.def  |  18 +-
 grub-core/commands/efi/efifwsetup.c  |   8 +-
 grub-core/commands/efi/shim_lock.c   |  12 -
 grub-core/commands/i386/rdmsr.c  |  25 +-
 grub-core/commands/i386/tpm.c| 182 
 grub-core/commands/i386/wrmsr.c  |  25 +-
 grub-core/commands/{tpm.c => tpm_verifier.c} |   6 +-
 grub-core/kern/efi/efi.c |  30 +-
 grub-core/lib/i386/relocator32.S |  14 +
 grub-core/lib/i386/xen/relocator.S   |   6 +-
 grub-core/lib/x86_64/xen/relocator.S |   4 +-
 grub-core/loader/i386/bsd.c  |   7 +
 grub-core/loader/i386/linux.c| 320 ++-
 grub-core/loader/i386/skinit.c   | 162 
 grub-core/loader/i386/slaunch.c  | 326 +++
 grub-core/loader/i386/txt/acmod.c| 575 
 grub-core/loader/i386/txt/txt.c  | 886 +++
 grub-core/loader/i386/txt/verify.c   | 297 +++
 grub-core/loader/i386/xen.c  |  61 +-
 grub-core/loader/i386/xnu.c  |   3 +
 grub-core/loader/multiboot.c |   5 +
 grub-core/mmap/mmap.c|  64 ++
 grub-core/video/efi_gop.c|   2 +-
 include/grub/efi/api.h   |  19 +-
 include/grub/efi/efi.h   |  12 +-
 include/grub/file.h  |   3 +
 include/grub/i386/cpuid.h|  13 +
 include/grub/i386/crfr.h | 186 
 include/grub/i386/linux.h|  28 +-
 include/grub/i386/memory.h   |   8 +-
 include/grub/i386/mmio.h |  90 ++
 include/grub/i386/msr.h  | 135 +++
 include/grub/i386/{wrmsr.h => skinit.h}  |  35 +-
 include/grub/i386/slaunch.h  |  64 ++
 include/grub/i386/{rdmsr.h => tpm.h} |  31 +-
 include/grub/i386/txt.h  | 690 +++
 include/grub/memory.h|   3 +
 39 files changed, 4212 insertions(+), 161 deletions(-

Re: Multiboot2 on aarch64: Alignment of ELF Headers

2020-09-22 Thread Krystian Hebel

On 21.09.2020 21:14, Chris Plant wrote:

On Sat, 2020-05-23 at 14:33 +0200, Hans Ulrich Niedermann wrote:

On Sat, 23 May 2020 12:21:27 +0100
Chris Plant via Grub-devel  wrote:


On Sat, 2020-05-23 at 12:43 +0200, Hans Ulrich Niedermann wrote:

On Fri, 22 May 2020 17:23:35 +0100
Chris Plant via Grub-devel  wrote:
   

I'm continuing to work on Multiboot2 support on aarch64, and
I'm
looking at the alignment of the ELF headers which are passed
through
MB2.

At the risk of me sounding stupid...

Having read the MB2 specs quite thoroughly in the past few
months, I
still have no idea what "ELF headers" being "passed through MB2"
could
be about. The MB2 spec defines a MB2 header consisting of a four
MB2
header magic fields and a set of MB2 header tags.

The only thing ELF related I could find there is the MB2 header
address
tag which duplicates some information from ELF (if OS image is in
ELF format) or contains address information (if OS image is in
non-ELF format). Is that what you are talking about?

Yes, this is what I'm talking about.  I'm using the MB2 tag (type
9)
to see where the ELF section headers are.

Ah. So the type 9 you are referring to is the "ELF-Symbols" boot
information tag (i.e. information the bootloader communicates to the
OS
image), not an MB2 header tag (information the OS image communicates
to
the bootloader).

I am catching up with you, finally.


Apologies, I've not been clear enough and rambled too much.  The
issue
I see is nothing to do with grub's MB2 implementation, but instead
in
the way grub is loading the ELF section headers.

The ELF section headers appear to be loaded on a 4 byte alignment
not
an 8 byte alignment.  You can read the 4 byte members of the ELF
header structure fine, but not the 8 byte members as they are
aligned
to 4 bytes.

So, my question is, should grub load the ELF headers to an 8 byte
alignment, or should the OS be prepared for them to be aligned to 4
byte?

The 64bit part of the ELF spec appears to specifically made such that
64bit values are aligned to 64bit boundaries (I have taken a look at
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format for an
overview).

Therefore, loading an ELF64 image with its many 64bit values to an
address not aligned to 8 byte boundaries sounds to me like a probable
oversight going back to ELF32 days and thus a bug for ELF64, unless
someone has a very good argument to the contrary.

On this basis, is the logical change to fix the definition of the "ELF-
Symbols" boot information tag, which is currently:

struct multiboot_tag_elf_sections
{
   multiboot_uint32_t type;
   multiboot_uint32_t size;
   multiboot_uint32_t num;
   multiboot_uint32_t entsize;
   multiboot_uint32_t shndx;
   char sections[0];
};

grub aligns this to an 8 byte boundary, but then the odd number of
uint32_t mean that sections is on a 4 byte boundary and is designed
within it's ELF defintion to be on 8 byte boundary.

So I would propose adding a 4 byte pad between shndx and sections, so
that sections on an 8 byte boundary.  This might break things until
they're recompiled but won't require any changes to code elsewhere and
I can't see how else to fix it without a new information defintion.

This WILL break things until they are recompiled in every MB2 kernel,
in addition to grub, every other MB2-capable bootloader and documentation.
Until then, the kernel would have to somewhat guess whether it was given
the old (not aligned) tag or the new one. While it may be possible as long
as the padding is filled with a value that cannot appear in the first bytes
of sections, the users would have to add the discovery code into kernels.
MB2 is one of the most commonly used (if not the most common) boot protocols
for hobby OSes.

IMHO the only way out of it would be to create a new tag type and leave the
old one as it is right now. This won't break current implementations, though
it will pass redundant information. After some transition period we may drop
the old format.

I can include this in my patch (first one, taking time and will be
terrible) to enable multiboot2 on ARM64 if this is the approach
required/desired?

Chris


Uli

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel



--
Krystian Hebel
Firmware Engineer
https://3mdeb.com | @3mdeb_com


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [GRUB PATCH RFC 15/18] i386/txt: Add Intel TXT core implementation

2020-05-22 Thread Krystian Hebel
ar address space)."

Also that spec:
"A breadth-first search of page tables must produce increasing physical 
addresses."


Maybe I misunderstood, but does it mean that the paging structures 
themselves cannot
be mapped? Or does it apply to the page tables only, not to the 
addresses of pages in PTEs?



+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;
IMHO using 'grub_uint64_t' would result in less type casting and cleaner 
code below.

+  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_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"));

This test should be the first one, before messing with TPM and MTTRs.

+
+  return GRUB_ERR_NONE;
+}

Best regards,

--
Krystian Hebel
Firmware Engineer
https://3mdeb.com | @3mdeb_com


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [GRUB PATCH 1/1] loader/i386/linux: Fix an underflow in the setup_header length calculation

2019-12-18 Thread Krystian Hebel

Sorry it took so long.

Tested with mismatch between kernel and GRUB size of that structure, 
works as

expected.

Reviewed-by: Krystian Hebel 

--
Krystian Hebel
Firmware Engineer
https://3mdeb.com | @3mdeb_com


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH] Implement relocator for SKINIT

2019-12-18 Thread Krystian Hebel
SKINIT is AMD's implementation of Dynamic Root of Trust for Measurement
(DRTM). It's operation is described in section 15.27 of AMD Architecture
Programmer’s Manual Volume 2 [1].

SKINIT instruction takes only one argument in EAX register - a pointer
to the SLB (Secure Launch Block). No other registers are preserved by
SKINIT, so there is no need to set the rest of CPU state.

The patch implements the relocator only. The rest of the requirements
(SLB alignment, TPM state, APs in INIT state) must be ensured by code
calling this relocator.

[1]: https://www.amd.com/system/files/TechDocs/24593.pdf

Signed-off-by: Krystian Hebel 
---
 grub-core/Makefile.core.def|  2 +
 grub-core/lib/i386/relocator_slaunch.c | 71 ++
 grub-core/lib/i386/relocator_slaunch_asm.S | 37 +++
 include/grub/i386/relocator.h  |  4 ++
 4 files changed, 114 insertions(+)
 create mode 100644 grub-core/lib/i386/relocator_slaunch.c
 create mode 100644 grub-core/lib/i386/relocator_slaunch_asm.S

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 23459a7fca37..1d5b0d96f1fc 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1644,6 +1644,8 @@ module = {
   x86_64_xen = lib/x86_64/xen/relocator.S;
   xen = lib/i386/relocator_common_c.c;
   x86_64_efi = lib/x86_64/efi/relocator.c;
+  x86 = lib/i386/relocator_slaunch_asm.S;
+  x86 = lib/i386/relocator_slaunch.c;
 
   extra_dist = lib/i386/relocator_common.S;
   extra_dist = kern/powerpc/cache_flush.S;
diff --git a/grub-core/lib/i386/relocator_slaunch.c 
b/grub-core/lib/i386/relocator_slaunch.c
new file mode 100644
index ..458091d93dcc
--- /dev/null
+++ b/grub-core/lib/i386/relocator_slaunch.c
@@ -0,0 +1,71 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *  Copyright (C) 2019 3mdeb Embedded Systems Consulting
+ *
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+extern grub_uint8_t grub_relocator_skinit_start;
+extern grub_uint8_t grub_relocator_skinit_end;
+extern grub_uint32_t *grub_relocator_skinit_slb;
+
+
+#define RELOCATOR_SIZEOF(x)(_relocator##x##_end - 
_relocator##x##_start)
+
+grub_err_t
+grub_relocator_skinit_boot (struct grub_relocator *rel,
+  grub_uint32_t *slb,
+  int avoid_efi_bootservices)
+{
+  grub_err_t err;
+  void *relst;
+  grub_relocator_chunk_t ch;
+
+  err = grub_relocator_alloc_chunk_align (rel, , 0x1000,
+ 0x1 - RELOCATOR_SIZEOF 
(_skinit),
+ RELOCATOR_SIZEOF (_skinit), 16,
+ GRUB_RELOCATOR_PREFERENCE_LOW,
+ avoid_efi_bootservices);
+  if (err)
+return err;
+
+  grub_relocator_skinit_slb = slb;
+
+  grub_memmove (get_virtual_current_address (ch), _relocator_skinit_start,
+   RELOCATOR_SIZEOF (_skinit));
+
+  err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
+  , NULL);
+  if (err)
+return err;
+
+  asm volatile ("cli");
+  ((void (*) (void)) relst) ();
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/lib/i386/relocator_slaunch_asm.S 
b/grub-core/lib/i386/relocator_slaunch_asm.S
new file mode 100644
index ..0d19c743131d
--- /dev/null
+++ b/grub-core/lib/i386/relocator_slaunch_asm.S
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2019 3mdeb Embedded Systems Consulting
+ *
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ *