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

2020-05-04 Thread Daniel Kiper
From: Ross Philipson 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
---
 grub-core/loader/i386/txt/txt.c | 887 
 include/grub/i386/memory.h  |   5 +
 2 files changed, 892 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 0..3e25890c3
--- /dev/null
+++ b/grub-core/loader/i386/txt/txt.c
@@ -0,0 +1,887 @@
+/*
+ * 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_SMX_PARAMETER_MAX_VERSIONS)
+{
+

[GRUB PATCH RFC 18/18] i386/slaunch: Add secure launch framework and commands

2020-05-04 Thread Daniel Kiper
From: Ross Philipson 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
---
 grub-core/Makefile.am|   3 +
 grub-core/Makefile.core.def  |  15 +++
 grub-core/lib/i386/relocator32.S |   8 ++
 grub-core/loader/i386/bsd.c  |   7 ++
 grub-core/loader/i386/linux.c| 206 ---
 grub-core/loader/i386/slaunch.c  | 194 
 grub-core/loader/i386/xnu.c  |   3 +
 grub-core/loader/multiboot.c |   5 +
 include/grub/file.h  |   3 +
 include/grub/i386/linux.h|  14 ++-
 include/grub/i386/slaunch.h  |  56 +++
 11 files changed, 500 insertions(+), 14 deletions(-)
 create mode 100644 grub-core/loader/i386/slaunch.c
 create mode 100644 include/grub/i386/slaunch.h

diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index 3ea8e7ff4..ae6676e6f 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -99,6 +99,7 @@ KERNEL_HEADER_FILES += 
$(top_builddir)/include/grub/machine/kernel.h
 KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
 KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h
 endif
 
 if COND_i386_xen_pvh
@@ -118,6 +119,7 @@ KERNEL_HEADER_FILES += 
$(top_builddir)/include/grub/machine/kernel.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
@@ -179,6 +181,7 @@ KERNEL_HEADER_FILES += 
$(top_builddir)/include/grub/machine/kernel.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/slaunch.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index b74a34f0c..a07811b51 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1824,6 +1824,15 @@ module = {
 };
 
 module = {
+  name = slaunch;
+  x86 = loader/i386/slaunch.c;
+  x86 = loader/i386/txt/txt.c;
+  x86 = loader/i386/txt/acmod.c;
+  x86 = loader/i386/txt/verify.c;
+  enable = x86;
+};
+
+module = {
   name = fdt;
   efi = loader/efi/fdt.c;
   common = lib/fdt.c;
@@ -2497,6 +2506,12 @@ module = {
 };
 
 module = {
+  name = tpm;
+  x86 = commands/i386/tpm.c;
+  enable = x86;
+};
+
+module = {
   name = tpm_verifier;
   common = commands/tpm_verifier.c;
   efi = commands/efi/tpm.c;
diff --git a/grub-core/lib/i386/relocator32.S b/grub-core/lib/i386/relocator32.S
index 09ce56ad0..a2b377197 100644
--- a/grub-core/lib/i386/relocator32.S
+++ b/grub-core/lib/i386/relocator32.S
@@ -24,6 +24,8 @@
 
 #include "relocator_common.S"
 
+#include 
+
.p2align4   /* force 16-byte alignment */
 
 VARIABLE(grub_relocator32_start)
@@ -110,11 +112,17 @@ VARIABLE(grub_relocator32_edx)
   payload and makes this implementation easier.  */
cld
 
+   cmpl$SLP_INTEL_TXT, %edi
+   je  LOCAL(intel_txt)
+
.byte   0xea
 VARIABLE(grub_relocator32_eip)
.long   0
.word   CODE_SEGMENT
 
+LOCAL(intel_txt):
+   getsec
+
/* GDT. Copied from loader/i386/linux.c. */
.p2align4
 LOCAL(gdt):
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index eb82391db..53bb2af93 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -21,6 +21,10 @@
 #include 
 #include 
 #include 
+#if 0
+#include 
+#endif
+#define SLP_NONE 0
 #include 
 #include 
 #include 
@@ -791,6 +795,7 @@ grub_freebsd_boot (void)
 #endif
 
   grub_memcpy ([9], , sizeof (bi));
