Re: Running bootstrap script fails on Debian unstable

2023-02-21 Thread John Paul Adrian Glaubitz
Hi Glenn!

On Mon, 2023-02-20 at 21:29 -0600, Glenn Washburn wrote:
> It looks like the debian build log[1] for sid has the same messages, up
> to here. The package goes on to build successfully.

Yes, but the Debian build does not seem to run the bootstrap script which
is probably why the problem doesn't show there.

> > configure.ac:423: error: possibly undefined macro: AC_CHECK_HEADERS
> >   If this token and others are legitimate, please use
> > m4_pattern_allow. See the Autoconf documentation.
> > configure.ac:514: error: possibly undefined macro: AC_LINK_IFELSE
> > configure.ac:1608: error: possibly undefined macro: AC_LANG_CALL
> > autoreconf: error: /usr/bin/autoconf failed with exit status: 1
> > ./bootstrap: autoreconf failed
> 
> Do you have installed all the packages that are installed in that build
> log? Are you applying all the patches or just building from 2.06 git?

Building from git, no patches applied. Will try openSUSE Tumbelweed later today.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

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


Re: Running bootstrap script fails on Debian unstable

2023-02-21 Thread John Paul Adrian Glaubitz
Hi Glenn!

On Tue, 2023-02-21 at 10:58 +0100, John Paul Adrian Glaubitz wrote:
> > Do you have installed all the packages that are installed in that build
> > log? Are you applying all the patches or just building from 2.06 git?
> 
> Building from git, no patches applied. Will try openSUSE Tumbelweed later 
> today.

Installing the pkg-config package fixes the problem. Will be testing now.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

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


Re: [PATCH v1 2/2] Add a module for the Boot Loader Interface

2023-02-21 Thread Daniel Kiper
On Mon, Feb 20, 2023 at 08:15:35AM -0800, Oliver Steffen wrote:
> Thank you for the comments, Daniel.
>
> Quoting Daniel Kiper (2023-02-15 19:27:03)
> > On Mon, Jan 16, 2023 at 12:40:53PM +0100, Oliver Steffen wrote:
> > > Add a new module named boot_loader_interface, which provides a command
> >
> > I would prefer something shorter than boot_loader_interface. bli?
>
> Then bli it is.

Cool! Thanks!

> > > with the same name. It implements a small but quite useful part of the
> > > Boot Loader Interface [0].  This interface uses EFI variables for
> > > communication between the boot loader and the operating system.
> > >
> > > This module sets two EFI variables under the vendor GUID
> > > 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f:
> > >
> > > - LoaderInfo: contains GRUB + .
> > >   This allows the running operating system to identify the boot loader
> > >   used during boot.
> > >
> > > - LoaderDevicePartUUID: contains the partition UUID of the
> > >   EFI System Partition (ESP).  This is used by
> > >   systemd-gpt-auto-generator [1] to find the root partitions (and others
> > >   too), via partition type IDs [2].
> > >
> > > This module is only available on EFI platforms.
> > >
> > > [0] https://systemd.io/BOOT_LOADER_INTERFACE/
> > > [1] 
> > > https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html
> > > [2] 
> > > https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
> > >
> > > Signed-off-by: Oliver Steffen 
> > > ---
> > >  grub-core/Makefile.core.def|   6 +
> > >  grub-core/commands/boot_loader_interface.c | 217 +
> > >  2 files changed, 223 insertions(+)
> > >  create mode 100644 grub-core/commands/boot_loader_interface.c
> > >
> > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> > > index ba967aac8..23455fb71 100644
> > > --- a/grub-core/Makefile.core.def
> > > +++ b/grub-core/Makefile.core.def
> > > @@ -2547,3 +2547,9 @@ module = {
> > >common = commands/i386/wrmsr.c;
> > >enable = x86;
> > >  };
> > > +
> > > +module = {
> > > +  name = boot_loader_interface;
> >
> > s/boot_loader_interface/bli/?
> >
> > > +  efi = commands/boot_loader_interface.c;
> >
> > Ditto and below if needed...
> >
> > > +  enable = efi;
> > > +};
> > > diff --git a/grub-core/commands/boot_loader_interface.c 
> > > b/grub-core/commands/boot_loader_interface.c
> > > new file mode 100644
> > > index 0..ccd7fa3d9
> > > --- /dev/null
> > > +++ b/grub-core/commands/boot_loader_interface.c
> > > @@ -0,0 +1,217 @@
> > > +/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/
> >
> > Could you move this to the end of the file? Good example you can find in
> > the Xen project [1].
>
> I personally do not care about this, it was just part of the file I used
> as a template. Is this wanted, or can we just drop it?

If you do not need it please drop it.

[...]

> > > +  guid = &entry.guid;
> > > +  *part_uuid = grub_xasprintf (
> > > +  "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
> > > +  grub_le_to_cpu32 (guid->data1), grub_le_to_cpu16 (guid->data2),
> > > +  grub_le_to_cpu16 (guid->data3), guid->data4[0], guid->data4[1],
> > > +  guid->data4[2], guid->data4[3], guid->data4[4], guid->data4[5],
> > > +  guid->data4[6], guid->data4[7]);
> >
> > I think this is generic thing and can be converted into a function.
> > Similar code is in the grub-core/commands/probe.c and util/grub-probe.c.
> > It seems to me it is at least easy to make one function for the GRUB
> > core code. Please do that. Of course in separate patch.
>
> There are multiple representations of a GUID:
>  - grub_gpt_part_guid (gpt_partition.h)
>  - grub_efi_guid (efi/api.h)
>  - grub_efi_packed_guid (efi/api.h)
>
> I would add a function for the first kind to gpt_partition.h and
> partmap/gpt.c that prints into a string buffer (length checked).
>
> It would be nice to add a format specifier for GUIDs to the printf
> implementation,
> but that only makes much sense (I think) if the GUID repesentations
> could be unified into one first, in a central place.

Could you do the unification and introduce format specifier for GUIDs?

