Re: [PATCH v11 19/20] tpm2: Enable tpm2 module for grub-emu

2024-04-12 Thread Stefan Berger



On 4/12/24 04:39, Gary Lin via Grub-devel wrote:

As a preparation to test TPM 2.0 TSS stack with grub-emu, the new
option, --tpm-device, is introduced to specify the TPM device for
grub-emu so that grub-emu can share the emulated TPM device with
the host.

Since grub-emu can directly access the device node on host, it's easy to
implement the essential TCG2 command submission function with the
read/write functions and enable tpm2 module for grub-emu, so that we can
further test TPM key unsealing with grub-emu.

Signed-off-by: Gary Lin 

Reviewed-by: Stefan Berger 


---
  grub-core/Makefile.core.def |  2 ++
  grub-core/kern/emu/main.c   | 11 +++-
  grub-core/kern/emu/misc.c   | 51 
  grub-core/tpm2/tcg2-emu.c   | 52 +
  include/grub/emu/misc.h |  5 
  5 files changed, 120 insertions(+), 1 deletion(-)
  create mode 100644 grub-core/tpm2/tcg2-emu.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index e937f6538..962090d2c 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2567,7 +2567,9 @@ module = {
common = tpm2/tpm2key.c;
common = tpm2/tpm2key_asn1_tab.c;
efi = tpm2/tcg2.c;
+  emu = tpm2/tcg2-emu.c;
enable = efi;
+  enable = emu;
  };
  
  module = {

diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c
index 855b11c3d..c10838613 100644
--- a/grub-core/kern/emu/main.c
+++ b/grub-core/kern/emu/main.c
@@ -55,7 +55,7 @@
  static jmp_buf main_env;
  
  /* Store the prefix specified by an argument.  */

-static char *root_dev = NULL, *dir = NULL;
+static char *root_dev = NULL, *dir = NULL, *tpm_dev = NULL;
  
  grub_addr_t grub_modbase = 0;
  
@@ -108,6 +108,7 @@ static struct argp_option options[] = {

{"verbose", 'v', 0,  0, N_("print verbose messages."), 0},
{"hold", 'H', N_("SECS"),  OPTION_ARG_OPTIONAL, N_("wait until a 
debugger will attach"), 0},
{"kexec",   'X', 0,  0, N_("use kexec to boot Linux kernels via 
systemctl (pass twice to enable dangerous fallback to non-systemctl)."), 0},
+  {"tpm-device",  't', N_("DEV"), 0, N_("Set TPM device."), 0},
{ 0, 0, 0, 0, 0, 0 }
  };
  
@@ -168,6 +169,10 @@ argp_parser (int key, char *arg, struct argp_state *state)

  case 'X':
grub_util_set_kexecute ();
break;
+case 't':
+  free (tpm_dev);
+  tpm_dev = xstrdup (arg);
+  break;
  
  case ARGP_KEY_ARG:

{
@@ -276,6 +281,9 @@ main (int argc, char *argv[])
  
dir = xstrdup (dir);
  
+  if (tpm_dev)

+grub_util_tpm_open (tpm_dev);
+
/* Start GRUB!  */
if (setjmp (main_env) == 0)
  grub_main ();
@@ -283,6 +291,7 @@ main (int argc, char *argv[])
grub_fini_all ();
grub_hostfs_fini ();
grub_host_fini ();
+  grub_util_tpm_close ();
  
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
  
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c

index 521220b49..1db24fde7 100644
--- a/grub-core/kern/emu/misc.c
+++ b/grub-core/kern/emu/misc.c
@@ -28,6 +28,8 @@
  #include 
  #include 
  #include 
+#include 
+#include 
  
  #include 

  #include 
@@ -41,6 +43,8 @@
  int verbosity;
  int kexecute;
  
+static int grub_util_tpm_fd = -1;

+
  void
  grub_util_warn (const char *fmt, ...)
  {
@@ -230,3 +234,50 @@ grub_util_get_kexecute (void)
  {
return kexecute;
  }
+
+grub_err_t
+grub_util_tpm_open (const char *tpm_dev)
+{
+  if (grub_util_tpm_fd != -1)
+return GRUB_ERR_NONE;
+
+  grub_util_tpm_fd = open (tpm_dev, O_RDWR);
+  if (grub_util_tpm_fd == -1)
+grub_util_error (_("cannot open TPM device '%s': %s"), tpm_dev, strerror 
(errno));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_util_tpm_close (void)
+{
+  int err;
+
+  if (grub_util_tpm_fd == -1)
+return GRUB_ERR_NONE;
+
+  err = close (grub_util_tpm_fd);
+  if (err != GRUB_ERR_NONE)
+grub_util_error (_("cannot close TPM device: %s"), strerror (errno));
+
+  grub_util_tpm_fd = -1;
+  return GRUB_ERR_NONE;
+}
+
+grub_size_t
+grub_util_tpm_read (void *output, grub_size_t size)
+{
+  if (grub_util_tpm_fd == -1)
+return -1;
+
+  return read (grub_util_tpm_fd, output, size);
+}
+
+grub_size_t
+grub_util_tpm_write (const void *input, grub_size_t size)
+{
+  if (grub_util_tpm_fd == -1)
+return -1;
+
+  return write (grub_util_tpm_fd, input, size);
+}
diff --git a/grub-core/tpm2/tcg2-emu.c b/grub-core/tpm2/tcg2-emu.c
new file mode 100644
index 0..0d7b8b16e
--- /dev/null
+++ b/grub-core/tpm2/tcg2-emu.c
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2024 SUSE LLC
+ *
+ *  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 

[PATCH v11 19/20] tpm2: Enable tpm2 module for grub-emu

2024-04-12 Thread Gary Lin via Grub-devel
As a preparation to test TPM 2.0 TSS stack with grub-emu, the new
option, --tpm-device, is introduced to specify the TPM device for
grub-emu so that grub-emu can share the emulated TPM device with
the host.

Since grub-emu can directly access the device node on host, it's easy to
implement the essential TCG2 command submission function with the
read/write functions and enable tpm2 module for grub-emu, so that we can
further test TPM key unsealing with grub-emu.

Signed-off-by: Gary Lin 
---
 grub-core/Makefile.core.def |  2 ++
 grub-core/kern/emu/main.c   | 11 +++-
 grub-core/kern/emu/misc.c   | 51 
 grub-core/tpm2/tcg2-emu.c   | 52 +
 include/grub/emu/misc.h |  5 
 5 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 grub-core/tpm2/tcg2-emu.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index e937f6538..962090d2c 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2567,7 +2567,9 @@ module = {
   common = tpm2/tpm2key.c;
   common = tpm2/tpm2key_asn1_tab.c;
   efi = tpm2/tcg2.c;
+  emu = tpm2/tcg2-emu.c;
   enable = efi;
+  enable = emu;
 };
 
 module = {
diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c
index 855b11c3d..c10838613 100644
--- a/grub-core/kern/emu/main.c
+++ b/grub-core/kern/emu/main.c
@@ -55,7 +55,7 @@
 static jmp_buf main_env;
 
 /* Store the prefix specified by an argument.  */
-static char *root_dev = NULL, *dir = NULL;
+static char *root_dev = NULL, *dir = NULL, *tpm_dev = NULL;
 
 grub_addr_t grub_modbase = 0;
 
@@ -108,6 +108,7 @@ static struct argp_option options[] = {
   {"verbose", 'v', 0,  0, N_("print verbose messages."), 0},
   {"hold", 'H', N_("SECS"),  OPTION_ARG_OPTIONAL, N_("wait until a 
debugger will attach"), 0},
   {"kexec",   'X', 0,  0, N_("use kexec to boot Linux kernels via 
systemctl (pass twice to enable dangerous fallback to non-systemctl)."), 0},
+  {"tpm-device",  't', N_("DEV"), 0, N_("Set TPM device."), 0},
   { 0, 0, 0, 0, 0, 0 }
 };
 
@@ -168,6 +169,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
 case 'X':
   grub_util_set_kexecute ();
   break;
+case 't':
+  free (tpm_dev);
+  tpm_dev = xstrdup (arg);
+  break;
 
 case ARGP_KEY_ARG:
   {
@@ -276,6 +281,9 @@ main (int argc, char *argv[])
 
   dir = xstrdup (dir);
 
+  if (tpm_dev)
+grub_util_tpm_open (tpm_dev);
+
   /* Start GRUB!  */
   if (setjmp (main_env) == 0)
 grub_main ();
@@ -283,6 +291,7 @@ main (int argc, char *argv[])
   grub_fini_all ();
   grub_hostfs_fini ();
   grub_host_fini ();
+  grub_util_tpm_close ();
 
   grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
 
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
index 521220b49..1db24fde7 100644
--- a/grub-core/kern/emu/misc.c
+++ b/grub-core/kern/emu/misc.c
@@ -28,6 +28,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -41,6 +43,8 @@
 int verbosity;
 int kexecute;
 
+static int grub_util_tpm_fd = -1;
+
 void
 grub_util_warn (const char *fmt, ...)
 {
@@ -230,3 +234,50 @@ grub_util_get_kexecute (void)
 {
   return kexecute;
 }
+
+grub_err_t
+grub_util_tpm_open (const char *tpm_dev)
+{
+  if (grub_util_tpm_fd != -1)
+return GRUB_ERR_NONE;
+
+  grub_util_tpm_fd = open (tpm_dev, O_RDWR);
+  if (grub_util_tpm_fd == -1)
+grub_util_error (_("cannot open TPM device '%s': %s"), tpm_dev, strerror 
(errno));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_util_tpm_close (void)
+{
+  int err;
+
+  if (grub_util_tpm_fd == -1)
+return GRUB_ERR_NONE;
+
+  err = close (grub_util_tpm_fd);
+  if (err != GRUB_ERR_NONE)
+grub_util_error (_("cannot close TPM device: %s"), strerror (errno));
+
+  grub_util_tpm_fd = -1;
+  return GRUB_ERR_NONE;
+}
+
+grub_size_t
+grub_util_tpm_read (void *output, grub_size_t size)
+{
+  if (grub_util_tpm_fd == -1)
+return -1;
+
+  return read (grub_util_tpm_fd, output, size);
+}
+
+grub_size_t
+grub_util_tpm_write (const void *input, grub_size_t size)
+{
+  if (grub_util_tpm_fd == -1)
+return -1;
+
+  return write (grub_util_tpm_fd, input, size);
+}
diff --git a/grub-core/tpm2/tcg2-emu.c b/grub-core/tpm2/tcg2-emu.c
new file mode 100644
index 0..0d7b8b16e
--- /dev/null
+++ b/grub-core/tpm2/tcg2-emu.c
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2024 SUSE LLC
+ *
+ *  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.
+ *
+ *