+  state.edi = SLP_NONE;
   state.eip = entry;
   state.esp = stack_target;
   state.ebp = stack_target;
@@ -906,6 +911,7 @@ grub_openbsd_boot (void)
 return err;
 #endif
 
+  state.edi = SLP_NONE;
   state.eip = entry;
   state.ebp = state.esp
 = ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target;
@@ -1223,6 +1229,7 @@ grub_netbsd_boot (void)
 return err;
 #endif
 
+  state.edi = SLP_NONE;
   state.eip = entry;
   state.esp = stack_target;
   state.ebp = stack_target;
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 952eb1191..da8be621e 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -34,6 +34,8 @@
 #include 
 #include 
 #include 

[GRUB PATCH RFC 13/18] i386/slaunch: Add basic platform support for secure launch

2020-05-04 Thread Daniel Kiper
From: Ross Philipson 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
---
 include/grub/i386/cpuid.h |  13 
 include/grub/i386/crfr.h  | 186 ++
 include/grub/i386/mmio.h  |  90 ++
 include/grub/i386/msr.h   |  61 +++
 4 files changed, 350 insertions(+)
 create mode 100644 include/grub/i386/crfr.h
 create mode 100644 include/grub/i386/mmio.h

diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h
index f7ae4b0a4..8176e5d11 100644
--- a/include/grub/i386/cpuid.h
+++ b/include/grub/i386/cpuid.h
@@ -19,6 +19,19 @@
 #ifndef GRUB_CPU_CPUID_HEADER
 #define GRUB_CPU_CPUID_HEADER 1
 
+/* General  */
+#define GRUB_X86_CPUID_VENDOR  0x
+#define GRUB_X86_CPUID_FEATURES0x0001
+
+/* Intel  */
+#define GRUB_VMX_CPUID_FEATURE (1<<5)
+#define GRUB_SMX_CPUID_FEATURE (1<<6)
+
+/* AMD  */
+#define GRUB_AMD_CPUID_FEATURES0x8001
+#define GRUB_SVM_CPUID_FEATURE (1<<2)
+#define GRUB_AMD_CPUID_FUNC0x800a
+
 extern unsigned char grub_cpuid_has_longmode;
 extern unsigned char grub_cpuid_has_pae;
 