> > > +  if (!*part_uuid)
> > > +{
> > > +  status = grub_errno;
> > > +}
> >
> > Please drop redundant braces.
> >
> > > +finish:
> >
> > Labels should be prefixed with a space...
> >
> > > +  grub_disk_close (disk);
> > > +
> > > +  return status;
> > > +}
> > > +
> > > +static grub_err_t
> > > +set_efi_str_variable (const char *name, const grub_efi_guid_t *guid,
> > > +  const char *value)
> > > +{
> > > +  grub_size_t len;
> > > +  grub_size_t len16;
> >
> > grub_size_t len, len16;
> >
> > > +  grub_efi_char16_t *value_16;
> > > +  grub_err_t status;
> > > +
> > > +  len = grub_strlen (value);
> > > +  len16 = len * GRUB_MAX_UTF16_PER_UTF8;
> >
> > What will happen when len == 0?
> >
> > Is there any chance for overflow here? If yes please use overflow awa

Re: Running bootstrap script fails on Debian unstable

2023-02-21 Thread Glenn Washburn
On Tue, 21 Feb 2023 14:56:18 +0100
John Paul Adrian Glaubitz  wrote:

> Hi Glenn!
> 
> On Tue, 2023-02-21 at 10:58 +0100, John Paul Adrian Glaubitz wrote:
> > > Do you have installed all the packages that are installed in that
> > > build log? Are you applying all the patches or just building from
> > > 2.06 git?
> > 
> > Building from git, no patches applied. Will try openSUSE Tumbelweed
> > later today.
> 
> Installing the pkg-config package fixes the problem. Will be testing
> now.

So sounds like the debian schroot doesn't add pkg-config by default.
I've checked and pkg-config is mentioned as required in the build
documentation. Is there something more you think we can do to avoid
this type of problem for others in the future?

Looking at bootstrap.conf it looks like it might be good to add a line
to the $buildreq variable with "pkg-config -". Would you recreate your
schroot which causes the failure (ie no pkg-config), then modify
bootstrap.conf and see if it fails with the messages "Error:
'pkg-config' not found" and "Please install the prerequisite programs"?
And then install pkg-config and verify that the bulid works as expected?

If all that works, could you send a patch to the list? (I can do it
also if you wish and add you as tested-by). I think this should prevent
this confusion in the future.

Glenn

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


[PATCH] efi: Allow expression as func argument to efi_call_* macros on all platforms

2023-02-21 Thread Glenn Washburn
On EFI platforms where EFI calls do not require a wrapper (notably i386-efi
and arm64-efi), the func argument needs to be wrapped in parenthesis to
allow valid syntax when func is an expression which evaluates to a function
pointer. On EFI platforms that do need a wrapper, this was never an issue
because func is passed to the C function wrapper as an argument and thus
does not need parenthesis to be evaluated.

Signed-off-by: Glenn Washburn 
---
This is not needed by the current GRUB code base. However, it is needed by
some local modifications I've made. Regardless, I think this makes the official
source better.

Glenn
---
 include/grub/efi/api.h | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index ad2680341b..b4c4646651 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1799,15 +1799,15 @@ typedef struct initrd_media_device_path 
initrd_media_device_path_t;
   || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
   || defined(__riscv)
 
-#define efi_call_0(func)   func()
-#define efi_call_1(func, a)func(a)
-#define efi_call_2(func, a, b) func(a, b)
-#define efi_call_3(func, a, b, c)  func(a, b, c)
-#define efi_call_4(func, a, b, c, d)   func(a, b, c, d)
-#define efi_call_5(func, a, b, c, d, e)func(a, b, c, d, e)
-#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f)
-#define efi_call_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g)
-#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j)func(a, b, c, 
d, e, f, g, h, i, j)
+#define efi_call_0(func)   (func)()
+#define efi_call_1(func, a)(func)(a)
+#define efi_call_2(func, a, b) (func)(a, b)
+#define efi_call_3(func, a, b, c)  (func)(a, b, c)
+#define efi_call_4(func, a, b, c, d)   (func)(a, b, c, d)
+#define efi_call_5(func, a, b, c, d, e)(func)(a, b, c, d, e)
+#define efi_call_6(func, a, b, c, d, e, f) (func)(a, b, c, d, e, f)
+#define efi_call_7(func, a, b, c, d, e, f, g) (func)(a, b, c, d, e, f, g)
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j)(func)(a, b, c, 
d, e, f, g, h, i, j)
 
 #else
 
-- 
2.34.1


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


[PATCH 0/3] GDB script fixes

2023-02-21 Thread Glenn Washburn
This series is the first 3 patches of the previous series "GDB script fixes
and improvements", which I think it better to break into separate logical
series. These are (most of) the fixes from that that series that stand alone.

Glenn

Glenn Washburn (3):
  gdb: Fix redirection issue in dump_module_sections
  gdb: Prevent wrapping when writing to .segments.tmp
  gdb: If no modules have been loaded, do not try to load module symbols

 grub-core/gdb_grub.in | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

-- 
2.34.1


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


[PATCH 2/3] gdb: Prevent wrapping when writing to .segments.tmp

2023-02-21 Thread Glenn Washburn
GDB logging is redirected to write .segments.tmp, which means that GDB
will wrap lines longer than what it thinks is the screen width
(typically 80 characters). When wrapping does occur it causes gmodule.pl
to misbehave. So disable line wrapping by using GDB's "with" command so
that its guaranteed to return the width to the previous value upon
command completion.

Also disable command tracing when dumping the module sections because
that output will go to .segments.tmp and thus cause gmodule.pl to
misbehave.

Signed-off-by: Glenn Washburn 
---
 grub-core/gdb_grub.in | 4 
 1 file changed, 4 insertions(+)

diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in
index 4e45ad5622..edb5a8872c 100644
--- a/grub-core/gdb_grub.in
+++ b/grub-core/gdb_grub.in
@@ -22,6 +22,10 @@ define dump_module_sections_helper
 end
 
 define dump_module_sections
+   # Set unlimited width so that lines don't get wrapped writing
+   # to .segments.tmp
+   with width 0 -- \
+   with trace-commands off -- \
pipe dump_module_sections_helper $arg0 | sh -c 'cat >>.segments.tmp'
 end
 document dump_module_sections
-- 
2.34.1


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


[PATCH 1/3] gdb: Fix redirection issue in dump_module_sections

2023-02-21 Thread Glenn Washburn
An error in any GDB command causes it to immediately abort with an error,
this includes any command that calls that command. This leads to an issue
in dump_module_sections where an error causes the command to exit without
turning off file redirection. The user then ends up with a GDB command
line where commands output nothing to the console.

Instead do the work of dump_module_sections in the command
dump_module_sections_helper and run the command using GDB's pipe command
which does the redirection and undoes the redirection when it finishes
regardless of any errors in the command.

Also, remove .segments.tmp file prior to loading modules in case one was
left from a previous run.

Signed-off-by: Glenn Washburn 
---
 grub-core/gdb_grub.in | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in
index e322d3dc10..4e45ad5622 100644
--- a/grub-core/gdb_grub.in
+++ b/grub-core/gdb_grub.in
@@ -10,15 +10,8 @@
 ###
 
 # Add section numbers and addresses to .segments.tmp
-define dump_module_sections
+define dump_module_sections_helper
set $mod = $arg0
-
-   # FIXME: save logging status
-   set logging file .segments.tmp
-   set logging redirect on
-   set logging overwrite off
-   set logging on
-
printf "%s", $mod->name
set $segment = $mod->segment
while ($segment)
@@ -26,9 +19,10 @@ define dump_module_sections
set $segment = $segment->next
end
printf "\n"
+end
 
-   set logging off
-   # FIXME: restore logging status
+define dump_module_sections
+   pipe dump_module_sections_helper $arg0 | sh -c 'cat >>.segments.tmp'
 end
 document dump_module_sections
Gather information about module whose mod structure was
@@ -59,6 +53,7 @@ document load_module
 end
 
 define load_all_modules
+   shell rm -f .segments.tmp
set $this = grub_dl_head
while ($this != 0)
dump_module_sections $this
-- 
2.34.1


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


[PATCH 3/3] gdb: If no modules have been loaded, do not try to load module symbols

2023-02-21 Thread Glenn Washburn
This prevents load_all_modules from failing when called before any
modules have been loaded. Failures in GDB user-defined functions cause
any function which called them to also fail.

Signed-off-by: Glenn Washburn 
---
 grub-core/gdb_grub.in | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in
index edb5a8872c..fc17e3d899 100644
--- a/grub-core/gdb_grub.in
+++ b/grub-core/gdb_grub.in
@@ -63,7 +63,9 @@ define load_all_modules
dump_module_sections $this
set $this = $this->next
end
-   match_and_load_symbols
+   if (grub_dl_head != 0)
+   match_and_load_symbols
+   end
 end
 document load_all_modules
Load debugging information for all loaded modules.
-- 
2.34.1


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


Re: [v7 PATCH 2/3] efi: Remove arch specific image headers for RISC-V & ARM64

