Re: [PATCH v11 19/20] tpm2: Enable tpm2 module for grub-emu
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
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. + * + *