diff --git a/include/grub/i386/crfr.h b/include/grub/i386/crfr.h
new file mode 100644
index 0..284d6967b
--- /dev/null
+++ b/include/grub/i386/crfr.h
@@ -0,0 +1,186 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2020  Oracle and/or its affiliates.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see .
+ */
+
+#ifndef GRUB_CRFR_H
+#define GRUB_CRFR_H 1
+
+#include 
+
+/* Routines for R/W of control and flags registers */
+
+#define GRUB_CR0_X86_PE0x0001 /* Enable Protected Mode */
+#define GRUB_CR0_X86_MP0x0002 /* "Math" (FPU) Present */
+#define GRUB_CR0_X86_EM0x0004 /* EMulate FPU */
+#define GRUB_CR0_X86_TS0x0008 /* Task Switched */
+#define GRUB_CR0_X86_PG0x8000 /* Enable PaGing */
+
+#define GRUB_CR0_X86_NE0x0020 /* Numeric Error enable 
(EX16 vs IRQ13) */
+#define GRUB_CR0_X86_WP0x0001 /* Write Protect */
+#define GRUB_CR0_X86_AM0x0004 /* Alignment Mask */
+#define GRUB_CR0_X86_NW0x2000 /* Not Write-through */
+#define GRUB_CR0_X86_CD0x4000 /* Cache Disable */
+
+#define GRUB_CR4_X86_VME   0x0001 /* Virtual 8086 mode extensions */
+#define GRUB_CR4_X86_PVI   0x0002 /* Protected-mode virtual interrupts 
*/
+#define GRUB_CR4_X86_TSD   0x0004 /* Time stamp disable */
+#define GRUB_CR4_X86_DE0x0008 /* Debugging extensions */
+#define GRUB_CR4_X86_PSE   0x0010 /* Page size extensions */
+#define GRUB_CR4_X86_PAE   0x0020 /* Physical address extension */
+#define GRUB_CR4_X86_MCE   0x0040 /* Enable Machine check enable */
+#define GRUB_CR4_X86_PGE   0x0080 /* Enable Page global */
+#define GRUB_CR4_X86_PCE   0x0100 /* Enable Performance monitoring 
counter */
+#define GRUB_CR4_X86_FXSR  0x0200 /* Fast FPU save/restore */
+#define GRUB_CR4_X86_XMM   0x0400 /* Enable SIMD/MMX2 to use except 16 
*/
+#define GRUB_CR4_X86_VMXE  0x2000 /* Enable VMX */
+#define GRUB_CR4_X86_SMXE  0x4000 /* Enable SMX */
+#define GRUB_CR4_X86_PCIDE 0x0002 /* Enable PCID */
+
+static inline unsigned long
+grub_read_cr4 (void)
+{
+  unsigned long val;
+
+  asm volatile ("mov %%cr4, %0" : "=r" (val) : : "memory");
+
+  return val;
+}
+
+static inline void
+grub_write_cr4 (unsigned long val)
+{
+  asm volatile ("mov %0, %%cr4" : : "r" (val) : "memory");
+}
+
+#define GRUB_CR0   0
+#define GRUB_CR1   1
+#define GRUB_CR2   2
+#define GRUB_CR3   3
+#define GRUB_CR4   4
+
+#ifdef __x86_64__
+#define read_cr(r, d) asm volatile ("movq %%cr" r ", %0" : "=r" (d))
+#else
+#define read_cr(r, d) asm volatile ("movl %%cr" r ", %0" : "=r" (d))
+#endif
+
+static inline unsigned long
+grub_read_control_register(grub_uint8_t reg)
+{
+  unsigned long data;
+
+  switch (reg)
+  {
+  case GRUB_CR0:
+read_cr("0", data);
+break;
+  case GRUB_CR1:
+read_cr("1", data);
+break;
+  case GRUB_CR2:
+read_cr("2", data);
+break;
+  case GRUB_CR3:
+read_cr("3", data);
+break;
+  case GRUB_CR4:
+read_cr("4", data);
+break;
+  default:
+/* TODO: Loudly complain if 

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

2020-05-04 Thread Daniel Kiper
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 
---
 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 81bc49f84..7eeac6019 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -223,8 +223,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;
@@ -261,7 +264,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)
@@ -275,6 +278,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 8b2a0f1f5..83d958f99 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.11.0


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


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

2020-05-04 Thread Daniel Kiper
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 
---
 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 ac1fae72e..952eb1191 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)
 {
@@ -579,6 +660,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)
@@ -790,7 +874,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 ce30e7fb0..6aea73ddb 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 setup_sects;/* The size of the setup in sectors */
@@ 

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

2020-05-04 Thread Daniel Kiper
It will be used by Intel TXT secure launcher introduced
by subsequent patches.

Signed-off-by: Daniel Kiper 
---
 grub-core/commands/i386/tpm.c | 182 ++
 include/grub/i386/tpm.h   |  36 +
 2 files changed, 218 insertions(+)
 create mode 100644 grub-core/commands/i386/tpm.c
 create mode 100644 include/grub/i386/tpm.h

diff --git a/grub-core/commands/i386/tpm.c b/grub-core/commands/i386/tpm.c
new file mode 100644
index 0..ff29c2e85
--- /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 + 
TPM_INTF_CAPABILITY));
+
+  if (intf_cap.interface_version == 

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

2020-05-04 Thread Daniel Kiper
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 
---
 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 7a137a72a..eaca03283 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 3a708ed72..81bc49f84 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -222,9 +222,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;
@@ -233,13 +233,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_malloc ((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;
 
@@ -250,14 +251,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);
@@ -265,12 +266,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 be446f8d2..7fe0cdabf 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 e90e00dc4..8b2a0f1f5 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,
+  const grub_efi_guid_t 
*guid,
+   

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

2020-05-04 Thread Daniel Kiper
From: Ross Philipson 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
---
 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 0..8280e461e
--- /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_uint32_t extended_id;
+} 

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

2020-05-04 Thread Daniel Kiper
The functions calculate lowest and highest available RAM
addresses respectively.

Both functions are needed to calculate PMR boundaries for
Intel TXT secure launcher introduced by subsequent patches.

Signed-off-by: Daniel Kiper 
---
 grub-core/mmap/mmap.c | 64 +++
 include/grub/memory.h |  3 +++
 2 files changed, 67 insertions(+)

diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
index b569cb23b..cf4b69f56 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 6da114a1b..8f22f7525 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.11.0


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


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

2020-05-04 Thread Daniel Kiper
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 
---
 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 764098cfc..d8f52d721 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 937058d68..e634afd61 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
@@ -1690,6 +1695,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.11.0


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


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

2020-05-04 Thread Daniel Kiper
It does not make sense to have separate headers for separate static
functions. Additionally, we have to add some constants with MSR addresses
in subsequent patches. So, make one common place to store them.

Signed-off-by: Daniel Kiper 
---
 grub-core/commands/i386/rdmsr.c  |  2 +-
 grub-core/commands/i386/wrmsr.c  |  2 +-
 include/grub/i386/{wrmsr.h => msr.h} | 16 +---
 include/grub/i386/rdmsr.h| 37 
 4 files changed, 15 insertions(+), 42 deletions(-)
 rename include/grub/i386/{wrmsr.h => msr.h} (78%)
 delete mode 100644 include/grub/i386/rdmsr.h

diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c
index 46c4346da..fa4622f9e 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 fa76f5aed..9b7abba7c 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 dea60aed1..7b52b5d61 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 c0a0c717a..0
--- 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.11.0


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


[GRUB PATCH RFC 03/18] i386/msr: Extract and improve MSR support detection code

2020-05-04 Thread Daniel Kiper
Currently rdmsr and wrmsr commands have own MSR support detection code.
This code is the same. So, it is duplicated. Additionally, this code
cannot be reused by others. Hence, extract this code to a function and
make it public. By the way, improve a code a bit.

Additionally, use GRUB_ERR_BAD_DEVICE instead of GRUB_ERR_BUG to signal
an error because errors encountered by this new routine are not bugs.

Signed-off-by: Daniel Kiper 
---
 grub-core/commands/i386/rdmsr.c | 21 +
 grub-core/commands/i386/wrmsr.c | 21 +
 include/grub/i386/msr.h | 29 +
 3 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c
index 89ece7657..2e42f6197 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 e3e9f2ee3..d14bb3176 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 4fba1b8e0..1e838c022 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.11.0


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


[GRUB PATCH RFC 00/18] i386: Intel TXT secure launcher

2020-05-04 Thread Daniel Kiper
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


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


[GRUB PATCH RFC 05/18] i386/memory: Rename PAGE_SIZE to GRUB_PAGE_SIZE and make it global

2020-05-04 Thread Daniel Kiper
Subsequent patches will use that constant.

Signed-off-by: Daniel Kiper 
---
 grub-core/loader/i386/xen.c | 35 +--
 include/grub/i386/memory.h  |  1 +
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
index fe92874e0..dfdddfeed 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -91,8 +91,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)
@@ -228,7 +227,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--)
 {
@@ -323,7 +322,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,
@@ -379,9 +378,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,
@@ -430,9 +429,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;
@@ -537,7 +536,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);
@@ -675,7 +674,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;
@@ -698,10 +697,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);
 
   err = grub_relocator_alloc_chunk_addr (xen_state.relocator, , kern_start,
 kern_end - kern_start);