2023-02-21 Thread Atish Patra
On Tue, Feb 14, 2023 at 4:41 AM Daniel Kiper  wrote:
>
> On Thu, Feb 09, 2023 at 04:27:11PM -0800, Atish Patra wrote:
> > On Thu, Feb 2, 2023 at 12:12 PM Daniel Kiper  
> > wrote:
> > >
> > > On Fri, Jan 20, 2023 at 05:17:13PM -0800, Atish Patra wrote:
> > > > The arch specific image header details are not very useful as
> > > > most of the grub just looks at the PE/COFF spec parameters (PE32 magic
> > > > and header offset).
> > > >
> > > > Remove the arch specific images headers and define a generic
> > > > arch headers that provide enough PE/COFF fields for grub to parse kernel
> > > > images correctly.
> > > >
> > > > Signed-off-by: Atish Patra 
> > > > ---
> > > >  grub-core/commands/file.c |  8 +++---
> > > >  grub-core/loader/arm64/xen_boot.c |  3 +-
> > > >  grub-core/loader/efi/linux.c  |  1 -
> > > >  include/grub/arm64/linux.h| 48 ---
> > > >  include/grub/efi/efi.h| 11 ++-
> > > >  include/grub/riscv32/linux.h  | 41 --
> > > >  include/grub/riscv64/linux.h  | 43 ---
> > > >  7 files changed, 15 insertions(+), 140 deletions(-)
> > > >  delete mode 100644 include/grub/arm64/linux.h
> > > >  delete mode 100644 include/grub/riscv32/linux.h
> > > >  delete mode 100644 include/grub/riscv64/linux.h
> > >
> > > Sadly this patch broke normal ARM builds. I had to apply following fix...
> >
> > Sorry for breaking the ARM build. Can you share your build steps ?
> > I tried a few different build configurations (no modules, a bunch of
> > random modules that I built for RISC-V). Everything seems to build
> > fine
> > when cross compiling for ARM.
> >
> > FWIW, here is my configuration command line
> > ./configure --target=arm-linux-gnueabi --with-platform=efi
>
> At least this build is broken:
>   ./configure --target=arm-linux-gnueabihf --with-platform=coreboot ...
>

Ahh. I did not test that option earlier. Thanks!

> > > diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c
> > > index 9ba0e5eca..db9fdc5f2 100644
> > > --- a/grub-core/commands/file.c
> > > +++ b/grub-core/commands/file.c
> > > @@ -391,7 +391,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, 
> > > char **args)
> > >}
> > >  case IS_ARM_LINUX:
> > >{
> > > -   struct linux_arm_kernel_header lh;
> > > +   struct linux_arch_kernel_header lh;
> > >
> > > if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
> > >   break;
> > > diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
> > > index f00b538eb..19ddedbc2 100644
> > > --- a/grub-core/loader/arm/linux.c
> > > +++ b/grub-core/loader/arm/linux.c
> > > @@ -26,6 +26,7 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -304,7 +305,7 @@ linux_boot (void)
> > >  static grub_err_t
> > >  linux_load (const char *filename, grub_file_t file)
> > >  {
> > > -  struct linux_arm_kernel_header *lh;
> > > +  struct linux_arch_kernel_header *lh;
> > >int size;
> > >
> > >size = grub_file_size (file);
> > > diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
> > > index f38e695b1..5b8fb14e0 100644
> > > --- a/include/grub/arm/linux.h
> > > +++ b/include/grub/arm/linux.h
> > > @@ -24,26 +24,6 @@
> > >
> > >  #include 
> > >
> > > -#define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
> > > -
> > > -struct linux_arm_kernel_header {
> > > -  grub_uint32_t code0;
> > > -  grub_uint32_t reserved1[8];
> > > -  grub_uint32_t magic;
> > > -  grub_uint32_t start; /* _start */
> > > -  grub_uint32_t end;   /* _edata */
> > > -  grub_uint32_t reserved2[3];
> > > -  grub_uint32_t hdr_offset;
> > > -#if defined GRUB_MACHINE_EFI
> > > -  struct grub_pe_image_header pe_image_header;
> > > -#endif
> > > -};
> > > -
> > > -#if defined(__arm__)
> > > -# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
> > > -# define linux_arch_kernel_header linux_arm_kernel_header
> > > -#endif
> > > -
> > >  #if defined GRUB_MACHINE_UBOOT
> > >  # include 
> > >  # define LINUX_ADDRESS(start_of_ram + 0x8000)
> > > diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
> > > index b9e7f6724..329c4f9b2 100644
> > > --- a/include/grub/efi/efi.h
> > > +++ b/include/grub/efi/efi.h
> > > @@ -25,13 +25,15 @@
> > >  #include 
> > >  #include 
> > >
> > > +#define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
> > > +
> > >  struct linux_arch_kernel_header {
> > > -   grub_uint32_t code0;
> > > -   grub_uint32_t code1;
> > > -   grub_uint64_t reserved[6];
> > > -   grub_uint32_t reserved1;
> > > -   grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
> > > -   struct grub_pe_image_header pe_image_header;
> > > +  grub_uint32_t code0;
> > > +  grub_uint32_t code1;
> > > +  grub_uint64_t reserved[6];
> > > +  grub_uint32_t magic;
> > > +  grub_uint32_t hdr_offset; /* Offset of PE/COFF h

[PATCH 03/14] protectors: Add TPM2 Key Protector

2023-02-21 Thread Gary Lin via Grub-devel
From: Hernan Gatta 

The TPM2 key protector is a module that enables the automatic retrieval of a
fully-encrypted disk's unlocking key from a TPM 2.0.

The theory of operation is such that the module accepts various arguments, most
of which are optional and therefore possess reasonable defaults. One of these
arguments is the keyfile parameter, which is mandatory.

The value of this parameter must be a path to a sealed key file (e.g.,
(hd0,gpt1)/boot/grub2/sealed_key). This sealed key file is created via the
grub-protect tool. The tool utilizes the TPM's sealing functionality to seal
(i.e., encrypt) an unlocking key using a Storage Root Key (SRK) to the values of
various Platform Configuration Registers (PCRs). These PCRs reflect the state of
the system as it boots. If the values are as expected, the system may be
considered trustworthy, at which point the TPM allows for a caller to utilize
the private component of the SRK to unseal (i.e., decrypt) the sealed key file.
The caller, in this case, is this key protector.

The TPM2 key protector registers two commands:

- tpm2_key_protector_init: Initializes the state of the TPM2 key protector for
   later usage, clearing any previous state, too, if
   any.

- tpm2_key_protector_clear: Clears any state set by tpm2_key_protector_init.

The way this is expected to be used requires the user to, either interactively
or, normally, via a boot script, initialize (i.e., configure) the key protector
and then specify that it be used by the cryptomount command (modifications to
this command are in a different patch).

For instance:

tpm2_key_protector_init --keyfile=KEYFILE1
cryptomount DISK1 -k tpm2

tpm2_key_protector_init --keyfile=KEYFILE2 --pcrs=7,11
cryptomount DISK2 -k tpm2

If a user does not initialize the key protector and attempts to use it anyway,
the protector returns an error.

Signed-off-by: Hernan Gatta 
Signed-off-by: Gary Lin 
---
 grub-core/Makefile.core.def   |  11 +
 grub-core/tpm2/args.c | 129 ++
 grub-core/tpm2/module.c   | 710 ++
 include/grub/tpm2/internal/args.h |  39 ++
 4 files changed, 889 insertions(+)
 create mode 100644 grub-core/tpm2/args.c
 create mode 100644 grub-core/tpm2/module.c
 create mode 100644 include/grub/tpm2/internal/args.h

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index f301b4617..3cfc3b93c 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2518,6 +2518,17 @@ module = {
   enable = efi;
 };
 
+module = {
+  name = tpm2;
+  common = tpm2/args.c;
+  common = tpm2/buffer.c;
+  common = tpm2/module.c;
+  common = tpm2/mu.c;
+  common = tpm2/tpm2.c;
+  efi = tpm2/tcg2.c;
+  enable = efi;
+};
+
 module = {
   name = tr;
   common = commands/tr.c;
diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c
new file mode 100644
index 0..49011b377
--- /dev/null
+++ b/grub-core/tpm2/args.c
@@ -0,0 +1,129 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *
+ *  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 
+
+grub_err_t
+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
+   grub_uint8_t *pcr_count)
+{
+  char *current_pcr = value;
+  char *next_pcr;
+  unsigned long pcr;
+  grub_uint8_t i;
+
+  if (grub_strlen (value) == 0)
+return GRUB_ERR_BAD_ARGUMENT;
+
+  *pcr_count = 0;
+  for (i = 0; i < TPM_MAX_PCRS; i++)
+{
+  next_pcr = grub_strchr (current_pcr, ',');
+  if (next_pcr == current_pcr)
+   return grub_error (GRUB_ERR_BAD_ARGUMENT,
+  N_("Empty entry in PCR list"));
+  if (next_pcr)
+   *next_pcr = '\0';
+
+  grub_errno = GRUB_ERR_NONE;
+  pcr = grub_strtoul (current_pcr, NULL, 10);
+  if (grub_errno != GRUB_ERR_NONE)
+   return grub_error (grub_errno,
+  N_("Entry '%s' in PCR list is not a number"),
+  current_pcr);
+
+  if (pcr > TPM_MAX_PCRS)
+   return grub_error (GRUB_ERR_OUT_OF_RANGE,
+  N_("Entry %lu in PCR list is too large to be a PCR "
+ "number, PCR numbers range from 0 to %u"),
+  pcr, TPM_MAX_PCRS);
+
+  pcrs[i] = (grub_uint8_t)pcr;
+  

[PATCH 01/14] protectors: Add key protectors framework

2023-02-21 Thread Gary Lin via Grub-devel
From: Hernan Gatta 

A key protector encapsulates functionality to retrieve an unlocking key for a
fully-encrypted disk from a specific source. A key protector module registers
itself with the key protectors framework when it is loaded and unregisters when
unloaded. Additionally, a key protector may accept parameters that describe how
it should operate.

The key protectors framework, besides offering registration and unregistration
functions, also offers a one-stop routine for finding and invoking a key
protector by name. If a key protector with the specified name exists and if an
unlocking key is successfully retrieved by it, the function returns to the
caller the retrieved key and its length.

Signed-off-by: Hernan Gatta 
Signed-off-by: Gary Lin 
---
 grub-core/Makefile.am   |  1 +
 grub-core/Makefile.core.def |  1 +
 grub-core/kern/protectors.c | 75 +
 include/grub/protector.h| 48 
 4 files changed, 125 insertions(+)
 create mode 100644 grub-core/kern/protectors.c
 create mode 100644 include/grub/protector.h

diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index 80e7a83ed..79d17a3d2 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -90,6 +90,7 @@ endif
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/protector.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 71093a100..f301b4617 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -144,6 +144,7 @@ kernel = {
   common = kern/misc.c;
   common = kern/parser.c;
   common = kern/partition.c;
+  common = kern/protectors.c;
   common = kern/rescue_parser.c;
   common = kern/rescue_reader.c;
   common = kern/term.c;
diff --git a/grub-core/kern/protectors.c b/grub-core/kern/protectors.c
new file mode 100644
index 0..934f831cd
--- /dev/null
+++ b/grub-core/kern/protectors.c
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *
+ *  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 
+
+struct grub_key_protector *grub_key_protectors = NULL;
+
+grub_err_t
+grub_key_protector_register (struct grub_key_protector *protector)
+{
+  if (!protector || !protector->name || !grub_strlen(protector->name))
+return GRUB_ERR_BAD_ARGUMENT;
+
+  if (grub_key_protectors &&
+  grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
+   protector->name))
+return GRUB_ERR_BAD_ARGUMENT;
+
+  grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors),
+ GRUB_AS_LIST (protector));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_key_protector_unregister (struct grub_key_protector *protector)
+{
+  if (!protector)
+return GRUB_ERR_BAD_ARGUMENT;
+
+  grub_list_remove (GRUB_AS_LIST (protector));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
+   grub_size_t *key_size)
+{
+  struct grub_key_protector *kp = NULL;
+
+  if (!grub_key_protectors)
+return GRUB_ERR_OUT_OF_RANGE;
+
+  if (!protector || !grub_strlen (protector))
+return GRUB_ERR_BAD_ARGUMENT;
+
+  kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
+protector);
+  if (!kp)
+return grub_error (GRUB_ERR_OUT_OF_RANGE,
+  N_("A key protector with name '%s' could not be found. "
+ "Is the name spelled correctly and is the "
+ "corresponding module loaded?"), protector);
+
+  return kp->recover_key (key, key_size);
+}
diff --git a/include/grub/protector.h b/include/grub/protector.h
new file mode 100644
index 0..3d9f69bce
--- /dev/null
+++ b/include/grub/protector.h
@@ -0,0 +1,48 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under

[PATCH 06/14] crytodisk: fix cryptodisk module looking up

2023-02-21 Thread Gary Lin via Grub-devel
From: Michael Chang 

The error "no cryptodisk module can handle this device" may happen even
encrypted disk were correctly formatted and required modules were loaded.

It is casued by missing break to the loop in which cryptodisk modules are
iterated to find the one matching target's disk format. With the break
statement, the loop will be always ended with testing last cryptodisk module on
the list that may not be able to handle the format of encrypted disk's.

Signed-off-by: Michael Chang 
---
 grub-core/disk/cryptodisk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index c990d5985..e199f550f 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -1119,6 +1119,7 @@ grub_cryptodisk_scan_device_real (const char *name,
 if (!dev)
   continue;
 crd = cr;
+break;
   }
 
   if (!dev)
-- 
2.35.3


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


[PATCH 02/14] tpm2: Add TPM Software Stack (TSS)

2023-02-21 Thread Gary Lin via Grub-devel
From: Hernan Gatta 

A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to compose,
submit, and parse TPM commands and responses.

A limited number of TPM commands may be accessed via the EFI TCG2 protocol. This
protocol exposes functionality that is primarily geared toward TPM usage within
the context of Secure Boot. For all other TPM commands, however, such as sealing
and unsealing, this protocol does not provide any help, with the exception of
passthrough command submission.

The SubmitCommand method allows a caller to send raw commands to the system's
TPM and to receive the corresponding response. These command/response pairs are
formatted using the TPM wire protocol. To construct commands in this way, and to
parse the TPM's response, it is necessary to, first, possess knowledge of the
various TPM structures, and, two, of the TPM wire protocol itself.

As such, this patch includes a set of header files that define the necessary TPM
structures and TSS functions, implementations of various TPM2_* functions
(inventoried below), and logic to write and read command and response buffers,
respectively, using the TPM wire protocol.

Functions: TPM2_Create, TPM2_CreatePrimary, TPM2_EvictControl,
TPM2_FlushContext, TPM2_Load, TPM2_PCR_Read, TPM2_PolicyGetDigest,
TPM2_PolicyPCR, TPM2_ReadPublic, TPM2_StartAuthSession, TPM2_Unseal.

Signed-off-by: Hernan Gatta 
Signed-off-by: Gary Lin 
---
 grub-core/tpm2/buffer.c| 145 +
 grub-core/tpm2/mu.c| 807 +
 grub-core/tpm2/tcg2.c  | 143 +
 grub-core/tpm2/tpm2.c  | 711 ++
 include/grub/tpm2/buffer.h |  65 ++
 include/grub/tpm2/internal/functions.h | 117 
 include/grub/tpm2/internal/structs.h   | 675 +
 include/grub/tpm2/internal/types.h | 372 
 include/grub/tpm2/mu.h | 292 +
 include/grub/tpm2/tcg2.h   |  34 ++
 include/grub/tpm2/tpm2.h   |  38 ++
 11 files changed, 3399 insertions(+)
 create mode 100644 grub-core/tpm2/buffer.c
 create mode 100644 grub-core/tpm2/mu.c
 create mode 100644 grub-core/tpm2/tcg2.c
 create mode 100644 grub-core/tpm2/tpm2.c
 create mode 100644 include/grub/tpm2/buffer.h
 create mode 100644 include/grub/tpm2/internal/functions.h
 create mode 100644 include/grub/tpm2/internal/structs.h
 create mode 100644 include/grub/tpm2/internal/types.h
 create mode 100644 include/grub/tpm2/mu.h
 create mode 100644 include/grub/tpm2/tcg2.h
 create mode 100644 include/grub/tpm2/tpm2.h

diff --git a/grub-core/tpm2/buffer.c b/grub-core/tpm2/buffer.c
new file mode 100644
index 0..3b340b965
--- /dev/null
+++ b/grub-core/tpm2/buffer.c
@@ -0,0 +1,145 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *
+ *  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 
+
+void grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer)
+{
+  grub_memset (buffer->data, 0xDD, sizeof (buffer->data));
+  buffer->size = 0;
+  buffer->offset = 0;
+  buffer->cap = sizeof (buffer->data);
+  buffer->error = 0;
+}
+
+void
+grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data,
+  grub_size_t size)
+{
+  grub_uint32_t r = buffer->cap - buffer->size;
+
+  if (buffer->error)
+return;
+
+  if (size > r)
+{
+  buffer->error = 1;
+  return;
+}
+
+  grub_memcpy (&buffer->data[buffer->size], (void*) data, size);
+  buffer->size += size;
+}
+
+void
+grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value)
+{
+  grub_tpm2_buffer_pack (buffer, (const char*) &value, sizeof (value));
+}
+
+void
+grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value)
+{
+  grub_uint16_t tmp = grub_swap_bytes16 (value);
+  grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp));
+}
+
+void
+grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value)
+{
+  grub_uint32_t tmp = grub_swap_bytes32 (value);
+  grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp));
+}
+
+void
+grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data,
+grub_size_t size)
+{
+  grub_uint32_t r = buffer->size - buffer->offset;
+
+  if (buffer->error)
+return;
+
+  if (size > r)
+{
+  buffer->error = 1;
+  

[PATCH 11/14] tpm2: check the command parameters of TPM2 commands

2023-02-21 Thread Gary Lin via Grub-devel
Some command parameters should not be NULL. Add the conditional check to
avoid the potential NULL pointer reference.

Besides, for TPM2_StartAuthSession, when 'tpmKey' is 'TPM_RH_NULL', the
size of 'encryptedSalt' must be 0 per "TCG TPM2 Part3 Commands".

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/tpm2.c | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index bc1d797d4..ad9d52cd4 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -127,6 +127,9 @@ TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
   TPM_RC responseCode;
   grub_uint32_t parameterSize;
 
+  if (!inSensitive || !inPublic || !outsideInfo || !creationPCR)
+return TPM_RC_VALUE;
+
   if (!objectHandle)
 objectHandle = &objectHandleTmp;
   if (!outPublic)
@@ -210,6 +213,13 @@ TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
   TPM_RC responseCode;
   grub_uint32_t param_size;
 
+  if (!nonceCaller || !symmetric)
+return TPM_RC_VALUE;
+
+  if (tpmKey == TPM_RH_NULL &&
+  (encryptedSalt && encryptedSalt->size != 0))
+return TPM_RC_VALUE;
+
   if (!sessionHandle)
 sessionHandle = &sessionHandleTmp;
   if (!nonceTpm)
@@ -272,6 +282,9 @@ TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions,
   TPM_RC responseCode;
   grub_uint32_t param_size;
 
+  if (!pcrs)
+return TPM_RC_VALUE;
+
   if (!authResponse)
 authResponse = &authResponseTmp;
 
@@ -363,6 +376,9 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle,
   TPM_RC responseCode;
   grub_uint32_t param_size;
 
+  if (!inPrivate || !inPublic)
+return TPM_RC_VALUE;
+
   if (!objectHandle)
 objectHandle = &objectHandleTmp;
   if (!name)
@@ -506,7 +522,7 @@ TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
   grub_uint32_t parameterSize;
 
   if (!pcrSelectionIn)
-return TPM_RC_FAILURE;
+return TPM_RC_VALUE;
 
   if (!pcrUpdateCounter)
 pcrUpdateCounter = &pcrUpdateCounterTmp;
@@ -625,6 +641,9 @@ TPM2_Create (const TPMI_DH_OBJECT parentHandle,
   TPM_RC rc;
   grub_uint32_t parameterSize;
 
+  if (!inSensitive || !inPublic || !outsideInfo || !creationPCR)
+return TPM_RC_VALUE;
+
   if (!outPrivate)
 outPrivate = &outPrivateTmp;
   if (!outPublic)
-- 
2.35.3


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


[PATCH 04/14] cryptodisk: Support key protectors

2023-02-21 Thread Gary Lin via Grub-devel
From: Hernan Gatta 

Add a new parameter to cryptomount to support the key protectors framework: -k.
The parameter is used to automatically retrieve a key from specified key
protectors. The parameter may be repeated to specify any number of key
protectors. These are tried in order until one provides a usable key for any
given disk.

Signed-off-by: 
Signed-off-by: Gary Lin 
---
 Makefile.util.def   |   1 +
 grub-core/disk/cryptodisk.c | 175 +---
 include/grub/cryptodisk.h   |  14 +++
 3 files changed, 157 insertions(+), 33 deletions(-)

diff --git a/Makefile.util.def b/Makefile.util.def
index beaef1168..1da5a826c 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -35,6 +35,7 @@ library = {
   common = grub-core/kern/list.c;
   common = grub-core/kern/misc.c;
   common = grub-core/kern/partition.c;
+  common = grub-core/kern/protectors.c;
   common = grub-core/lib/crypto.c;
   common = grub-core/lib/json/json.c;
   common = grub-core/disk/luks.c;
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 34b67a705..c990d5985 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef GRUB_UTIL
 #include 
@@ -44,7 +45,8 @@ enum
 OPTION_KEYFILE,
 OPTION_KEYFILE_OFFSET,
 OPTION_KEYFILE_SIZE,
-OPTION_HEADER
+OPTION_HEADER,
+OPTION_PROTECTOR
   };
 
 static const struct grub_arg_option options[] =
@@ -58,6 +60,8 @@ static const struct grub_arg_option options[] =
 {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
 {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, 
ARG_TYPE_INT},
 {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
+{"protector", 'k', GRUB_ARG_OPTION_REPEATABLE,
+ N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
 {0, 0, 0, 0, 0, 0}
   };
 
@@ -1060,7 +1064,8 @@ grub_cryptodisk_scan_device_real (const char *name,
 {
   grub_err_t ret = GRUB_ERR_NONE;
   grub_cryptodisk_t dev;
-  grub_cryptodisk_dev_t cr;
+  grub_cryptodisk_dev_t cr, crd = NULL;
+  int i;
   struct cryptodisk_read_hook_ctx read_hook_data = {0};
   int askpass = 0;
   char *part = NULL;
@@ -1113,41 +1118,112 @@ grub_cryptodisk_scan_device_real (const char *name,
   goto error_no_close;
 if (!dev)
   continue;
+crd = cr;
+  }
 
-if (!cargs->key_len)
-  {
-   /* Get the passphrase from the user, if no key data. */
-   askpass = 1;
-   part = grub_partition_get_name (source->partition);
-   grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
-source->partition != NULL ? "," : "",
-part != NULL ? part : N_("UNKNOWN"),
-dev->uuid);
-   grub_free (part);
-
-   cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
-   if (cargs->key_data == NULL)
- goto error_no_close;
-
-   if (!grub_password_get ((char *) cargs->key_data, 
GRUB_CRYPTODISK_MAX_PASSPHRASE))
- {
-   grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
-   goto error;
- }
-   cargs->key_len = grub_strlen ((char *) cargs->key_data);
-  }
+  if (!dev)
+{
+  grub_error (GRUB_ERR_BAD_MODULE,
+  "no cryptodisk module can handle this device");
+  goto error_no_close;
+}
 
-ret = cr->recover_key (source, dev, cargs);
-if (ret != GRUB_ERR_NONE)
-  goto error;
+  if (cargs->protectors)
+{
+  for (i = 0; cargs->protectors[i]; i++)
+{
+  if (cargs->key_cache[i].invalid)
+continue;
+
+  if (!cargs->key_cache[i].key)
+{
+  ret = grub_key_protector_recover_key (cargs->protectors[i],
+&cargs->key_cache[i].key,
+
&cargs->key_cache[i].key_len);
+  if (ret)
+{
+  if (grub_errno)
+{
+  grub_print_error ();
+  grub_errno = GRUB_ERR_NONE;
+}
+
+  grub_dprintf ("cryptodisk",
+"failed to recover a key from key protector "
+"%s, will not try it again for any other "
+"disks, if any, during this invocation of "
+"cryptomount\n",
+cargs->protectors[i]);
+
+  cargs->key_cache[i].invalid = 1;
+  continue;
+}
+}
+
+  cargs->key_data = cargs->key_cache[i].key;
+  cargs->key_len = cargs->key_cache[i].key_len;
+
+  ret = crd->recover_key (source, dev, cargs);
+  if (ret)
+{
+  part = grub_partition_get_name (source->part

[PATCH 05/14] util/grub-protect: Add new tool

2023-02-21 Thread Gary Lin via Grub-devel
From: Hernan Gatta 

To utilize the key protectors framework, there must be a way to protect
full-disk encryption keys in the first place. The grub-protect tool includes
support for the TPM2 key protector but other protectors that require setup ahead
of time can be supported in the future.

For the TPM2 key protector, the intended flow is for a user to have a LUKS 1 or
LUKS 2-protected fully-encrypted disk. The user then creates a new key file, say
by reading /dev/urandom into a file, and creates a new LUKS key slot for this
key. Then, the user invokes the grub-protect tool to seal this key file to a set
of PCRs using the system's TPM 2.0. The resulting sealed key file is stored in
an unencrypted partition such as the EFI System Partition (ESP) so that GRUB may
read it. The user also ensures the cryptomount command is included in GRUB's
boot script and that it carries the requisite key protector (-k) parameter.

Sample usage:

$ dd if=/dev/urandom of=key bs=1 count=32
$ sudo cryptsetup luksAddKey /dev/sdb1 key --pbkdf=pbkdf2 --hash=sha512

$ sudo grub-protect --action=add
--protector=tpm2
--tpm2-keyfile=key
--tpm2-outfile=/boot/efi/boot/grub2/sealed_key

Then, in the boot script:

tpm2_key_protector_init -k (hd0,gpt1)/boot/grub2/sealed_key
cryptomount -u b20f95d0834842bc9197bd78b36732f8 -k tpm2

where the UUID corresponds to /dev/sdb1.

Signed-off-by: Hernan Gatta 
Signed-off-by: Gary Lin 
---
 .gitignore  |1 +
 Makefile.util.def   |   18 +
 configure.ac|1 +
 util/grub-protect.c | 1314 +++
 4 files changed, 1334 insertions(+)
 create mode 100644 util/grub-protect.c

diff --git a/.gitignore b/.gitignore
index 4064d3d1e..f25f94aad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -167,6 +167,7 @@ widthspec.bin
 /grub-ofpathname.exe
 /grub-probe
 /grub-probe.exe
+/grub-protect
 /grub-reboot
 /grub-render-label
 /grub-render-label.exe
diff --git a/Makefile.util.def b/Makefile.util.def
index 1da5a826c..2e8e4891e 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -206,6 +206,24 @@ program = {
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
+program = {
+  name = grub-protect;
+
+  common = grub-core/osdep/init.c;
+  common = grub-core/tpm2/args.c;
+  common = grub-core/tpm2/buffer.c;
+  common = grub-core/tpm2/mu.c;
+  common = grub-core/tpm2/tpm2.c;
+  common = util/grub-protect.c;
+  common = util/probe.c;
+
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/lib/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
+};
+
 program = {
   name = grub-mkrelpath;
   mansection = 1;
diff --git a/configure.ac b/configure.ac
index 93626b798..e2c66df0d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,7 @@ grub_TRANSFORM([grub-mkpasswd-pbkdf2])
 grub_TRANSFORM([grub-mkrelpath])
 grub_TRANSFORM([grub-mkrescue])
 grub_TRANSFORM([grub-probe])
+grub_TRANSFORM([grub-protect])
 grub_TRANSFORM([grub-reboot])
 grub_TRANSFORM([grub-script-check])
 grub_TRANSFORM([grub-set-default])
diff --git a/util/grub-protect.c b/util/grub-protect.c
new file mode 100644
index 0..acd30642f
--- /dev/null
+++ b/util/grub-protect.c
@@ -0,0 +1,1314 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *
+ *  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 
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#include 
+#pragma GCC diagnostic error "-Wmissing-prototypes"
+#pragma GCC diagnostic error "-Wmissing-declarations"
+
+#include "progname.h"
+
+/* Unprintable option keys for argp */
+typedef enum grub_protect_opt
+{
+  /* General */
+  GRUB_PROTECT_OPT_ACTION  = 'a',
+  GRUB_PROTECT_OPT_PROTECTOR   = 'p',
+  /* TPM2 */
+  GRUB_PROTECT_OPT_TPM2_DEVICE = 0x100,
+  GRUB_PROTECT_OPT_TPM2_PCRS,
+  GRUB_PROTECT_OPT_TPM2_ASYMMETRIC,
+  GRUB_PROTECT_OPT_TPM2_BANK,
+  GRUB_PROTECT_OPT_TPM2_SRK,
+  GRUB_PROTECT_OPT_TPM2_KEYFILE,
+  GRUB_PROTECT_OPT_TPM2_OUTFILE,
+  GRUB_PROTECT_OPT_TPM2_PERSIST,
+  GRUB_PROTECT_OPT

[PATCH 12/14] tpm2: pack the missing authorization command for TPM2_PCR_Read

2023-02-21 Thread Gary Lin via Grub-devel
When the caller of TPM2_PCR_Read() passes a valid authorization command,
we should pack it into the 'in' buffer before sending the command.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/tpm2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index ad9d52cd4..470fe7fc1 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -535,6 +535,8 @@ TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
 
   /* Marshal */
   grub_tpm2_buffer_init (&in);
+  if (authCommand)
+grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
   grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn);
   if (in.error)
 return TPM_RC_FAILURE;
-- 
2.35.3


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


[PATCH 14/14] tpm2: remove the unnecessary variables

2023-02-21 Thread Gary Lin via Grub-devel
Since the NULL 'encryptedSalt' of 'TPM2_StartAuthSession' is handled as
an empty TPM2B structure, there is no need to declare an empty salt.
As for 'nonceTPM', we don't use in the following TPM2 commands, so we
can safely ignore it.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/module.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index bebdecd1c..580c1f972 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -311,9 +311,7 @@ grub_tpm2_protector_srk_recover (const struct 
grub_tpm2_protector_context *ctx,
   grub_size_t sealed_key_size;
   TPM_HANDLE srk_handle;
   TPM2B_NONCE nonceCaller = { 0 };
-  TPM2B_ENCRYPTED_SECRET salt = { 0 };
   TPMT_SYM_DEF symmetric = { 0 };
-  TPM2B_NONCE nonceTPM = { 0 };
   TPMI_SH_AUTH_SESSION session;
   TPML_PCR_SELECTION pcrSel = {
 .count = 1,
@@ -364,9 +362,9 @@ grub_tpm2_protector_srk_recover (const struct 
grub_tpm2_protector_context *ctx,
   nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
   symmetric.algorithm = TPM_ALG_NULL;
 
-  rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonceCaller, &salt,
+  rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, 
NULL,
  TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256,
- &session, &nonceTPM, 0);
+ &session, NULL, NULL);
   if (rc)
 {
   grub_error (err, N_("Failed to start auth session (TPM2_StartAuthSession 
"
-- 
2.35.3


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


[PATCH 07/14] tpm2: Don't measure the sealed key

2023-02-21 Thread Gary Lin via Grub-devel
Based on the patch from Olaf Kirch 

The sealed key is the subject to change and measuring the file into PCR9
makes the prediction of PCR9 value impossible. This commit opens the
file with GRUB_FILE_TYPE_SIGNATURE to avoid the measurement.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/module.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index c35bfabdb..bebdecd1c 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -139,7 +139,9 @@ grub_tpm2_protector_srk_read_keyfile (const char *filepath, 
void **buffer,
   void *sealed_key_buffer;
   grub_off_t sealed_key_read;
 
-  sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE);
+  /* Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into 
PCR9
+   * otherwise we'll never be able to predict the value of PCR9 at unseal time 
*/
+  sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE);
   if (!sealed_key_file)
 {
   grub_dprintf ("tpm2", "Could not open sealed key file.\n");
-- 
2.35.3


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


[PATCH 08/14] tpm2: adjust the input parameters of TPM2_EvictControl

2023-02-21 Thread Gary Lin via Grub-devel
Per "TCG TPM2 Part3 Commands", 'persistentHandle' of TPM2_EvictControl
is in the parameter area, i.e. after the authorization command. Adjust
the order of the arguments to match the spec definition.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/tpm2.c  | 2 +-
 include/grub/tpm2/internal/functions.h | 2 +-
 util/grub-protect.c| 8 
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 7baa4c6e5..85bd4ef23 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -662,8 +662,8 @@ TPM2_Create (TPMI_DH_OBJECT parentHandle,
 TPM_RC
 TPM2_EvictControl (TPMI_RH_PROVISION auth,
   TPMI_DH_OBJECT objectHandle,
-  TPMI_DH_PERSISTENT persistentHandle,
   const TPMS_AUTH_COMMAND *authCommand,
+  TPMI_DH_PERSISTENT persistentHandle,
   TPMS_AUTH_RESPONSE *authResponse)
 {
   struct grub_tpm2_buffer in;
diff --git a/include/grub/tpm2/internal/functions.h 
b/include/grub/tpm2/internal/functions.h
index 9d5823975..f88ea2dfe 100644
--- a/include/grub/tpm2/internal/functions.h
+++ b/include/grub/tpm2/internal/functions.h
@@ -110,8 +110,8 @@ TPM2_Create (TPMI_DH_OBJECT parentHandle,
 TPM_RC
 TPM2_EvictControl (TPMI_RH_PROVISION auth,
   TPMI_DH_OBJECT objectHandle,
-  TPMI_DH_PERSISTENT persistentHandle,
   const TPMS_AUTH_COMMAND *authCommand,
+  TPMI_DH_PERSISTENT persistentHandle,
   TPMS_AUTH_RESPONSE *authResponse);
 
 #endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */
diff --git a/util/grub-protect.c b/util/grub-protect.c
index acd30642f..f0f27af0a 100644
--- a/util/grub-protect.c
+++ b/util/grub-protect.c
@@ -695,8 +695,8 @@ grub_protect_tpm2_get_srk (struct grub_protect_args *args, 
TPM_HANDLE *srk)
   /* Persist SRK */
   if (args->tpm2_persist)
 {
-  rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, args->tpm2_srk,
- &authCommand, NULL);
+  rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, &authCommand,
+ args->tpm2_srk, NULL);
   if (rc == TPM_RC_SUCCESS)
{
  TPM2_FlushContext (srkHandle);
@@ -877,8 +877,8 @@ grub_protect_tpm2_remove (struct grub_protect_args *args)
   /* Evict SRK */
   authCommand.sessionHandle = TPM_RS_PW;
 
-  rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, args->tpm2_srk,
- &authCommand, NULL);
+  rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, &authCommand,
+ args->tpm2_srk, NULL);
   if (rc != TPM_RC_SUCCESS)
 {
   fprintf (stderr,
-- 
2.35.3


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


[PATCH 13/14] tpm2: allow some command parameters to be NULL

2023-02-21 Thread Gary Lin via Grub-devel
There are some parameters of TPM2 commmands allowing to be empty such
as 'encryptedSalt' of 'TPM2_StartAuthSession' and 'pcrDigest' of
'TPM2_PolicyPCR'. Instead of forcing the user of those functions to
declare an empty variable, we can just pack a u16 zero to fabricate an
empty variable when the user passes NULL for them.

This also fixes the potential crash caused by
grub_tpm2_protector_srk_recover() that invokes TPM2_PolicyPCR() with a
NULL pcrDigest.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/tpm2.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 470fe7fc1..d67699a24 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -238,7 +238,10 @@ TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
   if (tag == TPM_ST_SESSIONS)
 grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
   grub_tpm2_mu_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer);
-  grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret);
+  if (encryptedSalt)
+grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, 
encryptedSalt->secret);
+  else
+grub_tpm2_buffer_pack_u16 (&in, 0);
   grub_tpm2_buffer_pack_u8 (&in, sessionType);
   grub_tpm2_mu_TPMT_SYM_DEF_Marshal (&in, symmetric);
   grub_tpm2_buffer_pack_u16 (&in, authHash);
@@ -295,7 +298,10 @@ TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions,
   grub_tpm2_buffer_pack_u32 (&in, policySessions);
   if (tag == TPM_ST_SESSIONS)
 grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
-  grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer);
+  if (pcrDigest)
+grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer);
+  else
+grub_tpm2_buffer_pack_u16 (&in, 0);
   grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrs);
   if (in.error)
 return TPM_RC_FAILURE;
-- 
2.35.3


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


[PATCH 10/14] tpm2: resend the command on TPM_RC_RETRY

2023-02-21 Thread Gary Lin via Grub-devel
Sometimes TPM may return TPM_RC_RETRY for some reason, and the only
thing we can do is to send the command again. To avoid pending in the
while loop indefinitely, just try to send the command 3 times.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/tpm2.c | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 6c476ff31..bc1d797d4 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -25,11 +25,11 @@
 #include 
 
 static TPM_RC
-grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag,
- const TPM_CC commandCode,
- TPM_RC *responseCode,
- const struct grub_tpm2_buffer *in,
- struct grub_tpm2_buffer *out)
+grub_tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG tag,
+  const TPM_CC commandCode,
+  TPM_RC *responseCode,
+  const struct grub_tpm2_buffer *in,
+  struct grub_tpm2_buffer *out)
 {
   grub_err_t err;
   struct grub_tpm2_buffer buf;
@@ -75,6 +75,29 @@ grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag,
   return TPM_RC_SUCCESS;
 }
 
+static TPM_RC
+grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag,
+ const TPM_CC commandCode,
+ TPM_RC *responseCode,
+ const struct grub_tpm2_buffer *in,
+ struct grub_tpm2_buffer *out)
+{
+  TPM_RC err;
+  int retry_cnt = 0;
+
+  /* Catch TPM_RC_RETRY and send the command again */
+  do {
+err = grub_tpm2_submit_command_real (tag, commandCode, responseCode,
+in, out);
+if (*responseCode != TPM_RC_RETRY)
+  break;
+
+retry_cnt++;
+  } while (retry_cnt < 3);
+
+  return err;
+}
+
 TPM_RC
 TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
const TPMS_AUTH_COMMAND *authCommand,
-- 
2.35.3


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


[PATCH 09/14] tpm2: declare the input arguments of TPM2 functions as const

2023-02-21 Thread Gary Lin via Grub-devel
The arguments, except the buffer, of the marshal functions are the pure
inputs. Also, the TPM2 command parameters are supposed not changed by
the command. Declare those arguments as 'const' so that the compiler can
help to detect the undesired change on those arguments. Besides, when
looking up the TPM2 command functions, it's easier to tell which arguments
are the command parameters (the constant arguments) and which are the
response parameters.

Signed-off-by: Gary Lin 
---
 grub-core/tpm2/mu.c| 64 
 grub-core/tpm2/tpm2.c  | 68 +-
 include/grub/tpm2/internal/functions.h | 64 
 include/grub/tpm2/mu.h | 64 
 4 files changed, 130 insertions(+), 130 deletions(-)

diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c
index 2492f1305..60907abfa 100644
--- a/grub-core/tpm2/mu.c
+++ b/grub-core/tpm2/mu.c
@@ -49,7 +49,7 @@ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t 
buffer,
 
 void
 grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
-   grub_uint16_t size,
+   const grub_uint16_t size,
const grub_uint8_t* b)
 {
   grub_tpm2_buffer_pack_u16 (buffer, size);
@@ -60,8 +60,8 @@ grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
 
 void
 grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
-   TPMI_ALG_SYM_OBJECT algorithm,
-   TPMU_SYM_KEY_BITS *p)
+   const TPMI_ALG_SYM_OBJECT algorithm,
+   const TPMU_SYM_KEY_BITS *p)
 {
   switch (algorithm)
 {
@@ -78,8 +78,8 @@ grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t 
buffer,
 
 void
 grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
-   TPMI_ALG_SYM_OBJECT algorithm,
-   TPMU_SYM_MODE *p)
+   const TPMI_ALG_SYM_OBJECT algorithm,
+   const TPMU_SYM_MODE *p)
 {
   switch (algorithm)
 {
@@ -96,7 +96,7 @@ grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
 
 void
 grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer,
-  TPMT_SYM_DEF *p)
+  const TPMT_SYM_DEF *p)
 {
   grub_tpm2_buffer_pack_u16 (buffer, p->algorithm);
   grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits);
@@ -134,7 +134,7 @@ grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
 
 void
 grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_SCHEME_XOR *p)
+ const TPMS_SCHEME_XOR *p)
 {
   grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
   grub_tpm2_buffer_pack_u16 (buffer, p->kdf);
@@ -142,15 +142,15 @@ grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t 
buffer,
 
 void
 grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer,
-  TPMS_SCHEME_HMAC *p)
+  const TPMS_SCHEME_HMAC *p)
 {
   grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
 }
 
 void
 grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