@@ -722,7 +721,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 -
@@ -821,7 +820,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
  

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

2020-05-04 Thread Daniel Kiper
..to avoid naming collision with TPM TIS and CRB driver introduced
by subsequent patch.

Signed-off-by: Daniel Kiper 
---
 docs/grub.texi   | 15 ---
 grub-core/Makefile.core.def  |  4 ++--
 grub-core/commands/{tpm.c => tpm_verifier.c} |  6 +++---
 3 files changed, 13 insertions(+), 12 deletions(-)
 rename grub-core/commands/{tpm.c => tpm_verifier.c} (96%)

diff --git a/docs/grub.texi b/docs/grub.texi
index d6408d242..395431bce 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5940,10 +5940,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
@@ -5968,9 +5968,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 48b82e763..b74a34f0c 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 = x86_64_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 1441c494d..6fff17720 100644
--- a/grub-core/commands/tpm.c
+++ b/grub-core/commands/tpm_verifier.c
@@ -85,18 +85,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.11.0


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


[GRUB PATCH RFC 02/18] i386/msr: Rename grub_msr_read() and grub_msr_write()

2020-05-04 Thread Daniel Kiper
.. to grub_rdmsr() and grub_wrmsr() respectively. New names are more
obvious than older ones.

Signed-off-by: Daniel Kiper 
---
 grub-core/commands/i386/rdmsr.c | 2 +-
 grub-core/commands/i386/wrmsr.c | 2 +-
 include/grub/i386/msr.h | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c