-   TPMI_ALG_KEYEDHASH_SCHEME scheme,
-   TPMU_SCHEME_KEYEDHASH *p)
+   const TPMI_ALG_KEYEDHASH_SCHEME 
scheme,
+   const TPMU_SCHEME_KEYEDHASH *p)
 {
   switch (scheme)
 {
@@ -170,7 +170,7 @@ grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal 
(grub_tpm2_buffer_t buffer,
 
 void
 grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
-   TPMT_KEYEDHASH_SCHEME *p)
+   const TPMT_KEYEDHASH_SCHEME *p)
 {
   grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
   grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, &p->details);
@@ -178,14 +178,14 @@ grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal 
(grub_tpm2_buffer_t buffer,
 
 void
 grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer,
-  TPMS_KEYEDHASH_PARMS *p)
+  const TPMS_KEYEDHASH_PARMS *p)
 {
   grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme);
 }
 
 void
 grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_SYM_DEF_OBJECT *p)
+ const TPMT_SYM_DEF_OBJECT *p)
 {
   grub_tpm2_buffer_pack_u16 (buffer, p->algorithm);
   grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits);
@@ -194,8 +194,8 @@ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Mar

[PATCH 00/14] Automatic Disk Unlock with TPM2

2023-02-21 Thread Gary Lin via Grub-devel
The patch series "Automatic TPM Disk Unlock" posted by Hernan Gatta
introduces the key protector framework and TPM2 stack to GRUB2, and it's
a useful feature for the systems to implement full disk encryption.
However, it seems the development was stalled for a while, and I'd like
to push it forward.

Patch 1~5 are Hernan Gatta's patch series(*) with a few modifications:
- Converting 8 spaces into 1 tab
- Merging the minor build fix from Michael Chang
  - Replacing "lu" with "PRIuGRUB_SIZE" for grub_dprintf
  - Adding "enable = efi" to the tpm2 module in grub-core/Makefile.core.def
- Rebasing "cryptodisk: Support key protectors" to the git master

To minimize the changes to Patch 1~5, the follow-up fixes (Patch 6~14)
from my colleagues and me are committed separately. Those patches fix
the problems we found while testing the original patchset.

Quote from Hernan Gatta's cover letter:

"
Updates since v1:

1. One key can unlock multiple disks:
   It is now possible to use key protectors with cryptomount's -a and -b
   options.

2. No passphrase prompt on error if key protector(s) specified:
   cryptomount no longer prompts for a passphrase if key protectors are
   specified but fail to provide a working unlock key seeing as the user
   explicitly requested unlocking via key protectors.

3. Key protector parameterization is separate:
   Previously, one would parameterize a key protector via a colon-separated
   argument list nested within a cryptomount argument. Now, key protectors
   are expected to provide an initialization function, if necessary.

   As such, instead of:

   cryptomount -k tpm2:mode=srk:keyfile=KEYFILE:pcrs=7,11...

   one now writes:

   tpm2_key_protector_init --mode=srk --keyfile=KEYFILE --pcrs=7,11 ...
   cryptomount -k tpm2

   Additionally, one may write:

   cryptomount -k protector_1 -k protector_2 ...

   where cryptomount will try each in order on failure.