index fa4622f9e..89ece7657 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 9b7abba7c..e3e9f2ee3 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 7b52b5d61..4fba1b8e0 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.11.0


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


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

2020-05-04 Thread Daniel Kiper
From: Ross Philipson 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
---
 grub-core/loader/i386/txt/acmod.c | 575 ++
 1 file changed, 575 insertions(+)
 create mode 100644 grub-core/loader/i386/txt/acmod.c

diff --git a/grub-core/loader/i386/txt/acmod.c 
b/grub-core/loader/i386/txt/acmod.c
new file mode 100644
index 0..ed2fbab7b
--- /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 17/18] i386/txt: Add Intel TXT verification routines

2020-05-04 Thread Daniel Kiper
From: Ross Philipson 

Signed-off-by: Ross Philipson 
Signed-off-by: Daniel Kiper 
---
 grub-core/loader/i386/txt/verify.c | 297 +
 1 file changed, 297 insertions(+)
 create mode 100644 grub-core/loader/i386/txt/verify.c

diff --git a/grub-core/loader/i386/txt/verify.c 
b/grub-core/loader/i386/txt/verify.c
new file mode 100644
index 0..97f3b325d
--- /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_txt_heap_ext_data_element *elt)
+{

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

2020-05-04 Thread Daniel Kiper
..to avoid potential conflicts and confusion.

Signed-off-by: Daniel Kiper 
---
 grub-core/lib/i386/xen/relocator.S   |  6 +++---
 grub-core/lib/x86_64/xen/relocator.S |  4 ++--
 grub-core/loader/i386/xen.c  | 28 ++--
 include/grub/i386/memory.h   |  2 +-
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/grub-core/lib/i386/xen/relocator.S 
b/grub-core/lib/i386/xen/relocator.S
index 96e51b59a..dab4d8ace 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 f5364ed0f..852cd40aa 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 8f662c8ac..fe92874e0 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -91,7 +91,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)
@@ -102,7 +102,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
@@ -141,7 +141,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;
@@ -246,11 +246,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);
@@ -328,16 +328,16 @@ grub_xen_p2m_alloc (void)
 {
   err = get_pgtable_size (xen_state.xen_inf.p2m_base,
  xen_state.xen_inf.p2m_base + p2msize,
- (xen_state.max_addr + p2msize) >> PAGE_SHIFT);
+ (xen_state.max_addr + p2msize) >> 
GRUB_PAGE_SHIFT);
   if (err)
return err;
 
-  map->area.pfn_start = xen_state.max_addr >> PAGE_SHIFT;
+  map->area.pfn_start = xen_state.max_addr >> GRUB_PAGE_SHIFT;
   p2malloc = p2msize + page2offset (map->area.n_pt_pages);
   xen_state.n_mappings++;
   xen_state.next_start.mfn_list = xen_state.xen_inf.p2m_base;
   xen_state.next_start.first_p2m_pfn = map->area.pfn_start;
-  xen_state.next_start.nr_p2m_frames = p2malloc >> PAGE_SHIFT;
+  

[PATCH 1/1] GRUB_SESAME support. (Take 2)

2020-05-04 Thread Stephen R. van den Berg
If set, it will keep the menu from appearing until the sesame-phrase
has been typed.  The intended usage is so that you can have two devices
both running grub/Linux, each device with a single serial port.
Connect both serial ports against each other, and the two devices will
not accidentally trigger grub to do anything, unless the sesame-phrase
will have been entered.
---
 debian/changelog |  6 ++
 docs/grub.texi   |  7 +++
 grub-core/normal/menu.c  | 35 +++
 util/grub-mkconfig.in|  1 +
 util/grub.d/00_header.in |  5 +
 5 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 0d25df0fe..f8fee9919 100644