4. Standard argument parsing:
   The TPM2 key protector now uses 'struct grub_arg_option' and the
   grub-protect tool uses 'struct argp_option'. Additionally, common
   argument parsing functionality is now shared between the module and
   the tool.

5. More useful messages:
   Both the TPM2 module and the grub-protect tool now provide more
   useful messages to help the user learn how to use their functionality
   (--help and --usage) as well as to determine what is wrong, if
   anything. Furthermore, the module now prints additional debug output
   to help diagnose problems.

I forgot to mention last time that this patch series intends to address:
https://bugzilla.redhat.com/show_bug.cgi?id=1854177

Previous series:
https://lists.gnu.org/archive/html/grub-devel/2022-01/msg00125.html
"

(*) https://lists.gnu.org/archive/html/grub-devel/2022-02/msg6.html

Gary Lin (8):
  tpm2: Don't measure the sealed key
  tpm2: adjust the input parameters of TPM2_EvictControl
  tpm2: declare the input arguments of TPM2 functions as const
  tpm2: resend the command on TPM_RC_RETRY
  tpm2: check the command parameters of TPM2 commands
  tpm2: pack the missing authorization command for TPM2_PCR_Read
  tpm2: allow some command parameters to be NULL
  tpm2: remove the unnecessary variables

Hernan Gatta (5):
  protectors: Add key protectors framework
  tpm2: Add TPM Software Stack (TSS)
  protectors: Add TPM2 Key Protector
  cryptodisk: Support key protectors
  util/grub-protect: Add new tool