diff --git a/docs/grub.texi b/docs/grub.texi
index f1216d19d..d9283c5b1 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1315,6 +1315,13 @@ If the timeout expires before either of these happens, 
it will boot the
 default entry.  In the @samp{countdown} case, it will show a one-line
 indication of the remaining time.
 
+@item GRUB_SESAME
+Assigning a phrase to this option will only have effect if
+@samp{GRUB_TIMEOUT_STYLE} is set to either @samp{countdown} or @samp{hidden}.
+If set, it will keep the menu from appearing until the sesame-phrase
+has been typed.  Entering the phrase needs to have been completed before
+@samp{GRUB_TIMEOUT} expires.
+
 @item GRUB_DEFAULT_BUTTON
 @itemx GRUB_TIMEOUT_BUTTON
 @itemx GRUB_TIMEOUT_STYLE_BUTTON
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 906a480a2..17087e1e2 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -580,6 +580,9 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
   int default_entry, current_entry;
   int timeout;
   enum timeout_style timeout_style;
+  const char *sesameword;
+  char *sesamebuf = 0;
+  unsigned sesamelen;
 
   default_entry = get_entry_number (menu, "default");
 
@@ -597,6 +600,17 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
 grub_env_unset ("timeout_style");
 
   timeout_style = get_timeout_style ();
+  sesameword = grub_env_get ("sesame");
+
+  if (sesameword) {
+if (!*sesameword)
+  sesameword = 0;
+else
+  {
+sesamelen = grub_strlen (sesameword);
+sesamebuf = grub_zalloc (sesamelen-- + 1);
+  }
+  }
 
   if (timeout_style == TIMEOUT_STYLE_COUNTDOWN
   || timeout_style == TIMEOUT_STYLE_HIDDEN)
@@ -652,7 +666,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
  mods |= term->getkeystatus (term);
  }
 
- if (mods >= 0 &&
+ if (mods >= 0 && !sesameword &&
  (mods & (GRUB_TERM_STATUS_LSHIFT
   | GRUB_TERM_STATUS_RSHIFT)) != 0)
{
@@ -663,9 +677,19 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
  key = grub_getkey_noblock ();
  if (key != GRUB_TERM_NO_KEY)
{
- entry = get_entry_index_by_hotkey (menu, key);
- if (entry >= 0)
-   break;
+ if (sesameword)
+   {
+ grub_memmove (sesamebuf, sesamebuf+1, sesamelen);
+ sesamebuf[sesamelen] = key;
+ key = grub_strcmp (sesamebuf, sesameword)
+ ? GRUB_TERM_NO_KEY : GRUB_TERM_ESC;
+   }
+ else
+   {
+ entry = get_entry_index_by_hotkey (menu, key);
+ if (entry >= 0)
+   break;
+   }
}
  if (key == GRUB_TERM_ESC)
{
@@ -685,8 +709,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
break;
}
 
+  if (sesamebuf)
+grub_free (sesamebuf);
   grub_env_unset ("timeout");
   grub_env_unset ("timeout_style");
+  grub_env_unset ("sesame");
   if (entry >= 0)
{
  *auto_boot = 0;
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index ad716384b..7e29680c4 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -211,6 +211,7 @@ export GRUB_DEFAULT \
   GRUB_HIDDEN_TIMEOUT_QUIET \
   GRUB_TIMEOUT \
   GRUB_TIMEOUT_STYLE \
+  GRUB_SESAME \
   GRUB_DEFAULT_BUTTON \
   GRUB_HIDDEN_TIMEOUT_BUTTON \
   GRUB_TIMEOUT_BUTTON \
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
index 674a76140..d8ec4bb77 100644
--- a/util/grub.d/00_header.in
+++ b/util/grub.d/00_header.in
@@ -328,6 +328,11 @@ fi
 
 make_timeout ()
 {
+if [ "x${GRUB_SESAME}" != "x" ] ; then
+cat << EOF
+set sesame="${GRUB_SESAME}"
+EOF
+fi
 cat << EOF
 if [ "\${recordfail}" = 1 ] ; then
   set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
-- 
2.20.1


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