Michael Chang (1):
  crytodisk: fix cryptodisk module looking up

 .gitignore |1 +
 Makefile.util.def  |   19 +
 configure.ac   |1 +
 grub-core/Makefile.am  |1 +
 grub-core/Makefile.core.def|   12 +
 grub-core/disk/cryptodisk.c|  176 +++-
 grub-core/kern/protectors.c|   75 ++
 grub-core/tpm2/args.c  |  129 +++
 grub-core/tpm2/buffer.c|  145 +++
 grub-core/tpm2/module.c|  710 +
 grub-core/tpm2/mu.c|  807 +++
 grub-core/tpm2/tcg2.c  |  143 +++
 grub-core/tpm2/tpm2.c  |  761 ++
 include/grub/cryptodisk.h  |   14 +
 include/grub/protector.h   |   48 +
 include/grub/tpm2/buffer.h |   65 ++
 include/grub/tpm2/internal/args.h  |   39 +
 include/grub/tpm2/internal/functions.h |  117 +++
 include/grub/tpm2/internal/structs.h   |  675 
 include/grub/tpm2/internal/types.h |  372 +++
 include/grub/tpm2/mu.h |  292 ++
 include/grub/tpm2/tcg2.h   |   34 +
 include/grub/tpm2/tpm2.h   |   38 +
 util/grub-protect.c| 1314 
 24 files changed, 5955 insertions(+), 33 deletions(-)
 create mode 100644 grub-core/kern/protectors.c
 create mode 100644 grub-core/tpm2/args.c
 create mode 100644 grub-core/tpm2/buffer.c
 create mode 100644 grub-core/tpm2/module.c
 creat