diff --git a/0001-cli_lock-Add-build-option-to-block-command-line-inte.patch b/0001-cli_lock-Add-build-option-to-block-command-line-inte.patch new file mode 100644 index 0000000..60c236d --- /dev/null +++ b/0001-cli_lock-Add-build-option-to-block-command-line-inte.patch @@ -0,0 +1,374 @@ +From c7dd3dd296592fef6166170121b54aafe634369f Mon Sep 17 00:00:00 2001 +From: Alec Brown +Date: Wed, 24 Jan 2024 06:26:37 +0000 +Subject: [PATCH 1/2] cli_lock: Add build option to block command line + interface + +Add functionality to disable command line interface access and editing of GRUB +menu entries if GRUB image is built with --disable-cli. + +Signed-off-by: Alec Brown +Reviewed-by: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + docs/grub.texi | 6 ++++-- + grub-core/kern/main.c | 28 ++++++++++++++++++++++++++++ + grub-core/kern/rescue_reader.c | 13 +++++++++++++ + grub-core/normal/auth.c | 3 +++ + grub-core/normal/menu_text.c | 31 +++++++++++++++++-------------- + include/grub/kernel.h | 3 ++- + include/grub/misc.h | 2 ++ + include/grub/util/install.h | 8 ++++++-- + util/grub-install-common.c | 11 ++++++++--- + util/grub-mkimage.c | 9 ++++++++- + util/mkimage.c | 16 +++++++++++++++- + 11 files changed, 106 insertions(+), 24 deletions(-) + +diff --git a/docs/grub.texi b/docs/grub.texi +index 00c5fdc44..e89007920 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -6523,8 +6523,10 @@ the GRUB command line, edit menu entries, and execute any menu entry. If + @samp{superusers} is set, then use of the command line and editing of menu + entries are automatically restricted to superusers. Setting @samp{superusers} + to empty string effectively disables both access to CLI and editing of menu +-entries. Note: The environment variable needs to be exported to also affect +-the section defined by the @samp{submenu} command (@pxref{submenu}). ++entries. Building a grub image with @samp{--disable-cli} option will also ++disable access to CLI and editing of menu entries, as well as disabling rescue ++mode. Note: The environment variable needs to be exported to also affect the ++section defined by the @samp{submenu} command (@pxref{submenu}). + + Other users may be allowed to execute specific menu entries by giving a list of + usernames (as above) using the @option{--users} option to the +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 02df49206..07b6940d2 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -30,11 +30,14 @@ + #include + #include + #include ++#include + + #ifdef GRUB_MACHINE_PCBIOS + #include + #endif + ++static bool cli_disabled = false; ++ + grub_addr_t + grub_modules_get_end (void) + { +@@ -237,6 +240,28 @@ grub_load_normal_mode (void) + grub_command_execute ("normal", 0, 0); + } + ++bool ++grub_is_cli_disabled (void) ++{ ++ return cli_disabled; ++} ++ ++static void ++check_is_cli_disabled (void) ++{ ++ struct grub_module_header *header; ++ header = 0; ++ ++ FOR_MODULES (header) ++ { ++ if (header->type == OBJ_TYPE_DISABLE_CLI) ++ { ++ cli_disabled = true; ++ return; ++ } ++ } ++} ++ + static void + reclaim_module_space (void) + { +@@ -294,6 +319,9 @@ grub_main (void) + + grub_boot_time ("After loading embedded modules."); + ++ /* Check if the CLI should be disabled */ ++ check_is_cli_disabled (); ++ + /* It is better to set the root device as soon as possible, + for convenience. */ + grub_set_prefix_and_root (); +diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c +index dcd7d4439..4259857ba 100644 +--- a/grub-core/kern/rescue_reader.c ++++ b/grub-core/kern/rescue_reader.c +@@ -78,6 +78,19 @@ grub_rescue_read_line (char **line, int cont, + void __attribute__ ((noreturn)) + grub_rescue_run (void) + { ++ /* Stall if the CLI has been disabled */ ++ if (grub_is_cli_disabled ()) ++ { ++ grub_printf ("Rescue mode has been disabled...\n"); ++ ++ do ++ { ++ /* Do not optimize out the loop. */ ++ asm volatile (""); ++ } ++ while (1); ++ } ++ + grub_printf ("Entering rescue mode...\n"); + + while (1) +diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c +index 517fc623f..d94020186 100644 +--- a/grub-core/normal/auth.c ++++ b/grub-core/normal/auth.c +@@ -209,6 +209,9 @@ grub_auth_check_authentication (const char *userlist) + char entered[GRUB_AUTH_MAX_PASSLEN]; + struct grub_auth_user *user; + ++ if (grub_is_cli_disabled ()) ++ return GRUB_ACCESS_DENIED; ++ + grub_memset (login, 0, sizeof (login)); + + if (is_authenticated (userlist)) +diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c +index ae92050d7..56c6f7797 100644 +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -194,21 +194,24 @@ command-line or ESC to discard edits and return to the GRUB menu."), + grub_free (msg_translated); + #endif + +- if (nested) ++ if (!grub_is_cli_disabled ()) + { +- ret += grub_print_message_indented_real +- (_("Press enter to boot the selected OS, " +- "`e' to edit the commands before booting " +- "or `c' for a command-line. ESC to return previous menu."), +- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); +- } +- else +- { +- ret += grub_print_message_indented_real +- (_("Press enter to boot the selected OS, " +- "`e' to edit the commands before booting " +- "or `c' for a command-line."), +- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++ if (nested) ++ { ++ ret += grub_print_message_indented_real ++ (_("Press enter to boot the selected OS, " ++ "`e' to edit the commands before booting " ++ "or `c' for a command-line. ESC to return previous menu."), ++ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++ } ++ else ++ { ++ ret += grub_print_message_indented_real ++ (_("Press enter to boot the selected OS, " ++ "`e' to edit the commands before booting " ++ "or `c' for a command-line."), ++ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++ } + } + } + return ret; +diff --git a/include/grub/kernel.h b/include/grub/kernel.h +index d3aafc884..9f3e2031f 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -31,7 +31,8 @@ enum + OBJ_TYPE_GPG_PUBKEY, + OBJ_TYPE_X509_PUBKEY, + OBJ_TYPE_DTB, +- OBJ_TYPE_DISABLE_SHIM_LOCK ++ OBJ_TYPE_DISABLE_SHIM_LOCK, ++ OBJ_TYPE_DISABLE_CLI + }; + + /* The module header. */ +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 1b35a167f..1578f36c3 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -391,6 +391,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t d, + grub_uint64_t *r); + ++extern bool EXPORT_FUNC(grub_is_cli_disabled) (void); ++ + /* Must match softdiv group in gentpl.py. */ + #if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ + (defined(__riscv) && (__riscv_xlen == 32))) +diff --git a/include/grub/util/install.h b/include/grub/util/install.h +index 38c6da73b..a4aac7b85 100644 +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -72,6 +72,8 @@ + { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ + "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ + 1}, \ ++ { "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, \ ++ N_("disabled command line interface access"), 0 }, \ + { "verbose", 'v', 0, 0, \ + N_("print verbose messages."), 1 } + +@@ -136,7 +138,8 @@ enum grub_install_options { + GRUB_INSTALL_OPTIONS_DTB, + GRUB_INSTALL_OPTIONS_SBAT, + GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, +- GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE ++ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE, ++ GRUB_INSTALL_OPTIONS_DISABLE_CLI + }; + + extern char *grub_install_source_directory; +@@ -199,7 +202,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + const struct grub_install_image_target_desc *image_target, + int note, size_t appsig_size, + grub_compression_t comp, const char *dtb_file, +- const char *sbat_path, const int disable_shim_lock); ++ const char *sbat_path, const int disable_shim_lock, ++ const int disable_cli); + + const struct grub_install_image_target_desc * + grub_install_get_image_target (const char *arg); +diff --git a/util/grub-install-common.c b/util/grub-install-common.c +index 75fa03995..344dca664 100644 +--- a/util/grub-install-common.c ++++ b/util/grub-install-common.c +@@ -469,6 +469,7 @@ static char **x509keys; + static size_t nx509keys; + static grub_compression_t compression; + static size_t appsig_size; ++static int disable_cli; + + int + grub_install_parse (int key, char *arg) +@@ -514,6 +515,9 @@ grub_install_parse (int key, char *arg) + * (nx509keys + 1)); + x509keys[nx509keys++] = xstrdup (arg); + return 1; ++ case GRUB_INSTALL_OPTIONS_DISABLE_CLI: ++ disable_cli = 1; ++ return 1; + + case GRUB_INSTALL_OPTIONS_VERBOSITY: + verbosity++; +@@ -707,12 +711,13 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, + + grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'" + " --format '%s' --compression '%s'" +- " --appended-signature-size %zu%s%s%s\n", ++ " --appended-signature-size %zu%s%s%s%s\n", + dir, prefix, outname, + mkimage_target, compnames[compression], + appsig_size, + note ? " --note" : "", +- disable_shim_lock ? " --disable-shim-lock" : "", s); ++ disable_shim_lock ? " --disable-shim-lock" : "", ++ disable_cli ? " --disable-cli" : "", s); + free (s); + + tgt = grub_install_get_image_target (mkimage_target); +@@ -724,7 +729,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, + pubkeys, npubkeys, x509keys, nx509keys, + config_path, tgt, + note, appsig_size, compression, dtb, sbat, +- disable_shim_lock); ++ disable_shim_lock, disable_cli); + while (dc--) + grub_install_pop_module (); + } +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 7d61ef3ea..351a5e430 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -84,6 +84,7 @@ static struct argp_option options[] = { + {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0}, + {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0}, + {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0}, ++ {"disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, N_("disable command line interface access"), 0}, + {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, + {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0}, + { 0, 0, 0, 0, 0, 0 } +@@ -133,6 +134,7 @@ struct arguments + int note; + int disable_shim_lock; + size_t appsig_size; ++ int disable_cli; + const struct grub_install_image_target_desc *image_target; + grub_compression_t comp; + }; +@@ -259,6 +261,10 @@ argp_parser (int key, char *arg, struct argp_state *state) + arguments->disable_shim_lock = 1; + break; + ++ case GRUB_INSTALL_OPTIONS_DISABLE_CLI: ++ arguments->disable_cli = 1; ++ break; ++ + case 'v': + verbosity++; + break; +@@ -347,7 +353,8 @@ main (int argc, char *argv[]) + arguments.image_target, arguments.note, + arguments.appsig_size, + arguments.comp, arguments.dtb, +- arguments.sbat, arguments.disable_shim_lock); ++ arguments.sbat, arguments.disable_shim_lock, ++ arguments.disable_cli); + + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout", +diff --git a/util/mkimage.c b/util/mkimage.c +index 0737935fd..d6cc13475 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -889,7 +889,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + const struct grub_install_image_target_desc *image_target, + int note, size_t appsig_size, grub_compression_t comp, + const char *dtb_path, const char *sbat_path, +- int disable_shim_lock) ++ int disable_shim_lock, ++ int disable_cli) + { + char *kernel_img, *core_img; + size_t total_module_size, core_size; +@@ -964,6 +965,9 @@ grub_install_generate_image (const char *dir, const char *prefix, + if (disable_shim_lock) + total_module_size += sizeof (struct grub_module_header); + ++ if (disable_cli) ++ total_module_size += sizeof (struct grub_module_header); ++ + if (config_path) + { + config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1); +@@ -1130,6 +1134,16 @@ grub_install_generate_image (const char *dir, const char *prefix, + offset += sizeof (*header); + } + ++ if (disable_cli) ++ { ++ struct grub_module_header *header; ++ ++ header = (struct grub_module_header *) (kernel_img + offset); ++ header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_CLI); ++ header->size = grub_host_to_target32 (sizeof (*header)); ++ offset += sizeof (*header); ++ } ++ + if (config_path) + { + struct grub_module_header *header; +-- +2.46.0 + diff --git a/0001-kern-main-Fix-cmdpath-in-root-directory.patch b/0001-kern-main-Fix-cmdpath-in-root-directory.patch new file mode 100644 index 0000000..efc700b --- /dev/null +++ b/0001-kern-main-Fix-cmdpath-in-root-directory.patch @@ -0,0 +1,66 @@ +From 56b221476d31310de485af26550c8651618832bb Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 29 Oct 2024 11:54:28 +0800 +Subject: [PATCH] kern/main: Fix cmdpath in root directory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The "cmdpath" environment variable is set at startup to the location +from which the grub image is loaded. It includes a device part and, +optionally, an absolute directory name if the grub image is booted as a +file in a local file-system directory, or in a remote server directory, +like TFTP. + +This entire process relies on firmware to provide the correct device +path of the booted image. + +We encountered an issue when the image is booted from the root +directory, where the absolute directory name "/" is discarded. This +makes it unclear whether the root path was missing in the firmware +provided device path or if it is simply the root directory. This +ambiguity can cause confusion in custom scripts, potentially causing +them to interpret firmware data incorrectly and trigger unintended +fallback measures. + +This patch fixes the problem by properly assigning the "fwpath" returned +by "grub_machine_get_bootlocation()" to "cmdpath". The fix is based on +the fact that fwpath is NULL if the firmware didn’t provide a path part +or an NUL character, "", if it represents the root directory. With this, +it becomes possible to clearly distinguish: + +- cmdpath=(hd0,1) - Either the image is booted from the first (raw) + partition, or the firmware failed to provide the path part. +- cmdpath=(hd0,1)/ - The image is booted from the root directory in the + first partition. + +As a side note, the fix is similar to [1], but without the renaming +part. + +[1] https://mail.gnu.org/archive/html/grub-devel/2024-10/msg00155.html + +Signed-off-by: Michael Chang +--- + grub-core/kern/main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index ef3b3756d..f9ab12c74 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -136,7 +136,11 @@ grub_set_prefix_and_root (void) + { + char *cmdpath; + +- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); ++ if (fwpath && *fwpath == '\0') ++ cmdpath = grub_xasprintf ("(%s)/", fwdevice); ++ else ++ cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); ++ + if (cmdpath) + { + grub_env_set ("cmdpath", cmdpath); +-- +2.47.0 + diff --git a/0003-key_protector-Add-TPM2-Key-Protector.patch b/0001-key_protector-Add-TPM2-Key-Protector.patch similarity index 62% rename from 0003-key_protector-Add-TPM2-Key-Protector.patch rename to 0001-key_protector-Add-TPM2-Key-Protector.patch index e3ae0d6..18a727f 100644 --- a/0003-key_protector-Add-TPM2-Key-Protector.patch +++ b/0001-key_protector-Add-TPM2-Key-Protector.patch @@ -1,7 +1,7 @@ -From 2cb2b00028ca7f43fc069472fbad7b9f129ec24b Mon Sep 17 00:00:00 2001 +From 00dcaa44f08c7aae5d05b85c8ea751d1cd881db3 Mon Sep 17 00:00:00 2001 From: Hernan Gatta Date: Tue, 1 Feb 2022 05:02:55 -0800 -Subject: [PATCH 3/5] key_protector: Add TPM2 Key Protector +Subject: [PATCH] key_protector: Add TPM2 Key Protector 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. @@ -78,18 +78,18 @@ command (modifications to this command are in a different patch). For instance, to unseal the raw sealed key file: -tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub2/sealed-1.key +tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub/sealed-1.key cryptomount -u -P tpm2 -tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub2/sealed-2.key --pcrs=7,11 +tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub/sealed-2.key --pcrs=7,11 cryptomount -u -P tpm2 Or, to unseal the TPM 2.0 Key file: -tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub2/sealed-1.tpm +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub/sealed-1.tpm cryptomount -u -P tpm2 -tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub2/sealed-2.tpm --pcrs=7,11 +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub/sealed-2.tpm --pcrs=7,11 cryptomount -u -P tpm2 If a user does not initialize the key protector and attempts to use it @@ -115,61 +115,62 @@ This commit only supports one policy command: TPM2_PolicyPCR. The command set will be extended to support advanced features, such as authorized policy, in the later commits. -Cc: Stefan Berger Cc: James Bottomley Signed-off-by: Hernan Gatta Signed-off-by: Gary Lin +Reviewed-by: Daniel Kiper +Reviewed-by: Stefan Berger --- - grub-core/Makefile.core.def | 13 + - grub-core/tpm2/args.c | 140 ++++ - grub-core/tpm2/module.c | 1226 +++++++++++++++++++++++++++++ - grub-core/tpm2/tpm2key.asn | 33 + - grub-core/tpm2/tpm2key.c | 476 +++++++++++ - grub-core/tpm2/tpm2key_asn1_tab.c | 45 ++ - include/grub/tpm2/internal/args.h | 49 ++ - include/grub/tpm2/tpm2key.h | 86 ++ - 8 files changed, 2068 insertions(+) - create mode 100644 grub-core/tpm2/args.c - create mode 100644 grub-core/tpm2/module.c - create mode 100644 grub-core/tpm2/tpm2key.asn - create mode 100644 grub-core/tpm2/tpm2key.c - create mode 100644 grub-core/tpm2/tpm2key_asn1_tab.c - create mode 100644 include/grub/tpm2/internal/args.h - create mode 100644 include/grub/tpm2/tpm2key.h + grub-core/Makefile.core.def | 11 + + grub-core/commands/tpm2_key_protector/args.c | 127 ++ + .../commands/tpm2_key_protector/module.c | 1153 +++++++++++++++++ + grub-core/commands/tpm2_key_protector/tpm2.h | 36 + + .../commands/tpm2_key_protector/tpm2_args.h | 49 + + .../commands/tpm2_key_protector/tpm2key.asn | 49 + + .../commands/tpm2_key_protector/tpm2key.c | 499 +++++++ + .../commands/tpm2_key_protector/tpm2key.h | 87 ++ + .../tpm2_key_protector/tpm2key_asn1_tab.c | 63 + + 9 files changed, 2074 insertions(+) + create mode 100644 grub-core/commands/tpm2_key_protector/args.c + create mode 100644 grub-core/commands/tpm2_key_protector/module.c + create mode 100644 grub-core/commands/tpm2_key_protector/tpm2.h + create mode 100644 grub-core/commands/tpm2_key_protector/tpm2_args.h + create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key.asn + create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key.c + create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key.h + create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 4307b8e2d..a3c728442 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2612,6 +2612,19 @@ module = { - enable = efi; +Index: grub-2.12/grub-core/Makefile.core.def +=================================================================== +--- grub-2.12.orig/grub-core/Makefile.core.def ++++ grub-2.12/grub-core/Makefile.core.def +@@ -2620,6 +2620,17 @@ module = { }; -+module = { -+ name = tpm2; -+ common = tpm2/args.c; -+ common = tpm2/buffer.c; -+ common = tpm2/module.c; -+ common = tpm2/mu.c; -+ common = tpm2/tpm2.c; -+ common = tpm2/tpm2key.c; -+ common = tpm2/tpm2key_asn1_tab.c; -+ efi = tpm2/tcg2.c; + module = { ++ name = tpm2_key_protector; ++ common = commands/tpm2_key_protector/args.c; ++ common = commands/tpm2_key_protector/module.c; ++ common = commands/tpm2_key_protector/tpm2key.c; ++ common = commands/tpm2_key_protector/tpm2key_asn1_tab.c; ++ /* The plaform support of tpm2_key_protector depends on the tcg2 implementation in tss2. */ + enable = efi; ++ cppflags = '-I$(srcdir)/lib/tss2'; +}; + - module = { ++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 000000000..c11280ab9 + }; +Index: grub-2.12/grub-core/commands/tpm2_key_protector/args.c +=================================================================== --- /dev/null -+++ b/grub-core/tpm2/args.c -@@ -0,0 +1,140 @@ ++++ grub-2.12/grub-core/commands/tpm2_key_protector/args.c +@@ -0,0 +1,127 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 @@ -188,7 +189,8 @@ index 000000000..c11280ab9 +#include +#include +#include -+#include ++ ++#include "tpm2_args.h" + +grub_err_t +grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, @@ -196,7 +198,8 @@ index 000000000..c11280ab9 +{ + char *current_pcr = value; + char *next_pcr; -+ unsigned long pcr; ++ const char *pcr_end; ++ grub_uint64_t pcr; + grub_uint8_t i; + + if (grub_strlen (value) == 0) @@ -207,40 +210,30 @@ index 000000000..c11280ab9 + { + 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) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("empty entry in PCR list")); ++ if (next_pcr != NULL) + *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); ++ pcr = grub_strtoul (current_pcr, &pcr_end, 10); ++ if (*current_pcr == '\0' || *pcr_end != '\0') ++ return grub_error (GRUB_ERR_BAD_NUMBER, 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); ++ if (pcr > TPM_MAX_PCRS - 1) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("entry %llu in PCR list is too large to be a PCR number, PCR numbers range from 0 to %u"), (unsigned long long)pcr, TPM_MAX_PCRS - 1); + -+ pcrs[i] = (grub_uint8_t)pcr; -+ *pcr_count += 1; ++ pcrs[i] = (grub_uint8_t) pcr; ++ ++(*pcr_count); + + if (next_pcr == NULL) + break; + + current_pcr = next_pcr + 1; + if (*current_pcr == '\0') -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Trailing comma at the end of PCR list")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("trailing comma at the end of PCR list")); + } + + if (i == TPM_MAX_PCRS) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Too many PCRs in PCR list, the maximum number of " -+ "PCRs is %u"), TPM_MAX_PCRS); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("too many PCRs in PCR list, the maximum number of PCRs is %u"), TPM_MAX_PCRS); + + return GRUB_ERR_NONE; +} @@ -262,15 +255,13 @@ index 000000000..c11280ab9 + srk_type->detail.rsa_bits = 2048; + } + else -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Value '%s' is not a valid asymmetric key type"), -+ value); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid asymmetric key type"), value); + + return GRUB_ERR_NONE; +} + +grub_err_t -+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank) ++grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID_t *bank) +{ + if (grub_strcasecmp (value, "SHA1") == 0) + *bank = TPM_ALG_SHA1; @@ -281,41 +272,37 @@ index 000000000..c11280ab9 + else if (grub_strcasecmp (value, "SHA512") == 0) + *bank = TPM_ALG_SHA512; + else -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Value '%s' is not a valid PCR bank"), value); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid PCR bank"), value); + + return GRUB_ERR_NONE; +} + +grub_err_t -+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle) ++grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE_t *handle) +{ -+ unsigned long num; ++ grub_uint64_t num; ++ const char *str_end; + -+ grub_errno = GRUB_ERR_NONE; -+ num = grub_strtoul (value, NULL, 0); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_error (grub_errno, N_("TPM handle value '%s' is not a number"), -+ value); ++ num = grub_strtoul (value, &str_end, 0); ++ if (*value == '\0' || *str_end != '\0') ++ return grub_error (GRUB_ERR_BAD_NUMBER, N_("TPM handle value '%s' is not a number"), value); + + if (num > GRUB_UINT_MAX) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Value %lu is too large to be a TPM handle, TPM " -+ "handles are unsigned 32-bit integers"), num); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value %llu is too large to be a TPM handle, TPM handles are unsigned 32-bit integers"), (unsigned long long)num); + -+ *handle = (TPM_HANDLE)num; ++ *handle = (TPM_HANDLE_t) num; + + return GRUB_ERR_NONE; +} -diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c -new file mode 100644 -index 000000000..3db25ceca +Index: grub-2.12/grub-core/commands/tpm2_key_protector/module.c +=================================================================== --- /dev/null -+++ b/grub-core/tpm2/module.c -@@ -0,0 +1,1226 @@ ++++ grub-2.12/grub-core/commands/tpm2_key_protector/module.c +@@ -0,0 +1,1153 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 @@ -334,28 +321,29 @@ index 000000000..3db25ceca +#include +#include +#include -+#include +#include +#include +#include +#include -+#include -+#include -+#include -+#include -+#include -+#include ++ ++#include ++#include ++#include ++ ++#include "tpm2_args.h" ++#include "tpm2.h" ++#include "tpm2key.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + -+typedef enum grub_tpm2_protector_mode ++typedef enum tpm2_protector_mode +{ -+ GRUB_TPM2_PROTECTOR_MODE_UNSET, -+ GRUB_TPM2_PROTECTOR_MODE_SRK, -+ GRUB_TPM2_PROTECTOR_MODE_NV -+} grub_tpm2_protector_mode_t; ++ TPM2_PROTECTOR_MODE_UNSET, ++ TPM2_PROTECTOR_MODE_SRK, ++ TPM2_PROTECTOR_MODE_NV ++} tpm2_protector_mode_t; + -+enum grub_tpm2_protector_options ++typedef enum tpm2_protector_options +{ + OPTION_MODE, + OPTION_PCRS, @@ -365,22 +353,22 @@ index 000000000..3db25ceca + OPTION_SRK, + OPTION_ASYMMETRIC, + OPTION_NVINDEX -+}; ++} tpm2_protector_options_t; + -+struct grub_tpm2_protector_context ++typedef struct tpm2_protector_context +{ -+ grub_tpm2_protector_mode_t mode; ++ tpm2_protector_mode_t mode; + grub_uint8_t pcrs[TPM_MAX_PCRS]; + grub_uint8_t pcr_count; + grub_srk_type_t srk_type; -+ TPM_ALG_ID bank; ++ TPM_ALG_ID_t bank; + const char *tpm2key; + const char *keyfile; -+ TPM_HANDLE srk; -+ TPM_HANDLE nv; -+}; ++ TPM_HANDLE_t srk; ++ TPM_HANDLE_t nv; ++} tpm2_protector_context_t; + -+static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] = ++static const struct grub_arg_option tpm2_protector_init_cmd_options[] = + { + /* Options for all modes */ + { @@ -469,13 +457,12 @@ index 000000000..3db25ceca + {0, 0, 0, 0, 0, 0} + }; + -+static grub_extcmd_t grub_tpm2_protector_init_cmd; -+static grub_extcmd_t grub_tpm2_protector_clear_cmd; -+static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = { 0 }; ++static grub_extcmd_t tpm2_protector_init_cmd; ++static grub_extcmd_t tpm2_protector_clear_cmd; ++static tpm2_protector_context_t tpm2_protector_ctx = {0}; + +static grub_err_t -+grub_tpm2_protector_srk_read_file (const char *filepath, void **buffer, -+ grub_size_t *buffer_size) ++tpm2_protector_srk_read_file (const char *filepath, void **buffer, grub_size_t *buffer_size) +{ + grub_file_t file; + grub_off_t file_size; @@ -483,34 +470,30 @@ index 000000000..3db25ceca + grub_off_t read_n; + grub_err_t err; + -+ /* 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 */ ++ /* ++ * 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 ++ */ + file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE); + if (file == NULL) + { + /* Push errno from grub_file_open() into the error message stack */ + grub_error_push(); -+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, -+ N_("Could not open file: %s\n"), -+ filepath); ++ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("could not open file: %s"), filepath); + goto error; + } + + file_size = grub_file_size (file); + if (file_size == 0) + { -+ err = grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Could not read file size: %s"), -+ filepath); ++ err = grub_error (GRUB_ERR_OUT_OF_RANGE, N_("could not read file size: %s"), filepath); + goto error; + } + + read_buffer = grub_malloc (file_size); + if (read_buffer == NULL) + { -+ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Could not allocate buffer for %s"), -+ filepath); ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("could not allocate buffer for %s"), filepath); + goto error; + } + @@ -518,9 +501,7 @@ index 000000000..3db25ceca + if (read_n != file_size) + { + grub_free (read_buffer); -+ err = grub_error (GRUB_ERR_FILE_READ_ERROR, -+ N_("Could not retrieve file contents: %s"), -+ filepath); ++ err = grub_error (GRUB_ERR_FILE_READ_ERROR, N_("could not retrieve file contents: %s"), filepath); + goto error; + } + @@ -529,7 +510,7 @@ index 000000000..3db25ceca + + err = GRUB_ERR_NONE; + -+error: ++ error: + if (file != NULL) + grub_file_close (file); + @@ -537,38 +518,36 @@ index 000000000..3db25ceca +} + +static grub_err_t -+grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key, -+ grub_size_t sealed_key_size, -+ TPM2_SEALED_KEY *sk) ++tpm2_protector_srk_unmarshal_keyfile (void *sealed_key, ++ grub_size_t sealed_key_size, ++ tpm2_sealed_key_t *sk) +{ + struct grub_tpm2_buffer buf; + + grub_tpm2_buffer_init (&buf); + if (sealed_key_size > buf.cap) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Sealed key larger than %" PRIuGRUB_SIZE " bytes"), -+ buf.cap); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("sealed key larger than %llu bytes"), (unsigned long long)buf.cap); + + grub_memcpy (buf.data, sealed_key, sealed_key_size); + buf.size = sealed_key_size; + -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); -+ grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private); ++ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); ++ grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private); + -+ if (buf.error) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Malformed TPM wire key file")); ++ if (buf.error != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("malformed TPM wire key file")); + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_tpm2_protector_srk_unmarshal_tpm2key (void *sealed_key, -+ grub_size_t sealed_key_size, -+ tpm2key_policy_t *policy_seq, -+ tpm2key_authpolicy_t *authpol_seq, -+ grub_uint8_t *rsaparent, -+ grub_uint32_t *parent, -+ TPM2_SEALED_KEY *sk) ++tpm2_protector_srk_unmarshal_tpm2key (void *sealed_key, ++ grub_size_t sealed_key_size, ++ tpm2key_policy_t *policy_seq, ++ tpm2key_authpolicy_t *authpol_seq, ++ grub_uint8_t *rsaparent, ++ grub_uint32_t *parent, ++ tpm2_sealed_key_t *sk) +{ + asn1_node tpm2key = NULL; + grub_uint8_t rsaparent_tmp; @@ -650,9 +629,7 @@ index 000000000..3db25ceca + grub_tpm2_buffer_init (&buf); + if (sealed_pub_size + sealed_priv_size > buf.cap) + { -+ err = grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Sealed key larger than %" PRIuGRUB_SIZE " bytes"), -+ buf.cap); ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("sealed key larger than %llu bytes"), (unsigned long long)buf.cap); + goto error; + } + @@ -661,18 +638,18 @@ index 000000000..3db25ceca + + buf.offset = 0; + -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); -+ grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private); ++ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); ++ grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private); + -+ if (buf.error) ++ if (buf.error != 0) + { -+ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Malformed TPM 2.0 key file")); ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("malformed TPM 2.0 key file")); + goto error; + } + + err = GRUB_ERR_NONE; + -+error: ++ error: + /* End the parsing */ + grub_tpm2key_end_parsing (tpm2key); + grub_free (sealed_pub); @@ -683,40 +660,38 @@ index 000000000..3db25ceca + +/* Check if the SRK exists in the specified handle */ +static grub_err_t -+grub_tpm2_protector_srk_check (const TPM_HANDLE srk_handle) ++tpm2_protector_srk_check (const TPM_HANDLE_t srk_handle) +{ -+ TPM_RC rc; -+ TPM2B_PUBLIC public; ++ TPM_RC_t rc; ++ TPM2B_PUBLIC_t public; + + /* Find SRK */ -+ rc = TPM2_ReadPublic (srk_handle, NULL, &public); ++ rc = grub_tpm2_readpublic (srk_handle, NULL, &public); + if (rc == TPM_RC_SUCCESS) + return GRUB_ERR_NONE; + -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x)"), -+ srk_handle, rc); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x)", srk_handle, rc); +} + +/* Get the SRK with the template */ +static grub_err_t -+grub_tpm2_protector_srk_get (const grub_srk_type_t srk_type, -+ const TPM_HANDLE parent, -+ TPM_HANDLE *srk_handle) ++tpm2_protector_srk_get (const grub_srk_type_t srk_type, ++ const TPM_HANDLE_t parent, ++ TPM_HANDLE_t *srk_handle) +{ -+ TPM_RC rc; -+ TPMT_PUBLIC_PARMS parms = { 0 }; -+ TPMS_AUTH_COMMAND authCommand = { 0 }; -+ TPM2B_SENSITIVE_CREATE inSensitive = { 0 }; -+ TPM2B_PUBLIC inPublic = { 0 }; -+ TPM2B_DATA outsideInfo = { 0 }; -+ TPML_PCR_SELECTION creationPcr = { 0 }; -+ TPM2B_PUBLIC outPublic = { 0 }; -+ TPM2B_CREATION_DATA creationData = { 0 }; -+ TPM2B_DIGEST creationHash = { 0 }; -+ TPMT_TK_CREATION creationTicket = { 0 }; -+ TPM2B_NAME srkName = { 0 }; -+ TPM_HANDLE tmp_handle = 0; ++ TPM_RC_t rc; ++ TPMT_PUBLIC_PARMS_t parms = {0}; ++ TPMS_AUTH_COMMAND_t authCommand = {0}; ++ TPM2B_SENSITIVE_CREATE_t inSensitive = {0}; ++ TPM2B_PUBLIC_t inPublic = {0}; ++ TPM2B_DATA_t outsideInfo = {0}; ++ TPML_PCR_SELECTION_t creationPcr = {0}; ++ TPM2B_PUBLIC_t outPublic = {0}; ++ TPM2B_CREATION_DATA_t creationData = {0}; ++ TPM2B_DIGEST_t creationHash = {0}; ++ TPMT_TK_CREATION_t creationTicket = {0}; ++ TPM2B_NAME_t srkName = {0}; ++ TPM_HANDLE_t tmp_handle = 0; + + inPublic.publicArea.type = srk_type.type; + inPublic.publicArea.nameAlg = TPM_ALG_SHA256; @@ -747,52 +722,49 @@ index 000000000..3db25ceca + inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; + } + else -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown SRK algorithm")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown SRK algorithm"); + + /* Test the parameters before SRK generation */ + parms.type = srk_type.type; + grub_memcpy (&parms.parameters, &inPublic.publicArea.parameters, -+ sizeof (TPMU_PUBLIC_PARMS)); ++ sizeof (TPMU_PUBLIC_PARMS_t)); + -+ rc = TPM2_TestParms (&parms, NULL); ++ rc = grub_tpm2_testparms (&parms, NULL); + if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Unsupported SRK template (TPM2_TestParms: 0x%x)"), -+ rc); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unsupported SRK template (TPM2_TestParms: 0x%x)", rc); + + /* Create SRK */ + authCommand.sessionHandle = TPM_RS_PW; -+ rc = TPM2_CreatePrimary (parent, &authCommand, &inSensitive, &inPublic, -+ &outsideInfo, &creationPcr, &tmp_handle, &outPublic, -+ &creationData, &creationHash, &creationTicket, -+ &srkName, NULL); ++ rc = grub_tpm2_createprimary (parent, &authCommand, &inSensitive, &inPublic, ++ &outsideInfo, &creationPcr, &tmp_handle, &outPublic, ++ &creationData, &creationHash, &creationTicket, ++ &srkName, NULL); + if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Could not create SRK (TPM2_CreatePrimary: 0x%x)"), -+ rc); ++ return grub_error (GRUB_ERR_BAD_DEVICE, "could not create SRK (TPM2_CreatePrimary: 0x%x)", rc); + + *srk_handle = tmp_handle; + + return GRUB_ERR_NONE; +} + -+/* Load the SRK from the persistent handle or create one with a given type of -+ template, and then associate the sealed key with the SRK -+ Return values: -+ * GRUB_ERR_NONE: Everything is fine. -+ * GRUB_ERR_BAD_ARGUMENT: The SRK doesn't match. Try another one. -+ * Other: Something went wrong. -+*/ ++/* ++ * Load the SRK from the persistent handle or create one with a given type of ++ * template, and then associate the sealed key with the SRK ++ * Return values: ++ * - GRUB_ERR_NONE: Everything is fine. ++ * - GRUB_ERR_BAD_ARGUMENT: The SRK doesn't match. Try another one. ++ * - Other: Something went wrong. ++ */ +static grub_err_t -+grub_tpm2_protector_srk_load (const grub_srk_type_t srk_type, -+ const TPM2_SEALED_KEY *sealed_key, -+ const TPM_HANDLE parent, -+ TPM_HANDLE *sealed_handle, -+ TPM_HANDLE *srk_handle) ++tpm2_protector_srk_load (const grub_srk_type_t srk_type, ++ const tpm2_sealed_key_t *sealed_key, ++ const TPM_HANDLE_t parent, ++ TPM_HANDLE_t *sealed_handle, ++ TPM_HANDLE_t *srk_handle) +{ -+ TPMS_AUTH_COMMAND authCmd = { 0 }; -+ TPM2B_NAME name = { 0 }; -+ TPM_RC rc; ++ TPMS_AUTH_COMMAND_t authCmd = {0}; ++ TPM2B_NAME_t name = {0}; ++ TPM_RC_t rc; + grub_err_t err; + + if (srk_handle == NULL) @@ -800,41 +772,41 @@ index 000000000..3db25ceca + + if (*srk_handle != 0) + { -+ err = grub_tpm2_protector_srk_check (*srk_handle); ++ err = tpm2_protector_srk_check (*srk_handle); + if (err != GRUB_ERR_NONE) + return err; + } + else + { -+ err = grub_tpm2_protector_srk_get (srk_type, parent, srk_handle); ++ err = tpm2_protector_srk_get (srk_type, parent, srk_handle); + if (err != GRUB_ERR_NONE) + return err; + } + + /* Load the sealed key and associate it with the SRK */ + authCmd.sessionHandle = TPM_RS_PW; -+ rc = TPM2_Load (*srk_handle, &authCmd, &sealed_key->private, &sealed_key->public, -+ sealed_handle, &name, NULL); -+ /* If TPM2_Load returns (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1), then it -+ implies the wrong SRK is used. */ ++ rc = grub_tpm2_load (*srk_handle, &authCmd, &sealed_key->private, &sealed_key->public, ++ sealed_handle, &name, NULL); ++ /* ++ * If TPM2_Load returns (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1), then it ++ * implies the wrong SRK is used. ++ */ + if (rc == (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1)) + { -+ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("SRK not matched")); ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, "SRK not matched"); + goto error; + } + else if (rc != TPM_RC_SUCCESS) + { -+ err = grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to load sealed key (TPM2_Load: 0x%x)"), -+ rc); ++ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to load sealed key (TPM2_Load: 0x%x)", rc); + goto error; + } + + return GRUB_ERR_NONE; + -+error: ++ error: + if (!TPM_HT_IS_PERSISTENT (*srk_handle)) -+ TPM2_FlushContext (*srk_handle); ++ grub_tpm2_flushcontext (*srk_handle); + + return err; +} @@ -842,32 +814,20 @@ index 000000000..3db25ceca +static const char * +srk_type_to_name (grub_srk_type_t srk_type) +{ -+ if (srk_type.type == TPM_ALG_ECC) -+ { -+ switch (srk_type.detail.ecc_curve) -+ { -+ case TPM_ECC_NIST_P256: -+ return "ECC_NIST_P256"; -+ } -+ } -+ else if (srk_type.type == TPM_ALG_RSA) -+ { -+ switch (srk_type.detail.rsa_bits) -+ { -+ case 2048: -+ return "RSA2048"; -+ } -+ } ++ if (srk_type.type == TPM_ALG_ECC && srk_type.detail.ecc_curve == TPM_ECC_NIST_P256) ++ return "ECC_NIST_P256"; ++ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 2048) ++ return "RSA2048"; + + return "Unknown"; +} + +static grub_err_t -+grub_tpm2_protector_load_key (const struct grub_tpm2_protector_context *ctx, -+ const TPM2_SEALED_KEY *sealed_key, -+ const TPM_HANDLE parent_handle, -+ TPM_HANDLE *sealed_handle, -+ TPM_HANDLE *srk_handle) ++tpm2_protector_load_key (const tpm2_protector_context_t *ctx, ++ const tpm2_sealed_key_t *sealed_key, ++ const TPM_HANDLE_t parent_handle, ++ TPM_HANDLE_t *sealed_handle, ++ TPM_HANDLE_t *srk_handle) +{ + grub_err_t err; + int i; @@ -888,15 +848,14 @@ index 000000000..3db25ceca + /* Try the given persistent SRK if exists */ + if (*srk_handle != 0) + { -+ err = grub_tpm2_protector_srk_load (ctx->srk_type, sealed_key, -+ parent_handle, sealed_handle, -+ srk_handle); ++ err = tpm2_protector_srk_load (ctx->srk_type, sealed_key, ++ parent_handle, sealed_handle, ++ srk_handle); + if (err != GRUB_ERR_BAD_ARGUMENT) + return err; + + grub_print_error (); -+ grub_printf_ (N_("Trying the specified SRK algorithm: %s\n"), -+ srk_type_to_name (ctx->srk_type)); ++ grub_printf ("Trying the specified SRK algorithm: %s\n", srk_type_to_name (ctx->srk_type)); + grub_errno = GRUB_ERR_NONE; + *srk_handle = 0; + } @@ -904,9 +863,9 @@ index 000000000..3db25ceca + /* Try the specified algorithm for the SRK template */ + if (*srk_handle == 0) + { -+ err = grub_tpm2_protector_srk_load (ctx->srk_type, sealed_key, -+ parent_handle, sealed_handle, -+ srk_handle); ++ err = tpm2_protector_srk_load (ctx->srk_type, sealed_key, ++ parent_handle, sealed_handle, ++ srk_handle); + if (err != GRUB_ERR_BAD_ARGUMENT) + return err; + @@ -924,14 +883,13 @@ index 000000000..3db25ceca + fallback_srks[i].detail.ecc_curve == ctx->srk_type.detail.ecc_curve)) + continue; + -+ grub_printf_ (N_("Trying fallback %s template\n"), -+ srk_type_to_name (fallback_srks[i])); ++ grub_printf ("Trying fallback %s template\n", srk_type_to_name (fallback_srks[i])); + + *srk_handle = 0; + -+ err = grub_tpm2_protector_srk_load (fallback_srks[i], sealed_key, -+ parent_handle, sealed_handle, -+ srk_handle); ++ err = tpm2_protector_srk_load (fallback_srks[i], sealed_key, ++ parent_handle, sealed_handle, ++ srk_handle); + if (err != GRUB_ERR_BAD_ARGUMENT) + return err; + @@ -943,38 +901,33 @@ index 000000000..3db25ceca +} + +static grub_err_t -+grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session, -+ struct grub_tpm2_buffer *cmd_buf) ++tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffer *cmd_buf) +{ -+ TPM2B_DIGEST pcr_digest; -+ TPML_PCR_SELECTION pcr_sel; -+ TPM_RC rc; ++ TPM2B_DIGEST_t pcr_digest; ++ TPML_PCR_SELECTION_t pcr_sel; ++ TPM_RC_t rc; + -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &pcr_digest); -+ grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (cmd_buf, &pcr_sel); -+ if (cmd_buf->error) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to unmarshal CommandPolicy for TPM2_PolicyPCR")); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &pcr_digest); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (cmd_buf, &pcr_sel); ++ if (cmd_buf->error != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to unmarshal commandPolicy for TPM2_PolicyPCR"); + -+ rc = TPM2_PolicyPCR (session, NULL, &pcr_digest, &pcr_sel, NULL); ++ rc = grub_tpm2_policypcr (session, NULL, &pcr_digest, &pcr_sel, NULL); + if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x)"), -+ rc); ++ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to submit PCR policy (TPM2_PolicyPCR: 0x%x)", rc); + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session) ++tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t session) +{ + struct grub_tpm2_buffer buf; + grub_err_t err; + + grub_tpm2_buffer_init (&buf); + if (policy->cmd_policy_len > buf.cap) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("CommandPolicy larger than TPM buffer")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "CommandPolicy larger than TPM buffer"); + + grub_memcpy (buf.data, policy->cmd_policy, policy->cmd_policy_len); + buf.size = policy->cmd_policy_len; @@ -982,26 +935,24 @@ index 000000000..3db25ceca + switch (policy->cmd_code) + { + case TPM_CC_PolicyPCR: -+ err = grub_tpm2_protector_policypcr (session, &buf); ++ err = tpm2_protector_policypcr (session, &buf); + break; + default: -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Unknown TPM Command: 0x%x"), policy->cmd_code); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown TPM Command: 0x%x", policy->cmd_code); + } + + return err; +} + +static grub_err_t -+grub_tpm2_protector_enforce_policy_seq (tpm2key_policy_t policy_seq, -+ TPMI_SH_AUTH_SESSION session) ++tpm2_protector_enforce_policy_seq (tpm2key_policy_t policy_seq, TPMI_SH_AUTH_SESSION_t session) +{ + tpm2key_policy_t policy; + grub_err_t err; + + FOR_LIST_ELEMENTS (policy, policy_seq) + { -+ err = grub_tpm2_protector_enforce_policy (policy, session); ++ err = tpm2_protector_enforce_policy (policy, session); + if (err != GRUB_ERR_NONE) + return err; + } @@ -1010,18 +961,18 @@ index 000000000..3db25ceca +} + +static grub_err_t -+grub_tpm2_protector_simple_policy_seq (const struct grub_tpm2_protector_context *ctx, -+ tpm2key_policy_t *policy_seq) ++tpm2_protector_simple_policy_seq (const tpm2_protector_context_t *ctx, ++ tpm2key_policy_t *policy_seq) +{ + tpm2key_policy_t policy = NULL; + struct grub_tpm2_buffer buf; -+ TPML_PCR_SELECTION pcr_sel = { ++ TPML_PCR_SELECTION_t pcr_sel = { + .count = 1, + .pcrSelections = { + { + .hash = ctx->bank, + .sizeOfSelect = 3, -+ .pcrSelect = { 0 } ++ .pcrSelect = {0} + }, + } + }; @@ -1037,9 +988,9 @@ index 000000000..3db25ceca + TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], ctx->pcrs[i]); + + grub_tpm2_buffer_pack_u16 (&buf, 0); -+ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&buf, &pcr_sel); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&buf, &pcr_sel); + -+ if (buf.error) ++ if (buf.error != 0) + return GRUB_ERR_BAD_ARGUMENT; + + policy = grub_malloc (sizeof(struct tpm2key_policy)); @@ -1062,49 +1013,45 @@ index 000000000..3db25ceca + + return GRUB_ERR_NONE; + -+error: ++ error: + grub_free (policy); + + return err; +} + +static grub_err_t -+grub_tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE sealed_handle, -+ grub_uint8_t **key, grub_size_t *key_size) ++tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE_t sealed_handle, ++ grub_uint8_t **key, grub_size_t *key_size) +{ -+ TPMS_AUTH_COMMAND authCmd = { 0 }; -+ TPM2B_SENSITIVE_DATA data; -+ TPM2B_NONCE nonceCaller = { 0 }; -+ TPMT_SYM_DEF symmetric = { 0 }; -+ TPMI_SH_AUTH_SESSION session; ++ TPMS_AUTH_COMMAND_t authCmd = {0}; ++ TPM2B_SENSITIVE_DATA_t data; ++ TPM2B_NONCE_t nonceCaller = {0}; ++ TPMT_SYM_DEF_t symmetric = {0}; ++ TPMI_SH_AUTH_SESSION_t session; + grub_uint8_t *key_out; -+ TPM_RC rc; ++ TPM_RC_t rc; + grub_err_t err; + + /* Start Auth Session */ + nonceCaller.size = TPM_SHA256_DIGEST_SIZE; + symmetric.algorithm = TPM_ALG_NULL; -+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, NULL, -+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256, -+ &session, NULL, NULL); ++ rc = grub_tpm2_startauthsession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, NULL, ++ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256, ++ &session, NULL, NULL); + if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to start auth session (TPM2_StartAuthSession: 0x%x)"), -+ rc); ++ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to start auth session (TPM2_StartAuthSession: 0x%x)", rc); + + /* Enforce the policy command sequence */ -+ err = grub_tpm2_protector_enforce_policy_seq (policy_seq, session); ++ err = tpm2_protector_enforce_policy_seq (policy_seq, session); + if (err != GRUB_ERR_NONE) + goto error; + + /* Unseal Sealed Key */ + authCmd.sessionHandle = session; -+ rc = TPM2_Unseal (sealed_handle, &authCmd, &data, NULL); ++ rc = grub_tpm2_unseal (sealed_handle, &authCmd, &data, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ err = grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to unseal sealed key (TPM2_Unseal: 0x%x)"), -+ rc); ++ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to unseal sealed key (TPM2_Unseal: 0x%x)", rc); + goto error; + } + @@ -1112,8 +1059,7 @@ index 000000000..3db25ceca + key_out = grub_malloc (data.size); + if (key_out == NULL) + { -+ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("No memory left to allocate unlock key buffer")); ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("no memory left to allocate unlock key buffer")); + goto error; + } + @@ -1124,23 +1070,23 @@ index 000000000..3db25ceca + + err = GRUB_ERR_NONE; + -+error: -+ TPM2_FlushContext (session); ++ error: ++ grub_tpm2_flushcontext (session); + + return err; +} + +static grub_err_t -+grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx, -+ grub_uint8_t **key, grub_size_t *key_size) ++tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx, ++ grub_uint8_t **key, grub_size_t *key_size) +{ -+ TPM2_SEALED_KEY sealed_key = { 0 }; ++ tpm2_sealed_key_t sealed_key = {0}; + void *file_bytes = NULL; + grub_size_t file_size = 0; + grub_uint8_t rsaparent = 0; -+ TPM_HANDLE parent_handle = 0; -+ TPM_HANDLE srk_handle = 0; -+ TPM_HANDLE sealed_handle = 0; ++ TPM_HANDLE_t parent_handle = 0; ++ TPM_HANDLE_t srk_handle = 0; ++ TPM_HANDLE_t sealed_handle = 0; + tpm2key_policy_t policy_seq = NULL; + tpm2key_authpolicy_t authpol = NULL; + tpm2key_authpolicy_t authpol_seq = NULL; @@ -1150,44 +1096,41 @@ index 000000000..3db25ceca + * Retrieve sealed key, parent handle, policy sequence, and authpolicy + * sequence from the key file + */ -+ if (ctx->tpm2key) ++ if (ctx->tpm2key != NULL) + { -+ err = grub_tpm2_protector_srk_read_file (ctx->tpm2key, &file_bytes, ++ err = tpm2_protector_srk_read_file (ctx->tpm2key, &file_bytes, + &file_size); + if (err != GRUB_ERR_NONE) + return err; + -+ err = grub_tpm2_protector_srk_unmarshal_tpm2key (file_bytes, -+ file_size, -+ &policy_seq, -+ &authpol_seq, -+ &rsaparent, -+ &parent_handle, -+ &sealed_key); ++ err = tpm2_protector_srk_unmarshal_tpm2key (file_bytes, ++ file_size, ++ &policy_seq, ++ &authpol_seq, ++ &rsaparent, ++ &parent_handle, ++ &sealed_key); + if (err != GRUB_ERR_NONE) + goto exit1; + + if (rsaparent == 1) + { -+ struct grub_tpm2_protector_context *ctx_w; ++ tpm2_protector_context_t *ctx_w; + + /* Overwrite the SRK type as noted in the key */ -+ ctx_w = (struct grub_tpm2_protector_context *)ctx; ++ ctx_w = (tpm2_protector_context_t *)ctx; + ctx_w->srk_type.type = TPM_ALG_RSA; + ctx_w->srk_type.detail.rsa_bits = 2048; + } + } + else + { -+ err = grub_tpm2_protector_srk_read_file (ctx->keyfile, &file_bytes, -+ &file_size); ++ err = tpm2_protector_srk_read_file (ctx->keyfile, &file_bytes, &file_size); + if (err != GRUB_ERR_NONE) + return err; + + parent_handle = TPM_RH_OWNER; -+ err = grub_tpm2_protector_srk_unmarshal_keyfile (file_bytes, -+ file_size, -+ &sealed_key); ++ err = tpm2_protector_srk_unmarshal_keyfile (file_bytes, file_size, &sealed_key); + if (err != GRUB_ERR_NONE) + goto exit1; + } @@ -1199,8 +1142,7 @@ index 000000000..3db25ceca + srk_handle = parent_handle; + + /* Load the sealed key into TPM and associate it with the SRK */ -+ err = grub_tpm2_protector_load_key (ctx, &sealed_key, parent_handle, -+ &sealed_handle, &srk_handle); ++ err = tpm2_protector_load_key (ctx, &sealed_key, parent_handle, &sealed_handle, &srk_handle); + if (err != GRUB_ERR_NONE) + goto exit1; + @@ -1213,8 +1155,7 @@ index 000000000..3db25ceca + /* Iterate the authpolicy sequence to find one that unseals the key */ + FOR_LIST_ELEMENTS (authpol, authpol_seq) + { -+ err = grub_tpm2_protector_unseal (authpol->policy_seq, sealed_handle, -+ key, key_size); ++ err = tpm2_protector_unseal (authpol->policy_seq, sealed_handle, key, key_size); + if (err == GRUB_ERR_NONE) + break; + @@ -1237,25 +1178,25 @@ index 000000000..3db25ceca + */ + if (policy_seq == NULL) + { -+ err = grub_tpm2_protector_simple_policy_seq (ctx, &policy_seq); ++ err = tpm2_protector_simple_policy_seq (ctx, &policy_seq); + if (err != GRUB_ERR_NONE) + goto exit2; + } + -+ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size); ++ err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size); + } + + /* Pop error messages on success */ + if (err == GRUB_ERR_NONE) + while (grub_error_pop ()); + -+exit2: -+ TPM2_FlushContext (sealed_handle); ++ exit2: ++ grub_tpm2_flushcontext (sealed_handle); + + if (!TPM_HT_IS_PERSISTENT (srk_handle)) -+ TPM2_FlushContext (srk_handle); ++ grub_tpm2_flushcontext (srk_handle); + -+exit1: ++ exit1: + grub_tpm2key_free_policy_seq (policy_seq); + grub_tpm2key_free_authpolicy_seq (authpol_seq); + grub_free (file_bytes); @@ -1263,90 +1204,73 @@ index 000000000..3db25ceca +} + +static grub_err_t -+grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx, -+ grub_uint8_t **key, grub_size_t *key_size) ++tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx __attribute__ ((unused)), ++ grub_uint8_t **key __attribute__ ((unused)), ++ grub_size_t *key_size __attribute__ ((unused))) +{ -+ (void)ctx; -+ (void)key; -+ (void)key_size; -+ -+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ N_("NV Index mode is not implemented yet")); ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "NV Index mode is not implemented yet"); +} + +static grub_err_t -+grub_tpm2_protector_recover (const struct grub_tpm2_protector_context *ctx, -+ grub_uint8_t **key, grub_size_t *key_size) ++tpm2_protector_recover (const tpm2_protector_context_t *ctx, ++ grub_uint8_t **key, grub_size_t *key_size) +{ + switch (ctx->mode) + { -+ case GRUB_TPM2_PROTECTOR_MODE_SRK: -+ return grub_tpm2_protector_srk_recover (ctx, key, key_size); -+ case GRUB_TPM2_PROTECTOR_MODE_NV: -+ return grub_tpm2_protector_nv_recover (ctx, key, key_size); ++ case TPM2_PROTECTOR_MODE_SRK: ++ return tpm2_protector_srk_recover (ctx, key, key_size); ++ case TPM2_PROTECTOR_MODE_NV: ++ return tpm2_protector_nv_recover (ctx, key, key_size); + default: + return GRUB_ERR_BAD_ARGUMENT; + } +} + +static grub_err_t -+grub_tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size) ++tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size) +{ + /* Expect a call to tpm2_protector_init before anybody tries to use us */ -+ if (grub_tpm2_protector_ctx.mode == GRUB_TPM2_PROTECTOR_MODE_UNSET) -+ return grub_error (GRUB_ERR_INVALID_COMMAND, -+ N_("Cannot use TPM2 key protector without initializing " -+ "it, call tpm2_protector_init first")); ++ if (tpm2_protector_ctx.mode == TPM2_PROTECTOR_MODE_UNSET) ++ return grub_error (GRUB_ERR_INVALID_COMMAND, N_("cannot use TPM2 key protector without initializing it, call tpm2_protector_init first")); + + if (key == NULL || key_size == NULL) + return GRUB_ERR_BAD_ARGUMENT; + -+ return grub_tpm2_protector_recover (&grub_tpm2_protector_ctx, key, key_size); ++ return tpm2_protector_recover (&tpm2_protector_ctx, key, key_size); +} + +static grub_err_t -+grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx) ++tpm2_protector_check_args (tpm2_protector_context_t *ctx) +{ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET) -+ ctx->mode = GRUB_TPM2_PROTECTOR_MODE_SRK; ++ if (ctx->mode == TPM2_PROTECTOR_MODE_UNSET) ++ ctx->mode = TPM2_PROTECTOR_MODE_SRK; + + /* Checks for SRK mode */ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ++ if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && + (ctx->keyfile == NULL && ctx->tpm2key == NULL)) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In SRK mode, a key file must be specified: " -+ "--tpm2key/-T or --keyfile/-k")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in SRK mode, a key file must be specified: --tpm2key/-T or --keyfile/-k")); + -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ++ if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && + (ctx->keyfile != NULL && ctx->tpm2key != NULL)) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In SRK mode, please specify a key file with " -+ "only --tpm2key/-T or --keyfile/-k")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in SRK mode, please specify a key file with only --tpm2key/-T or --keyfile/-k")); + -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->nv != 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In SRK mode, an NV Index cannot be specified")); ++ if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && ctx->nv != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in SRK mode, an NV Index cannot be specified")); + + /* Checks for NV mode */ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->nv == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In NV Index mode, an NV Index must be specified: " -+ "--nvindex or -n")); ++ if (ctx->mode == TPM2_PROTECTOR_MODE_NV && ctx->nv == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an NV Index must be specified: --nvindex or -n")); + -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ++ if (ctx->mode == TPM2_PROTECTOR_MODE_NV && + (ctx->tpm2key != NULL || ctx->keyfile != NULL)) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In NV Index mode, a keyfile cannot be specified")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, a keyfile cannot be specified")); + -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->srk != 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In NV Index mode, an SRK cannot be specified")); ++ if (ctx->mode == TPM2_PROTECTOR_MODE_NV && ctx->srk != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an SRK cannot be specified")); + -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ++ if (ctx->mode == TPM2_PROTECTOR_MODE_NV && + ctx->srk_type.type != TPM_ALG_ERROR) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In NV Index mode, an asymmetric key type cannot be " -+ "specified")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an asymmetric key type cannot be specified")); + + /* Defaults assignment */ + if (ctx->bank == TPM_ALG_ERROR) @@ -1358,7 +1282,7 @@ index 000000000..3db25ceca + ctx->pcr_count = 1; + } + -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ++ if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && + ctx->srk_type.type == TPM_ALG_ERROR) + { + ctx->srk_type.type = TPM_ALG_ECC; @@ -1369,55 +1293,47 @@ index 000000000..3db25ceca +} + +static grub_err_t -+grub_tpm2_protector_parse_file (const char *value, const char **file) ++tpm2_protector_parse_file (const char *value, const char **file) +{ + if (grub_strlen (value) == 0) + return GRUB_ERR_BAD_ARGUMENT; + + *file = grub_strdup (value); + if (*file == NULL) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("No memory to duplicate file path")); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("no memory to duplicate file path")); + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_tpm2_protector_parse_mode (const char *value, -+ grub_tpm2_protector_mode_t *mode) ++tpm2_protector_parse_mode (const char *value, tpm2_protector_mode_t *mode) +{ + if (grub_strcmp (value, "srk") == 0) -+ *mode = GRUB_TPM2_PROTECTOR_MODE_SRK; ++ *mode = TPM2_PROTECTOR_MODE_SRK; + else if (grub_strcmp (value, "nv") == 0) -+ *mode = GRUB_TPM2_PROTECTOR_MODE_NV; ++ *mode = TPM2_PROTECTOR_MODE_NV; + else -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Value '%s' is not a valid TPM2 key protector mode"), -+ value); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid TPM2 key protector mode"), value); + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc, -+ char **args __attribute__ ((unused))) ++tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc, ++ char **args __attribute__ ((unused))) +{ + struct grub_arg_list *state = ctxt->state; + grub_err_t err; + + if (argc) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("The TPM2 key protector does not accept any " -+ "non-option arguments (i.e., like -o and/or --option " -+ "only)")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("the TPM2 key protector does not accept any non-option arguments (i.e., like -o and/or --option only)")); + -+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); -+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); ++ grub_free ((void *) tpm2_protector_ctx.keyfile); ++ grub_memset (&tpm2_protector_ctx, 0, sizeof (tpm2_protector_ctx)); + + if (state[OPTION_MODE].set) /* mode */ + { -+ err = grub_tpm2_protector_parse_mode (state[OPTION_MODE].arg, -+ &grub_tpm2_protector_ctx.mode); ++ err = tpm2_protector_parse_mode (state[OPTION_MODE].arg, &tpm2_protector_ctx.mode); + if (err != GRUB_ERR_NONE) + return err; + } @@ -1425,8 +1341,8 @@ index 000000000..3db25ceca + if (state[OPTION_PCRS].set) /* pcrs */ + { + err = grub_tpm2_protector_parse_pcrs (state[OPTION_PCRS].arg, -+ grub_tpm2_protector_ctx.pcrs, -+ &grub_tpm2_protector_ctx.pcr_count); ++ tpm2_protector_ctx.pcrs, ++ &tpm2_protector_ctx.pcr_count); + if (err != GRUB_ERR_NONE) + return err; + } @@ -1434,23 +1350,23 @@ index 000000000..3db25ceca + if (state[OPTION_BANK].set) /* bank */ + { + err = grub_tpm2_protector_parse_bank (state[OPTION_BANK].arg, -+ &grub_tpm2_protector_ctx.bank); ++ &tpm2_protector_ctx.bank); + if (err != GRUB_ERR_NONE) + return err; + } + + if (state[OPTION_TPM2KEY].set) /* tpm2key */ + { -+ err = grub_tpm2_protector_parse_file (state[OPTION_TPM2KEY].arg, -+ &grub_tpm2_protector_ctx.tpm2key); ++ err = tpm2_protector_parse_file (state[OPTION_TPM2KEY].arg, ++ &tpm2_protector_ctx.tpm2key); + if (err != GRUB_ERR_NONE) + return err; + } + + if (state[OPTION_KEYFILE].set) /* keyfile */ + { -+ err = grub_tpm2_protector_parse_file (state[OPTION_KEYFILE].arg, -+ &grub_tpm2_protector_ctx.keyfile); ++ err = tpm2_protector_parse_file (state[OPTION_KEYFILE].arg, ++ &tpm2_protector_ctx.keyfile); + if (err != GRUB_ERR_NONE) + return err; + } @@ -1458,7 +1374,7 @@ index 000000000..3db25ceca + if (state[OPTION_SRK].set) /* srk */ + { + err = grub_tpm2_protector_parse_tpm_handle (state[OPTION_SRK].arg, -+ &grub_tpm2_protector_ctx.srk); ++ &tpm2_protector_ctx.srk); + if (err != GRUB_ERR_NONE) + return err; + } @@ -1466,7 +1382,7 @@ index 000000000..3db25ceca + if (state[OPTION_ASYMMETRIC].set) /* asymmetric */ + { + err = grub_tpm2_protector_parse_asymmetric (state[OPTION_ASYMMETRIC].arg, -+ &grub_tpm2_protector_ctx.srk_type); ++ &tpm2_protector_ctx.srk_type); + if (err != GRUB_ERR_NONE) + return err; + } @@ -1474,12 +1390,12 @@ index 000000000..3db25ceca + if (state[OPTION_NVINDEX].set) /* nvindex */ + { + err = grub_tpm2_protector_parse_tpm_handle (state[OPTION_NVINDEX].arg, -+ &grub_tpm2_protector_ctx.nv); ++ &tpm2_protector_ctx.nv); + if (err != GRUB_ERR_NONE) + return err; + } + -+ err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx); ++ err = tpm2_protector_check_args (&tpm2_protector_ctx); + + /* This command only initializes the protector, so nothing else to do. */ + @@ -1487,31 +1403,29 @@ index 000000000..3db25ceca +} + +static grub_err_t -+grub_tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__ ((unused)), -+ int argc, -+ char **args __attribute__ ((unused))) ++tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__ ((unused)), ++ int argc, char **args __attribute__ ((unused))) +{ -+ if (argc) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("tpm2_key_protector_clear accepts no arguments")); ++ if (argc != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("tpm2_key_protector_clear accepts no arguments")); + -+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); -+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); ++ grub_free ((void *) tpm2_protector_ctx.keyfile); ++ grub_memset (&tpm2_protector_ctx, 0, sizeof (tpm2_protector_ctx)); + + return GRUB_ERR_NONE; +} + -+static struct grub_key_protector grub_tpm2_key_protector = ++static struct grub_key_protector tpm2_key_protector = + { + .name = "tpm2", -+ .recover_key = grub_tpm2_protector_recover_key ++ .recover_key = tpm2_protector_recover_key + }; + -+GRUB_MOD_INIT (tpm2) ++GRUB_MOD_INIT (tpm2_key_protector) +{ -+ grub_tpm2_protector_init_cmd = ++ tpm2_protector_init_cmd = + grub_register_extcmd ("tpm2_key_protector_init", -+ grub_tpm2_protector_init_cmd_handler, 0, ++ tpm2_protector_init_cmd_handler, 0, + N_("[-m mode] " + "[-p pcr_list] " + "[-b pcr_bank] " @@ -1521,32 +1435,141 @@ index 000000000..3db25ceca + "[-a asymmetric_key_type] " + "[-n nv_index]"), + N_("Initialize the TPM2 key protector."), -+ grub_tpm2_protector_init_cmd_options); -+ grub_tpm2_protector_clear_cmd = ++ tpm2_protector_init_cmd_options); ++ tpm2_protector_clear_cmd = + grub_register_extcmd ("tpm2_key_protector_clear", -+ grub_tpm2_protector_clear_cmd_handler, 0, NULL, ++ tpm2_protector_clear_cmd_handler, 0, NULL, + N_("Clear the TPM2 key protector if previously initialized."), + NULL); -+ grub_key_protector_register (&grub_tpm2_key_protector); ++ grub_key_protector_register (&tpm2_key_protector); +} + -+GRUB_MOD_FINI (tpm2) ++GRUB_MOD_FINI (tpm2_key_protector) +{ -+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); -+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); ++ grub_free ((void *) tpm2_protector_ctx.keyfile); + -+ grub_key_protector_unregister (&grub_tpm2_key_protector); -+ grub_unregister_extcmd (grub_tpm2_protector_clear_cmd); -+ grub_unregister_extcmd (grub_tpm2_protector_init_cmd); ++ grub_key_protector_unregister (&tpm2_key_protector); ++ grub_unregister_extcmd (tpm2_protector_clear_cmd); ++ grub_unregister_extcmd (tpm2_protector_init_cmd); +} -diff --git a/grub-core/tpm2/tpm2key.asn b/grub-core/tpm2/tpm2key.asn -new file mode 100644 -index 000000000..7ad4b6a2a +Index: grub-2.12/grub-core/commands/tpm2_key_protector/tpm2.h +=================================================================== --- /dev/null -+++ b/grub-core/tpm2/tpm2key.asn -@@ -0,0 +1,33 @@ ++++ grub-2.12/grub-core/commands/tpm2_key_protector/tpm2.h +@@ -0,0 +1,36 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_TPM2_HEADER ++#define GRUB_TPM2_TPM2_HEADER 1 ++ ++#include ++#include ++#include ++ ++/* Well-Known Windows SRK handle */ ++#define TPM2_SRK_HANDLE 0x81000001 ++ ++struct tpm2_sealed_key { ++ TPM2B_PUBLIC_t public; ++ TPM2B_PRIVATE_t private; ++}; ++typedef struct tpm2_sealed_key tpm2_sealed_key_t; ++ ++#endif /* ! GRUB_TPM2_TPM2_HEADER */ +Index: grub-2.12/grub-core/commands/tpm2_key_protector/tpm2_args.h +=================================================================== +--- /dev/null ++++ grub-2.12/grub-core/commands/tpm2_key_protector/tpm2_args.h +@@ -0,0 +1,49 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_INTERNAL_ARGS_HEADER ++#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1 ++ ++#include ++ ++#include "tpm2.h" ++ ++struct grub_srk_type ++{ ++ TPMI_ALG_PUBLIC_t type; ++ union { ++ TPM_KEY_BITS_t rsa_bits; ++ TPM_ECC_CURVE_t ecc_curve; ++ } detail; ++}; ++typedef struct grub_srk_type grub_srk_type_t; ++ ++extern grub_err_t ++grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, grub_uint8_t *pcr_count); ++ ++extern grub_err_t ++grub_tpm2_protector_parse_asymmetric (const char *value, grub_srk_type_t *srk_type); ++ ++extern grub_err_t ++grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID_t *bank); ++ ++extern grub_err_t ++grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE_t *handle); ++ ++#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */ +Index: grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key.asn +=================================================================== +--- /dev/null ++++ grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key.asn +@@ -0,0 +1,49 @@ +-- -+-- TPM 2.0 key file format ++-- GRUB: GRand Unified Bootloader ++-- Copyright (C) 2024 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 . ++-- ++-- This file describes TPM 2.0 Key File format for libtasn1. +-- To generate tpm2key_asn1_tab.c: asn1Parser tpm2key.asn +-- +TPM2KEY {} @@ -1578,15 +1601,15 @@ index 000000000..7ad4b6a2a +} + +END -diff --git a/grub-core/tpm2/tpm2key.c b/grub-core/tpm2/tpm2key.c -new file mode 100644 -index 000000000..7a55644e5 +Index: grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key.c +=================================================================== --- /dev/null -+++ b/grub-core/tpm2/tpm2key.c -@@ -0,0 +1,476 @@ ++++ grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key.c +@@ -0,0 +1,499 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2023 SUSE LLC ++ * Copyright (C) 2024 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 @@ -1602,12 +1625,13 @@ index 000000000..7a55644e5 + * along with GRUB. If not, see . + */ + -+#include +#include +#include +#include -+#include -+#include ++ ++#include ++ ++#include "tpm2key.h" + +extern asn1_static_node tpm2key_asn1_tab[]; +const char *sealed_key_oid = "2.23.133.10.1.5"; @@ -1653,19 +1677,39 @@ index 000000000..7a55644e5 + if (ret != ASN1_SUCCESS) + return ret; + ++ /* ++ * ASN.1 INTEGER is encoded in the following format: ++ * ++ * TAG LENGTH OCTECTS ++ * ++ * The integer TAG is 02 and LENGTH is the number of followed OCTECTS in ++ * big endian. For example: ++ * ++ * 0x1: 02 01 01 ++ * 0xabcd: 02 02 ab cd ++ * ++ * To decribe 0x1, it only takes 1 octect, so LENGTH is 0x01 and the ++ * octect is 0x01. On the other hand, 0xabcd requires 2 octects: 'ab" and ++ * 'cd', so LENGTH is 0x02. ++ * ++ * This function only expects a uint32 integer, so it rejects any integer ++ * containing more than 4 octects. ++ */ + if (data_size > 4) + { + ret = ASN1_MEM_ERROR; + goto error; + } + -+ /* convert the big-endian integer to host uint32 */ -+ ptr = (grub_uint8_t *)&tmp + (4 - data_size); ++ /* Copy the octects into 'tmp' to make it a big-endian uint32 */ ++ ptr = (grub_uint8_t *) &tmp + (4 - data_size); + grub_memcpy (ptr, data, data_size); ++ ++ /* Convert the big-endian integer to host uint32 */ + tmp = grub_be_to_cpu32 (tmp); + + *out = tmp; -+error: ++ error: + if (data) + grub_free (data); + return ret; @@ -1700,29 +1744,24 @@ index 000000000..7a55644e5 + */ + ret = asn1_array2tree (tpm2key_asn1_tab, &tpm2key_asn1, NULL); + if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to parse TPM2KEY ASN.1 array")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to parse TPM2KEY ASN.1 array"); + + ret = asn1_create_element (tpm2key_asn1, "TPM2KEY.TPMKey", &tpm2key); + if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to create TPM2KEY.TPMKey")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to create TPM2KEY.TPMKey"); + + ret = asn1_der_decoding (&tpm2key, data, size, NULL); + if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to decode TPM2KEY DER")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to decode TPM2KEY DER"); + + /* Check if 'type' is Sealed Key or not */ + ret = asn1_allocate_and_read (tpm2key, "type", &type_oid, &type_oid_size); + if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ N_("Not a valid TPM2KEY file")); ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a valid TPM2KEY file"); + + if (grub_memcmp (sealed_key_oid, type_oid, type_oid_size) != 0) + { -+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ N_("Not a valid TPM2KEY file")); ++ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a valid TPM2KEY file"); + goto error; + } + @@ -1730,7 +1769,7 @@ index 000000000..7a55644e5 + ret = asn1_allocate_and_read (tpm2key, "emptyAuth", &empty_auth, &empty_auth_size); + if (ret != ASN1_SUCCESS || grub_strncmp ("TRUE", empty_auth, empty_auth_size) != 0) + { -+ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("emptyAuth not TRUE")); ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, "emptyAuth not TRUE"); + goto error; + } + @@ -1738,8 +1777,7 @@ index 000000000..7a55644e5 + ret = asn1_read_value (tpm2key, "secret", NULL, &tmp_size); + if (ret != ASN1_ELEMENT_NOT_FOUND) + { -+ err = grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("\"secret\" not allowed for Sealed Key")); ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, "\"secret\" not allowed for Sealed Key"); + goto error; + } + @@ -1747,7 +1785,7 @@ index 000000000..7a55644e5 + + err = GRUB_ERR_NONE; + -+error: ++ error: + grub_free (type_oid); + grub_free (empty_auth); + @@ -1769,10 +1807,10 @@ index 000000000..7a55644e5 + int ret; + + if (rsaparent == NULL) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer detected")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "NULL pointer detected"); + + if (tpm2key == NULL) -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Invalid parent node")); ++ return grub_error (GRUB_ERR_READ_ERROR, "invalid parent node"); + + ret = asn1_allocate_and_read (tpm2key, "rsaParent", &bool_str, &bool_str_size); + if (ret == ASN1_SUCCESS) @@ -1785,7 +1823,7 @@ index 000000000..7a55644e5 + else if (ret == ASN1_ELEMENT_NOT_FOUND) + *rsaparent = 0; + else -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve rsaParent")); ++ return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve rsaParent"); + + grub_free (bool_str); + @@ -1798,14 +1836,14 @@ index 000000000..7a55644e5 + int ret; + + if (parent == NULL) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer detected")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "NULL pointer detected"); + + if (tpm2key == NULL) -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Invalid parent node")); ++ return grub_error (GRUB_ERR_READ_ERROR, "invalid parent node"); + + ret = asn1_read_uint32 (tpm2key, "parent", parent); + if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve parent")); ++ return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve parent"); + + return GRUB_ERR_NONE; +} @@ -1816,16 +1854,14 @@ index 000000000..7a55644e5 + int ret; + + if (name == NULL || data == NULL || size == NULL) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter(s)")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid parameter(s)"); + + if (tpm2key == NULL) -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Invalid %s node"), name); ++ return grub_error (GRUB_ERR_READ_ERROR, "invalid %s node", name); + + ret = asn1_allocate_and_read (tpm2key, name, data, size); + if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_READ_ERROR, -+ N_("Failed to retrieve %s"), -+ name); ++ return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve %s", name); + + return GRUB_ERR_NONE; +} @@ -1843,6 +1879,18 @@ index 000000000..7a55644e5 +} + +/* ++ * The maximum and minimum number of elements for 'policy' and 'authPolicy' sequences ++ * ++ * Although there is no limit for the number of sequences elements, we set the upper ++ * bound to 99 to make it easier to implement the code. ++ * ++ * Any 'policy' or 'authPolicy' contains more than 99 commands/policies would become ++ * extremely complex to manage so it is impractical to support such use case. ++ */ ++#define TPM2KEY_ELEMENTS_MAX 99 ++#define TPM2KEY_ELEMENTS_MIN 1 ++ ++/* + * The string to fetch 'Policy' from 'authPolicy': + * authPolicy.?XX.Policy + */ @@ -1884,7 +1932,7 @@ index 000000000..7a55644e5 + * in practice, it takes one or two policy commands to unseal the key, + * so the 99 commands limit is more than enough. + */ -+ if (policy_n > 100 || policy_n < 1) ++ if (policy_n > TPM2KEY_ELEMENTS_MAX || policy_n < TPM2KEY_ELEMENTS_MIN) + return ASN1_VALUE_NOT_VALID; + + /* @@ -1932,8 +1980,8 @@ index 000000000..7a55644e5 + + return ASN1_SUCCESS; + -+error: -+ if (policy) ++ error: ++ if (policy != NULL) + { + grub_free (policy->cmd_policy); + grub_free (policy); @@ -1956,7 +2004,7 @@ index 000000000..7a55644e5 + return GRUB_ERR_NONE; + } + else if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve policy")); ++ return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve policy"); + + return GRUB_ERR_NONE; +} @@ -1996,12 +2044,11 @@ index 000000000..7a55644e5 + return GRUB_ERR_NONE; + } + else if (ret != ASN1_SUCCESS) -+ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve authPolicy")); ++ return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve authPolicy"); + + /* Limit the number of authPolicy elements to two digits (99) */ -+ if (authpol_n > 100 || authpol_n < 1) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Invalid number of authPolicy elements")); ++ if (authpol_n > TPM2KEY_ELEMENTS_MAX || authpol_n < TPM2KEY_ELEMENTS_MIN) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid number of authPolicy elements"); + + /* + * Iterate the authPolicy elements backwards since grub_list_push() prepends @@ -2011,8 +2058,7 @@ index 000000000..7a55644e5 + authpol = grub_zalloc (sizeof (struct tpm2key_authpolicy)); + if (authpol == NULL) + { -+ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Failed to allocate memory for authPolicy")); ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate memory for authPolicy"); + goto error; + } + grub_snprintf (authpol_pol, AUTHPOLICY_POL_MAX, "authPolicy.?%d.Policy", i); @@ -2020,8 +2066,7 @@ index 000000000..7a55644e5 + ret = tpm2key_get_policy_seq (tpm2key, authpol_pol, &authpol->policy_seq); + if (ret != ASN1_SUCCESS) + { -+ err = grub_error (GRUB_ERR_READ_ERROR, -+ N_("Failed to retrieve policy from authPolicy")); ++ err = grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve policy from authPolicy"); + goto error; + } + @@ -2033,8 +2078,8 @@ index 000000000..7a55644e5 + + return GRUB_ERR_NONE; + -+error: -+ if (authpol) ++ error: ++ if (authpol != NULL) + { + grub_tpm2key_free_policy_seq (authpol->policy_seq); + grub_free (authpol); @@ -2060,121 +2105,15 @@ index 000000000..7a55644e5 + grub_free (authpol); + } +} -diff --git a/grub-core/tpm2/tpm2key_asn1_tab.c b/grub-core/tpm2/tpm2key_asn1_tab.c -new file mode 100644 -index 000000000..6868924f9 +Index: grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key.h +=================================================================== --- /dev/null -+++ b/grub-core/tpm2/tpm2key_asn1_tab.c -@@ -0,0 +1,45 @@ -+/* -+ * This file is generated by 'asn1Parser tpm2key.asn' and the '#include' -+ * headers are replaced with the ones in grub2. -+ * - 'grub/mm.h' for the definition of 'NULL' -+ * - 'grub/libtasn1.h' for the definition of 'asn1_static_node' -+ */ -+ -+#include -+#include -+ -+const asn1_static_node tpm2key_asn1_tab[] = { -+ { "TPM2KEY", 536875024, NULL }, -+ { NULL, 1073741836, NULL }, -+ { "TPMPolicy", 1610612741, NULL }, -+ { "CommandCode", 1610620931, NULL }, -+ { NULL, 2056, "0"}, -+ { "CommandPolicy", 536879111, NULL }, -+ { NULL, 2056, "1"}, -+ { "TPMAuthPolicy", 1610612741, NULL }, -+ { "Name", 1610637346, NULL }, -+ { NULL, 2056, "0"}, -+ { "Policy", 536879115, NULL }, -+ { NULL, 1073743880, "1"}, -+ { NULL, 2, "TPMPolicy"}, -+ { "TPMKey", 536870917, NULL }, -+ { "type", 1073741836, NULL }, -+ { "emptyAuth", 1610637316, NULL }, -+ { NULL, 2056, "0"}, -+ { "policy", 1610637323, NULL }, -+ { NULL, 1073743880, "1"}, -+ { NULL, 2, "TPMPolicy"}, -+ { "secret", 1610637319, NULL }, -+ { NULL, 2056, "2"}, -+ { "authPolicy", 1610637323, NULL }, -+ { NULL, 1073743880, "3"}, -+ { NULL, 2, "TPMAuthPolicy"}, -+ { "description", 1610637346, NULL }, -+ { NULL, 2056, "4"}, -+ { "rsaParent", 1610637316, NULL }, -+ { NULL, 2056, "5"}, -+ { "parent", 1073741827, NULL }, -+ { "pubkey", 1073741831, NULL }, -+ { "privkey", 7, NULL }, -+ { NULL, 0, NULL } -+}; -diff --git a/include/grub/tpm2/internal/args.h b/include/grub/tpm2/internal/args.h -new file mode 100644 -index 000000000..9f4c0eb9f ---- /dev/null -+++ b/include/grub/tpm2/internal/args.h -@@ -0,0 +1,49 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER -+#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1 -+ -+#include -+#include -+ -+struct grub_srk_type -+{ -+ TPMI_ALG_PUBLIC type; -+ union { -+ TPM_KEY_BITS rsa_bits; -+ TPM_ECC_CURVE ecc_curve; -+ } detail; -+}; -+typedef struct grub_srk_type grub_srk_type_t; -+ -+grub_err_t -+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, -+ grub_uint8_t *pcr_count); -+ -+grub_err_t -+grub_tpm2_protector_parse_asymmetric (const char *value, -+ grub_srk_type_t *srk_type); -+ -+grub_err_t -+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank); -+ -+grub_err_t -+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle); -+ -+#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */ -diff --git a/include/grub/tpm2/tpm2key.h b/include/grub/tpm2/tpm2key.h -new file mode 100644 -index 000000000..c27b5305e ---- /dev/null -+++ b/include/grub/tpm2/tpm2key.h -@@ -0,0 +1,86 @@ ++++ grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key.h +@@ -0,0 +1,87 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2023 SUSE LLC ++ * Copyright (C) 2024 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 @@ -2227,37 +2166,102 @@ index 000000000..c27b5305e +}; +typedef struct tpm2key_authpolicy *tpm2key_authpolicy_t; + -+grub_err_t ++extern grub_err_t +grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size); + -+void ++extern void +grub_tpm2key_end_parsing (asn1_node tpm2key); + -+grub_err_t ++extern grub_err_t +grub_tpm2key_get_rsaparent (asn1_node tpm2key, grub_uint8_t *rsaparent); + -+grub_err_t ++extern grub_err_t +grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent); + -+grub_err_t ++extern grub_err_t +grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size); + -+grub_err_t ++extern grub_err_t +grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size); + -+grub_err_t ++extern grub_err_t +grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq); + -+void ++extern void +grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq); + -+grub_err_t ++extern grub_err_t +grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq); + -+void ++extern void +grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq); + +#endif /* GRUB_TPM2_TPM2KEY_HEADER */ --- -2.35.3 - +Index: grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c +=================================================================== +--- /dev/null ++++ grub-2.12/grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c +@@ -0,0 +1,63 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2024 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 . ++ */ ++ ++/* ++ * This file is generated by 'asn1Parser tpm2key.asn' and the '#include' ++ * headers are replaced with the ones in grub2. ++ * - 'grub/mm.h' for the definition of 'NULL' ++ * - 'libtasn1.h' for the definition of 'asn1_static_node' ++ */ ++ ++#include ++#include ++ ++const asn1_static_node tpm2key_asn1_tab[] = { ++ { "TPM2KEY", 536875024, NULL }, ++ { NULL, 1073741836, NULL }, ++ { "TPMPolicy", 1610612741, NULL }, ++ { "CommandCode", 1610620931, NULL }, ++ { NULL, 2056, "0"}, ++ { "CommandPolicy", 536879111, NULL }, ++ { NULL, 2056, "1"}, ++ { "TPMAuthPolicy", 1610612741, NULL }, ++ { "Name", 1610637346, NULL }, ++ { NULL, 2056, "0"}, ++ { "Policy", 536879115, NULL }, ++ { NULL, 1073743880, "1"}, ++ { NULL, 2, "TPMPolicy"}, ++ { "TPMKey", 536870917, NULL }, ++ { "type", 1073741836, NULL }, ++ { "emptyAuth", 1610637316, NULL }, ++ { NULL, 2056, "0"}, ++ { "policy", 1610637323, NULL }, ++ { NULL, 1073743880, "1"}, ++ { NULL, 2, "TPMPolicy"}, ++ { "secret", 1610637319, NULL }, ++ { NULL, 2056, "2"}, ++ { "authPolicy", 1610637323, NULL }, ++ { NULL, 1073743880, "3"}, ++ { NULL, 2, "TPMAuthPolicy"}, ++ { "description", 1610637346, NULL }, ++ { NULL, 2056, "4"}, ++ { "rsaParent", 1610637316, NULL }, ++ { NULL, 2056, "5"}, ++ { "parent", 1073741827, NULL }, ++ { "pubkey", 1073741831, NULL }, ++ { "privkey", 7, NULL }, ++ { NULL, 0, NULL } ++}; diff --git a/0001-key_protector-Add-key-protectors-framework.patch b/0001-key_protector-Add-key-protectors-framework.patch index a59e7bb..1c4afeb 100644 --- a/0001-key_protector-Add-key-protectors-framework.patch +++ b/0001-key_protector-Add-key-protectors-framework.patch @@ -1,7 +1,7 @@ -From bf09618c47c6632b763960e265436294ab98dd43 Mon Sep 17 00:00:00 2001 +From 1bc53f8fc980914132040670b85a010e094559ec Mon Sep 17 00:00:00 2001 From: Hernan Gatta Date: Tue, 1 Feb 2022 05:02:53 -0800 -Subject: [PATCH 1/5] key_protector: Add key protectors framework +Subject: [PATCH] key_protector: Add key protectors framework A key protector encapsulates functionality to retrieve an unlocking key for a fully-encrypted disk from a specific source. A key protector @@ -19,17 +19,18 @@ Cc: Vladimir Serbinenko Signed-off-by: Hernan Gatta Signed-off-by: Gary Lin Reviewed-by: Stefan Berger +Reviewed-by: Daniel Kiper --- grub-core/Makefile.am | 1 + grub-core/Makefile.core.def | 5 +++ - grub-core/disk/key_protector.c | 78 ++++++++++++++++++++++++++++++++++ - include/grub/key_protector.h | 46 ++++++++++++++++++++ - 4 files changed, 130 insertions(+) + grub-core/disk/key_protector.c | 73 ++++++++++++++++++++++++++++++++++ + include/grub/key_protector.h | 47 ++++++++++++++++++++++ + 4 files changed, 126 insertions(+) create mode 100644 grub-core/disk/key_protector.c create mode 100644 include/grub/key_protector.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index f18550c1c..9d3d5f519 100644 +index 1eda467e0..e50db8106 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -90,6 +90,7 @@ endif @@ -41,10 +42,10 @@ index f18550c1c..9d3d5f519 100644 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 bc893e547..4307b8e2d 100644 +index a38955e18..37f131ae2 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -1302,6 +1302,11 @@ module = { +@@ -1282,6 +1282,11 @@ module = { common = disk/raid6_recover.c; }; @@ -58,13 +59,14 @@ index bc893e547..4307b8e2d 100644 common = disk/scsi.c; diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c new file mode 100644 -index 000000000..b84afe1c7 +index 000000000..0d146c1c0 --- /dev/null +++ b/grub-core/disk/key_protector.c -@@ -0,0 +1,78 @@ +@@ -0,0 +1,73 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 @@ -93,16 +95,14 @@ index 000000000..b84afe1c7 +grub_err_t +grub_key_protector_register (struct grub_key_protector *protector) +{ -+ if (protector == NULL || protector->name == NULL || grub_strlen (protector->name) == 0) -+ return GRUB_ERR_BAD_ARGUMENT; ++ if (protector == NULL || protector->name == NULL || protector->name[0] == '\0') ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for registration"); + -+ if (grub_key_protectors && -+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), -+ protector->name)) -+ return GRUB_ERR_BAD_ARGUMENT; ++ if (grub_key_protectors != NULL && ++ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector->name) != NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Key protector '%s' already registered", protector->name); + -+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), -+ GRUB_AS_LIST (protector)); ++ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector)); + + return GRUB_ERR_NONE; +} @@ -111,7 +111,7 @@ index 000000000..b84afe1c7 +grub_key_protector_unregister (struct grub_key_protector *protector) +{ + if (protector == NULL) -+ return GRUB_ERR_BAD_ARGUMENT; ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration"); + + grub_list_remove (GRUB_AS_LIST (protector)); + @@ -125,30 +125,27 @@ index 000000000..b84afe1c7 + struct grub_key_protector *kp = NULL; + + if (grub_key_protectors == NULL) -+ return GRUB_ERR_OUT_OF_RANGE; ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered"); + -+ if (protector == NULL || grub_strlen (protector) == 0) -+ return GRUB_ERR_BAD_ARGUMENT; ++ if (protector == NULL || protector[0] == '\0') ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector"); + -+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), -+ protector); ++ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector); + if (kp == NULL) -+ 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 grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector); + + return kp->recover_key (key, key_size); +} diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h new file mode 100644 -index 000000000..6e6a6fb24 +index 000000000..00b15c13d --- /dev/null +++ b/include/grub/key_protector.h -@@ -0,0 +1,46 @@ +@@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 @@ -193,5 +190,5 @@ index 000000000..6e6a6fb24 + +#endif /* ! GRUB_PROTECTOR_HEADER */ -- -2.35.3 +2.43.0 diff --git a/0001-tpm2-Add-extra-RSA-SRK-types.patch b/0001-tpm2-Add-extra-RSA-SRK-types.patch index b324309..7311468 100644 --- a/0001-tpm2-Add-extra-RSA-SRK-types.patch +++ b/0001-tpm2-Add-extra-RSA-SRK-types.patch @@ -1,4 +1,4 @@ -From f41a45b080cb9c6f59879a3e23f9ec2380015a16 Mon Sep 17 00:00:00 2001 +From 5b4ecd408417249dec8bfc71a3c0b7ef1070d3fa Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Thu, 25 Apr 2024 16:21:45 +0800 Subject: [PATCH] tpm2: Add extra RSA SRK types @@ -8,16 +8,16 @@ to support those parameters. Signed-off-by: Gary Lin --- - grub-core/tpm2/args.c | 12 ++++++++++++ - grub-core/tpm2/module.c | 16 ++++++++++++++-- - util/grub-protect.c | 4 ++-- + grub-core/commands/tpm2_key_protector/args.c | 12 ++++++++++++ + grub-core/commands/tpm2_key_protector/module.c | 16 ++++++++++++++-- + util/grub-protect.c | 4 ++-- 3 files changed, 28 insertions(+), 4 deletions(-) -diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c -index c11280ab9..d140364d2 100644 ---- a/grub-core/tpm2/args.c -+++ b/grub-core/tpm2/args.c -@@ -92,6 +92,18 @@ grub_tpm2_protector_parse_asymmetric (const char *value, +diff --git a/grub-core/commands/tpm2_key_protector/args.c b/grub-core/commands/tpm2_key_protector/args.c +index 48c39de01..b291793a7 100644 +--- a/grub-core/commands/tpm2_key_protector/args.c ++++ b/grub-core/commands/tpm2_key_protector/args.c +@@ -85,6 +85,18 @@ grub_tpm2_protector_parse_asymmetric (const char *value, srk_type->type = TPM_ALG_RSA; srk_type->detail.rsa_bits = 2048; } @@ -34,13 +34,13 @@ index c11280ab9..d140364d2 100644 + srk_type->detail.rsa_bits = 4096; + } else - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("Value '%s' is not a valid asymmetric key type"), -diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c -index b754b38df..8b72ed6fa 100644 ---- a/grub-core/tpm2/module.c -+++ b/grub-core/tpm2/module.c -@@ -136,8 +136,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] = + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid asymmetric key type"), value); + +diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c +index 74e79a545..ee16d7f15 100644 +--- a/grub-core/commands/tpm2_key_protector/module.c ++++ b/grub-core/commands/tpm2_key_protector/module.c +@@ -138,8 +138,8 @@ static const struct grub_arg_option tpm2_protector_init_cmd_options[] = .arg = NULL, .type = ARG_TYPE_STRING, .doc = @@ -51,18 +51,18 @@ index b754b38df..8b72ed6fa 100644 }, /* NV Index-mode options */ { -@@ -541,6 +541,10 @@ srk_type_to_name (grub_srk_type_t srk_type) - { - case 2048: - return "RSA2048"; -+ case 3072: -+ return "RSA3072"; -+ case 4096: -+ return "RSA4096"; - } - } +@@ -517,6 +517,10 @@ srk_type_to_name (grub_srk_type_t srk_type) + return "ECC_NIST_P256"; + else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 2048) + return "RSA2048"; ++ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 3072) ++ return "RSA3072"; ++ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 4096) ++ return "RSA4096"; -@@ -561,6 +565,14 @@ grub_tpm2_protector_load_key (const struct grub_tpm2_protector_context *ctx, + return "Unknown"; + } +@@ -535,6 +539,14 @@ tpm2_protector_load_key (const tpm2_protector_context_t *ctx, .type = TPM_ALG_ECC, .detail.ecc_curve = TPM_ECC_NIST_P256, }, @@ -78,20 +78,20 @@ index b754b38df..8b72ed6fa 100644 .type = TPM_ALG_RSA, .detail.rsa_bits = 2048, diff --git a/util/grub-protect.c b/util/grub-protect.c -index 869f45861..00be03ca0 100644 +index 5b7e952f4..f1108f2c5 100644 --- a/util/grub-protect.c +++ b/util/grub-protect.c -@@ -199,8 +199,8 @@ static struct argp_option grub_protect_options[] = +@@ -202,8 +202,8 @@ static struct argp_option protect_options[] = .arg = "TYPE", .flags = 0, .doc = -- N_("The type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)." +- N_("Set the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)." - "(default: ECC)"), -+ N_("The type of SRK: RSA (RSA2048), RSA3072, RSA4096, " ++ N_("Set the type of SRK: RSA (RSA2048), RSA3072, RSA4096, " + "and ECC (ECC_NIST_P256). (default: ECC)"), .group = 0 }, { -- -2.35.3 +2.43.0 diff --git a/0001-tpm2-Support-authorized-policy.patch b/0001-tpm2-Support-authorized-policy.patch deleted file mode 100644 index 7bfbe25..0000000 --- a/0001-tpm2-Support-authorized-policy.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 26a66098d5fa50b9462c8c815429a4c18f20310b Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Thu, 6 Apr 2023 16:00:25 +0800 -Subject: [PATCH] tpm2: Support authorized policy - -This commit handles the TPM2_PolicyAuthorize command from the key file -in TPM 2.0 Key File format. - -TPM2_PolicyAuthorize is the essential command to support authorized -policy which allows the users to sign TPM policies with their own keys. -Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize -comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and -'TPMT_SIGNATURE signature'. To verify the signature, the current policy -digest is hashed with the hash algorithm written in 'signature', and then -'signature' is verified with the hashed policy digest and 'pubkey'. Once -TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the -signed policy. - -To create the key file with authorized policy, here are the pcr-oracle(*2) -commands: - - # Generate the RSA key and create the authorized policy file - $ pcr-oracle \ - --rsa-generate-key \ - --private-key policy-key.pem \ - --auth authorized.policy \ - create-authorized-policy 0,2,4,7,9 - - # Seal the secret with the authorized policy - $ pcr-oracle \ - --key-format tpm2.0 \ - --auth authorized.policy \ - --input disk-secret.txt \ - --output sealed.key \ - seal-secret - - # Sign the predicted PCR policy - $ pcr-oracle \ - --key-format tpm2.0 \ - --private-key policy-key.pem \ - --from eventlog \ - --stop-event "grub-file=grub.cfg" \ - --after \ - --input sealed.key \ - --output sealed.tpm \ - sign 0,2,4,7,9 - -Then specify the key file and the key protector to grub.cfg in the EFI -system partition: - -tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm -cryptomount -u -P tpm2 - -For any change in the boot components, just run the 'sign' command again -to update the signature in sealed.tpm, and TPM can unseal the key file -with the updated PCR policy. - -(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html -(*2) https://github.com/okirch/pcr-oracle - -Signed-off-by: Gary Lin -Reviewed-by: Stefan Berger ---- - grub-core/tpm2/module.c | 84 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 84 insertions(+) - -diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c -index 3db25ceca..e83b02865 100644 ---- a/grub-core/tpm2/module.c -+++ b/grub-core/tpm2/module.c -@@ -650,6 +650,87 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session, - return GRUB_ERR_NONE; - } - -+static grub_err_t -+grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session, -+ struct grub_tpm2_buffer *cmd_buf) -+{ -+ TPM2B_PUBLIC pubkey; -+ TPM2B_DIGEST policy_ref; -+ TPMT_SIGNATURE signature; -+ TPM2B_DIGEST pcr_policy; -+ TPM2B_DIGEST pcr_policy_hash; -+ TPMI_ALG_HASH sig_hash; -+ TPMT_TK_VERIFIED verification_ticket; -+ TPM_HANDLE pubkey_handle = 0; -+ TPM2B_NAME pubname; -+ TPM_RC rc; -+ grub_err_t err; -+ -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref); -+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature); -+ if (cmd_buf->error != 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to unmarshal the buffer for TPM2_PolicyAuthorize")); -+ -+ /* Retrieve Policy Digest */ -+ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x)."), -+ rc); -+ -+ /* Calculate the digest of the polcy for VerifySignature */ -+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature); -+ if (sig_hash == TPM_ALG_NULL) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Failed to get the hash algorithm of the signature")); -+ -+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash, -+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"), -+ rc); -+ -+ /* Load the public key */ -+ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER, -+ &pubkey_handle, &pubname, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to load public key (TPM2_LoadExternal: 0x%x)"), -+ rc); -+ -+ /* Verify the signature against the public key and the policy digest */ -+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature, -+ &verification_ticket, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ err = grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to verify signature (TPM2_VerifySignature: 0x%x)"), -+ rc); -+ goto error; -+ } -+ -+ /* Authorize the signed policy with the public key and the verification ticket */ -+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname, -+ &verification_ticket, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ err = grub_error (GRUB_ERR_BAD_DEVICE, -+ N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)"), -+ rc); -+ goto error; -+ } -+ -+ err = GRUB_ERR_NONE; -+ -+error: -+ TPM2_FlushContext (pubkey_handle); -+ -+ return err; -+} -+ - static grub_err_t - grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session) - { -@@ -669,6 +750,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO - case TPM_CC_PolicyPCR: - err = grub_tpm2_protector_policypcr (session, &buf); - break; -+ case TPM_CC_PolicyAuthorize: -+ err = grub_tpm2_protector_policyauthorize (session, &buf); -+ break; - default: - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("Unknown TPM Command: 0x%x"), policy->cmd_code); --- -2.35.3 - diff --git a/0001-tpm2-Implement-NV-index.patch b/0001-tpm2_key_protector-Implement-NV-index.patch similarity index 53% rename from 0001-tpm2-Implement-NV-index.patch rename to 0001-tpm2_key_protector-Implement-NV-index.patch index baf150a..2f6e53b 100644 --- a/0001-tpm2-Implement-NV-index.patch +++ b/0001-tpm2_key_protector-Implement-NV-index.patch @@ -1,12 +1,12 @@ -From 947009d79e3f17b10a7753bdde8d3a4a7b757bed Mon Sep 17 00:00:00 2001 +From 53e24662523d033ae3506b73787b972ef332db36 Mon Sep 17 00:00:00 2001 From: Patrick Colp Date: Mon, 31 Jul 2023 07:01:45 -0700 -Subject: [PATCH 1/4] tpm2: Implement NV index +Subject: [PATCH] tpm2_key_protector: Implement NV index Currently with the TPM2 protector, only SRK mode is supported and NV index support is just a stub. Implement the NV index option. -Note: This only extends support on the unseal path. grub2_protect +Note: This only extends support on the unseal path. grub-protect has not been updated. tpm2-tools can be used to insert a key into the NV index. @@ -36,41 +36,40 @@ Then to unseal the key in grub, add this to grub.cfg: Signed-off-by: Patrick Colp Signed-off-by: Gary Lin Reviewed-by: Stefan Berger +Reviewed-by: Daniel Kiper --- - grub-core/tpm2/module.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) + .../commands/tpm2_key_protector/module.c | 23 +++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) -diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c -index e83b02865..b754b38df 100644 ---- a/grub-core/tpm2/module.c -+++ b/grub-core/tpm2/module.c -@@ -1035,12 +1035,27 @@ static grub_err_t - grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx, - grub_uint8_t **key, grub_size_t *key_size) +diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c +index 6b4b5d460..74e79a545 100644 +--- a/grub-core/commands/tpm2_key_protector/module.c ++++ b/grub-core/commands/tpm2_key_protector/module.c +@@ -973,11 +973,26 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx, + } + + static grub_err_t +-tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx __attribute__ ((unused)), +- grub_uint8_t **key __attribute__ ((unused)), +- grub_size_t *key_size __attribute__ ((unused))) ++tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx, ++ grub_uint8_t **key, grub_size_t *key_size) { -- (void)ctx; -- (void)key; -- (void)key_size; -+ TPM_HANDLE sealed_handle = ctx->nv; +- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "NV Index mode is not implemented yet"); ++ TPM_HANDLE_t sealed_handle = ctx->nv; + tpm2key_policy_t policy_seq = NULL; + grub_err_t err; + + /* Create a basic policy sequence based on the given PCR selection */ -+ err = grub_tpm2_protector_simple_policy_seq (ctx, &policy_seq); ++ err = tpm2_protector_simple_policy_seq (ctx, &policy_seq); + if (err != GRUB_ERR_NONE) + goto exit; + -+ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size); ++ err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size); + -+ /* Pop error messages on success */ -+ if (err == GRUB_ERR_NONE) -+ while (grub_error_pop ()); ++ exit: ++ grub_tpm2_flushcontext (sealed_handle); + -+exit: -+ TPM2_FlushContext (sealed_handle); - -- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -- N_("NV Index mode is not implemented yet")); + grub_tpm2key_free_policy_seq (policy_seq); + + return err; @@ -78,5 +77,5 @@ index e83b02865..b754b38df 100644 static grub_err_t -- -2.35.3 +2.43.0 diff --git a/0001-tpm2_key_protector-Support-authorized-policy.patch b/0001-tpm2_key_protector-Support-authorized-policy.patch new file mode 100644 index 0000000..391e98a --- /dev/null +++ b/0001-tpm2_key_protector-Support-authorized-policy.patch @@ -0,0 +1,158 @@ +From 7ef1b9b357c803cb8e30bbbebd44494b2b5c9d09 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 6 Apr 2023 16:00:25 +0800 +Subject: [PATCH] tpm2_key_protector: Support authorized policy + +This commit handles the TPM2_PolicyAuthorize command from the key file +in TPM 2.0 Key File format. + +TPM2_PolicyAuthorize is the essential command to support authorized +policy which allows the users to sign TPM policies with their own keys. +Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize +comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and +'TPMT_SIGNATURE signature'. To verify the signature, the current policy +digest is hashed with the hash algorithm written in 'signature', and then +'signature' is verified with the hashed policy digest and 'pubkey'. Once +TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the +signed policy. + +To create the key file with authorized policy, here are the pcr-oracle(*2) +commands: + + # Generate the RSA key and create the authorized policy file + $ pcr-oracle \ + --rsa-generate-key \ + --private-key policy-key.pem \ + --auth authorized.policy \ + create-authorized-policy 0,2,4,7,9 + + # Seal the secret with the authorized policy + $ pcr-oracle \ + --key-format tpm2.0 \ + --auth authorized.policy \ + --input disk-secret.txt \ + --output sealed.key \ + seal-secret + + # Sign the predicted PCR policy + $ pcr-oracle \ + --key-format tpm2.0 \ + --private-key policy-key.pem \ + --from eventlog \ + --stop-event "grub-file=grub.cfg" \ + --after \ + --input sealed.key \ + --output /boot/efi/efi/grub/sealed.tpm \ + sign 0,2,4,7,9 + +Then specify the key file and the key protector to grub.cfg in the EFI +system partition: + +tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/efi/grub/sealed.tpm +cryptomount -u -P tpm2 + +For any change in the boot components, just run the 'sign' command again +to update the signature in sealed.tpm, and TPM can unseal the key file +with the updated PCR policy. + +(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html +(*2) https://github.com/okirch/pcr-oracle + +Signed-off-by: Gary Lin +Reviewed-by: Stefan Berger +Reviewed-by: Daniel Kiper +--- + .../commands/tpm2_key_protector/module.c | 70 +++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c +index 70d4d0df7..6b4b5d460 100644 +--- a/grub-core/commands/tpm2_key_protector/module.c ++++ b/grub-core/commands/tpm2_key_protector/module.c +@@ -618,6 +618,73 @@ tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffe + return GRUB_ERR_NONE; + } + ++static grub_err_t ++tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffer *cmd_buf) ++{ ++ TPM2B_PUBLIC_t pubkey; ++ TPM2B_DIGEST_t policy_ref; ++ TPMT_SIGNATURE_t signature; ++ TPM2B_DIGEST_t pcr_policy; ++ TPM2B_DIGEST_t pcr_policy_hash; ++ TPMI_ALG_HASH_t sig_hash; ++ TPMT_TK_VERIFIED_t verification_ticket; ++ TPM_HANDLE_t pubkey_handle = 0; ++ TPM2B_NAME_t pubname; ++ TPM_RC_t rc; ++ grub_err_t err; ++ ++ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref); ++ grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature); ++ if (cmd_buf->error != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to unmarshal the buffer for TPM2_PolicyAuthorize"); ++ ++ /* Retrieve Policy Digest */ ++ rc = grub_tpm2_policygetdigest (session, NULL, &pcr_policy, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).", rc); ++ ++ /* Calculate the digest of the polcy for VerifySignature */ ++ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature); ++ if (sig_hash == TPM_ALG_NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to get the hash algorithm of the signature"); ++ ++ rc = grub_tpm2_hash (NULL, (TPM2B_MAX_BUFFER_t *) &pcr_policy, sig_hash, ++ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to create PCR policy hash (TPM2_Hash: 0x%x)", rc); ++ ++ /* Load the public key */ ++ rc = grub_tpm2_loadexternal (NULL, NULL, &pubkey, TPM_RH_OWNER, &pubkey_handle, &pubname, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to load public key (TPM2_LoadExternal: 0x%x)", rc); ++ ++ /* Verify the signature against the public key and the policy digest */ ++ rc = grub_tpm2_verifysignature (pubkey_handle, NULL, &pcr_policy_hash, &signature, ++ &verification_ticket, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to verify signature (TPM2_VerifySignature: 0x%x)", rc); ++ goto error; ++ } ++ ++ /* Authorize the signed policy with the public key and the verification ticket */ ++ rc = grub_tpm2_policyauthorize (session, NULL, &pcr_policy, &policy_ref, &pubname, ++ &verification_ticket, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)", rc); ++ goto error; ++ } ++ ++ err = GRUB_ERR_NONE; ++ ++ error: ++ grub_tpm2_flushcontext (pubkey_handle); ++ ++ return err; ++} ++ + static grub_err_t + tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t session) + { +@@ -636,6 +703,9 @@ tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t s + case TPM_CC_PolicyPCR: + err = tpm2_protector_policypcr (session, &buf); + break; ++ case TPM_CC_PolicyAuthorize: ++ err = tpm2_protector_policyauthorize (session, &buf); ++ break; + default: + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown TPM Command: 0x%x", policy->cmd_code); + } +-- +2.43.0 + diff --git a/0005-util-grub-protect-Add-new-tool.patch b/0001-util-grub-protect-Add-new-tool.patch similarity index 59% rename from 0005-util-grub-protect-Add-new-tool.patch rename to 0001-util-grub-protect-Add-new-tool.patch index 7c8c676..8885d43 100644 --- a/0005-util-grub-protect-Add-new-tool.patch +++ b/0001-util-grub-protect-Add-new-tool.patch @@ -1,7 +1,7 @@ -From c8c567c463cbe6090e086430251efc0dd4f58164 Mon Sep 17 00:00:00 2001 +From efaca9fb03399c706191e047b68f5fede49421ab Mon Sep 17 00:00:00 2001 From: Hernan Gatta Date: Tue, 1 Feb 2022 05:02:57 -0800 -Subject: [PATCH 5/5] util/grub-protect: Add new tool +Subject: [PATCH] util/grub-protect: Add new tool 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 @@ -27,43 +27,44 @@ To seal the key with TPM 2.0 Key File (recommended): $ sudo grub-protect --action=add \ --protector=tpm2 \ - --tpm2-pcrs=0,2,4,7,9 \ + --tpm2-pcrs=0,2,4,7,9 \ --tpm2key \ --tpm2-keyfile=luks-key \ - --tpm2-outfile=/boot/efi/boot/grub2/sealed.tpm + --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm Or, to seal the key with the raw sealed key: $ sudo grub-protect --action=add \ --protector=tpm2 \ - --tpm2-pcrs=0,2,4,7,9 \ + --tpm2-pcrs=0,2,4,7,9 \ --tpm2-keyfile=luks-key \ - --tpm2-outfile=/boot/efi/boot/grub2/sealed.key + --tpm2-outfile=/boot/efi/efi/grub/sealed.key Then, in the boot script, for TPM 2.0 Key File: -tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub/sealed.tpm cryptomount -u -P tpm2 Or, for the raw sealed key: -tpm2_key_protector_init --keyfile=(hd0,gpt1)/boot/grub2/sealed.key --pcrs=0,2,4,7,9 +tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub/sealed.key --pcrs=0,2,4,7,9 cryptomount -u -P tpm2 The benefit of using TPM 2.0 Key File is that the PCR set is already written in the key file, so there is no need to specify PCRs when invoking tpm2_key_protector_init. -Cc: Stefan Berger Signed-off-by: Hernan Gatta Signed-off-by: Gary Lin +Reviewed-by: Stefan Berger +Reviewed-by: Daniel Kiper --- .gitignore | 2 + - Makefile.util.def | 24 + + Makefile.util.def | 26 + configure.ac | 30 + docs/man/grub-protect.h2m | 4 + - util/grub-protect.c | 1420 +++++++++++++++++++++++++++++++++++++ - 5 files changed, 1480 insertions(+) + util/grub-protect.c | 1407 +++++++++++++++++++++++++++++++++++++ + 5 files changed, 1469 insertions(+) create mode 100644 docs/man/grub-protect.h2m create mode 100644 util/grub-protect.c @@ -71,7 +72,7 @@ Index: grub-2.12/Makefile.util.def =================================================================== --- grub-2.12.orig/Makefile.util.def +++ grub-2.12/Makefile.util.def -@@ -208,6 +208,30 @@ program = { +@@ -208,6 +208,32 @@ program = { }; program = { @@ -80,14 +81,16 @@ Index: grub-2.12/Makefile.util.def + + common = grub-core/kern/emu/argp_common.c; + 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 = grub-core/tpm2/tpm2key_asn1_tab.c; ++ common = grub-core/lib/tss2/buffer.c; ++ common = grub-core/lib/tss2/tss2_mu.c; ++ common = grub-core/lib/tss2/tpm2_cmd.c; ++ common = grub-core/commands/tpm2_key_protector/args.c; ++ common = grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c; + common = util/grub-protect.c; + common = util/probe.c; + ++ cflags = '-I$(srcdir)/grub-core/lib/tss2 -I$(srcdir)/grub-core/commands/tpm2_key_protector'; ++ + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; @@ -172,16 +175,17 @@ Index: grub-2.12/docs/man/grub-protect.h2m +[NAME] +grub-protect \- protect a disk key with a key protector +[DESCRIPTION] -+grub-protect helps to pretect a disk encryption key with a specified key protector. ++grub-protect helps to protect a disk encryption key with a specified key protector. Index: grub-2.12/util/grub-protect.c =================================================================== --- /dev/null +++ grub-2.12/util/grub-protect.c -@@ -0,0 +1,1420 @@ +@@ -0,0 +1,1407 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Microsoft Corporation + * Copyright (C) 2023 SUSE LLC ++ * Copyright (C) 2024 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 @@ -208,13 +212,15 @@ Index: grub-2.12/util/grub-protect.c + +#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 @@ -224,73 +230,73 @@ Index: grub-2.12/util/grub-protect.c +#include "progname.h" + +/* Unprintable option keys for argp */ -+typedef enum grub_protect_opt ++typedef enum protect_opt +{ + /* General */ -+ GRUB_PROTECT_OPT_ACTION = 'a', -+ GRUB_PROTECT_OPT_PROTECTOR = 'p', ++ PROTECT_OPT_ACTION = 'a', ++ 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_EVICT, -+ GRUB_PROTECT_OPT_TPM2_TPM2KEY -+} grub_protect_opt; ++ PROTECT_OPT_TPM2_DEVICE = 0x100, ++ PROTECT_OPT_TPM2_PCRS, ++ PROTECT_OPT_TPM2_ASYMMETRIC, ++ PROTECT_OPT_TPM2_BANK, ++ PROTECT_OPT_TPM2_SRK, ++ PROTECT_OPT_TPM2_KEYFILE, ++ PROTECT_OPT_TPM2_OUTFILE, ++ PROTECT_OPT_TPM2_EVICT, ++ PROTECT_OPT_TPM2_TPM2KEY ++} protect_opt_t; + +/* Option flags to keep track of specified arguments */ -+typedef enum grub_protect_arg ++typedef enum protect_arg +{ + /* General */ -+ GRUB_PROTECT_ARG_ACTION = 1 << 0, -+ GRUB_PROTECT_ARG_PROTECTOR = 1 << 1, ++ PROTECT_ARG_ACTION = 1 << 0, ++ PROTECT_ARG_PROTECTOR = 1 << 1, + /* TPM2 */ -+ GRUB_PROTECT_ARG_TPM2_DEVICE = 1 << 2, -+ GRUB_PROTECT_ARG_TPM2_PCRS = 1 << 3, -+ GRUB_PROTECT_ARG_TPM2_ASYMMETRIC = 1 << 4, -+ GRUB_PROTECT_ARG_TPM2_BANK = 1 << 5, -+ GRUB_PROTECT_ARG_TPM2_SRK = 1 << 6, -+ GRUB_PROTECT_ARG_TPM2_KEYFILE = 1 << 7, -+ GRUB_PROTECT_ARG_TPM2_OUTFILE = 1 << 8, -+ GRUB_PROTECT_ARG_TPM2_EVICT = 1 << 9, -+ GRUB_PROTECT_ARG_TPM2_TPM2KEY = 1 << 10 -+} grub_protect_arg_t; ++ PROTECT_ARG_TPM2_DEVICE = 1 << 2, ++ PROTECT_ARG_TPM2_PCRS = 1 << 3, ++ PROTECT_ARG_TPM2_ASYMMETRIC = 1 << 4, ++ PROTECT_ARG_TPM2_BANK = 1 << 5, ++ PROTECT_ARG_TPM2_SRK = 1 << 6, ++ PROTECT_ARG_TPM2_KEYFILE = 1 << 7, ++ PROTECT_ARG_TPM2_OUTFILE = 1 << 8, ++ PROTECT_ARG_TPM2_EVICT = 1 << 9, ++ PROTECT_ARG_TPM2_TPM2KEY = 1 << 10 ++} protect_arg_t; + -+typedef enum grub_protect_protector ++typedef enum protect_protector +{ -+ GRUB_PROTECT_TYPE_ERROR, -+ GRUB_PROTECT_TYPE_TPM2 -+} grub_protect_protector_t; ++ PROTECT_TYPE_ERROR, ++ PROTECT_TYPE_TPM2 ++} protect_protector_t; + -+typedef enum grub_protect_action ++typedef enum protect_action +{ -+ GRUB_PROTECT_ACTION_ERROR, -+ GRUB_PROTECT_ACTION_ADD, -+ GRUB_PROTECT_ACTION_REMOVE -+} grub_protect_action_t; ++ PROTECT_ACTION_ERROR, ++ PROTECT_ACTION_ADD, ++ PROTECT_ACTION_REMOVE ++} protect_action_t; + -+struct grub_protect_args ++typedef struct protect_args +{ -+ grub_protect_arg_t args; -+ grub_protect_action_t action; -+ grub_protect_protector_t protector; ++ protect_arg_t args; ++ protect_action_t action; ++ protect_protector_t protector; + + const char *tpm2_device; + grub_uint8_t tpm2_pcrs[TPM_MAX_PCRS]; + grub_uint8_t tpm2_pcr_count; + grub_srk_type_t srk_type; -+ TPM_ALG_ID tpm2_bank; -+ TPM_HANDLE tpm2_srk; ++ TPM_ALG_ID_t tpm2_bank; ++ TPM_HANDLE_t tpm2_srk; + const char *tpm2_keyfile; + const char *tpm2_outfile; -+ int tpm2_evict; -+ int tpm2_tpm2key; -+}; ++ bool tpm2_evict; ++ bool tpm2_tpm2key; ++} protect_args_t; + -+static struct argp_option grub_protect_options[] = ++static struct argp_option protect_options[] = + { + /* Top-level options */ + { @@ -308,84 +314,84 @@ Index: grub-2.12/util/grub-protect.c + .arg = "tpm2", + .flags = 0, + .doc = -+ N_("Key protector to use (only tpm2 is currently supported)."), ++ N_("Set key protector to use (only tpm2 is currently supported)."), + .group = 0 + }, + /* TPM2 key protector options */ + { + .name = "tpm2-device", -+ .key = GRUB_PROTECT_OPT_TPM2_DEVICE, ++ .key = PROTECT_OPT_TPM2_DEVICE, + .arg = "FILE", + .flags = 0, + .doc = -+ N_("Path to the TPM2 device. (default: /dev/tpm0)"), ++ N_("Set the path to the TPM2 device. (default: /dev/tpm0)"), + .group = 0 + }, + { + .name = "tpm2-pcrs", -+ .key = GRUB_PROTECT_OPT_TPM2_PCRS, ++ .key = PROTECT_OPT_TPM2_PCRS, + .arg = "0[,1]...", + .flags = 0, + .doc = -+ N_("Comma-separated list of PCRs used to authorize key release " ++ N_("Set a comma-separated list of PCRs used to authorize key release " + "e.g., '7,11'. Please be aware that PCR 0~7 are used by the " + "firmware and the measurement result may change after a " + "firmware update (for baremetal systems) or a package " -+ "(OVMF/SeaBIOS/SLOF) update in the VM host. This may lead to" ++ "(OVMF/SLOF) update in the VM host. This may lead to " + "the failure of key unsealing. (default: 7)"), + .group = 0 + }, + { + .name = "tpm2-bank", -+ .key = GRUB_PROTECT_OPT_TPM2_BANK, ++ .key = PROTECT_OPT_TPM2_BANK, + .arg = "ALG", + .flags = 0, + .doc = -+ N_("Bank of PCRs used to authorize key release: " ++ N_("Set the bank of PCRs used to authorize key release: " + "SHA1, SHA256, SHA384, or SHA512. (default: SHA256)"), + .group = 0 + }, + { + .name = "tpm2-keyfile", -+ .key = GRUB_PROTECT_OPT_TPM2_KEYFILE, ++ .key = PROTECT_OPT_TPM2_KEYFILE, + .arg = "FILE", + .flags = 0, + .doc = -+ N_("Path to a file that contains the cleartext key to protect."), ++ N_("Set the path to a file that contains the cleartext key to protect."), + .group = 0 + }, + { + .name = "tpm2-outfile", -+ .key = GRUB_PROTECT_OPT_TPM2_OUTFILE, ++ .key = PROTECT_OPT_TPM2_OUTFILE, + .arg = "FILE", + .flags = 0, + .doc = -+ N_("Path to the file that will contain the key after sealing (must be " -+ "accessible to GRUB during boot)."), ++ N_("Set the path to the file that will contain the key after sealing " ++ "(must be accessible to GRUB during boot)."), + .group = 0 + }, + { + .name = "tpm2-srk", -+ .key = GRUB_PROTECT_OPT_TPM2_SRK, ++ .key = PROTECT_OPT_TPM2_SRK, + .arg = "NUM", + .flags = 0, + .doc = -+ N_("The SRK handle if the SRK is to be made persistent."), ++ N_("Set the SRK handle if the SRK is to be made persistent."), + .group = 0 + }, + { + .name = "tpm2-asymmetric", -+ .key = GRUB_PROTECT_OPT_TPM2_ASYMMETRIC, ++ .key = PROTECT_OPT_TPM2_ASYMMETRIC, + .arg = "TYPE", + .flags = 0, + .doc = -+ N_("The type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)." ++ N_("Set the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)." + "(default: ECC)"), + .group = 0 + }, + { + .name = "tpm2-evict", -+ .key = GRUB_PROTECT_OPT_TPM2_EVICT, ++ .key = PROTECT_OPT_TPM2_EVICT, + .arg = NULL, + .flags = 0, + .doc = @@ -394,22 +400,21 @@ Index: grub-2.12/util/grub-protect.c + }, + { + .name = "tpm2key", -+ .key = GRUB_PROTECT_OPT_TPM2_TPM2KEY, ++ .key = PROTECT_OPT_TPM2_TPM2KEY, + .arg = NULL, + .flags = 0, + .doc = -+ N_("Use TPM 2.0 Key File format instead of the raw format."), ++ N_("Use TPM 2.0 Key File format."), + .group = 0 + }, + /* End of list */ + { 0, 0, 0, 0, 0, 0 } + }; + -+static int grub_protector_tpm2_fd = -1; ++static int protector_tpm2_fd = -1; + +static grub_err_t -+grub_protect_read_file (const char *filepath, void **buffer, -+ size_t *buffer_size) ++protect_read_file (const char *filepath, void **buffer, size_t *buffer_size) +{ + grub_err_t err; + FILE *f; @@ -418,19 +423,24 @@ Index: grub-2.12/util/grub-protect.c + + f = fopen (filepath, "rb"); + if (f == NULL) -+ return GRUB_ERR_FILE_NOT_FOUND; ++ { ++ fprintf (stderr, N_("Could not open file: %s\n"), filepath); ++ return GRUB_ERR_FILE_NOT_FOUND; ++ } + + if (fseek (f, 0, SEEK_END)) + { -+ err = GRUB_ERR_FILE_READ_ERROR; -+ goto exit1; ++ fprintf (stderr, N_("Could not seek file: %s\n"), filepath); ++ err = GRUB_ERR_FILE_READ_ERROR; ++ goto exit1; + } + + len = ftell (f); + if (len <= 0) + { -+ err = GRUB_ERR_FILE_READ_ERROR; -+ goto exit1; ++ fprintf (stderr, N_("Could not get file length: %s\n"), filepath); ++ err = GRUB_ERR_FILE_READ_ERROR; ++ goto exit1; + } + + rewind (f); @@ -438,14 +448,16 @@ Index: grub-2.12/util/grub-protect.c + buf = grub_malloc (len); + if (buf == NULL) + { -+ err = GRUB_ERR_OUT_OF_MEMORY; -+ goto exit1; ++ fprintf (stderr, N_("Could not allocate memory for file: %s\n"), filepath); ++ err = GRUB_ERR_OUT_OF_MEMORY; ++ goto exit1; + } + + if (fread (buf, len, 1, f) != 1) + { -+ err = GRUB_ERR_FILE_READ_ERROR; -+ goto exit2; ++ fprintf (stderr, N_("Could not read file: %s\n"), filepath); ++ err = GRUB_ERR_FILE_READ_ERROR; ++ goto exit2; + } + + *buffer = buf; @@ -454,17 +466,17 @@ Index: grub-2.12/util/grub-protect.c + buf = NULL; + err = GRUB_ERR_NONE; + -+exit2: ++ exit2: + grub_free (buf); + -+exit1: ++ exit1: + fclose (f); + + return err; +} + +static grub_err_t -+grub_protect_write_file (const char *filepath, void *buffer, size_t buffer_size) ++protect_write_file (const char *filepath, void *buffer, size_t buffer_size) +{ + grub_err_t err; + FILE *f; @@ -476,12 +488,12 @@ Index: grub-2.12/util/grub-protect.c + if (fwrite (buffer, buffer_size, 1, f) != 1) + { + err = GRUB_ERR_WRITE_ERROR; -+ goto exit1; ++ goto exit; + } + + err = GRUB_ERR_NONE; + -+exit1: ++ exit: + fclose (f); + + return err; @@ -502,28 +514,31 @@ Index: grub-2.12/util/grub-protect.c +grub_tcg2_submit_command (grub_size_t input_size, grub_uint8_t *input, + grub_size_t output_size, grub_uint8_t *output) +{ -+ static const grub_size_t header_size = sizeof (grub_uint16_t) + -+ (2 * sizeof(grub_uint32_t)); ++ if (write (protector_tpm2_fd, input, input_size) != input_size) ++ { ++ fprintf (stderr, N_("Could not send TPM command.\n")); ++ return GRUB_ERR_BAD_DEVICE; ++ } + -+ if (write (grub_protector_tpm2_fd, input, input_size) != input_size) -+ return GRUB_ERR_BAD_DEVICE; -+ -+ if (read (grub_protector_tpm2_fd, output, output_size) < header_size) -+ return GRUB_ERR_BAD_DEVICE; ++ if (read (protector_tpm2_fd, output, output_size) < sizeof (TPM_RESPONSE_HEADER_t)) ++ { ++ fprintf (stderr, N_("Could not get TPM response.\n")); ++ return GRUB_ERR_BAD_DEVICE; ++ } + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_protect_tpm2_open_device (const char *dev_node) ++protect_tpm2_open_device (const char *dev_node) +{ -+ if (grub_protector_tpm2_fd != -1) ++ if (protector_tpm2_fd != -1) + return GRUB_ERR_NONE; + -+ grub_protector_tpm2_fd = open (dev_node, O_RDWR); -+ if (grub_protector_tpm2_fd == -1) ++ protector_tpm2_fd = open (dev_node, O_RDWR); ++ if (protector_tpm2_fd == -1) + { -+ fprintf (stderr, _("Could not open TPM device (%s).\n"), strerror (errno)); ++ fprintf (stderr, N_("Could not open TPM device (%s).\n"), strerror (errno)); + return GRUB_ERR_FILE_NOT_FOUND; + } + @@ -531,51 +546,50 @@ Index: grub-2.12/util/grub-protect.c +} + +static grub_err_t -+grub_protect_tpm2_close_device (void) ++protect_tpm2_close_device (void) +{ + int err; + -+ if (grub_protector_tpm2_fd == -1) ++ if (protector_tpm2_fd == -1) + return GRUB_ERR_NONE; + -+ err = close (grub_protector_tpm2_fd); ++ err = close (protector_tpm2_fd); + if (err != GRUB_ERR_NONE) + { -+ fprintf (stderr, _("Could not close TPM device (Error: %u).\n"), errno); ++ fprintf (stderr, N_("Could not close TPM device (%s).\n"), strerror (errno)); + return GRUB_ERR_IO; + } + -+ grub_protector_tpm2_fd = -1; ++ protector_tpm2_fd = -1; + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_protect_tpm2_get_policy_digest (struct grub_protect_args *args, -+ TPM2B_DIGEST *digest) ++protect_tpm2_get_policy_digest (protect_args_t *args, TPM2B_DIGEST_t *digest) +{ -+ TPM_RC rc; -+ TPML_PCR_SELECTION pcr_sel = { ++ TPM_RC_t rc; ++ TPML_PCR_SELECTION_t pcr_sel = { + .count = 1, + .pcrSelections = { + { + .hash = args->tpm2_bank, + .sizeOfSelect = 3, -+ .pcrSelect = { 0 } ++ .pcrSelect = {0} + }, + } + }; -+ TPML_PCR_SELECTION pcr_sel_out = { 0 }; -+ TPML_DIGEST pcr_values = { 0 }; -+ TPM2B_DIGEST pcr_digest = { 0 }; ++ TPML_PCR_SELECTION_t pcr_sel_out = {0}; ++ TPML_DIGEST_t pcr_values = {0}; ++ TPM2B_DIGEST_t pcr_digest = {0}; + grub_size_t pcr_digest_len; -+ TPM2B_MAX_BUFFER pcr_concat = { 0 }; ++ TPM2B_MAX_BUFFER_t pcr_concat = {0}; + grub_size_t pcr_concat_len; + grub_uint8_t *pcr_cursor; -+ TPM2B_NONCE nonce = { 0 }; -+ TPM2B_ENCRYPTED_SECRET salt = { 0 }; -+ TPMT_SYM_DEF symmetric = { 0 }; -+ TPMI_SH_AUTH_SESSION session = 0; -+ TPM2B_DIGEST policy_digest = { 0 }; ++ TPM2B_NONCE_t nonce = {0}; ++ TPM2B_ENCRYPTED_SECRET_t salt = {0}; ++ TPMT_SYM_DEF_t symmetric = {0}; ++ TPMI_SH_AUTH_SESSION_t session = 0; ++ TPM2B_DIGEST_t policy_digest = {0}; + grub_uint8_t i; + grub_err_t err; + @@ -583,10 +597,10 @@ Index: grub-2.12/util/grub-protect.c + for (i = 0; i < args->tpm2_pcr_count; i++) + TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], args->tpm2_pcrs[i]); + -+ rc = TPM2_PCR_Read (NULL, &pcr_sel, NULL, &pcr_sel_out, &pcr_values, NULL); ++ rc = grub_tpm2_pcr_read (NULL, &pcr_sel, NULL, &pcr_sel_out, &pcr_values, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("Failed to read PCRs (TPM2_PCR_Read: 0x%x).\n"), rc); ++ fprintf (stderr, "Failed to read PCRs (TPM2_PCR_Read: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + @@ -594,7 +608,7 @@ Index: grub-2.12/util/grub-protect.c + (pcr_sel.pcrSelections[0].sizeOfSelect != + pcr_sel_out.pcrSelections[0].sizeOfSelect)) + { -+ fprintf (stderr, _("Could not read all the specified PCRs.\n")); ++ fprintf (stderr, N_("Could not read all the specified PCRs.\n")); + return GRUB_ERR_BAD_DEVICE; + } + @@ -620,7 +634,7 @@ Index: grub-2.12/util/grub-protect.c + pcr_concat_len = pcr_digest_len * args->tpm2_pcr_count; + if (pcr_concat_len > TPM_MAX_DIGEST_BUFFER) + { -+ fprintf (stderr, _("PCR concatenation buffer not enough.\n")); ++ fprintf (stderr, N_("PCR concatenation buffer not big enough.\n")); + return GRUB_ERR_OUT_OF_RANGE; + } + @@ -630,8 +644,8 @@ Index: grub-2.12/util/grub-protect.c + if (pcr_values.digests[i].size != pcr_digest_len) + { + fprintf (stderr, -+ _("Bad PCR value size: expected %" PRIuGRUB_SIZE " bytes but got %u bytes.\n"), -+ pcr_digest_len, pcr_values.digests[i].size); ++ N_("Bad PCR value size: expected %llu bytes but got %u bytes.\n"), ++ (long long unsigned int)pcr_digest_len, pcr_values.digests[i].size); + return GRUB_ERR_BAD_ARGUMENT; + } + @@ -640,11 +654,10 @@ Index: grub-2.12/util/grub-protect.c + } + pcr_concat.size = pcr_concat_len; + -+ rc = TPM2_Hash (NULL, &pcr_concat, args->tpm2_bank, TPM_RH_NULL, &pcr_digest, -+ NULL, NULL); ++ rc = grub_tpm2_hash (NULL, &pcr_concat, args->tpm2_bank, TPM_RH_NULL, &pcr_digest, NULL, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("Failed to generate PCR digest (TPM2_Hash: 0x%x)\n"), rc); ++ fprintf (stderr, "Failed to generate PCR digest (TPM2_Hash: 0x%x)\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + @@ -652,33 +665,29 @@ Index: grub-2.12/util/grub-protect.c + nonce.size = TPM_SHA256_DIGEST_SIZE; + symmetric.algorithm = TPM_ALG_NULL; + -+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonce, &salt, -+ TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA256, -+ &session, NULL, 0); ++ rc = grub_tpm2_startauthsession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonce, &salt, ++ TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA256, ++ &session, NULL, 0); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, -+ _("Failed to start trial policy session (TPM2_StartAuthSession: 0x%x).\n"), -+ rc); ++ fprintf (stderr, "Failed to start trial policy session (TPM2_StartAuthSession: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* PCR Policy */ -+ rc = TPM2_PolicyPCR (session, NULL, &pcr_digest, &pcr_sel, NULL); ++ rc = grub_tpm2_policypcr (session, NULL, &pcr_digest, &pcr_sel, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x).\n"), -+ rc); ++ fprintf (stderr, "Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x).\n", rc); + err = GRUB_ERR_BAD_DEVICE; + goto error; + } + + /* Retrieve Policy Digest */ -+ rc = TPM2_PolicyGetDigest (session, NULL, &policy_digest, NULL); ++ rc = grub_tpm2_policygetdigest (session, NULL, &policy_digest, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).\n"), -+ rc); ++ fprintf (stderr, "Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).\n", rc); + err = GRUB_ERR_BAD_DEVICE; + goto error; + } @@ -687,36 +696,36 @@ Index: grub-2.12/util/grub-protect.c + *digest = policy_digest; + err = GRUB_ERR_NONE; + -+error: -+ TPM2_FlushContext (session); ++ error: ++ grub_tpm2_flushcontext (session); + + return err; +} + +static grub_err_t -+grub_protect_tpm2_get_srk (struct grub_protect_args *args, TPM_HANDLE *srk) ++protect_tpm2_get_srk (protect_args_t *args, TPM_HANDLE_t *srk) +{ -+ TPM_RC rc; -+ TPM2B_PUBLIC public; -+ TPMS_AUTH_COMMAND authCommand = { 0 }; -+ TPM2B_SENSITIVE_CREATE inSensitive = { 0 }; -+ TPM2B_PUBLIC inPublic = { 0 }; -+ TPM2B_DATA outsideInfo = { 0 }; -+ TPML_PCR_SELECTION creationPcr = { 0 }; -+ TPM2B_PUBLIC outPublic = { 0 }; -+ TPM2B_CREATION_DATA creationData = { 0 }; -+ TPM2B_DIGEST creationHash = { 0 }; -+ TPMT_TK_CREATION creationTicket = { 0 }; -+ TPM2B_NAME srkName = { 0 }; -+ TPM_HANDLE srkHandle; ++ TPM_RC_t rc; ++ TPM2B_PUBLIC_t public; ++ TPMS_AUTH_COMMAND_t authCommand = {0}; ++ TPM2B_SENSITIVE_CREATE_t inSensitive = {0}; ++ TPM2B_PUBLIC_t inPublic = {0}; ++ TPM2B_DATA_t outsideInfo = {0}; ++ TPML_PCR_SELECTION_t creationPcr = {0}; ++ TPM2B_PUBLIC_t outPublic = {0}; ++ TPM2B_CREATION_DATA_t creationData = {0}; ++ TPM2B_DIGEST_t creationHash = {0}; ++ TPMT_TK_CREATION_t creationTicket = {0}; ++ TPM2B_NAME_t srkName = {0}; ++ TPM_HANDLE_t srkHandle; + + if (args->tpm2_srk != 0) + { + /* Find SRK */ -+ rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public); ++ rc = grub_tpm2_readpublic (args->tpm2_srk, NULL, &public); + if (rc == TPM_RC_SUCCESS) + { -+ printf (_("Read SRK from 0x%x\n"), args->tpm2_srk); ++ printf ("Read SRK from 0x%x\n", args->tpm2_srk); + *srk = args->tpm2_srk; + return GRUB_ERR_NONE; + } @@ -724,9 +733,7 @@ Index: grub-2.12/util/grub-protect.c + /* The handle exists but its public area could not be read. */ + if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE) + { -+ fprintf (stderr, -+ _("Failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x).\n"), -+ args->tpm2_srk, rc); ++ fprintf (stderr, "Failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x).\n", args->tpm2_srk, rc); + return GRUB_ERR_BAD_DEVICE; + } + } @@ -767,30 +774,29 @@ Index: grub-2.12/util/grub-protect.c + return GRUB_ERR_BAD_ARGUMENT; + } + -+ rc = TPM2_CreatePrimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic, -+ &outsideInfo, &creationPcr, &srkHandle, &outPublic, -+ &creationData, &creationHash, &creationTicket, -+ &srkName, NULL); ++ rc = grub_tpm2_createprimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic, ++ &outsideInfo, &creationPcr, &srkHandle, &outPublic, ++ &creationData, &creationHash, &creationTicket, ++ &srkName, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("Failed to create SRK (TPM2_CreatePrimary: 0x%x).\n"), rc); ++ fprintf (stderr, "Failed to create SRK (TPM2_CreatePrimary: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* Persist SRK */ + if (args->tpm2_srk != 0) + { -+ rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, &authCommand, -+ args->tpm2_srk, NULL); ++ rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, srkHandle, &authCommand, args->tpm2_srk, NULL); + if (rc == TPM_RC_SUCCESS) + { -+ TPM2_FlushContext (srkHandle); ++ grub_tpm2_flushcontext (srkHandle); + srkHandle = args->tpm2_srk; + } + else + fprintf (stderr, -+ _("Warning: Failed to persist SRK (0x%x) (TPM2_EvictControl: 0x%x\n). " -+ "Continuing anyway...\n"), args->tpm2_srk, rc); ++ "Warning: Failed to persist SRK (0x%x) (TPM2_EvictControl: 0x%x).\n" ++ "Continuing anyway...\n", args->tpm2_srk, rc); + } + + /* Epilogue */ @@ -800,18 +806,18 @@ Index: grub-2.12/util/grub-protect.c +} + +static grub_err_t -+grub_protect_tpm2_seal (TPM2B_DIGEST *policyDigest, TPM_HANDLE srk, -+ grub_uint8_t *clearText, grub_size_t clearTextLength, -+ TPM2_SEALED_KEY *sealed_key) ++protect_tpm2_seal (TPM2B_DIGEST_t *policyDigest, TPM_HANDLE_t srk, ++ grub_uint8_t *clearText, grub_size_t clearTextLength, ++ tpm2_sealed_key_t *sealed_key) +{ -+ TPM_RC rc; -+ TPMS_AUTH_COMMAND authCommand = { 0 }; -+ TPM2B_SENSITIVE_CREATE inSensitive = { 0 }; -+ TPM2B_PUBLIC inPublic = { 0 }; -+ TPM2B_DATA outsideInfo = { 0 }; -+ TPML_PCR_SELECTION pcr_sel = { 0 }; -+ TPM2B_PRIVATE outPrivate = { 0 }; -+ TPM2B_PUBLIC outPublic = { 0 }; ++ TPM_RC_t rc; ++ TPMS_AUTH_COMMAND_t authCommand = {0}; ++ TPM2B_SENSITIVE_CREATE_t inSensitive = {0}; ++ TPM2B_PUBLIC_t inPublic = {0}; ++ TPM2B_DATA_t outsideInfo = {0}; ++ TPML_PCR_SELECTION_t pcr_sel = {0}; ++ TPM2B_PRIVATE_t outPrivate = {0}; ++ TPM2B_PUBLIC_t outPublic = {0}; + + /* Seal Data */ + authCommand.sessionHandle = TPM_RS_PW; @@ -824,11 +830,11 @@ Index: grub-2.12/util/grub-protect.c + inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL; + inPublic.publicArea.authPolicy = *policyDigest; + -+ rc = TPM2_Create (srk, &authCommand, &inSensitive, &inPublic, &outsideInfo, -+ &pcr_sel, &outPrivate, &outPublic, NULL, NULL, NULL, NULL); ++ rc = grub_tpm2_create (srk, &authCommand, &inSensitive, &inPublic, &outsideInfo, ++ &pcr_sel, &outPrivate, &outPublic, NULL, NULL, NULL, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("Failed to seal key (TPM2_Create: 0x%x).\n"), rc); ++ fprintf (stderr, "Failed to seal key (TPM2_Create: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + @@ -841,23 +847,26 @@ Index: grub-2.12/util/grub-protect.c + +extern asn1_static_node tpm2key_asn1_tab[]; + ++/* id-sealedkey OID defined in TPM 2.0 Key Files Spec */ ++#define TPM2KEY_SEALED_KEY_OID "2.23.133.10.1.5" ++ +static grub_err_t -+grub_protect_tpm2_export_tpm2key (const struct grub_protect_args *args, -+ TPM2_SEALED_KEY *sealed_key) ++protect_tpm2_export_tpm2key (const protect_args_t *args, ++ tpm2_sealed_key_t *sealed_key) +{ -+ const char *sealed_key_oid = "2.23.133.10.1.5"; ++ const char *sealed_key_oid = TPM2KEY_SEALED_KEY_OID; + asn1_node asn1_def = NULL; + asn1_node tpm2key = NULL; + grub_uint32_t parent; + grub_uint32_t cmd_code; + struct grub_tpm2_buffer pol_buf; -+ TPML_PCR_SELECTION pcr_sel = { ++ TPML_PCR_SELECTION_t pcr_sel = { + .count = 1, + .pcrSelections = { + { + .hash = args->tpm2_bank, + .sizeOfSelect = 3, -+ .pcrSelect = { 0 } ++ .pcrSelect = {0} + }, + } + }; @@ -878,12 +887,12 @@ Index: grub-2.12/util/grub-protect.c + */ + grub_tpm2_buffer_init (&pol_buf); + grub_tpm2_buffer_pack_u16 (&pol_buf, 0); -+ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&pol_buf, &pcr_sel); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&pol_buf, &pcr_sel); + + grub_tpm2_buffer_init (&pub_buf); -+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&pub_buf, &sealed_key->public); ++ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&pub_buf, &sealed_key->public); + grub_tpm2_buffer_init (&priv_buf); -+ grub_tpm2_mu_TPM2B_Marshal (&priv_buf, sealed_key->private.size, ++ grub_Tss2_MU_TPM2B_Marshal (&priv_buf, sealed_key->private.size, + sealed_key->private.buffer); + if (pub_buf.error != 0 || priv_buf.error != 0) + return GRUB_ERR_BAD_ARGUMENT; @@ -900,7 +909,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "type", sealed_key_oid, 1); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'type': 0x%u\n"), ret); ++ fprintf (stderr, "Failed to set 'type': 0x%u\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -909,7 +918,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "emptyAuth", "TRUE", 1); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'emptyAuth': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'emptyAuth': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -918,7 +927,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "policy", "NEW", 1); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'policy': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'policy': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -927,7 +936,7 @@ Index: grub-2.12/util/grub-protect.c + sizeof (cmd_code)); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'policy CommandCode': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'policy CommandCode': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -935,7 +944,7 @@ Index: grub-2.12/util/grub-protect.c + pol_buf.size); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'policy CommandPolicy': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'policy CommandPolicy': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -944,7 +953,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "secret", NULL, 0); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to remove 'secret': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to remove 'secret': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -953,7 +962,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "authPolicy", NULL, 0); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to remove 'authPolicy': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to remove 'authPolicy': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -962,7 +971,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "description", NULL, 0); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to remove 'description': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to remove 'description': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -978,7 +987,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "parent", &parent, sizeof (parent)); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'parent': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'parent': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -994,7 +1003,7 @@ Index: grub-2.12/util/grub-protect.c + + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'rsaParent': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'rsaParent': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -1003,7 +1012,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "pubkey", pub_buf.data, pub_buf.size); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'pubkey': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'pubkey': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -1012,7 +1021,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_write_value (tpm2key, "privkey", priv_buf.data, priv_buf.size); + if (ret != ASN1_SUCCESS) + { -+ fprintf (stderr, _("Failed to set 'privkey': 0x%x\n"), ret); ++ fprintf (stderr, "Failed to set 'privkey': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -1022,7 +1031,7 @@ Index: grub-2.12/util/grub-protect.c + ret = asn1_der_coding (tpm2key, "", NULL, &der_buf_size, NULL); + if (ret != ASN1_MEM_ERROR) + { -+ fprintf (stderr, _("Failed to get DER size: 0x%x\n"), ret); ++ fprintf (stderr, "Failed to get DER size: 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } @@ -1030,7 +1039,7 @@ Index: grub-2.12/util/grub-protect.c + der_buf = grub_malloc (der_buf_size); + if (der_buf == NULL) + { -+ fprintf (stderr, _("Failed to allocate memory for DER encoding\n")); ++ fprintf (stderr, "Failed to allocate memory for DER encoding\n"); + err = GRUB_ERR_OUT_OF_MEMORY; + goto error; + } @@ -1043,12 +1052,11 @@ Index: grub-2.12/util/grub-protect.c + goto error; + } + -+ err = grub_protect_write_file (args->tpm2_outfile, der_buf, der_buf_size); ++ err = protect_write_file (args->tpm2_outfile, der_buf, der_buf_size); + if (err != GRUB_ERR_NONE) -+ fprintf (stderr, _("Could not write tpm2key file (Error: %u).\n"), -+ errno); ++ fprintf (stderr, N_("Could not write tpm2key file (%s).\n"), strerror (errno)); + -+error: ++ error: + grub_free (der_buf); + + if (tpm2key) @@ -1058,109 +1066,105 @@ Index: grub-2.12/util/grub-protect.c +} + +static grub_err_t -+grub_protect_tpm2_export_sealed_key (const char *filepath, -+ TPM2_SEALED_KEY *sealed_key) ++protect_tpm2_export_sealed_key (const char *filepath, ++ tpm2_sealed_key_t *sealed_key) +{ + grub_err_t err; + struct grub_tpm2_buffer buf; + + grub_tpm2_buffer_init (&buf); -+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public); -+ grub_tpm2_mu_TPM2B_Marshal (&buf, sealed_key->private.size, ++ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public); ++ grub_Tss2_MU_TPM2B_Marshal (&buf, sealed_key->private.size, + sealed_key->private.buffer); + if (buf.error != 0) + return GRUB_ERR_BAD_ARGUMENT; + -+ err = grub_protect_write_file (filepath, buf.data, buf.size); ++ err = protect_write_file (filepath, buf.data, buf.size); + if (err != GRUB_ERR_NONE) -+ fprintf (stderr, _("Could not write sealed key file (Error: %u).\n"), -+ errno); ++ fprintf (stderr, N_("Could not write sealed key file (%s).\n"), strerror (errno)); + + return err; +} + +static grub_err_t -+grub_protect_tpm2_add (struct grub_protect_args *args) ++protect_tpm2_add (protect_args_t *args) +{ + grub_err_t err; + grub_uint8_t *key = NULL; + grub_size_t key_size; -+ TPM_HANDLE srk; -+ TPM2B_DIGEST policy_digest; -+ TPM2_SEALED_KEY sealed_key; ++ TPM_HANDLE_t srk; ++ TPM2B_DIGEST_t policy_digest; ++ tpm2_sealed_key_t sealed_key; + -+ err = grub_protect_tpm2_open_device (args->tpm2_device); ++ err = protect_tpm2_open_device (args->tpm2_device); + if (err != GRUB_ERR_NONE) + return err; + -+ err = grub_protect_read_file (args->tpm2_keyfile, (void **)&key, &key_size); ++ err = protect_read_file (args->tpm2_keyfile, (void **)&key, &key_size); + if (err != GRUB_ERR_NONE) + goto exit1; + + if (key_size > TPM_MAX_SYM_DATA) -+ { -+ fprintf (stderr, -+ _("Input key is too long, maximum allowed size is %u bytes.\n"), -+ TPM_MAX_SYM_DATA); -+ err = GRUB_ERR_OUT_OF_RANGE; -+ goto exit2; -+ } ++ { ++ fprintf (stderr, N_("Input key size larger than %u bytes.\n"), TPM_MAX_SYM_DATA); ++ err = GRUB_ERR_OUT_OF_RANGE; ++ goto exit2; ++ } + -+ err = grub_protect_tpm2_get_srk (args, &srk); ++ err = protect_tpm2_get_srk (args, &srk); + if (err != GRUB_ERR_NONE) + goto exit2; + -+ err = grub_protect_tpm2_get_policy_digest (args, &policy_digest); ++ err = protect_tpm2_get_policy_digest (args, &policy_digest); + if (err != GRUB_ERR_NONE) + goto exit3; + -+ err = grub_protect_tpm2_seal (&policy_digest, srk, key, key_size, -+ &sealed_key); ++ err = protect_tpm2_seal (&policy_digest, srk, key, key_size, &sealed_key); + if (err != GRUB_ERR_NONE) + goto exit3; + -+ if (args->tpm2_tpm2key) -+ err = grub_protect_tpm2_export_tpm2key (args, &sealed_key); ++ if (args->tpm2_tpm2key != 0) ++ err = protect_tpm2_export_tpm2key (args, &sealed_key); + else -+ err = grub_protect_tpm2_export_sealed_key (args->tpm2_outfile, &sealed_key); ++ err = protect_tpm2_export_sealed_key (args->tpm2_outfile, &sealed_key); + if (err != GRUB_ERR_NONE) + goto exit3; + -+exit3: -+ TPM2_FlushContext (srk); ++ exit3: ++ grub_tpm2_flushcontext (srk); + -+exit2: ++ exit2: + grub_free (key); + -+exit1: -+ grub_protect_tpm2_close_device (); ++ exit1: ++ protect_tpm2_close_device (); + + return err; +} + +static grub_err_t -+grub_protect_tpm2_remove (struct grub_protect_args *args) ++protect_tpm2_remove (protect_args_t *args) +{ -+ TPM_RC rc; -+ TPM2B_PUBLIC public; -+ TPMS_AUTH_COMMAND authCommand = { 0 }; ++ TPM_RC_t rc; ++ TPM2B_PUBLIC_t public; ++ TPMS_AUTH_COMMAND_t authCommand = {0}; + grub_err_t err; + + if (args->tpm2_evict == 0) + { -+ printf (_("--tpm2-evict not specified, nothing to do.\n")); ++ printf ("--tpm2-evict not specified, nothing to do.\n"); + return GRUB_ERR_NONE; + } + -+ err = grub_protect_tpm2_open_device (args->tpm2_device); ++ err = protect_tpm2_open_device (args->tpm2_device); + if (err != GRUB_ERR_NONE) + return err; + + /* Find SRK */ -+ rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public); ++ rc = grub_tpm2_readpublic (args->tpm2_srk, NULL, &public); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, _("SRK with handle 0x%x not found.\n"), args->tpm2_srk); ++ fprintf (stderr, "SRK with handle 0x%x not found.\n", args->tpm2_srk); + err = GRUB_ERR_BAD_ARGUMENT; + goto exit1; + } @@ -1168,38 +1172,35 @@ Index: grub-2.12/util/grub-protect.c + /* Evict SRK */ + authCommand.sessionHandle = TPM_RS_PW; + -+ rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, &authCommand, -+ args->tpm2_srk, NULL); ++ rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, args->tpm2_srk, &authCommand, args->tpm2_srk, NULL); + if (rc != TPM_RC_SUCCESS) + { -+ fprintf (stderr, -+ _("Failed to evict SRK with handle 0x%x (TPM2_EvictControl: 0x%x).\n"), -+ args->tpm2_srk, rc); ++ fprintf (stderr, "Failed to evict SRK with handle 0x%x (TPM2_EvictControl: 0x%x).\n", args->tpm2_srk, rc); + err = GRUB_ERR_BAD_DEVICE; + goto exit2; + } + + err = GRUB_ERR_NONE; + -+exit2: -+ TPM2_FlushContext (args->tpm2_srk); ++ exit2: ++ grub_tpm2_flushcontext (args->tpm2_srk); + -+exit1: -+ grub_protect_tpm2_close_device (); ++ exit1: ++ protect_tpm2_close_device (); + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_protect_tpm2_run (struct grub_protect_args *args) ++protect_tpm2_run (protect_args_t *args) +{ + switch (args->action) + { -+ case GRUB_PROTECT_ACTION_ADD: -+ return grub_protect_tpm2_add (args); ++ case PROTECT_ACTION_ADD: ++ return protect_tpm2_add (args); + -+ case GRUB_PROTECT_ACTION_REMOVE: -+ return grub_protect_tpm2_remove (args); ++ case PROTECT_ACTION_REMOVE: ++ return protect_tpm2_remove (args); + + default: + return GRUB_ERR_BAD_ARGUMENT; @@ -1207,33 +1208,32 @@ Index: grub-2.12/util/grub-protect.c +} + +static grub_err_t -+grub_protect_tpm2_args_verify (struct grub_protect_args *args) ++protect_tpm2_args_verify (protect_args_t *args) +{ ++ if (args->tpm2_device == NULL) ++ args->tpm2_device = "/dev/tpm0"; ++ + switch (args->action) + { -+ case GRUB_PROTECT_ACTION_ADD: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT) ++ case PROTECT_ACTION_ADD: ++ if (args->args & PROTECT_ARG_TPM2_EVICT) + { -+ fprintf (stderr, -+ _("--tpm2-evict is invalid when --action is 'add'.\n")); ++ fprintf (stderr, N_("--tpm2-evict is invalid when --action is 'add'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_keyfile == NULL) + { -+ fprintf (stderr, _("--tpm2-keyfile must be specified.\n")); ++ fprintf (stderr, N_("--tpm2-keyfile must be specified.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_outfile == NULL) + { -+ fprintf (stderr, _("--tpm2-outfile must be specified.\n")); ++ fprintf (stderr, N_("--tpm2-outfile must be specified.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ if (args->tpm2_device == NULL) -+ args->tpm2_device = "/dev/tpm0"; -+ + if (args->tpm2_pcr_count == 0) + { + args->tpm2_pcrs[0] = 7; @@ -1251,58 +1251,47 @@ Index: grub-2.12/util/grub-protect.c + + break; + -+ case GRUB_PROTECT_ACTION_REMOVE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC) ++ case PROTECT_ACTION_REMOVE: ++ if (args->args & PROTECT_ARG_TPM2_ASYMMETRIC) + { -+ fprintf (stderr, -+ _("--tpm2-asymmetric is invalid when --action is 'remove'.\n")); ++ fprintf (stderr, N_("--tpm2-asymmetric is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ if (args->args & GRUB_PROTECT_ARG_TPM2_BANK) ++ if (args->args & PROTECT_ARG_TPM2_BANK) + { -+ fprintf (stderr, -+ _("--tpm2-bank is invalid when --action is 'remove'.\n")); ++ fprintf (stderr, N_("--tpm2-bank is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE) ++ if (args->args & PROTECT_ARG_TPM2_KEYFILE) + { -+ fprintf (stderr, -+ _("--tpm2-keyfile is invalid when --action is 'remove'.\n")); ++ fprintf (stderr, N_("--tpm2-keyfile is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE) ++ if (args->args & PROTECT_ARG_TPM2_OUTFILE) + { -+ fprintf (stderr, -+ _("--tpm2-outfile is invalid when --action is 'remove'.\n")); ++ fprintf (stderr, N_("--tpm2-outfile is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS) ++ if (args->args & PROTECT_ARG_TPM2_PCRS) + { -+ fprintf (stderr, -+ _("--tpm2-pcrs is invalid when --action is 'remove'.\n")); ++ fprintf (stderr, N_("--tpm2-pcrs is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_srk == 0) + { -+ fprintf (stderr, -+ _("--tpm2-srk is not specified when --action is 'remove'.\n")); ++ fprintf (stderr, N_("--tpm2-srk is not specified when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ if (args->tpm2_device == NULL) -+ args->tpm2_device = "/dev/tpm0"; -+ + break; + + default: -+ fprintf (stderr, -+ _("The TPM2 key protector only supports the following actions: " -+ "add, remove.\n")); ++ fprintf (stderr, N_("The TPM2 key protector only supports the following actions: add, remove.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + @@ -1310,66 +1299,66 @@ Index: grub-2.12/util/grub-protect.c +} + +static error_t -+grub_protect_argp_parser (int key, char *arg, struct argp_state *state) ++protect_argp_parser (int key, char *arg, struct argp_state *state) +{ + grub_err_t err; -+ struct grub_protect_args *args = state->input; ++ protect_args_t *args = state->input; + + switch (key) + { -+ case GRUB_PROTECT_OPT_ACTION: -+ if (args->args & GRUB_PROTECT_ARG_ACTION) ++ case PROTECT_OPT_ACTION: ++ if (args->args & PROTECT_ARG_ACTION) + { -+ fprintf (stderr, _("--action|-a can only be specified once.\n")); ++ fprintf (stderr, N_("--action|-a can only be specified once.\n")); + return EINVAL; + } + + if (grub_strcmp (arg, "add") == 0) -+ args->action = GRUB_PROTECT_ACTION_ADD; ++ args->action = PROTECT_ACTION_ADD; + else if (grub_strcmp (arg, "remove") == 0) -+ args->action = GRUB_PROTECT_ACTION_REMOVE; ++ args->action = PROTECT_ACTION_REMOVE; + else + { -+ fprintf (stderr, _("'%s' is not a valid action.\n"), arg); ++ fprintf (stderr, N_("'%s' is not a valid action.\n"), arg); + return EINVAL; + } + -+ args->args |= GRUB_PROTECT_ARG_ACTION; ++ args->args |= PROTECT_ARG_ACTION; + break; + -+ case GRUB_PROTECT_OPT_PROTECTOR: -+ if (args->args & GRUB_PROTECT_ARG_PROTECTOR) ++ case PROTECT_OPT_PROTECTOR: ++ if (args->args & PROTECT_ARG_PROTECTOR) + { -+ fprintf (stderr, _("--protector|-p can only be specified once.\n")); ++ fprintf (stderr, N_("--protector|-p can only be specified once.\n")); + return EINVAL; + } + + if (grub_strcmp (arg, "tpm2") == 0) -+ args->protector = GRUB_PROTECT_TYPE_TPM2; ++ args->protector = PROTECT_TYPE_TPM2; + else + { -+ fprintf (stderr, _("'%s' is not a valid protector.\n"), arg); ++ fprintf (stderr, N_("'%s' is not a valid protector.\n"), arg); + return EINVAL; + } + -+ args->args |= GRUB_PROTECT_ARG_PROTECTOR; ++ args->args |= PROTECT_ARG_PROTECTOR; + break; + -+ case GRUB_PROTECT_OPT_TPM2_DEVICE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_DEVICE) ++ case PROTECT_OPT_TPM2_DEVICE: ++ if (args->args & PROTECT_ARG_TPM2_DEVICE) + { -+ fprintf (stderr, _("--tpm2-device can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-device can only be specified once.\n")); + return EINVAL; + } + -+ args->tpm2_device = xstrdup(arg); -+ args->args |= GRUB_PROTECT_ARG_TPM2_DEVICE; ++ args->tpm2_device = xstrdup (arg); ++ args->args |= PROTECT_ARG_TPM2_DEVICE; + break; + -+ case GRUB_PROTECT_OPT_TPM2_PCRS: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS) ++ case PROTECT_OPT_TPM2_PCRS: ++ if (args->args & PROTECT_ARG_TPM2_PCRS) + { -+ fprintf (stderr, _("--tpm2-pcrs can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-pcrs can only be specified once.\n")); + return EINVAL; + } + @@ -1382,13 +1371,13 @@ Index: grub-2.12/util/grub-protect.c + return EINVAL; + } + -+ args->args |= GRUB_PROTECT_ARG_TPM2_PCRS; ++ args->args |= PROTECT_ARG_TPM2_PCRS; + break; + -+ case GRUB_PROTECT_OPT_TPM2_SRK: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_SRK) ++ case PROTECT_OPT_TPM2_SRK: ++ if (args->args & PROTECT_ARG_TPM2_SRK) + { -+ fprintf (stderr, _("--tpm2-srk can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-srk can only be specified once.\n")); + return EINVAL; + } + @@ -1400,13 +1389,13 @@ Index: grub-2.12/util/grub-protect.c + return EINVAL; + } + -+ args->args |= GRUB_PROTECT_ARG_TPM2_SRK; ++ args->args |= PROTECT_ARG_TPM2_SRK; + break; + -+ case GRUB_PROTECT_OPT_TPM2_ASYMMETRIC: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC) ++ case PROTECT_OPT_TPM2_ASYMMETRIC: ++ if (args->args & PROTECT_ARG_TPM2_ASYMMETRIC) + { -+ fprintf (stderr, _("--tpm2-asymmetric can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-asymmetric can only be specified once.\n")); + return EINVAL; + } + @@ -1418,13 +1407,13 @@ Index: grub-2.12/util/grub-protect.c + return EINVAL; + } + -+ args->args |= GRUB_PROTECT_ARG_TPM2_ASYMMETRIC; ++ args->args |= PROTECT_ARG_TPM2_ASYMMETRIC; + break; + -+ case GRUB_PROTECT_OPT_TPM2_BANK: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_BANK) ++ case PROTECT_OPT_TPM2_BANK: ++ if (args->args & PROTECT_ARG_TPM2_BANK) + { -+ fprintf (stderr, _("--tpm2-bank can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-bank can only be specified once.\n")); + return EINVAL; + } + @@ -1436,51 +1425,51 @@ Index: grub-2.12/util/grub-protect.c + return EINVAL; + } + -+ args->args |= GRUB_PROTECT_ARG_TPM2_BANK; ++ args->args |= PROTECT_ARG_TPM2_BANK; + break; + -+ case GRUB_PROTECT_OPT_TPM2_KEYFILE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE) ++ case PROTECT_OPT_TPM2_KEYFILE: ++ if (args->args & PROTECT_ARG_TPM2_KEYFILE) + { -+ fprintf (stderr, _("--tpm2-keyfile can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-keyfile can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_keyfile = xstrdup(arg); -+ args->args |= GRUB_PROTECT_ARG_TPM2_KEYFILE; ++ args->args |= PROTECT_ARG_TPM2_KEYFILE; + break; + -+ case GRUB_PROTECT_OPT_TPM2_OUTFILE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE) ++ case PROTECT_OPT_TPM2_OUTFILE: ++ if (args->args & PROTECT_ARG_TPM2_OUTFILE) + { -+ fprintf (stderr, _("--tpm2-outfile can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-outfile can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_outfile = xstrdup(arg); -+ args->args |= GRUB_PROTECT_ARG_TPM2_OUTFILE; ++ args->args |= PROTECT_ARG_TPM2_OUTFILE; + break; + -+ case GRUB_PROTECT_OPT_TPM2_EVICT: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT) ++ case PROTECT_OPT_TPM2_EVICT: ++ if (args->args & PROTECT_ARG_TPM2_EVICT) + { -+ fprintf (stderr, _("--tpm2-evict can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-evict can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_evict = 1; -+ args->args |= GRUB_PROTECT_ARG_TPM2_EVICT; ++ args->args |= PROTECT_ARG_TPM2_EVICT; + break; + -+ case GRUB_PROTECT_OPT_TPM2_TPM2KEY: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_TPM2KEY) ++ case PROTECT_OPT_TPM2_TPM2KEY: ++ if (args->args & PROTECT_ARG_TPM2_TPM2KEY) + { -+ fprintf (stderr, _("--tpm2-tpm2key can only be specified once.\n")); ++ fprintf (stderr, N_("--tpm2-tpm2key can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_tpm2key = 1; -+ args->args |= GRUB_PROTECT_ARG_TPM2_TPM2KEY; ++ args->args |= PROTECT_ARG_TPM2_TPM2KEY; + break; + + default: @@ -1491,28 +1480,28 @@ Index: grub-2.12/util/grub-protect.c +} + +static grub_err_t -+grub_protect_args_verify (struct grub_protect_args *args) ++protect_args_verify (protect_args_t *args) +{ -+ if (args->action == GRUB_PROTECT_ACTION_ERROR) ++ if (args->action == PROTECT_ACTION_ERROR) + { -+ fprintf (stderr, "--action is mandatory.\n"); ++ fprintf (stderr, N_("--action is mandatory.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + -+ /* At the moment, the only configurable key protector is the TPM2 one, so it -+ * is the only key protector supported by this tool. */ -+ if (args->protector != GRUB_PROTECT_TYPE_TPM2) ++ /* ++ * At the moment, the only configurable key protector is the TPM2 one, so it ++ * is the only key protector supported by this tool. ++ */ ++ if (args->protector != PROTECT_TYPE_TPM2) + { -+ fprintf (stderr, -+ _("--protector is mandatory and only 'tpm2' is currently " -+ "supported.\n")); ++ fprintf (stderr, N_("--protector is mandatory and only 'tpm2' is currently supported.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + switch (args->protector) + { -+ case GRUB_PROTECT_TYPE_TPM2: -+ return grub_protect_tpm2_args_verify (args); ++ case PROTECT_TYPE_TPM2: ++ return protect_tpm2_args_verify (args); + default: + return GRUB_ERR_BAD_ARGUMENT; + } @@ -1521,19 +1510,19 @@ Index: grub-2.12/util/grub-protect.c +} + +static grub_err_t -+grub_protect_dispatch (struct grub_protect_args *args) ++protect_dispatch (protect_args_t *args) +{ + switch (args->protector) + { -+ case GRUB_PROTECT_TYPE_TPM2: -+ return grub_protect_tpm2_run (args); ++ case PROTECT_TYPE_TPM2: ++ return protect_tpm2_run (args); + default: + return GRUB_ERR_BAD_ARGUMENT; + } +} + +static void -+grub_protect_init (int *argc, char **argv[]) ++protect_init (int *argc, char **argv[]) +{ + grub_util_host_init (argc, argv); + @@ -1552,16 +1541,16 @@ Index: grub-2.12/util/grub-protect.c +} + +static void -+grub_protect_fini (void) ++protect_fini (void) +{ + grub_fini_all (); + grub_util_biosdisk_fini (); +} + -+static struct argp grub_protect_argp = ++static struct argp protect_argp = +{ -+ .options = grub_protect_options, -+ .parser = grub_protect_argp_parser, ++ .options = protect_options, ++ .parser = protect_argp_parser, + .args_doc = NULL, + .doc = + N_("Protect a cleartext key using a GRUB key protector that can retrieve " @@ -1575,26 +1564,27 @@ Index: grub-2.12/util/grub-protect.c +main (int argc, char *argv[]) +{ + grub_err_t err; -+ struct grub_protect_args args = { 0 }; ++ protect_args_t args = {0}; + -+ if (argp_parse (&grub_protect_argp, argc, argv, 0, 0, &args) != 0) ++ if (argp_parse (&protect_argp, argc, argv, 0, 0, &args) != 0) + { -+ fprintf (stderr, _("Could not parse arguments.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; ++ fprintf (stderr, N_("Could not parse arguments.\n")); ++ return EXIT_FAILURE; + } + -+ grub_protect_init (&argc, &argv); ++ protect_init (&argc, &argv); + -+ err = grub_protect_args_verify (&args); ++ err = protect_args_verify (&args); + if (err != GRUB_ERR_NONE) + goto exit; + -+ err = grub_protect_dispatch (&args); ++ err = protect_dispatch (&args); ++ ++ exit: ++ protect_fini (); ++ + if (err != GRUB_ERR_NONE) -+ goto exit; ++ return EXIT_FAILURE; + -+exit: -+ grub_protect_fini (); -+ -+ return err; ++ return EXIT_SUCCESS; +} diff --git a/0002-Add-BLS-support-to-grub-mkconfig.patch b/0002-Add-BLS-support-to-grub-mkconfig.patch deleted file mode 100644 index bd8be6e..0000000 --- a/0002-Add-BLS-support-to-grub-mkconfig.patch +++ /dev/null @@ -1,411 +0,0 @@ -From 439de947262b0d8d4a02ca5afb1ef4f15853962c Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 9 Dec 2016 15:40:29 -0500 -Subject: [PATCH 2/9] Add BLS support to grub-mkconfig - -GRUB now has BootLoaderSpec support, the user can choose to use this by -setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup, -the boot menu entries are not added to the grub.cfg, instead BLS config -files are parsed by blscfg command and the entries created dynamically. - -A 10_linux_bls grub.d snippet to generate menu entries from BLS files -is also added that can be used on platforms where the bootloader doesn't -have BLS support and only can parse a normal grub configuration file. - -Portions of the 10_linux_bls were taken from the ostree-grub-generator -script that's included in the OSTree project. - -Fixes to support multi-devices and generate a BLS section even if no -kernels are found in the boot directory were proposed by Yclept Nemo -and Tom Gundersen respectively. - -Signed-off-by: Peter Jones -[javierm: remove outdated URL for BLS document] -Signed-off-by: Javier Martinez Canillas -[iwienand@redhat.com: skip machine ID check when updating entries] -Signed-off-by: Ian Wienand -[rharwood: commit message composits, drop man pages] -Signed-off-by: Robbie Harwood ---- - util/grub-mkconfig.in | 9 +- - util/grub-mkconfig_lib.in | 22 +++- - util/grub.d/10_linux.in | 244 +++++++++++++++++++++++++++++++++++++- - 3 files changed, 269 insertions(+), 6 deletions(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index cf5b79342..7af15df94 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -49,6 +49,8 @@ grub_script_check="${bindir}/@grub_script_check@" - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" - -+export GRUB_GRUBENV_UPDATE="yes" -+ - . "${pkgdatadir}/grub-mkconfig_lib" - - # Usage: usage -@@ -58,6 +60,7 @@ usage () { - gettext "Generate a grub config file"; echo - echo - print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")" -+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")" - print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-V, --version" "$(gettext "print the version information and exit")" - echo -@@ -93,6 +96,9 @@ do - --output=*) - grub_cfg=`echo "$option" | sed 's/--output=//'` - ;; -+ --no-grubenv-update) -+ GRUB_GRUBENV_UPDATE="no" -+ ;; - -*) - gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 - usage -@@ -300,7 +306,8 @@ export GRUB_DEFAULT \ - GRUB_DISABLE_SUBMENU \ - SUSE_BTRFS_SNAPSHOT_BOOTING \ - SUSE_CMDLINE_XENEFI \ -- SUSE_REMOVE_LINUX_ROOT_PARAM -+ SUSE_REMOVE_LINUX_ROOT_PARAM \ -+ GRUB_ENABLE_BLSCFG - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 22fb7668f..5db4337c6 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -30,6 +30,9 @@ fi - if test "x$grub_file" = x; then - grub_file="${bindir}/@grub_file@" - fi -+if test "x$grub_editenv" = x; then -+ grub_editenv="${bindir}/@grub_editenv@" -+fi - if test "x$grub_mkrelpath" = x; then - grub_mkrelpath="${bindir}/@grub_mkrelpath@" - fi -@@ -123,8 +126,19 @@ EOF - fi - } - -+prepare_grub_to_access_device_with_variable () -+{ -+ device_variable="$1" -+ shift -+ prepare_grub_to_access_device "$@" -+ unset "device_variable" -+} -+ - prepare_grub_to_access_device () - { -+ if [ -z "$device_variable" ]; then -+ device_variable="root" -+ fi - old_ifs="$IFS" - IFS=' - ' -@@ -159,18 +173,18 @@ prepare_grub_to_access_device () - # otherwise set root as per value in device.map. - fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" - if [ "x$fs_hint" != x ]; then -- echo "set root='$fs_hint'" -+ echo "set ${device_variable}='$fs_hint'" - fi - if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then - hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= - if [ "x$hints" != x ]; then - echo "if [ x\$feature_platform_search_hint = xy ]; then" -- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" -+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}" - echo "else" -- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" -+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" - echo "fi" - else -- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" -+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" - fi - fi - IFS="$old_ifs" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 5531239eb..49eccbeaf 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -91,6 +91,244 @@ if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then - LINUX_ROOT_DEVICE="" - fi - -+populate_header_warn() -+{ -+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -+ bls_parser="10_linux script" -+else -+ bls_parser="blscfg command" -+fi -+cat </dev/null | tac)) || : -+ -+ echo "${files[@]}" -+} -+ -+update_bls_cmdline() -+{ -+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ local -a files=($(get_sorted_bls)) -+ -+ for bls in "${files[@]}"; do -+ local options="${cmdline}" -+ if [ -z "${bls##*debug*}" ]; then -+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi -+ options="$(echo "${options}" | sed -e 's/\//\\\//g')" -+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf" -+ done -+} -+ -+populate_menu() -+{ -+ local -a files=($(get_sorted_bls)) -+ -+ gettext_printf "Generating boot entries from BLS files...\n" >&2 -+ -+ for bls in "${files[@]}"; do -+ read_config "${blsdir}/${bls}.conf" -+ -+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n" -+ menu="${menu}\t linux ${linux} ${options}\n" -+ if [ -n "${initrd}" ] ; then -+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n" -+ fi -+ menu="${menu}}\n\n" -+ done -+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation -+ printf "$menu" -+} -+ -+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. -+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then -+ GRUB_ENABLE_BLSCFG="true" -+fi -+ -+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then -+ if [ x$dirname = x/ ]; then -+ if [ -z "${prepare_root_cache}" ]; then -+ prepare_grub_to_access_device ${GRUB_DEVICE} -+ fi -+ else -+ if [ -z "${prepare_boot_cache}" ]; then -+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} -+ fi -+ fi -+ -+ if [ -d /sys/firmware/efi ]; then -+ bootefi_device="`${grub_probe} --target=device /boot/efi/`" -+ prepare_grub_to_access_device_with_variable boot ${bootefi_device} -+ else -+ boot_device="`${grub_probe} --target=device /boot/`" -+ prepare_grub_to_access_device_with_variable boot ${boot_device} -+ fi -+ -+ arch="$(uname -m)" -+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then -+ -+ BLS_POPULATE_MENU="true" -+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" -+ -+ if test -e ${petitboot_path}; then -+ read -r -d '' petitboot_version < ${petitboot_path} -+ petitboot_version="$(echo ${petitboot_version//v})" -+ -+ if test -n ${petitboot_version}; then -+ major_version="$(echo ${petitboot_version} | cut -d . -f1)" -+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)" -+ -+ re='^[0-9]+$' -+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && -+ ([[ ${major_version} -gt 1 ]] || -+ [[ ${major_version} -eq 1 && -+ ${minor_version} -ge 8 ]]); then -+ BLS_POPULATE_MENU="false" -+ fi -+ fi -+ fi -+ fi -+ -+ populate_header_warn -+ -+ cat << EOF -+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu -+# entries populated from BootLoaderSpec files that use this variable work correctly even -+# without a grubenv file, define a fallback kernelopts variable if this has not been set. -+# -+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by -+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX -+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both -+# the kernelopts variable in the grubenv file and the fallback kernelopts variable. -+if [ -z "\${kernelopts}" ]; then -+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+fi -+EOF -+ -+ update_bls_cmdline -+ -+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -+ populate_menu -+ else -+ cat << EOF -+ -+insmod blscfg -+blscfg -+EOF -+ fi -+ -+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then -+ blsdir="/boot/loader/entries" -+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})" -+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then -+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}") -+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then -+ ${grub_editenv} - set blsdir="${blsdir}" -+ fi -+ fi -+ -+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then -+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}" -+ fi -+ -+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then -+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}" -+ fi -+ -+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then -+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}" -+ fi -+ fi -+ -+ exit 0 -+fi -+ -+mktitle () -+{ -+ local title_type -+ local version -+ local OS_NAME -+ local OS_VERS -+ -+ title_type=$1 && shift -+ version=$1 && shift -+ -+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" -+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" -+ -+ case $title_type in -+ recovery) -+ title=$(printf '%s (%s) %s (recovery mode)' \ -+ "${OS_NAME}" "${version}" "${OS_VERS}") -+ ;; -+ *) -+ title=$(printf '%s (%s) %s' \ -+ "${OS_NAME}" "${version}" "${OS_VERS}") -+ ;; -+ esac -+ echo -n ${title} -+} -+ - title_correction_code= - - hotkey=1 -@@ -124,6 +362,7 @@ linux_entry () - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi -+ - if [ x$type != xsimple ] ; then - case $type in - recovery) -@@ -298,6 +537,7 @@ fi - is_top_level=true - for linux in ${reverse_sorted_list}; do - gettext_printf "Found linux image: %s\n" "$linux" >&2 -+ - basename=`basename $linux` - dirname=`dirname $linux` - rel_dirname=`make_system_path_relative_to_its_root $dirname` -@@ -348,7 +588,9 @@ for linux in ${reverse_sorted_list}; do - for i in ${initrd}; do - initrd_display="${initrd_display} ${dirname}/${i}" - done -- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 -+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then -+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 -+ fi - fi - - config= --- -2.44.0 - diff --git a/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch b/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch new file mode 100644 index 0000000..350d92e --- /dev/null +++ b/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch @@ -0,0 +1,290 @@ +From af8b106667aa2ca7a7613e10d8746959e182f8f1 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 29 Aug 2024 13:27:30 +0800 +Subject: [PATCH 2/2] Requiring authentication after tpm unlock for CLI access + +GRUB may use TPM to verify the integrity of boot components, and the +result can determine whether a previously sealed key can be released. If +everything checks out, showing nothing has been tampered with, the key +is released, and grub unlocks the encrypted root partition for the next +stage of booting. + +However, the liberal command line interface (CLI) can be misused by +anyone in this case to access files in the encrypted partition one way +or another. Despite efforts to keep the CLI secure by preventing utility +command output from leaking file content, many techniques in the wild +could still be used to exploit the CLI, enabling attacks or learning +methods to attack. It's nearly impossible to account for all scenarios +where a hack could be applied. + +Therefore, to mitigate potential misuse of the CLI after the root device +has been successfully unlocked via TPM, the user should be required to +authenticate using the LUKS password. This added layer of security +ensures that only authorized users can access the CLI, reducing the risk +of exploitation or unauthorized access to the encrypted partition. + +Fixes: CVE-2024-49504 + +Signed-off-by: Michael Chang +--- + grub-core/disk/cryptodisk.c | 80 +++++++++++++++++++++++++++++++++++ + grub-core/kern/main.c | 12 ++++++ + grub-core/normal/auth.c | 30 +++++++++++++ + grub-core/normal/main.c | 4 ++ + grub-core/normal/menu_entry.c | 4 ++ + include/grub/auth.h | 1 + + include/grub/cryptodisk.h | 3 ++ + include/grub/misc.h | 2 + + 8 files changed, 136 insertions(+) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index babc94868..77bc782fd 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -1188,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name, + goto error; + #ifndef GRUB_UTIL + is_tpmkey = 1; ++ grub_cli_set_auth_needed (); + #endif + goto cleanup; + } +@@ -1706,6 +1707,85 @@ luks_script_get (grub_size_t *sz) + return ret; + } + ++#ifdef GRUB_MACHINE_EFI ++grub_err_t ++grub_cryptodisk_challenge_password (void) ++{ ++ grub_cryptodisk_t cr_dev; ++ ++ for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next) ++ { ++ grub_cryptodisk_dev_t cr; ++ grub_disk_t source = NULL; ++ grub_err_t ret = GRUB_ERR_NONE; ++ grub_cryptodisk_t dev = NULL; ++ char *part = NULL; ++ struct grub_cryptomount_args cargs = {0}; ++ ++ cargs.check_boot = 0; ++ cargs.search_uuid = cr_dev->uuid; ++ ++ source = grub_disk_open (cr_dev->source); ++ ++ if (source == NULL) ++ goto error_out; ++ ++ FOR_CRYPTODISK_DEVS (cr) ++ { ++ dev = cr->scan (source, &cargs); ++ if (grub_errno) ++ goto error_out; ++ if (!dev) ++ continue; ++ break; ++ } ++ ++ if (dev == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_MODULE, ++ "no cryptodisk module can handle this device"); ++ goto error_out; ++ } ++ ++ 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"), cr_dev->uuid); ++ grub_free (part); ++ ++ cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); ++ if (cargs.key_data == NULL) ++ goto error_out; ++ ++ if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); ++ goto error_out; ++ } ++ cargs.key_len = grub_strlen ((char *) cargs.key_data); ++ ret = cr->recover_key (source, dev, &cargs); ++ if (ret != GRUB_ERR_NONE) ++ goto error_out; ++ ++ error_out: ++ if (source) ++ grub_disk_close (source); ++ if (dev) ++ cryptodisk_close (dev); ++ if (cargs.key_data) ++ { ++ grub_memset (cargs.key_data, 0, cargs.key_len); ++ grub_free (cargs.key_data); ++ } ++ ++ if (grub_errno != GRUB_ERR_NONE) ++ return grub_errno; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++#endif /* GRUB_MACHINE_EFI */ ++ + struct grub_procfs_entry luks_script = + { + .name = "luks_script", +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 07b6940d2..ef3b3756d 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -37,6 +37,7 @@ + #endif + + static bool cli_disabled = false; ++static bool cli_need_auth = false; + + grub_addr_t + grub_modules_get_end (void) +@@ -246,6 +247,17 @@ grub_is_cli_disabled (void) + return cli_disabled; + } + ++bool ++grub_is_cli_need_auth (void) ++{ ++ return cli_need_auth; ++} ++ ++void grub_cli_set_auth_needed (void) ++{ ++ cli_need_auth = true; ++} ++ + static void + check_is_cli_disabled (void) + { +diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c +index d94020186..2931ba604 100644 +--- a/grub-core/normal/auth.c ++++ b/grub-core/normal/auth.c +@@ -25,6 +25,10 @@ + #include + #include + ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif ++ + struct grub_auth_user + { + struct grub_auth_user *next; +@@ -200,6 +204,32 @@ grub_username_get (char buf[], unsigned buf_size) + return (key != GRUB_TERM_ESC); + } + ++grub_err_t ++grub_auth_check_cli_access (void) ++{ ++ if (grub_is_cli_need_auth () == true) ++ { ++#ifdef GRUB_MACHINE_EFI ++ static bool authenticated = false; ++ ++ if (authenticated == false) ++ { ++ grub_err_t ret; ++ ++ ret = grub_cryptodisk_challenge_password (); ++ if (ret == GRUB_ERR_NONE) ++ authenticated = true; ++ return ret; ++ } ++ return GRUB_ERR_NONE; ++#else ++ return GRUB_ACCESS_DENIED; ++#endif ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ + grub_err_t + grub_auth_check_authentication (const char *userlist) + { +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 8e58ced67..b08fd6977 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -560,9 +560,13 @@ grub_cmdline_run (int nested, int force_auth) + } + while (err && force_auth); + ++ if (err == GRUB_ERR_NONE) ++ err = grub_auth_check_cli_access (); ++ + if (err) + { + grub_print_error (); ++ grub_wait_after_message (); + grub_errno = GRUB_ERR_NONE; + return; + } +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index e5ba91ea4..06682a396 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -1256,9 +1256,13 @@ grub_menu_entry_run (grub_menu_entry_t entry) + + err = grub_auth_check_authentication (NULL); + ++ if (err == GRUB_ERR_NONE) ++ err = grub_auth_check_cli_access (); ++ + if (err) + { + grub_print_error (); ++ grub_wait_after_message (); + grub_errno = GRUB_ERR_NONE; + return; + } +diff --git a/include/grub/auth.h b/include/grub/auth.h +index 747334451..21d5190f0 100644 +--- a/include/grub/auth.h ++++ b/include/grub/auth.h +@@ -33,5 +33,6 @@ grub_err_t grub_auth_unregister_authentication (const char *user); + grub_err_t grub_auth_authenticate (const char *user); + grub_err_t grub_auth_deauthenticate (const char *user); + grub_err_t grub_auth_check_authentication (const char *userlist); ++grub_err_t grub_auth_check_cli_access (void); + + #endif /* ! GRUB_AUTH_HEADER */ +diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h +index 0b41e249e..b3291519b 100644 +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -203,4 +203,7 @@ grub_util_get_geli_uuid (const char *dev); + grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); + grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk); + ++#ifdef GRUB_MACHINE_EFI ++grub_err_t grub_cryptodisk_challenge_password (void); ++#endif + #endif +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 1578f36c3..6e94d18f5 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -392,6 +392,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t *r); + + extern bool EXPORT_FUNC(grub_is_cli_disabled) (void); ++extern bool EXPORT_FUNC(grub_is_cli_need_auth) (void); ++extern void EXPORT_FUNC(grub_cli_set_auth_needed) (void); + + /* Must match softdiv group in gentpl.py. */ + #if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ +-- +2.47.0 + diff --git a/0002-Restrict-file-access-on-cryptodisk-print.patch b/0002-Restrict-file-access-on-cryptodisk-print.patch deleted file mode 100644 index 2280169..0000000 --- a/0002-Restrict-file-access-on-cryptodisk-print.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 912384e63c1e3b6aa9d90effb71cd535a17da1e2 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Sat, 18 Nov 2023 19:02:31 +0800 -Subject: [PATCH 2/4] Restrict file access on cryptodisk print - -When the encrypted partition is automatically unlocked by TPM, granting -access to the system upon validation of its known good state, there's a -potential vulnerability. Grub gains access to file systems that were -previously inaccessible to the public, enabling certain commands from -the grub console to print content. This arises due to grub lacking -restrictions similar to those imposed by password authentication, which -typically occurs before privileged access is granted. - -Although the automatic unlocking process ensures system integrity and a -secure environment for grub to operate in, it doesn't directly address -the issue of authentication for viewing encrypted partition content. - -This commit addresses this security loophole by implementing a file -filter upon adding a TPM key. The newly added file filter will -specifically verify if the disk is encrypted, denying access and -returning an "Access Denied: prohibited to view encrypted data" error -message to alert the user. - -Since the policy to filter out unwanted commands from leaking encrypted -content is irreversible, it is advisable to make the loaded module -persistent to prevent its removal. - -This enhancement aims to bolster security measures and prevent -unauthorized access to encrypted data. - -Signed-Off-by Michael Chang ---- - grub-core/commands/crypttab.c | 35 ++++++++++++++++++++++++++++++++++- - grub-core/disk/diskfilter.c | 35 +++++++++++++++++++++++++++++++++++ - include/grub/disk.h | 10 ++++++++++ - include/grub/file.h | 1 + - 4 files changed, 80 insertions(+), 1 deletion(-) - -diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c -index 9397bede9..d3acc4b59 100644 ---- a/grub-core/commands/crypttab.c -+++ b/grub-core/commands/crypttab.c -@@ -6,11 +6,39 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - - grub_crypto_key_list_t *cryptokey_lst; - -+static grub_file_t -+grub_nocat_open (grub_file_t io, enum grub_file_type type) -+{ -+ grub_disk_t disk; -+ -+ /* Network device */ -+ if (!io->device->disk) -+ return io; -+ -+ disk = io->device->disk; -+ -+ if (grub_disk_is_crypto (disk)) -+ { -+ switch (type & GRUB_FILE_TYPE_MASK) -+ { -+ case GRUB_FILE_TYPE_CAT: -+ case GRUB_FILE_TYPE_HEXCAT: -+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to view encrypted data")); -+ return NULL; -+ default: -+ break; -+ } -+ } -+ -+ return io; -+} -+ - grub_err_t - grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey) - { -@@ -48,7 +76,11 @@ grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key - } - - if (is_tpmkey >= 0) -- cur->is_tpmkey = is_tpmkey; -+ { -+ cur->is_tpmkey = is_tpmkey; -+ if (is_tpmkey) -+ grub_file_filter_register (GRUB_FILE_FILTER_NOCAT, grub_nocat_open); -+ } - - if (!cur->name) - { -@@ -121,6 +153,7 @@ GRUB_MOD_INIT(crypttab) - { - cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry, - N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description")); -+ grub_dl_set_persistent (mod); - } - - GRUB_MOD_FINI(crypttab) -diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c -index 5c5fabe1a..b0c1c880d 100644 ---- a/grub-core/disk/diskfilter.c -+++ b/grub-core/disk/diskfilter.c -@@ -558,6 +558,39 @@ find_lv (const char *name) - return NULL; - } - -+static int -+grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv) -+{ -+ struct grub_diskfilter_pv *pv; -+ -+ if (!lv) -+ return 0; -+ -+ if (lv->vg->pvs) -+ for (pv = lv->vg->pvs; pv; pv = pv->next) -+ { -+ if (!pv->disk) -+ { -+ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'." -+ " Some modules may be missing from core image."), -+ pv->name); -+ continue; -+ } -+ -+ switch (pv->disk->dev->id) -+ { -+ case GRUB_DISK_DEVICE_CRYPTODISK_ID: -+ return 1; -+ case GRUB_DISK_DEVICE_DISKFILTER_ID: -+ return grub_diskfilter_has_cryptodisk (pv->disk->data); -+ default: -+ break; -+ } -+ } -+ -+ return 0; -+} -+ - static grub_err_t - grub_diskfilter_open (const char *name, grub_disk_t disk) - { -@@ -589,6 +622,8 @@ grub_diskfilter_open (const char *name, grub_disk_t disk) - - disk->total_sectors = lv->size; - disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; -+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv); -+ - return 0; - } - -diff --git a/include/grub/disk.h b/include/grub/disk.h -index 3b3db6222..63982f16c 100644 ---- a/include/grub/disk.h -+++ b/include/grub/disk.h -@@ -147,6 +147,8 @@ struct grub_disk - - /* Device-specific data. */ - void *data; -+ -+ int is_crypto_diskfilter; - }; - typedef struct grub_disk *grub_disk_t; - -@@ -314,4 +316,12 @@ void grub_mdraid1x_fini (void); - void grub_diskfilter_fini (void); - #endif - -+static inline int -+grub_disk_is_crypto (grub_disk_t disk) -+{ -+ return ((disk->is_crypto_diskfilter || -+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ? -+ 1 : 0); -+} -+ - #endif /* ! GRUB_DISK_HEADER */ -diff --git a/include/grub/file.h b/include/grub/file.h -index fde58f0fa..fcfd32ce2 100644 ---- a/include/grub/file.h -+++ b/include/grub/file.h -@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); - /* Filters with lower ID are executed first. */ - typedef enum grub_file_filter_id - { -+ GRUB_FILE_FILTER_NOCAT, - GRUB_FILE_FILTER_VERIFY, - GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_XZIO, --- -2.42.1 - diff --git a/0002-tpm2-Add-TPM-Software-Stack-TSS.patch b/0002-tpm2-Add-TPM-Software-Stack-TSS.patch deleted file mode 100644 index 8363a4b..0000000 --- a/0002-tpm2-Add-TPM-Software-Stack-TSS.patch +++ /dev/null @@ -1,4489 +0,0 @@ -From b24f2484393d468ee0286550c3275c2b090e3994 Mon Sep 17 00:00:00 2001 -From: Hernan Gatta -Date: Tue, 1 Feb 2022 05:02:54 -0800 -Subject: [PATCH 2/5] tpm2: Add TPM Software Stack (TSS) - -A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to -compose and submit TPM commands and parse reponses. - -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, -second, 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, -TPM2_LoadExternal, TPM2_Hash, TPM2_VerifySignature, -TPM2_PolicyAuthorize, TPM2_TestParms - -Signed-off-by: Hernan Gatta -Signed-off-by: Gary Lin -Reviewed-by: Stefan Berger ---- - grub-core/tpm2/buffer.c | 145 +++ - grub-core/tpm2/mu.c | 1168 ++++++++++++++++++++++++ - grub-core/tpm2/tcg2.c | 143 +++ - grub-core/tpm2/tpm2.c | 1048 +++++++++++++++++++++ - include/grub/tpm2/buffer.h | 65 ++ - include/grub/tpm2/internal/functions.h | 156 ++++ - include/grub/tpm2/internal/structs.h | 768 ++++++++++++++++ - include/grub/tpm2/internal/types.h | 403 ++++++++ - include/grub/tpm2/mu.h | 396 ++++++++ - include/grub/tpm2/tcg2.h | 34 + - include/grub/tpm2/tpm2.h | 34 + - 11 files changed, 4360 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 000000000..cb9f29497 ---- /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_cpu_to_be16 (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_cpu_to_be32 (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; -+ return; -+ } -+ -+ grub_memcpy (data, &buffer->data[buffer->offset], size); -+ buffer->offset += size; -+} -+ -+void -+grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t* value) -+{ -+ grub_uint32_t r = buffer->size - buffer->offset; -+ -+ if (buffer->error) -+ return; -+ -+ if (sizeof (*value) > r) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ grub_memcpy (value, &buffer->data[buffer->offset], sizeof (*value)); -+ buffer->offset += sizeof (*value); -+} -+ -+void -+grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t* value) -+{ -+ grub_uint16_t tmp; -+ grub_uint32_t r = buffer->size - buffer->offset; -+ -+ if (buffer->error) -+ return; -+ -+ if (sizeof (tmp) > r) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); -+ buffer->offset += sizeof (tmp); -+ *value = grub_be_to_cpu16 (tmp); -+} -+ -+void -+grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t* value) -+{ -+ grub_uint32_t tmp; -+ grub_uint32_t r = buffer->size - buffer->offset; -+ -+ if (buffer->error) -+ return; -+ -+ if (sizeof (tmp) > r) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); -+ buffer->offset += sizeof (tmp); -+ *value = grub_be_to_cpu32 (tmp); -+} -diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c -new file mode 100644 -index 000000000..10ed71c04 ---- /dev/null -+++ b/grub-core/tpm2/mu.c -@@ -0,0 +1,1168 @@ -+/* -+ * 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_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_AUTH_COMMAND* authCommand) -+{ -+ grub_uint32_t start; -+ grub_uint32_t tmp; -+ -+ grub_tpm2_buffer_pack_u32 (buffer, 0); -+ start = buffer->size; -+ -+ grub_tpm2_buffer_pack_u32 (buffer, authCommand->sessionHandle); -+ -+ grub_tpm2_buffer_pack_u16 (buffer, authCommand->nonce.size); -+ grub_tpm2_buffer_pack (buffer, authCommand->nonce.buffer, -+ authCommand->nonce.size); -+ -+ grub_tpm2_buffer_pack_u8 (buffer, -+ *((const grub_uint8_t*) &authCommand->sessionAttributes)); -+ -+ grub_tpm2_buffer_pack_u16 (buffer, authCommand->hmac.size); -+ grub_tpm2_buffer_pack (buffer, authCommand->hmac.buffer, -+ authCommand->hmac.size); -+ -+ tmp = grub_cpu_to_be32 (buffer->size - start); -+ grub_memcpy (&buffer->data[start - sizeof (grub_uint32_t)], &tmp, -+ sizeof (tmp)); -+} -+ -+void -+grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer, -+ const grub_uint16_t size, -+ const grub_uint8_t* b) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, size); -+ -+ for (grub_uint16_t i = 0; i < size; i++) -+ grub_tpm2_buffer_pack_u8 (buffer, b[i]); -+} -+ -+void -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_SYM_OBJECT algorithm, -+ const TPMU_SYM_KEY_BITS *p) -+{ -+ switch (algorithm) -+ { -+ case TPM_ALG_AES: -+ case TPM_ALG_SM4: -+ case TPM_ALG_CAMELLIA: -+ case TPM_ALG_XOR: -+ grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t*) p)); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_SYM_OBJECT algorithm, -+ const TPMU_SYM_MODE *p) -+{ -+ switch (algorithm) -+ { -+ case TPM_ALG_AES: -+ case TPM_ALG_SM4: -+ case TPM_ALG_CAMELLIA: -+ grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t*) p)); -+ break; -+ case TPM_ALG_XOR: -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, -+ 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); -+ grub_tpm2_mu_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); -+} -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_PCR_SELECTION* pcrSelection) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, pcrSelection->hash); -+ grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->sizeOfSelect); -+ -+ for (grub_uint32_t i = 0; i < pcrSelection->sizeOfSelect; i++) -+ grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->pcrSelect[i]); -+} -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, -+ const TPML_PCR_SELECTION* pcrSelection) -+{ -+ grub_tpm2_buffer_pack_u32 (buffer, pcrSelection->count); -+ -+ for (grub_uint32_t i = 0; i < pcrSelection->count; i++) -+ grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (buffer, -+ &pcrSelection->pcrSelections[i]); -+} -+ -+void -+grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMA_OBJECT *p) -+{ -+ grub_tpm2_buffer_pack_u32 (buffer, *((const grub_uint32_t*) p)); -+} -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SCHEME_XOR *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); -+ grub_tpm2_buffer_pack_u16 (buffer, p->kdf); -+} -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, -+ 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, -+ const TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ const TPMU_SCHEME_KEYEDHASH *p) -+{ -+ switch (scheme) -+ { -+ case TPM_ALG_HMAC: -+ grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (buffer, &p->hmac); -+ break; -+ case TPM_ALG_XOR: -+ grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (buffer, &p->exclusiveOr); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ 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); -+} -+ -+void -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ 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, -+ 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); -+ grub_tpm2_mu_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); -+} -+ -+void -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_RSA_DECRYPT scheme, -+ const TPMU_ASYM_SCHEME *p __attribute__ ((unused))) -+{ -+ switch (scheme) -+ { -+ case TPM_ALG_NULL: -+ break; -+ default: -+ /* Unsupported */ -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_RSA_SCHEME *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); -+ grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_RSA_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); -+ grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme); -+ grub_tpm2_buffer_pack_u16 (buffer, p->keyBits); -+ grub_tpm2_buffer_pack_u32 (buffer, p->exponent); -+} -+ -+void -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SYMCIPHER_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym); -+} -+ -+void -+grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_ECC_SCHEME *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); -+ grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_KDF scheme, -+ const TPMU_KDF_SCHEME *p) -+{ -+ switch (scheme) -+ { -+ case TPM_ALG_MGF1: -+ grub_tpm2_buffer_pack_u16 (buffer, p->mgf1.hashAlg); -+ break; -+ case TPM_ALG_KDF1_SP800_56A: -+ grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_56a.hashAlg); -+ break; -+ case TPM_ALG_KDF2: -+ grub_tpm2_buffer_pack_u16 (buffer, p->kdf2.hashAlg); -+ break; -+ case TPM_ALG_KDF1_SP800_108: -+ grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_108.hashAlg); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_KDF_SCHEME *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); -+ grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_ECC_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); -+ grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme); -+ grub_tpm2_buffer_pack_u16 (buffer, p->curveID); -+ grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (buffer, &p->kdf); -+} -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const grub_uint32_t type, -+ const TPMU_PUBLIC_PARMS *p) -+{ -+ switch (type) -+ { -+ case TPM_ALG_KEYEDHASH: -+ grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (buffer, &p->keyedHashDetail); -+ break; -+ case TPM_ALG_SYMCIPHER: -+ grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (buffer, &p->symDetail); -+ break; -+ case TPM_ALG_RSA: -+ grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (buffer, &p->rsaDetail); -+ break; -+ case TPM_ALG_ECC: -+ grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (buffer, &p->eccDetail); -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_ECC_POINT *p) -+{ -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->x.size, p->x.buffer); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->y.size, p->y.buffer); -+} -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_PUBLIC type, -+ const TPMU_PUBLIC_ID *p) -+{ -+ switch(type) -+ { -+ case TPM_ALG_KEYEDHASH: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->keyedHash.size, -+ p->keyedHash.buffer); -+ break; -+ case TPM_ALG_SYMCIPHER: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); -+ break; -+ case TPM_ALG_RSA: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); -+ break; -+ case TPM_ALG_ECC: -+ grub_tpm2_mu_TPMS_ECC_POINT_Marshal (buffer, &p->ecc); -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_PUBLIC_PARMS *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->type); -+ grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); -+} -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_PUBLIC *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->type); -+ grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg); -+ grub_tpm2_mu_TPMA_OBJECT_Marshal (buffer, &p->objectAttributes); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->authPolicy.size, p->authPolicy.buffer); -+ grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); -+ grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (buffer, p->type, &p->unique); -+} -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPM2B_PUBLIC *p) -+{ -+ grub_uint32_t start; -+ grub_uint16_t size; -+ -+ if (p) -+ { -+ grub_tpm2_buffer_pack_u16 (buffer, p->size); -+ -+ start = buffer->size; -+ grub_tpm2_mu_TPMT_PUBLIC_Marshal (buffer, &p->publicArea); -+ size = grub_cpu_to_be16 (buffer->size - start); -+ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, -+ sizeof (size)); -+ } -+ else -+ grub_tpm2_buffer_pack_u16 (buffer, 0); -+} -+ -+void -+grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SENSITIVE_CREATE *p) -+{ -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->userAuth.size, p->userAuth.buffer); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer); -+} -+ -+void -+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_PUBLIC type, -+ const TPMU_SENSITIVE_COMPOSITE *p) -+{ -+ switch(type) -+ { -+ case TPM_ALG_RSA: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); -+ break; -+ case TPM_ALG_ECC: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer); -+ break; -+ case TPM_ALG_KEYEDHASH: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer); -+ break; -+ case TPM_ALG_SYMCIPHER: -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); -+ break; -+ default: -+ buffer->error = 1; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_SENSITIVE *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->authValue.size, p->authValue.buffer); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->seedValue.size, p->seedValue.buffer); -+ grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType, -+ &p->sensitive); -+} -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPM2B_SENSITIVE *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->size); -+ grub_tpm2_mu_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea); -+} -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPM2B_SENSITIVE_CREATE *sensitiveCreate) -+{ -+ grub_uint32_t start; -+ grub_uint16_t size; -+ -+ if (sensitiveCreate) -+ { -+ grub_tpm2_buffer_pack_u16 (buffer, sensitiveCreate->size); -+ start = buffer->size; -+ grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (buffer, -+ &sensitiveCreate->sensitive); -+ size = grub_cpu_to_be16 (buffer->size - start); -+ -+ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, -+ sizeof (size)); -+ } -+ else -+ grub_tpm2_buffer_pack_u16 (buffer, 0); -+} -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SIGNATURE_RSA *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->hash); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer); -+} -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SIGNATURE_ECC *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->hash); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureR.size, p->signatureR.buffer); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureS.size, p->signatureS.buffer); -+} -+ -+void -+grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_HASH hashAlg, -+ const TPMU_HA *p) -+{ -+ switch (hashAlg) -+ { -+ case TPM_ALG_SHA1: -+ for (grub_uint16_t i = 0; i < TPM_SHA1_DIGEST_SIZE; i++) -+ grub_tpm2_buffer_pack_u8 (buffer, p->sha1[i]); -+ break; -+ case TPM_ALG_SHA256: -+ for (grub_uint16_t i = 0; i < TPM_SHA256_DIGEST_SIZE; i++) -+ grub_tpm2_buffer_pack_u8 (buffer, p->sha256[i]); -+ break; -+ case TPM_ALG_SHA384: -+ for (grub_uint16_t i = 0; i < TPM_SHA384_DIGEST_SIZE; i++) -+ grub_tpm2_buffer_pack_u8 (buffer, p->sha384[i]); -+ break; -+ case TPM_ALG_SHA512: -+ for (grub_uint16_t i = 0; i < TPM_SHA512_DIGEST_SIZE; i++) -+ grub_tpm2_buffer_pack_u8 (buffer, p->sha512[i]); -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_HA *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); -+ grub_tpm2_mu_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest); -+} -+ -+void -+grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_SIG_SCHEME sigAlg, -+ const TPMU_SIGNATURE *p) -+{ -+ switch (sigAlg) -+ { -+ case TPM_ALG_RSASSA: -+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa); -+ break; -+ case TPM_ALG_RSAPSS: -+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss); -+ break; -+ case TPM_ALG_ECDSA: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa); -+ break; -+ case TPM_ALG_ECDAA: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa); -+ break; -+ case TPM_ALG_SM2: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2); -+ break; -+ case TPM_ALG_ECSCHNORR: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr); -+ break; -+ case TPM_ALG_HMAC: -+ grub_tpm2_mu_TPMT_HA_Marshal (buffer, &p->hmac); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_SIGNATURE *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg); -+ grub_tpm2_mu_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature); -+} -+ -+void -+grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_TK_VERIFIED *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->tag); -+ grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy); -+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer); -+} -+ -+static void -+__tpm2_mu_TPM2B_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B* p, grub_uint16_t bound) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); -+ -+ if (p->size > bound) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ grub_tpm2_buffer_unpack (buffer, &p->buffer, p->size); -+} -+ -+#define TPM2B_BUFFER_UNMARSHAL(buffer, type, data) \ -+ __tpm2_mu_TPM2B_BUFFER_Unmarshal(buffer, (TPM2B *)data, sizeof(type) - sizeof(grub_uint16_t)) -+ -+void -+grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_AUTH_RESPONSE* p) -+{ -+ grub_uint8_t tmp; -+ grub_uint32_t tmp32; -+ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->nonce.size); -+ -+ if (p->nonce.size) -+ grub_tpm2_buffer_unpack (buffer, &p->nonce.buffer, p->nonce.size); -+ -+ grub_tpm2_buffer_unpack_u8 (buffer, &tmp); -+ tmp32 = tmp; -+ grub_memcpy (&p->sessionAttributes, &tmp32, sizeof (grub_uint32_t)); -+ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->hmac.size); -+ -+ if (p->hmac.size) -+ grub_tpm2_buffer_unpack (buffer, &p->hmac.buffer, p->hmac.size); -+} -+ -+void -+grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_DIGEST* digest) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DIGEST, digest); -+} -+ -+void -+grub_tpm2_mu_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_NONCE* nonce) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NONCE, nonce); -+} -+ -+void -+grub_tpm2_mu_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_DATA* data) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DATA, data); -+} -+ -+void -+grub_tpm2_mu_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_CREATION_DATA *data) -+{ -+ grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (buffer, &data->pcrSelect); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &data->pcrDigest); -+ grub_tpm2_buffer_unpack_u8 (buffer, (grub_uint8_t *)&data->locality); -+ grub_tpm2_buffer_unpack_u16 (buffer, &data->parentNameAlg); -+ grub_tpm2_mu_TPM2B_NAME_Unmarshal (buffer, &data->parentName); -+ grub_tpm2_mu_TPM2B_NAME_Unmarshal (buffer, &data->parentQualifiedName); -+ grub_tpm2_mu_TPM2B_DATA_Unmarshal (buffer, &data->outsideInfo); -+} -+ -+void -+grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_CREATION_DATA *data) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &data->size); -+ grub_tpm2_mu_TPMS_CREATION_DATA_Unmarshal (buffer, &data->creationData); -+} -+ -+void -+grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_PRIVATE *private) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PRIVATE, private); -+} -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_SENSITIVE_DATA *data) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_SENSITIVE_DATA, data); -+} -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_PUBLIC_KEY_RSA *rsa) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PUBLIC_KEY_RSA, rsa); -+} -+ -+void -+grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_ECC_PARAMETER *param) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_ECC_PARAMETER, param); -+} -+ -+void -+grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMA_OBJECT *p) -+{ -+ grub_tpm2_buffer_unpack_u32 (buffer, (grub_uint32_t*)p); -+} -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SCHEME_HMAC *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); -+} -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SCHEME_XOR *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf); -+} -+ -+void -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ TPMU_SCHEME_KEYEDHASH *p) -+{ -+ switch (scheme) -+ { -+ case TPM_ALG_HMAC: -+ grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (buffer, &p->hmac); -+ break; -+ case TPM_ALG_XOR: -+ grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (buffer, &p->exclusiveOr); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_KEYEDHASH_SCHEME *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); -+ grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_KEYEDHASH_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (buffer, &p->scheme); -+} -+ -+void -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_KEY_BITS *p) -+{ -+ switch (algorithm) -+ { -+ case TPM_ALG_AES: -+ case TPM_ALG_SM4: -+ case TPM_ALG_CAMELLIA: -+ case TPM_ALG_XOR: -+ grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t*) p); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_MODE *p) -+{ -+ switch (algorithm) -+ { -+ case TPM_ALG_AES: -+ case TPM_ALG_SM4: -+ case TPM_ALG_CAMELLIA: -+ grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t*) p); -+ break; -+ case TPM_ALG_XOR: -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_SYM_DEF_OBJECT *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->algorithm); -+ grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (buffer, p->algorithm, &p->keyBits); -+ grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (buffer, p->algorithm, &p->mode); -+} -+ -+void -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SYMCIPHER_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->sym); -+} -+ -+void -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_RSA_DECRYPT scheme, -+ TPMU_ASYM_SCHEME *p __attribute__((unused))) -+{ -+ switch (scheme) -+ { -+ case TPM_ALG_NULL: -+ break; -+ default: -+ /* Unsupported */ -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_RSA_SCHEME *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); -+ grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_RSA_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); -+ grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (buffer, &p->scheme); -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->keyBits); -+ grub_tpm2_buffer_unpack_u32 (buffer, &p->exponent); -+} -+ -+void -+grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_ECC_SCHEME *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); -+ grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_KDF scheme, -+ TPMU_KDF_SCHEME *p) -+{ -+ switch (scheme) -+ { -+ case TPM_ALG_MGF1: -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->mgf1.hashAlg); -+ break; -+ case TPM_ALG_KDF1_SP800_56A: -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_56a.hashAlg); -+ break; -+ case TPM_ALG_KDF2: -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf2.hashAlg); -+ break; -+ case TPM_ALG_KDF1_SP800_108: -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_108.hashAlg); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_KDF_SCHEME *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); -+ grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (buffer, p->scheme, &p->details); -+} -+ -+void -+grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_ECC_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); -+ grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (buffer, &p->scheme ); -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->curveID); -+ grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (buffer, &p->kdf); -+} -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ grub_uint32_t type, -+ TPMU_PUBLIC_PARMS *p) -+{ -+ switch (type) -+ { -+ case TPM_ALG_KEYEDHASH: -+ grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (buffer, &p->keyedHashDetail); -+ break; -+ case TPM_ALG_SYMCIPHER: -+ grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (buffer, &p->symDetail); -+ break; -+ case TPM_ALG_RSA: -+ grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (buffer, &p->rsaDetail); -+ break; -+ case TPM_ALG_ECC: -+ grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (buffer, &p->eccDetail); -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_ECC_POINT *p) -+{ -+ grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->x); -+ grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->y); -+} -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_PUBLIC type, -+ TPMU_PUBLIC_ID *p) -+{ -+ switch(type) -+ { -+ case TPM_ALG_KEYEDHASH: -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->keyedHash); -+ break; -+ case TPM_ALG_SYMCIPHER: -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->sym); -+ break; -+ case TPM_ALG_RSA: -+ grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &p->rsa); -+ break; -+ case TPM_ALG_ECC: -+ grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc); -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_PUBLIC *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->type); -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); -+ grub_tpm2_mu_TPMA_OBJECT_Unmarshal (buffer, &p->objectAttributes); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); -+ grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (buffer, p->type, &p->parameters); -+ grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (buffer, p->type, &p->unique); -+} -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_PUBLIC *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); -+ grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (buffer, &p->publicArea); -+} -+ -+void -+grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_NV_PUBLIC *p) -+{ -+ grub_tpm2_buffer_unpack_u32 (buffer, &p->nvIndex); -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); -+ grub_tpm2_buffer_unpack_u32 (buffer, &p->attributes); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->dataSize); -+} -+ -+void -+grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_NV_PUBLIC *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); -+ grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic); -+} -+ -+void -+grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_NAME *n) -+{ -+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NAME, n); -+} -+ -+void -+grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_TAGGED_PROPERTY* property) -+{ -+ grub_tpm2_buffer_unpack_u32 (buffer, &property->property); -+ grub_tpm2_buffer_unpack_u32 (buffer, &property->value); -+} -+ -+void -+grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_TK_CREATION *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); -+ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); -+} -+ -+void -+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_TK_HASHCHECK *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); -+ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); -+} -+ -+void -+grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_TK_VERIFIED *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); -+ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); -+} -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_PCR_SELECTION* pcrSelection) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &pcrSelection->hash); -+ grub_tpm2_buffer_unpack_u8 (buffer, &pcrSelection->sizeOfSelect); -+ -+ if (pcrSelection->sizeOfSelect > TPM_PCR_SELECT_MAX) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ for (grub_uint32_t i = 0; i < pcrSelection->sizeOfSelect; i++) -+ grub_tpm2_buffer_unpack_u8 (buffer, &pcrSelection->pcrSelect[i]); -+} -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPML_PCR_SELECTION* pcrSelection) -+{ -+ grub_tpm2_buffer_unpack_u32 (buffer, &pcrSelection->count); -+ -+ if (pcrSelection->count > TPM_NUM_PCR_BANKS) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ for (grub_uint32_t i = 0; i < pcrSelection->count; i++) -+ grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (buffer, &pcrSelection->pcrSelections[i]); -+} -+ -+void -+grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPML_DIGEST* digest) -+{ -+ grub_tpm2_buffer_unpack_u32 (buffer, &digest->count); -+ -+ if (digest->count > 8) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ for (grub_uint32_t i = 0; i < digest->count; i++) -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &digest->digests[i]); -+} -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SIGNATURE_RSA *rsa) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash); -+ grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &rsa->sig); -+} -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SIGNATURE_ECC *ecc) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash); -+ grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureR); -+ grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureS); -+} -+ -+void -+grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_HASH hashAlg, -+ TPMU_HA *p) -+{ -+ switch (hashAlg) -+ { -+ case TPM_ALG_SHA1: -+ grub_tpm2_buffer_unpack (buffer, &p->sha1, TPM_SHA1_DIGEST_SIZE); -+ break; -+ case TPM_ALG_SHA256: -+ grub_tpm2_buffer_unpack (buffer, &p->sha256, TPM_SHA256_DIGEST_SIZE); -+ break; -+ case TPM_ALG_SHA384: -+ grub_tpm2_buffer_unpack (buffer, &p->sha384, TPM_SHA384_DIGEST_SIZE); -+ break; -+ case TPM_ALG_SHA512: -+ grub_tpm2_buffer_unpack (buffer, &p->sha512, TPM_SHA512_DIGEST_SIZE); -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_HA *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); -+ grub_tpm2_mu_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest); -+} -+ -+void -+grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_SIG_SCHEME sigAlg, -+ TPMU_SIGNATURE *p) -+{ -+ switch (sigAlg) -+ { -+ case TPM_ALG_RSASSA: -+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa); -+ break; -+ case TPM_ALG_RSAPSS: -+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss); -+ break; -+ case TPM_ALG_ECDSA: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa); -+ break; -+ case TPM_ALG_ECDAA: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa); -+ break; -+ case TPM_ALG_SM2: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2); -+ break; -+ case TPM_ALG_ECSCHNORR: -+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr); -+ break; -+ case TPM_ALG_HMAC: -+ grub_tpm2_mu_TPMT_HA_Unmarshal (buffer, &p->hmac); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ default: -+ buffer->error = 1; -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_SIGNATURE *p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg); -+ grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, &p->signature); -+} -diff --git a/grub-core/tpm2/tcg2.c b/grub-core/tpm2/tcg2.c -new file mode 100644 -index 000000000..9e4b7f565 ---- /dev/null -+++ b/grub-core/tpm2/tcg2.c -@@ -0,0 +1,143 @@ -+/* -+ * 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 -+ -+static grub_err_t -+grub_tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2, -+ grub_size_t *max_output_size) -+{ -+ grub_efi_status_t status; -+ -+ static int has_caps = 0; -+ static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps = -+ { -+ .Size = (grub_uint8_t) sizeof (caps) -+ }; -+ -+ if (has_caps) -+ goto exit; -+ -+ status = protocol->get_capability (protocol, &caps); -+ if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ has_caps = 1; -+ -+exit: -+ if (tpm2) -+ *tpm2 = caps.TPMPresentFlag; -+ if (max_output_size) -+ *max_output_size = caps.MaxResponseSize; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol) -+{ -+ static grub_guid_t tpm2_guid = EFI_TPM2_GUID; -+ static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL; -+ -+ int tpm2; -+ grub_efi_handle_t *handles; -+ grub_efi_uintn_t num_handles; -+ grub_efi_handle_t tpm2_handle; -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ -+ if (tpm2_protocol) -+ { -+ *protocol = tpm2_protocol; -+ return GRUB_ERR_NONE; -+ } -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, -+ &num_handles); -+ if (!handles || !num_handles) -+ return err; -+ -+ tpm2_handle = handles[0]; -+ -+ tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (!tpm2_protocol) -+ goto exit; -+ -+ err = grub_tcg2_get_caps (tpm2_protocol, &tpm2, NULL); -+ if (err || !tpm2) -+ goto exit; -+ -+ *protocol = tpm2_protocol; -+ err = GRUB_ERR_NONE; -+ -+exit: -+ grub_free (handles); -+ return err; -+} -+ -+grub_err_t -+grub_tcg2_get_max_output_size (grub_size_t *size) -+{ -+ grub_err_t err; -+ grub_size_t max; -+ grub_efi_tpm2_protocol_t *protocol; -+ -+ if (!size) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ err = grub_tcg2_get_protocol (&protocol); -+ if (err) -+ return err; -+ -+ err = grub_tcg2_get_caps (protocol, NULL, &max); -+ if (err) -+ return err; -+ -+ *size = max; -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_tcg2_submit_command (grub_size_t input_size, -+ grub_uint8_t *input, -+ grub_size_t output_size, -+ grub_uint8_t *output) -+{ -+ grub_err_t err; -+ grub_efi_status_t status; -+ grub_efi_tpm2_protocol_t *protocol; -+ -+ if (!input_size || !input || !output_size || !output) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ err = grub_tcg2_get_protocol (&protocol); -+ if (err) -+ return err; -+ -+ status = protocol->submit_command (protocol, input_size, input, -+ output_size, output); -+ if (status != GRUB_EFI_SUCCESS) -+ return GRUB_ERR_INVALID_COMMAND; -+ -+ return GRUB_ERR_NONE; -+} -diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c -new file mode 100644 -index 000000000..06621c28d ---- /dev/null -+++ b/grub-core/tpm2/tpm2.c -@@ -0,0 +1,1048 @@ -+/* -+ * 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 -+ -+static TPM_RC -+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; -+ TPMI_ST_COMMAND_TAG tag_out; -+ grub_uint32_t command_size; -+ grub_size_t max_output_size; -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&buf); -+ grub_tpm2_buffer_pack_u16 (&buf, tag); -+ grub_tpm2_buffer_pack_u32 (&buf, 0); -+ grub_tpm2_buffer_pack_u32 (&buf, commandCode); -+ grub_tpm2_buffer_pack (&buf, in->data, in->size); -+ -+ if (buf.error) -+ return TPM_RC_FAILURE; -+ -+ command_size = grub_swap_bytes32 (buf.size); -+ grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size, -+ sizeof (command_size)); -+ -+ /* Stay within output block limits */ -+ err = grub_tcg2_get_max_output_size (&max_output_size); -+ if (err || max_output_size > out->cap) -+ max_output_size = out->cap - 1; -+ -+ /* Submit */ -+ err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size, -+ out->data); -+ if (err) -+ return TPM_RC_FAILURE; -+ -+ /* Unmarshal */ -+ out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) + -+ sizeof (grub_uint32_t); -+ grub_tpm2_buffer_unpack_u16 (out, &tag_out); -+ grub_tpm2_buffer_unpack_u32 (out, &command_size); -+ grub_tpm2_buffer_unpack_u32 (out, responseCode); -+ out->size = command_size; -+ if (out->error) -+ return TPM_RC_FAILURE; -+ -+ 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, -+ const TPM2B_SENSITIVE_CREATE *inSensitive, -+ const TPM2B_PUBLIC *inPublic, -+ const TPM2B_DATA *outsideInfo, -+ const TPML_PCR_SELECTION *creationPCR, -+ TPM_HANDLE *objectHandle, -+ TPM2B_PUBLIC *outPublic, -+ TPM2B_CREATION_DATA *creationData, -+ TPM2B_DIGEST *creationHash, -+ TPMT_TK_CREATION *creationTicket, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPM_HANDLE objectHandleTmp; -+ TPM2B_PUBLIC outPublicTmp; -+ TPM2B_CREATION_DATA creationDataTmp; -+ TPM2B_DIGEST creationHashTmp; -+ TPMT_TK_CREATION creationTicketTmp; -+ TPM2B_NAME nameTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t parameterSize; -+ -+ if (!inSensitive || !inPublic || !outsideInfo || !creationPCR) -+ return TPM_RC_VALUE; -+ -+ if (!objectHandle) -+ objectHandle = &objectHandleTmp; -+ if (!outPublic) -+ outPublic = &outPublicTmp; -+ if (!creationData) -+ creationData = &creationDataTmp; -+ if (!creationHash) -+ creationHash = &creationHashTmp; -+ if (!creationTicket) -+ creationTicket = &creationTicketTmp; -+ if (!name) -+ name = &nameTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (outPublic, 0, sizeof (*outPublic)); -+ grub_memset (creationData, 0, sizeof (*creationData)); -+ grub_memset (creationHash, 0, sizeof (*creationHash)); -+ grub_memset (creationTicket, 0, sizeof (*creationTicket)); -+ grub_memset (name, 0, sizeof (*name)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, primaryHandle); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); -+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); -+ grub_tpm2_mu_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); -+ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, creationPCR); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_CreatePrimary, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); -+ grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (&out, creationData); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, creationHash); -+ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); -+ grub_tpm2_mu_TPM2B_NAME_Unmarshal (&out, name); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey, -+ const TPMI_DH_ENTITY bind, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_NONCE *nonceCaller, -+ const TPM2B_ENCRYPTED_SECRET *encryptedSalt, -+ const TPM_SE sessionType, -+ const TPMT_SYM_DEF *symmetric, -+ const TPMI_ALG_HASH authHash, -+ TPMI_SH_AUTH_SESSION *sessionHandle, -+ TPM2B_NONCE *nonceTpm, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMI_SH_AUTH_SESSION sessionHandleTmp; -+ TPM2B_NONCE nonceTpmTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ 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) -+ nonceTpm = &nonceTpmTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (sessionHandle, 0, sizeof (*sessionHandle)); -+ grub_memset (nonceTpm, 0, sizeof (*nonceTpm)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, tpmKey); -+ grub_tpm2_buffer_pack_u32 (&in, bind); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_mu_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer); -+ 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); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_StartAuthSession, &responseCode, -+ &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ grub_tpm2_buffer_unpack_u32 (&out, sessionHandle); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPM2B_NONCE_Unmarshal (&out, nonceTpm); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_DIGEST *pcrDigest, -+ const TPML_PCR_SELECTION *pcrs, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (!pcrs) -+ return TPM_RC_VALUE; -+ -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, policySessions); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ 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; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyPCR, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal*/ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle, -+ const TPMS_AUTH_COMMAND* authCommand, -+ TPM2B_PUBLIC *outPublic) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t parameterSize; -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, objectHandle); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_ReadPublic, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_Load (const TPMI_DH_OBJECT parent_handle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_PRIVATE *inPrivate, -+ const TPM2B_PUBLIC *inPublic, -+ TPM_HANDLE *objectHandle, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPM_HANDLE objectHandleTmp; -+ TPM2B_NAME nonceTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (!inPrivate || !inPublic) -+ return TPM_RC_VALUE; -+ -+ if (!objectHandle) -+ objectHandle = &objectHandleTmp; -+ if (!name) -+ name = &nonceTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (objectHandle, 0, sizeof (*objectHandle)); -+ grub_memset (name, 0, sizeof (*name)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, parent_handle); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_mu_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer); -+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_Load, &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPM2B_NAME_Unmarshal (&out, name); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_SENSITIVE *inPrivate, -+ const TPM2B_PUBLIC *inPublic, -+ const TPMI_RH_HIERARCHY hierarchy, -+ TPM_HANDLE *objectHandle, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPM_HANDLE objectHandleTmp; -+ TPM2B_NAME nameTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (!inPublic) -+ return TPM_RC_VALUE; -+ -+ if (!objectHandle) -+ objectHandle = &objectHandleTmp; -+ if (!name) -+ name = &nameTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (objectHandle, 0, sizeof (*objectHandle)); -+ grub_memset (name, 0, sizeof (*name)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ if (inPrivate) -+ grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (&in, inPrivate); -+ else -+ grub_tpm2_buffer_pack_u16 (&in, 0); -+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); -+ grub_tpm2_buffer_pack_u32 (&in, hierarchy); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPM2B_NAME_Unmarshal (&out, name); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_Unseal (const TPMI_DH_OBJECT itemHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_DATA *outData, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPM2B_SENSITIVE_DATA outDataTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (!outData) -+ outData = &outDataTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (outData, 0, sizeof (*outData)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, itemHandle); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_Unseal, &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPM2B_SENSITIVE_DATA_Unmarshal (&out, outData); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_FlushContext (const TPMI_DH_CONTEXT handle) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPM_RC responseCode; -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, handle); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (TPM_ST_NO_SESSIONS, TPM_CC_FlushContext, -+ &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand, -+ const TPML_PCR_SELECTION *pcrSelectionIn, -+ grub_uint32_t *pcrUpdateCounter, -+ TPML_PCR_SELECTION *pcrSelectionOut, -+ TPML_DIGEST *pcrValues, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ grub_uint32_t pcrUpdateCounterTmp; -+ TPML_PCR_SELECTION pcrSelectionOutTmp; -+ TPML_DIGEST pcrValuesTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t parameterSize; -+ -+ if (!pcrSelectionIn) -+ return TPM_RC_VALUE; -+ -+ if (!pcrUpdateCounter) -+ pcrUpdateCounter = &pcrUpdateCounterTmp; -+ if (!pcrSelectionOut) -+ pcrSelectionOut = &pcrSelectionOutTmp; -+ if (!pcrValues) -+ pcrValues = &pcrValuesTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ /* 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; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_PCR_Read, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); -+ grub_tpm2_buffer_unpack_u32 (&out, pcrUpdateCounter); -+ grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (&out, pcrSelectionOut); -+ grub_tpm2_mu_TPML_DIGEST_Unmarshal (&out, pcrValues); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_DIGEST *policyDigest, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPM2B_DIGEST policyDigestTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t parameterSize; -+ -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ if (!policyDigest) -+ policyDigest = &policyDigestTmp; -+ -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ grub_memset (policyDigest, 0, sizeof (*policyDigest)); -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, policySession); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyGetDigest, &responseCode, -+ &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, policyDigest); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_Create (const TPMI_DH_OBJECT parentHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_SENSITIVE_CREATE *inSensitive, -+ const TPM2B_PUBLIC *inPublic, -+ const TPM2B_DATA *outsideInfo, -+ const TPML_PCR_SELECTION *creationPCR, -+ TPM2B_PRIVATE *outPrivate, -+ TPM2B_PUBLIC *outPublic, -+ TPM2B_CREATION_DATA *creationData, -+ TPM2B_DIGEST *creationHash, -+ TPMT_TK_CREATION *creationTicket, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPM2B_PUBLIC outPublicTmp; -+ TPM2B_PRIVATE outPrivateTmp; -+ TPM2B_CREATION_DATA creationDataTmp; -+ TPM2B_DIGEST creationHashTmp; -+ TPMT_TK_CREATION creationTicketTmp; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS:TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ TPM_RC rc; -+ grub_uint32_t parameterSize; -+ -+ if (!inSensitive || !inPublic || !outsideInfo || !creationPCR) -+ return TPM_RC_VALUE; -+ -+ if (!outPrivate) -+ outPrivate = &outPrivateTmp; -+ if (!outPublic) -+ outPublic = &outPublicTmp; -+ if (!creationData) -+ creationData = &creationDataTmp; -+ if (!creationHash) -+ creationHash = &creationHashTmp; -+ if (!creationTicket) -+ creationTicket = &creationTicketTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (outPrivate, 0, sizeof (*outPrivate)); -+ grub_memset (outPublic, 0, sizeof (*outPublic)); -+ grub_memset (creationData, 0, sizeof (*creationData)); -+ grub_memset (creationHash, 0, sizeof (*creationHash)); -+ grub_memset (creationTicket, 0, sizeof (*creationTicket)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, parentHandle); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); -+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); -+ grub_tpm2_mu_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); -+ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, creationPCR); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_Create, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); -+ grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (&out, outPrivate); -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); -+ grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (&out, creationData); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, creationHash); -+ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_EvictControl (const TPMI_RH_PROVISION auth, -+ const TPMI_DH_OBJECT objectHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPMI_DH_PERSISTENT persistentHandle, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ TPM_RC rc; -+ grub_uint32_t parameterSize; -+ -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, auth); -+ grub_tpm2_buffer_pack_u32 (&in, objectHandle); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_buffer_pack_u32 (&in, persistentHandle); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_EvictControl, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ { -+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); -+ } -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_MAX_BUFFER *data, -+ const TPMI_ALG_HASH hashAlg, -+ const TPMI_RH_HIERARCHY hierarchy, -+ TPM2B_DIGEST *outHash, -+ TPMT_TK_HASHCHECK *validation, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPM2B_DIGEST outHashTmp; -+ TPMT_TK_HASHCHECK validationTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (hashAlg == TPM_ALG_NULL) -+ return TPM_RC_VALUE; -+ -+ if (!outHash) -+ outHash = &outHashTmp; -+ if (!validation) -+ validation = &validationTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (outHash, 0, sizeof (*outHash)); -+ grub_memset (validation, 0, sizeof (*validation)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ if (data) -+ grub_tpm2_mu_TPM2B_Marshal (&in, data->size, data->buffer); -+ else -+ grub_tpm2_buffer_pack_u16 (&in, 0); -+ grub_tpm2_buffer_pack_u16 (&in, hashAlg); -+ grub_tpm2_buffer_pack_u32 (&in, hierarchy); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_Hash, &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, outHash); -+ grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_DIGEST *digest, -+ const TPMT_SIGNATURE *signature, -+ TPMT_TK_VERIFIED *validation, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPMT_TK_VERIFIED validationTmp; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (!digest || !signature) -+ return TPM_RC_VALUE; -+ -+ if (!validation) -+ validation = &validationTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (validation, 0, sizeof (*validation)); -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_buffer_pack_u32 (&in, keyHandle); -+ grub_tpm2_mu_TPM2B_Marshal (&in, digest->size, digest->buffer); -+ grub_tpm2_mu_TPMT_SIGNATURE_Marshal (&in, signature); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_VerifySignature, &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (&out, validation); -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_DIGEST *approvedPolicy, -+ const TPM2B_NONCE *policyRef, -+ const TPM2B_NAME *keySign, -+ const TPMT_TK_VERIFIED *checkTicket, -+ TPMS_AUTH_RESPONSE *authResponse) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMS_AUTH_RESPONSE authResponseTmp; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ grub_uint32_t param_size; -+ -+ if (!approvedPolicy || !keySign || !checkTicket) -+ return TPM_RC_VALUE; -+ -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ grub_memset (authResponse, 0, sizeof (*authResponse)); -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_buffer_pack_u32 (&in, policySession); -+ if (authCommand) -+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); -+ grub_tpm2_mu_TPM2B_Marshal (&in, approvedPolicy->size, approvedPolicy->buffer); -+ if (policyRef) -+ grub_tpm2_mu_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer); -+ else -+ grub_tpm2_buffer_pack_u16 (&in, 0); -+ grub_tpm2_mu_TPM2B_Marshal (&in, keySign->size, keySign->name); -+ grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (&in, checkTicket); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyAuthorize, &responseCode, &in, &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (tag == TPM_ST_SESSIONS) -+ { -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); -+ } -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -+ -+TPM_RC -+TPM2_TestParms (const TPMT_PUBLIC_PARMS *parms, -+ const TPMS_AUTH_COMMAND* authCommand) -+{ -+ TPM_RC rc; -+ struct grub_tpm2_buffer in; -+ struct grub_tpm2_buffer out; -+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; -+ TPM_RC responseCode; -+ -+ if (!parms) -+ return TPM_RC_VALUE; -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ grub_tpm2_mu_TPMT_PUBLIC_PARMS_Marshal (&in, parms); -+ if (in.error) -+ return TPM_RC_FAILURE; -+ -+ /* Submit */ -+ grub_tpm2_buffer_init (&out); -+ rc = grub_tpm2_submit_command (tag, TPM_CC_TestParms, &responseCode, &in, -+ &out); -+ if (rc != TPM_RC_SUCCESS) -+ return rc; -+ if (responseCode != TPM_RC_SUCCESS) -+ return responseCode; -+ -+ /* Unmarshal */ -+ if (out.error) -+ return TPM_RC_FAILURE; -+ -+ return TPM_RC_SUCCESS; -+} -diff --git a/include/grub/tpm2/buffer.h b/include/grub/tpm2/buffer.h -new file mode 100644 -index 000000000..87dcd8d6c ---- /dev/null -+++ b/include/grub/tpm2/buffer.h -@@ -0,0 +1,65 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_BUFFER_HEADER -+#define GRUB_TPM2_BUFFER_HEADER 1 -+ -+#include -+ -+#define GRUB_TPM2_BUFFER_CAPACITY 4096 -+ -+struct grub_tpm2_buffer -+{ -+ grub_uint8_t data[GRUB_TPM2_BUFFER_CAPACITY]; -+ grub_size_t size; -+ grub_size_t offset; -+ grub_size_t cap; -+ int error; -+}; -+typedef struct grub_tpm2_buffer *grub_tpm2_buffer_t; -+ -+void -+grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer); -+ -+void -+grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data, -+ grub_size_t size); -+ -+void -+grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value); -+ -+void -+grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value); -+ -+void -+grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value); -+ -+void -+grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data, -+ grub_size_t size); -+ -+void -+grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t* value); -+ -+void -+grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t* value); -+ -+void -+grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t* value); -+ -+#endif /* ! GRUB_TPM2_BUFFER_HEADER */ -diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h -new file mode 100644 -index 000000000..ac3154ef5 ---- /dev/null -+++ b/include/grub/tpm2/internal/functions.h -@@ -0,0 +1,156 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER -+#define GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER 1 -+ -+#include -+ -+TPM_RC -+TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_SENSITIVE_CREATE *inSensitive, -+ const TPM2B_PUBLIC *inPublic, -+ const TPM2B_DATA *outsideInfo, -+ const TPML_PCR_SELECTION *creationPCR, -+ TPM_HANDLE *objectHandle, -+ TPM2B_PUBLIC *outPublic, -+ TPM2B_CREATION_DATA *creationData, -+ TPM2B_DIGEST *creationHash, -+ TPMT_TK_CREATION *creationTicket, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey, -+ const TPMI_DH_ENTITY bind, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_NONCE *nonceCaller, -+ const TPM2B_ENCRYPTED_SECRET *encryptedSalt, -+ const TPM_SE sessionType, -+ const TPMT_SYM_DEF *symmetric, -+ const TPMI_ALG_HASH authHash, -+ TPMI_SH_AUTH_SESSION *sessionHandle, -+ TPM2B_NONCE *nonceTpm, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_PolicyPCR (const TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_DIGEST *pcrDigest, -+ const TPML_PCR_SELECTION *pcrs, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle, -+ const TPMS_AUTH_COMMAND* authCommand, -+ TPM2B_PUBLIC *outPublic); -+ -+TPM_RC -+TPM2_Load (const TPMI_DH_OBJECT parent_handle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_PRIVATE *inPrivate, -+ const TPM2B_PUBLIC *inPublic, -+ TPM_HANDLE *objectHandle, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_SENSITIVE *inPrivate, -+ const TPM2B_PUBLIC *inPublic, -+ const TPMI_RH_HIERARCHY hierarchy, -+ TPM_HANDLE *objectHandle, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_Unseal (const TPMI_DH_OBJECT item_handle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_DATA *outData, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_FlushContext (const TPMI_DH_CONTEXT handle); -+ -+TPM_RC -+TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand, -+ const TPML_PCR_SELECTION *pcrSelectionIn, -+ grub_uint32_t *pcrUpdateCounter, -+ TPML_PCR_SELECTION *pcrSelectionOut, -+ TPML_DIGEST *pcrValues, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_DIGEST *policyDigest, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_Create (const TPMI_DH_OBJECT parentHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_SENSITIVE_CREATE *inSensitive, -+ const TPM2B_PUBLIC *inPublic, -+ const TPM2B_DATA *outsideInfo, -+ const TPML_PCR_SELECTION *creationPCR, -+ TPM2B_PRIVATE *outPrivate, -+ TPM2B_PUBLIC *outPublic, -+ TPM2B_CREATION_DATA *creationData, -+ TPM2B_DIGEST *creationHash, -+ TPMT_TK_CREATION *creationTicket, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_EvictControl (const TPMI_RH_PROVISION auth, -+ const TPMI_DH_OBJECT objectHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPMI_DH_PERSISTENT persistentHandle, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_MAX_BUFFER *data, -+ const TPMI_ALG_HASH hashAlg, -+ const TPMI_RH_HIERARCHY hierarchy, -+ TPM2B_DIGEST *outHash, -+ TPMT_TK_HASHCHECK *validation, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_DIGEST *digest, -+ const TPMT_SIGNATURE *signature, -+ TPMT_TK_VERIFIED *validation, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ const TPM2B_DIGEST *approvedPolicy, -+ const TPM2B_NONCE *policyRef, -+ const TPM2B_NAME *keySign, -+ const TPMT_TK_VERIFIED *checkTicket, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_TestParms (const TPMT_PUBLIC_PARMS *parms, -+ const TPMS_AUTH_COMMAND* authCommand); -+ -+#endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */ -diff --git a/include/grub/tpm2/internal/structs.h b/include/grub/tpm2/internal/structs.h -new file mode 100644 -index 000000000..c615d71e9 ---- /dev/null -+++ b/include/grub/tpm2/internal/structs.h -@@ -0,0 +1,768 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_INTERNAL_STRUCTS_HEADER -+#define GRUB_TPM2_INTERNAL_STRUCTS_HEADER 1 -+ -+#include -+ -+/* TPMS_TAGGED_PROPERTY Structure */ -+struct TPMS_TAGGED_PROPERTY -+{ -+ TPM_PT property; -+ grub_uint32_t value; -+}; -+typedef struct TPMS_TAGGED_PROPERTY TPMS_TAGGED_PROPERTY; -+ -+/* TPML_TAGGED_TPM_PROPERTY Structure */ -+struct TPML_TAGGED_TPM_PROPERTY -+{ -+ grub_uint32_t count; -+ TPMS_TAGGED_PROPERTY tpmProperty[TPM_MAX_TPM_PROPERTIES]; -+}; -+typedef struct TPML_TAGGED_TPM_PROPERTY TPML_TAGGED_TPM_PROPERTY; -+ -+/* TPMU_CAPABILITIES Structure */ -+union TPMU_CAPABILITIES -+{ -+ TPML_TAGGED_TPM_PROPERTY tpmProperties; -+}; -+typedef union TPMU_CAPABILITIES TPMU_CAPABILITIES; -+ -+/* TPMS_CAPABILITY_DATA Structure */ -+struct TPMS_CAPABILITY_DATA -+{ -+ TPM_CAP capability; -+ TPMU_CAPABILITIES data; -+}; -+typedef struct TPMS_CAPABILITY_DATA TPMS_CAPABILITY_DATA; -+ -+/* TPMS_PCR_SELECT Structure */ -+struct TPMS_PCR_SELECT -+{ -+ grub_uint8_t sizeOfSelect; -+ grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; -+}; -+typedef struct TPMS_PCR_SELECT TPMS_PCR_SELECT; -+ -+/* TPMS_PCR_SELECTION Structure */ -+struct TPMS_PCR_SELECTION -+{ -+ TPMI_ALG_HASH hash; -+ grub_uint8_t sizeOfSelect; -+ grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; -+}; -+typedef struct TPMS_PCR_SELECTION TPMS_PCR_SELECTION; -+ -+static inline void TPMS_PCR_SELECTION_SelectPCR(TPMS_PCR_SELECTION* self, grub_uint32_t n) -+{ -+ self->pcrSelect[(n / 8)] |= (1 << (n % 8)); -+} -+ -+/* TPML_PCR_SELECTION Structure */ -+struct TPML_PCR_SELECTION -+{ -+ grub_uint32_t count; -+ TPMS_PCR_SELECTION pcrSelections[TPM_NUM_PCR_BANKS]; -+}; -+typedef struct TPML_PCR_SELECTION TPML_PCR_SELECTION; -+ -+/* TPMU_HA Structure */ -+union TPMU_HA -+{ -+ grub_uint8_t sha1[TPM_SHA1_DIGEST_SIZE]; -+ grub_uint8_t sha256[TPM_SHA256_DIGEST_SIZE]; -+ grub_uint8_t sha384[TPM_SHA384_DIGEST_SIZE]; -+ grub_uint8_t sha512[TPM_SHA512_DIGEST_SIZE]; -+ grub_uint8_t sm3_256[TPM_SM3_256_DIGEST_SIZE]; -+}; -+typedef union TPMU_HA TPMU_HA; -+ -+/* TPM2B Structure */ -+struct TPM2B -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[1]; -+}; -+typedef struct TPM2B TPM2B; -+ -+/* TPM2B_DIGEST Structure */ -+struct TPM2B_DIGEST -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[sizeof(TPMU_HA)]; -+}; -+typedef struct TPM2B_DIGEST TPM2B_DIGEST; -+ -+/* TPML_DIGEST Structure */ -+struct TPML_DIGEST -+{ -+ grub_uint32_t count; -+ TPM2B_DIGEST digests[8]; -+}; -+typedef struct TPML_DIGEST TPML_DIGEST; -+ -+/* TPM2B_NONCE Type */ -+typedef TPM2B_DIGEST TPM2B_NONCE; -+ -+/* TPMA_SESSION Structure */ -+struct TPMA_SESSION -+{ -+ unsigned int continueSession:1; -+ unsigned int auditExclusive:1; -+ unsigned int auditReset:1; -+ unsigned int reserved1:2; -+ unsigned int decrypt:1; -+ unsigned int encrypt:1; -+ unsigned int audit:1; -+ unsigned int reserved:24; -+}; -+typedef struct TPMA_SESSION TPMA_SESSION; -+ -+/* TPM2B_AUTH Type */ -+typedef TPM2B_DIGEST TPM2B_AUTH; -+ -+/* TPMS_AUTH_COMMAND Structure */ -+struct TPMS_AUTH_COMMAND -+{ -+ TPMI_SH_AUTH_SESSION sessionHandle; -+ TPM2B_NONCE nonce; -+ TPMA_SESSION sessionAttributes; -+ TPM2B_AUTH hmac; -+}; -+typedef struct TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND; -+ -+/* TPMS_AUTH_RESPONSE Structure */ -+struct TPMS_AUTH_RESPONSE -+{ -+ TPM2B_NONCE nonce; -+ TPMA_SESSION sessionAttributes; -+ TPM2B_AUTH hmac; -+}; -+typedef struct TPMS_AUTH_RESPONSE TPMS_AUTH_RESPONSE; -+ -+/* TPM2B_SENSITIVE_DATA Structure */ -+struct TPM2B_SENSITIVE_DATA -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_SYM_DATA]; -+}; -+typedef struct TPM2B_SENSITIVE_DATA TPM2B_SENSITIVE_DATA; -+ -+/* TPMS_SENSITIVE_CREATE Structure */ -+struct TPMS_SENSITIVE_CREATE -+{ -+ TPM2B_AUTH userAuth; -+ TPM2B_SENSITIVE_DATA data; -+}; -+typedef struct TPMS_SENSITIVE_CREATE TPMS_SENSITIVE_CREATE; -+ -+/* TPM2B_SENSITIVE_CREATE Structure */ -+struct TPM2B_SENSITIVE_CREATE -+{ -+ grub_uint16_t size; -+ TPMS_SENSITIVE_CREATE sensitive; -+}; -+typedef struct TPM2B_SENSITIVE_CREATE TPM2B_SENSITIVE_CREATE; -+ -+/* TPMA_OBJECT Structure */ -+struct TPMA_OBJECT -+{ -+ unsigned int reserved1:1; -+ unsigned int fixedTPM:1; -+ unsigned int stClear:1; -+ unsigned int reserved2:1; -+ unsigned int fixedParent:1; -+ unsigned int sensitiveDataOrigin:1; -+ unsigned int userWithAuth:1; -+ unsigned int adminWithPolicy:1; -+ unsigned int reserved3:2; -+ unsigned int noDA:1; -+ unsigned int encryptedDuplication:1; -+ unsigned int reserved4:4; -+ unsigned int restricted:1; -+ unsigned int decrypt:1; -+ unsigned int sign:1; -+ unsigned int reserved5:13; -+}; -+typedef struct TPMA_OBJECT TPMA_OBJECT; -+ -+/* TPMS_SCHEME_HASH Structure */ -+struct TPMS_SCHEME_HASH -+{ -+ TPMI_ALG_HASH hashAlg; -+}; -+typedef struct TPMS_SCHEME_HASH TPMS_SCHEME_HASH; -+ -+/* TPMS_SCHEME_HASH Types */ -+typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECDH; -+typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECMQV; -+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSASSA; -+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSAPSS; -+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDSA; -+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDAA; -+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_SM2; -+typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECSCHNORR; -+typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_RSAES; -+typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_OAEP; -+typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2; -+typedef TPMS_SCHEME_HASH TPMS_SCHEME_MGF1; -+typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_56A; -+typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2; -+typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_108; -+ -+/* TPMS_SCHEME_HMAC Type */ -+typedef TPMS_SCHEME_HASH TPMS_SCHEME_HMAC; -+ -+/* TPMS_SCHEME_XOR Structure */ -+struct TPMS_SCHEME_XOR -+{ -+ TPMI_ALG_HASH hashAlg; -+ TPMI_ALG_KDF kdf; -+}; -+typedef struct TPMS_SCHEME_XOR TPMS_SCHEME_XOR; -+ -+/* TPMU_SCHEME_KEYEDHASH Union */ -+union TPMU_SCHEME_KEYEDHASH -+{ -+ TPMS_SCHEME_HMAC hmac; -+ TPMS_SCHEME_XOR exclusiveOr; -+}; -+typedef union TPMU_SCHEME_KEYEDHASH TPMU_SCHEME_KEYEDHASH; -+ -+/* TPMT_KEYEDHASH_SCHEME Structure */ -+struct TPMT_KEYEDHASH_SCHEME -+{ -+ TPMI_ALG_KEYEDHASH_SCHEME scheme; -+ TPMU_SCHEME_KEYEDHASH details; -+}; -+typedef struct TPMT_KEYEDHASH_SCHEME TPMT_KEYEDHASH_SCHEME; -+ -+/* TPMS_KEYEDHASH_PARMS Structure */ -+struct TPMS_KEYEDHASH_PARMS -+{ -+ TPMT_KEYEDHASH_SCHEME scheme; -+}; -+typedef struct TPMS_KEYEDHASH_PARMS TPMS_KEYEDHASH_PARMS; -+ -+/* TPMU_SYM_KEY_BITS Union */ -+union TPMU_SYM_KEY_BITS -+{ -+ TPM_KEY_BITS aes; -+ TPM_KEY_BITS exclusiveOr; -+ TPM_KEY_BITS sm4; -+ TPM_KEY_BITS camellia; -+}; -+typedef union TPMU_SYM_KEY_BITS TPMU_SYM_KEY_BITS; -+ -+/* TPMU_SYM_MODE Union */ -+union TPMU_SYM_MODE -+{ -+ TPMI_ALG_SYM_MODE aes; -+ TPMI_ALG_SYM_MODE sm4; -+ TPMI_ALG_SYM_MODE camellia; -+ TPMI_ALG_SYM_MODE sym; -+}; -+typedef union TPMU_SYM_MODE TPMU_SYM_MODE; -+ -+/* TPMT_SYM_DEF_OBJECT Structure */ -+struct TPMT_SYM_DEF_OBJECT -+{ -+ TPMI_ALG_SYM_OBJECT algorithm; -+ TPMU_SYM_KEY_BITS keyBits; -+ TPMU_SYM_MODE mode; -+}; -+typedef struct TPMT_SYM_DEF_OBJECT TPMT_SYM_DEF_OBJECT; -+ -+/* TPMS_SYMCIPHER_PARMS Structure */ -+struct TPMS_SYMCIPHER_PARMS -+{ -+ TPMT_SYM_DEF_OBJECT sym; -+}; -+typedef struct TPMS_SYMCIPHER_PARMS TPMS_SYMCIPHER_PARMS; -+ -+/* TPMU_ASYM_SCHEME Union */ -+union TPMU_ASYM_SCHEME -+{ -+ TPMS_KEY_SCHEME_ECDH ecdh; -+ TPMS_KEY_SCHEME_ECMQV ecmqv; -+ TPMS_SIG_SCHEME_RSASSA rsassa; -+ TPMS_SIG_SCHEME_RSAPSS rsapss; -+ TPMS_SIG_SCHEME_ECDSA ecdsa; -+ TPMS_SIG_SCHEME_ECDAA ecdaa; -+ TPMS_SIG_SCHEME_SM2 sm2; -+ TPMS_SIG_SCHEME_ECSCHNORR ecschnorr; -+ TPMS_ENC_SCHEME_RSAES rsaes; -+ TPMS_ENC_SCHEME_OAEP oaep; -+ TPMS_SCHEME_HASH anySig; -+ unsigned char padding[4]; -+}; -+typedef union TPMU_ASYM_SCHEME TPMU_ASYM_SCHEME; -+ -+/* TPMT_RSA_SCHEME Structure */ -+struct TPMT_RSA_SCHEME -+{ -+ TPMI_ALG_RSA_SCHEME scheme; -+ TPMU_ASYM_SCHEME details; -+}; -+typedef struct TPMT_RSA_SCHEME TPMT_RSA_SCHEME; -+ -+/* TPMS_RSA_PARMS Structure */ -+struct TPMS_RSA_PARMS -+{ -+ TPMT_SYM_DEF_OBJECT symmetric; -+ TPMT_RSA_SCHEME scheme; -+ TPM_KEY_BITS keyBits; -+ grub_uint32_t exponent; -+}; -+typedef struct TPMS_RSA_PARMS TPMS_RSA_PARMS; -+ -+/* TPMT_ECC_SCHEME Structure */ -+struct TPMT_ECC_SCHEME -+{ -+ TPMI_ALG_ECC_SCHEME scheme; -+ TPMU_ASYM_SCHEME details; -+}; -+typedef struct TPMT_ECC_SCHEME TPMT_ECC_SCHEME; -+ -+/* TPMU_KDF_SCHEME Union */ -+union TPMU_KDF_SCHEME -+{ -+ TPMS_SCHEME_MGF1 mgf1; -+ TPMS_SCHEME_KDF1_SP800_56A kdf1_sp800_56a; -+ TPMS_SCHEME_KDF2 kdf2; -+ TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108; -+}; -+typedef union TPMU_KDF_SCHEME TPMU_KDF_SCHEME; -+ -+/* TPMT_KDF_SCHEME Structure */ -+struct TPMT_KDF_SCHEME -+{ -+ TPMI_ALG_KDF scheme; -+ TPMU_KDF_SCHEME details; -+}; -+typedef struct TPMT_KDF_SCHEME TPMT_KDF_SCHEME; -+ -+/* TPMS_ECC_PARMS Structure */ -+struct TPMS_ECC_PARMS -+{ -+ TPMT_SYM_DEF_OBJECT symmetric; -+ TPMT_ECC_SCHEME scheme; -+ TPMI_ECC_CURVE curveID; -+ TPMT_KDF_SCHEME kdf; -+}; -+typedef struct TPMS_ECC_PARMS TPMS_ECC_PARMS; -+ -+/* TPMT_ASYM_SCHEME Structure */ -+struct TPMT_ASYM_SCHEME -+{ -+ TPMI_ALG_ASYM_SCHEME scheme; -+ TPMU_ASYM_SCHEME details; -+}; -+typedef struct TPMT_ASYM_SCHEME TPMT_ASYM_SCHEME; -+ -+/* TPMS_ASYM_PARMS Structure */ -+struct TPMS_ASYM_PARMS -+{ -+ TPMT_SYM_DEF_OBJECT symmetric; -+ TPMT_ASYM_SCHEME scheme; -+}; -+typedef struct TPMS_ASYM_PARMS TPMS_ASYM_PARMS; -+ -+/* TPMU_PUBLIC_PARMS Union */ -+union TPMU_PUBLIC_PARMS -+{ -+ TPMS_KEYEDHASH_PARMS keyedHashDetail; -+ TPMS_SYMCIPHER_PARMS symDetail; -+ TPMS_RSA_PARMS rsaDetail; -+ TPMS_ECC_PARMS eccDetail; -+ TPMS_ASYM_PARMS asymDetail; -+}; -+typedef union TPMU_PUBLIC_PARMS TPMU_PUBLIC_PARMS; -+ -+/* TPMT_PUBLIC_PARMS Structure */ -+struct TPMT_PUBLIC_PARMS { -+ TPMI_ALG_PUBLIC type; -+ TPMU_PUBLIC_PARMS parameters; -+}; -+typedef struct TPMT_PUBLIC_PARMS TPMT_PUBLIC_PARMS; -+ -+/* TPM2B_PUBLIC_KEY_RSA Structure */ -+struct TPM2B_PUBLIC_KEY_RSA -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES]; -+}; -+typedef struct TPM2B_PUBLIC_KEY_RSA TPM2B_PUBLIC_KEY_RSA; -+ -+/* TPM2B_ECC_PARAMETER Structure */ -+struct TPM2B_ECC_PARAMETER -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_ECC_KEY_BYTES]; -+}; -+typedef struct TPM2B_ECC_PARAMETER TPM2B_ECC_PARAMETER; -+ -+/* TPMS_ECC_POINT Structure */ -+struct TPMS_ECC_POINT -+{ -+ TPM2B_ECC_PARAMETER x; -+ TPM2B_ECC_PARAMETER y; -+}; -+typedef struct TPMS_ECC_POINT TPMS_ECC_POINT; -+ -+/* TPMU_ENCRYPTED_SECRET Union */ -+union TPMU_ENCRYPTED_SECRET -+{ -+ grub_uint8_t ecc[sizeof(TPMS_ECC_POINT)]; -+ grub_uint8_t rsa[TPM_MAX_RSA_KEY_BYTES]; -+ grub_uint8_t symmetric[sizeof(TPM2B_DIGEST)]; -+ grub_uint8_t keyedHash[sizeof(TPM2B_DIGEST)]; -+}; -+typedef union TPMU_ENCRYPTED_SECRET TPMU_ENCRYPTED_SECRET; -+ -+/* TPM2B_ENCRYPTED_SECRET Structure */ -+struct TPM2B_ENCRYPTED_SECRET -+{ -+ grub_uint16_t size; -+ grub_uint8_t secret[sizeof(TPMU_ENCRYPTED_SECRET)]; -+}; -+typedef struct TPM2B_ENCRYPTED_SECRET TPM2B_ENCRYPTED_SECRET; -+ -+/* TPMU_PUBLIC_ID Union */ -+union TPMU_PUBLIC_ID -+{ -+ TPM2B_DIGEST keyedHash; -+ TPM2B_DIGEST sym; -+ TPM2B_PUBLIC_KEY_RSA rsa; -+ TPMS_ECC_POINT ecc; -+}; -+typedef union TPMU_PUBLIC_ID TPMU_PUBLIC_ID; -+ -+/* TPMT_PUBLIC Structure */ -+struct TPMT_PUBLIC -+{ -+ TPMI_ALG_PUBLIC type; -+ TPMI_ALG_HASH nameAlg; -+ TPMA_OBJECT objectAttributes; -+ TPM2B_DIGEST authPolicy; -+ TPMU_PUBLIC_PARMS parameters; -+ TPMU_PUBLIC_ID unique; -+}; -+typedef struct TPMT_PUBLIC TPMT_PUBLIC; -+ -+/* TPM2B_PUBLIC Structure */ -+struct TPM2B_PUBLIC -+{ -+ grub_uint16_t size; -+ TPMT_PUBLIC publicArea; -+}; -+typedef struct TPM2B_PUBLIC TPM2B_PUBLIC; -+ -+/* TPMT_HA Structure */ -+struct TPMT_HA -+{ -+ TPMI_ALG_HASH hashAlg; -+ TPMU_HA digest; -+}; -+typedef struct TPMT_HA TPMT_HA; -+ -+/* TPM2B_DATA Structure */ -+struct TPM2B_DATA -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[sizeof(TPMT_HA)]; -+}; -+typedef struct TPM2B_DATA TPM2B_DATA; -+ -+/* TPMA_LOCALITY Structure */ -+struct TPMA_LOCALITY -+{ -+ unsigned char TPM_LOC_ZERO:1; -+ unsigned char TPM_LOC_ONE:1; -+ unsigned char TPM_LOC_TWO:1; -+ unsigned char TPM_LOC_THREE:1; -+ unsigned char TPM_LOC_FOUR:1; -+ unsigned char Extended:3; -+}; -+typedef struct TPMA_LOCALITY TPMA_LOCALITY; -+ -+/* TPMU_NAME Union */ -+union TPMU_NAME -+{ -+ TPMT_HA digest; -+ TPM_HANDLE handle; -+}; -+typedef union TPMU_NAME TPMU_NAME; -+ -+/* TPM2B_NAME Structure */ -+struct TPM2B_NAME -+{ -+ grub_uint16_t size; -+ grub_uint8_t name[sizeof(TPMU_NAME)]; -+}; -+typedef struct TPM2B_NAME TPM2B_NAME; -+ -+/* TPMS_CREATION_DATA Structure */ -+struct TPMS_CREATION_DATA -+{ -+ TPML_PCR_SELECTION pcrSelect; -+ TPM2B_DIGEST pcrDigest; -+ TPMA_LOCALITY locality; -+ TPM_ALG_ID parentNameAlg; -+ TPM2B_NAME parentName; -+ TPM2B_NAME parentQualifiedName; -+ TPM2B_DATA outsideInfo; -+}; -+typedef struct TPMS_CREATION_DATA TPMS_CREATION_DATA; -+ -+/* TPM2B_CREATION_DATA Structure */ -+struct TPM2B_CREATION_DATA -+{ -+ grub_uint16_t size; -+ TPMS_CREATION_DATA creationData; -+}; -+typedef struct TPM2B_CREATION_DATA TPM2B_CREATION_DATA; -+ -+/* TPMT_SYM_DEF Structure */ -+struct TPMT_SYM_DEF -+{ -+ TPMI_ALG_SYM algorithm; -+ TPMU_SYM_KEY_BITS keyBits; -+ TPMU_SYM_MODE mode; -+}; -+typedef struct TPMT_SYM_DEF TPMT_SYM_DEF; -+ -+/* TPM2B_MAX_BUFFER Structure */ -+struct TPM2B_MAX_BUFFER -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_DIGEST_BUFFER]; -+}; -+typedef struct TPM2B_MAX_BUFFER TPM2B_MAX_BUFFER; -+ -+/* TPMT_TK_HASHCHECK Structure */ -+struct TPMT_TK_HASHCHECK -+{ -+ TPM_ST tag; -+ TPMI_RH_HIERARCHY hierarchy; -+ TPM2B_DIGEST digest; -+}; -+typedef struct TPMT_TK_HASHCHECK TPMT_TK_HASHCHECK; -+ -+/* TPM2B_SYM_KEY Structure */ -+struct TPM2B_SYM_KEY -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_SYM_KEY_BYTES]; -+}; -+typedef struct TPM2B_SYM_KEY TPM2B_SYM_KEY; -+ -+/* TPM2B_PRIVATE_KEY_RSA Structure */ -+struct TPM2B_PRIVATE_KEY_RSA -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES/2]; -+}; -+typedef struct TPM2B_PRIVATE_KEY_RSA TPM2B_PRIVATE_KEY_RSA; -+ -+/* TPM2B_PRIVATE_VENDOR_SPECIFIC Structure */ -+struct TPM2B_PRIVATE_VENDOR_SPECIFIC -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_PRIVATE_VENDOR_SPECIFIC_BYTES]; -+}; -+typedef struct TPM2B_PRIVATE_VENDOR_SPECIFIC TPM2B_PRIVATE_VENDOR_SPECIFIC; -+ -+/* TPM2B_PRIVATE_VENDOR_SPECIFIC Union */ -+union TPMU_SENSITIVE_COMPOSITE -+{ -+ TPM2B_PRIVATE_KEY_RSA rsa; -+ TPM2B_ECC_PARAMETER ecc; -+ TPM2B_SENSITIVE_DATA bits; -+ TPM2B_SYM_KEY sym; -+ TPM2B_PRIVATE_VENDOR_SPECIFIC any; -+}; -+typedef union TPMU_SENSITIVE_COMPOSITE TPMU_SENSITIVE_COMPOSITE; -+ -+/* TPMT_SENSITIVE Structure */ -+struct TPMT_SENSITIVE -+{ -+ TPMI_ALG_PUBLIC sensitiveType; -+ TPM2B_AUTH authValue; -+ TPM2B_DIGEST seedValue; -+ TPMU_SENSITIVE_COMPOSITE sensitive; -+}; -+typedef struct TPMT_SENSITIVE TPMT_SENSITIVE; -+ -+/* TPM2B_SENSITIVE Structure */ -+struct TPM2B_SENSITIVE -+{ -+ grub_uint16_t size; -+ TPMT_SENSITIVE sensitiveArea; -+}; -+typedef struct TPM2B_SENSITIVE TPM2B_SENSITIVE; -+ -+/* _PRIVATE Structure */ -+struct _PRIVATE -+{ -+ TPM2B_DIGEST integrityOuter; -+ TPM2B_DIGEST integrityInner; -+ TPM2B_SENSITIVE sensitive; -+}; -+typedef struct _PRIVATE _PRIVATE; -+ -+/* TPM2B_PRIVATE Structure */ -+struct TPM2B_PRIVATE -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[sizeof(_PRIVATE)]; -+}; -+typedef struct TPM2B_PRIVATE TPM2B_PRIVATE; -+ -+/* TPML_DIGEST_VALUES Structure */ -+struct TPML_DIGEST_VALUES -+{ -+ grub_uint16_t count; -+ TPMT_HA digests[TPM_NUM_PCR_BANKS]; -+}; -+typedef struct TPML_DIGEST_VALUES TPML_DIGEST_VALUES; -+ -+/* TPM2B_MAX_NV_BUFFER Structure */ -+struct TPM2B_MAX_NV_BUFFER -+{ -+ grub_uint16_t size; -+ grub_uint8_t buffer[TPM_MAX_NV_BUFFER_SIZE]; -+}; -+typedef struct TPM2B_MAX_NV_BUFFER TPM2B_MAX_NV_BUFFER; -+ -+/* TPMS_NV_PUBLIC Structure */ -+struct TPMS_NV_PUBLIC -+{ -+ TPMI_RH_NV_INDEX nvIndex; -+ TPMI_ALG_HASH nameAlg; -+ TPMA_NV attributes; -+ TPM2B_DIGEST authPolicy; -+ grub_uint16_t dataSize; -+}; -+typedef struct TPMS_NV_PUBLIC TPMS_NV_PUBLIC; -+ -+/* TPM2B_NV_PUBLIC Structure */ -+struct TPM2B_NV_PUBLIC -+{ -+ grub_uint16_t size; -+ TPMS_NV_PUBLIC nvPublic; -+}; -+typedef struct TPM2B_NV_PUBLIC TPM2B_NV_PUBLIC; -+ -+/* TPMT_TK_CREATION Structure */ -+struct TPMT_TK_CREATION -+{ -+ TPM_ST tag; -+ TPMI_RH_HIERARCHY hierarchy; -+ TPM2B_DIGEST digest; -+}; -+typedef struct TPMT_TK_CREATION TPMT_TK_CREATION; -+ -+/* TPMS_EMPTY Structure */ -+struct TPMS_EMPTY { -+ grub_uint8_t empty[1]; /* a structure with no member */ -+}; -+typedef struct TPMS_EMPTY TPMS_EMPTY; -+ -+/* TPMS_SIGNATURE_RSA Structure */ -+struct TPMS_SIGNATURE_RSA { -+ TPMI_ALG_HASH hash; -+ TPM2B_PUBLIC_KEY_RSA sig; -+}; -+typedef struct TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSA; -+ -+/* Definition of Types for RSA Signature */ -+typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSASSA; -+typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSAPSS; -+ -+/* TPMS_SIGNATURE_ECC Structure */ -+struct TPMS_SIGNATURE_ECC { -+ TPMI_ALG_HASH hash; -+ TPM2B_ECC_PARAMETER signatureR; -+ TPM2B_ECC_PARAMETER signatureS; -+}; -+typedef struct TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECC; -+ -+/* Definition of Types for ECC TPMS_SIGNATURE_ECC */ -+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA; -+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA; -+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_SM2; -+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECSCHNORR; -+ -+/* TPMU_SIGNATURE Structure */ -+union TPMU_SIGNATURE { -+ TPMS_SIGNATURE_RSASSA rsassa; -+ TPMS_SIGNATURE_RSAPSS rsapss; -+ TPMS_SIGNATURE_ECDSA ecdsa; -+ TPMS_SIGNATURE_ECDAA ecdaa; -+ TPMS_SIGNATURE_SM2 sm2; -+ TPMS_SIGNATURE_ECSCHNORR ecschnorr; -+ TPMT_HA hmac; -+ TPMS_SCHEME_HASH any; -+ TPMS_EMPTY null; -+}; -+typedef union TPMU_SIGNATURE TPMU_SIGNATURE; -+ -+/* TPMT_SIGNATURE Structure */ -+struct TPMT_SIGNATURE { -+ TPMI_ALG_SIG_SCHEME sigAlg; -+ TPMU_SIGNATURE signature; -+}; -+typedef struct TPMT_SIGNATURE TPMT_SIGNATURE; -+ -+static inline TPMI_ALG_HASH -+TPMT_SIGNATURE_get_hash_alg (TPMT_SIGNATURE *sig) -+{ -+ switch (sig->sigAlg) -+ { -+ case TPM_ALG_RSASSA: -+ return sig->signature.rsassa.hash; -+ case TPM_ALG_RSAPSS: -+ return sig->signature.rsapss.hash; -+ case TPM_ALG_ECDSA: -+ return sig->signature.ecdsa.hash; -+ case TPM_ALG_ECDAA: -+ return sig->signature.ecdaa.hash; -+ case TPM_ALG_SM2: -+ return sig->signature.sm2.hash; -+ case TPM_ALG_ECSCHNORR: -+ return sig->signature.ecschnorr.hash; -+ case TPM_ALG_HMAC: -+ return sig->signature.hmac.hashAlg; -+ default: -+ break; -+ } -+ -+ return TPM_ALG_NULL; -+} -+ -+/* TPMT_TK_VERIFIED Structure */ -+struct TPMT_TK_VERIFIED { -+ TPM_ST tag; -+ TPMI_RH_HIERARCHY hierarchy; -+ TPM2B_DIGEST digest; -+}; -+typedef struct TPMT_TK_VERIFIED TPMT_TK_VERIFIED; -+ -+#endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */ -diff --git a/include/grub/tpm2/internal/types.h b/include/grub/tpm2/internal/types.h -new file mode 100644 -index 000000000..7d754394d ---- /dev/null -+++ b/include/grub/tpm2/internal/types.h -@@ -0,0 +1,403 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_INTERNAL_TYPES_HEADER -+#define GRUB_TPM2_INTERNAL_TYPES_HEADER 1 -+ -+#include -+ -+/* TPM2_RC Constants */ -+typedef grub_uint32_t TPM_RC; -+ -+#define TPM_RC_1 ((TPM_RC) 0x100) -+#define TPM_RC_2 ((TPM_RC) 0x200) -+#define TPM_RC_3 ((TPM_RC) 0x300) -+#define TPM_RC_4 ((TPM_RC) 0x400) -+#define TPM_RC_5 ((TPM_RC) 0x500) -+#define TPM_RC_6 ((TPM_RC) 0x600) -+#define TPM_RC_7 ((TPM_RC) 0x700) -+#define TPM_RC_8 ((TPM_RC) 0x800) -+#define TPM_RC_9 ((TPM_RC) 0x900) -+#define TPM_RC_A ((TPM_RC) 0xA00) -+#define TPM_RC_ASYMMETRIC ((TPM_RC) 0x081) -+#define TPM_RC_ATTRIBUTES ((TPM_RC) 0x082) -+#define TPM_RC_AUTH_CONTEXT ((TPM_RC) 0x145) -+#define TPM_RC_AUTH_FAIL ((TPM_RC) 0x08E) -+#define TPM_RC_AUTH_MISSING ((TPM_RC) 0x125) -+#define TPM_RC_AUTHSIZE ((TPM_RC) 0x144) -+#define TPM_RC_AUTH_TYPE ((TPM_RC) 0x124) -+#define TPM_RC_AUTH_UNAVAILABLE ((TPM_RC) 0x12F) -+#define TPM_RC_B ((TPM_RC) 0xB00) -+#define TPM_RC_BAD_AUTH ((TPM_RC) 0x0A2) -+#define TPM_RC_BAD_CONTEXT ((TPM_RC) 0x150) -+#define TPM_RC_BAD_TAG ((TPM_RC) 0x01E) -+#define TPM_RC_BINDING ((TPM_RC) 0x0A5) -+#define TPM_RC_C ((TPM_RC) 0xC00) -+#define TPM_RC_CANCELED ((TPM_RC) 0x909) -+#define TPM_RC_COMMAND_CODE ((TPM_RC) 0x143) -+#define TPM_RC_COMMAND_SIZE ((TPM_RC) 0x142) -+#define TPM_RC_CONTEXT_GAP ((TPM_RC) 0x901) -+#define TPM_RC_CPHASH ((TPM_RC) 0x151) -+#define TPM_RC_CURVE ((TPM_RC) 0x0A6) -+#define TPM_RC_D ((TPM_RC) 0xD00) -+#define TPM_RC_DISABLED ((TPM_RC) 0x120) -+#define TPM_RC_E ((TPM_RC) 0xE00) -+#define TPM_RC_ECC_POINT ((TPM_RC) 0x0A7) -+#define TPM_RC_EXCLUSIVE ((TPM_RC) 0x121) -+#define TPM_RC_EXPIRED ((TPM_RC) 0x0A3) -+#define TPM_RC_F ((TPM_RC) 0xF00) -+#define TPM_RC_FAILURE ((TPM_RC) 0x101) -+#define TPM_RC_H ((TPM_RC) 0x000) -+#define TPM_RC_HANDLE ((TPM_RC) 0x08B) -+#define TPM_RC_HASH ((TPM_RC) 0x083) -+#define TPM_RC_HIERARCHY ((TPM_RC) 0x085) -+#define TPM_RC_HMAC ((TPM_RC) 0x119) -+#define TPM_RC_INITIALIZE ((TPM_RC) 0x100) -+#define TPM_RC_INSUFFICIENT ((TPM_RC) 0x09A) -+#define TPM_RC_INTEGRITY ((TPM_RC) 0x09F) -+#define TPM_RC_KDF ((TPM_RC) 0x08C) -+#define TPM_RC_KEY ((TPM_RC) 0x09C) -+#define TPM_RC_KEY_SIZE ((TPM_RC) 0x087) -+#define TPM_RC_LOCALITY ((TPM_RC) 0x907) -+#define TPM_RC_LOCKOUT ((TPM_RC) 0x921) -+#define TPM_RC_MEMORY ((TPM_RC) 0x904) -+#define TPM_RC_MGF ((TPM_RC) 0x088) -+#define TPM_RC_MODE ((TPM_RC) 0x089) -+#define TPM_RC_NEEDS_TEST ((TPM_RC) 0x153) -+#define TPM_RC_N_MASK ((TPM_RC) 0xF00) -+#define TPM_RC_NONCE ((TPM_RC) 0x08F) -+#define TPM_RC_NO_RESULT ((TPM_RC) 0x154) -+#define TPM_RC_NOT_USED ((TPM_RC) 0x97F) -+#define TPM_RC_NV_AUTHORIZATION ((TPM_RC) 0x149) -+#define TPM_RC_NV_DEFINED ((TPM_RC) 0x14C) -+#define TPM_RC_NV_LOCKED ((TPM_RC) 0x148) -+#define TPM_RC_NV_RANGE ((TPM_RC) 0x146) -+#define TPM_RC_NV_RATE ((TPM_RC) 0x920) -+#define TPM_RC_NV_SIZE ((TPM_RC) 0x147) -+#define TPM_RC_NV_SPACE ((TPM_RC) 0x14B) -+#define TPM_RC_NV_UNAVAILABLE ((TPM_RC) 0x923) -+#define TPM_RC_NV_UNINITIALIZED ((TPM_RC) 0x14A) -+#define TPM_RC_OBJECT_HANDLES ((TPM_RC) 0x906) -+#define TPM_RC_OBJECT_MEMORY ((TPM_RC) 0x902) -+#define TPM_RC_P ((TPM_RC) 0x040) -+#define TPM_RC_PARENT ((TPM_RC) 0x152) -+#define TPM_RC_PCR ((TPM_RC) 0x127) -+#define TPM_RC_PCR_CHANGED ((TPM_RC) 0x128) -+#define TPM_RC_POLICY ((TPM_RC) 0x126) -+#define TPM_RC_POLICY_CC ((TPM_RC) 0x0A4) -+#define TPM_RC_POLICY_FAIL ((TPM_RC) 0x09D) -+#define TPM_RC_PP ((TPM_RC) 0x090) -+#define TPM_RC_PRIVATE ((TPM_RC) 0x10B) -+#define TPM_RC_RANGE ((TPM_RC) 0x08D) -+#define TPM_RC_REBOOT ((TPM_RC) 0x130) -+#define TPM_RC_REFERENCE_H0 ((TPM_RC) 0x910) -+#define TPM_RC_REFERENCE_H1 ((TPM_RC) 0x911) -+#define TPM_RC_REFERENCE_H2 ((TPM_RC) 0x912) -+#define TPM_RC_REFERENCE_H3 ((TPM_RC) 0x913) -+#define TPM_RC_REFERENCE_H4 ((TPM_RC) 0x914) -+#define TPM_RC_REFERENCE_H5 ((TPM_RC) 0x915) -+#define TPM_RC_REFERENCE_H6 ((TPM_RC) 0x916) -+#define TPM_RC_REFERENCE_S0 ((TPM_RC) 0x918) -+#define TPM_RC_REFERENCE_S1 ((TPM_RC) 0x919) -+#define TPM_RC_REFERENCE_S2 ((TPM_RC) 0x91A) -+#define TPM_RC_REFERENCE_S3 ((TPM_RC) 0x91B) -+#define TPM_RC_REFERENCE_S4 ((TPM_RC) 0x91C) -+#define TPM_RC_REFERENCE_S5 ((TPM_RC) 0x91D) -+#define TPM_RC_REFERENCE_S6 ((TPM_RC) 0x91E) -+#define TPM_RC_RESERVED_BITS ((TPM_RC) 0x0A1) -+#define TPM_RC_RETRY ((TPM_RC) 0x922) -+#define TPM_RC_S ((TPM_RC) 0x800) -+#define TPM_RC_SCHEME ((TPM_RC) 0x092) -+#define TPM_RC_SELECTOR ((TPM_RC) 0x098) -+#define TPM_RC_SENSITIVE ((TPM_RC) 0x155) -+#define TPM_RC_SEQUENCE ((TPM_RC) 0x103) -+#define TPM_RC_SESSION_HANDLES ((TPM_RC) 0x905) -+#define TPM_RC_SESSION_MEMORY ((TPM_RC) 0x903) -+#define TPM_RC_SIGNATURE ((TPM_RC) 0x09B) -+#define TPM_RC_SIZE ((TPM_RC) 0x095) -+#define TPM_RC_SUCCESS ((TPM_RC) 0x000) -+#define TPM_RC_SYMMETRIC ((TPM_RC) 0x096) -+#define TPM_RC_TAG ((TPM_RC) 0x097) -+#define TPM_RC_TESTING ((TPM_RC) 0x90A) -+#define TPM_RC_TICKET ((TPM_RC) 0x0A0) -+#define TPM_RC_TOO_MANY_CONTEXTS ((TPM_RC) 0x12E) -+#define TPM_RC_TYPE ((TPM_RC) 0x08A) -+#define TPM_RC_UNBALANCED ((TPM_RC) 0x131) -+#define TPM_RC_UPGRADE ((TPM_RC) 0x12D) -+#define TPM_RC_VALUE ((TPM_RC) 0x084) -+#define TPM_RC_YIELDED ((TPM_RC) 0x908) -+ -+/* TPMA_NV Constants */ -+typedef grub_uint32_t TPMA_NV; -+ -+#define TPMA_NV_PPWRITE ((TPMA_NV) 0x00000001) -+#define TPMA_NV_OWNERWRITE ((TPMA_NV) 0x00000002) -+#define TPMA_NV_AUTHWRITE ((TPMA_NV) 0x00000004) -+#define TPMA_NV_POLICYWRITE ((TPMA_NV) 0x00000008) -+#define TPMA_NV_TPM2_NT_MASK ((TPMA_NV) 0x000000F0) -+#define TPMA_NV_TPM2_NT_SHIFT (4) -+#define TPMA_NV_RESERVED1_MASK ((TPMA_NV) 0x00000300) -+#define TPMA_NV_POLICY_DELETE ((TPMA_NV) 0x00000400) -+#define TPMA_NV_WRITELOCKED ((TPMA_NV) 0x00000800) -+#define TPMA_NV_WRITEALL ((TPMA_NV) 0x00001000) -+#define TPMA_NV_WRITEDEFINE ((TPMA_NV) 0x00002000) -+#define TPMA_NV_WRITE_STCLEAR ((TPMA_NV) 0x00004000) -+#define TPMA_NV_GLOBALLOCK ((TPMA_NV) 0x00008000) -+#define TPMA_NV_PPREAD ((TPMA_NV) 0x00010000) -+#define TPMA_NV_OWNERREAD ((TPMA_NV) 0x00020000) -+#define TPMA_NV_AUTHREAD ((TPMA_NV) 0x00040000) -+#define TPMA_NV_POLICYREAD ((TPMA_NV) 0x00080000) -+#define TPMA_NV_RESERVED2_MASK ((TPMA_NV) 0x01F00000) -+#define TPMA_NV_NO_DA ((TPMA_NV) 0x02000000) -+#define TPMA_NV_ORDERLY ((TPMA_NV) 0x04000000) -+#define TPMA_NV_CLEAR_STCLEAR ((TPMA_NV) 0x08000000) -+#define TPMA_NV_READLOCKED ((TPMA_NV) 0x10000000) -+#define TPMA_NV_WRITTEN ((TPMA_NV) 0x20000000) -+#define TPMA_NV_PLATFORMCREATE ((TPMA_NV) 0x40000000) -+#define TPMA_NV_READ_STCLEAR ((TPMA_NV) 0x80000000) -+ -+/* TPM_ALG_ID Constants */ -+typedef grub_uint16_t TPM_ALG_ID; -+ -+#define TPM_ALG_ERROR ((TPM_ALG_ID) 0x0000) -+#define TPM_ALG_AES ((TPM_ALG_ID) 0x0006) -+#define TPM_ALG_CAMELLIA ((TPM_ALG_ID) 0x0026) -+#define TPM_ALG_CBC ((TPM_ALG_ID) 0x0042) -+#define TPM_ALG_CFB ((TPM_ALG_ID) 0x0043) -+#define TPM_ALG_ECB ((TPM_ALG_ID) 0x0044) -+#define TPM_ALG_ECC ((TPM_ALG_ID) 0x0023) -+#define TPM_ALG_ECDAA ((TPM_ALG_ID) 0x001A) -+#define TPM_ALG_ECDSA ((TPM_ALG_ID) 0x0018) -+#define TPM_ALG_ECSCHNORR ((TPM_ALG_ID) 0x001C) -+#define TPM_ALG_HMAC ((TPM_ALG_ID) 0x0005) -+#define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID) 0x0022) -+#define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID) 0x0020) -+#define TPM_ALG_KDF2 ((TPM_ALG_ID) 0x0021) -+#define TPM_ALG_KEYEDHASH ((TPM_ALG_ID) 0x0008) -+#define TPM_ALG_MGF1 ((TPM_ALG_ID) 0x0007) -+#define TPM_ALG_NULL ((TPM_ALG_ID) 0x0010) -+#define TPM_ALG_RSA ((TPM_ALG_ID) 0x0001) -+#define TPM_ALG_RSASSA ((TPM_ALG_ID) 0x0014) -+#define TPM_ALG_RSAPSS ((TPM_ALG_ID) 0x0016) -+#define TPM_ALG_SHA1 ((TPM_ALG_ID) 0x0004) -+#define TPM_ALG_SHA256 ((TPM_ALG_ID) 0x000B) -+#define TPM_ALG_SHA384 ((TPM_ALG_ID) 0x000C) -+#define TPM_ALG_SHA512 ((TPM_ALG_ID) 0x000D) -+#define TPM_ALG_SM2 ((TPM_ALG_ID) 0x001B) -+#define TPM_ALG_SM3_256 ((TPM_ALG_ID) 0x0012) -+#define TPM_ALG_SM4 ((TPM_ALG_ID) 0x0013) -+#define TPM_ALG_SYMCIPHER ((TPM_ALG_ID) 0x0025) -+#define TPM_ALG_XOR ((TPM_ALG_ID) 0x000A) -+ -+/* TPM_CAP Constants */ -+typedef grub_uint32_t TPM_CAP; -+ -+#define TPM_CAP_FIRST ((TPM_CAP) 0x00000000) -+#define TPM_CAP_ALGS ((TPM_CAP) 0x00000000) -+#define TPM_CAP_HANDLES ((TPM_CAP) 0x00000001) -+#define TPM_CAP_COMMANDS ((TPM_CAP) 0x00000002) -+#define TPM_CAP_PP_COMMANDS ((TPM_CAP) 0x00000003) -+#define TPM_CAP_AUDIT_COMMANDS ((TPM_CAP) 0x00000004) -+#define TPM_CAP_PCRS ((TPM_CAP) 0x00000005) -+#define TPM_CAP_TPM_PROPERTIES ((TPM_CAP) 0x00000006) -+#define TPM_CAP_PCR_PROPERTIES ((TPM_CAP) 0x00000007) -+#define TPM_CAP_ECC_CURVES ((TPM_CAP) 0x00000008) -+#define TPM_CAP_LAST ((TPM_CAP) 0x00000008) -+#define TPM_CAP_VENDOR_PROPERTY ((TPM_CAP) 0x00000100) -+ -+/* TPM_PT Constants */ -+typedef grub_uint32_t TPM_PT; -+ -+#define TPM_PT_NONE ((TPM_PT) 0x00000000) -+#define PT_GROUP ((TPM_PT) 0x00000100) -+#define PT_FIXED ((TPM_PT) (PT_GROUP * 1)) -+#define TPM_PT_FAMILY_INDICATOR ((TPM_PT) (PT_FIXED + 0)) -+#define TPM_PT_LEVEL ((TPM_PT) (PT_FIXED + 1)) -+#define TPM_PT_REVISION ((TPM_PT) (PT_FIXED + 2)) -+#define TPM_PT_DAY_OF_YEAR ((TPM_PT) (PT_FIXED + 3)) -+#define TPM_PT_YEAR ((TPM_PT) (PT_FIXED + 4)) -+#define TPM_PT_PCR_COUNT ((TPM_PT) (PT_FIXED + 18)) -+ -+/* TPM_SE Constants */ -+typedef grub_uint8_t TPM_SE; -+ -+#define TPM_SE_HMAC ((TPM_SE) 0x00) -+#define TPM_SE_POLICY ((TPM_SE) 0x01) -+#define TPM_SE_TRIAL ((TPM_SE) 0x03) -+ -+/* TPMI_YES_NO Constants */ -+typedef grub_uint8_t TPMI_YES_NO; -+ -+#define TPM_NO ((TPMI_YES_NO)0) -+#define TPM_YES ((TPMI_YES_NO)1) -+ -+/* TPM_ST Constants */ -+typedef grub_uint16_t TPM_ST; -+typedef TPM_ST TPMI_ST_COMMAND_TAG; -+ -+#define TPM_ST_NO_SESSIONS ((TPMI_ST_COMMAND_TAG) 0x8001) -+#define TPM_ST_SESSIONS ((TPMI_ST_COMMAND_TAG) 0x8002) -+ -+/* TPM_HANDLE Types */ -+typedef grub_uint32_t TPM_HANDLE; -+ -+typedef TPM_HANDLE TPMI_RH_HIERARCHY; -+typedef TPM_HANDLE TPMI_RH_LOCKOUT; -+typedef TPM_HANDLE TPMI_SH_AUTH_SESSION; -+typedef TPM_HANDLE TPMI_DH_CONTEXT; -+typedef TPM_HANDLE TPMI_DH_OBJECT; -+typedef TPM_HANDLE TPMI_DH_ENTITY; -+typedef TPM_HANDLE TPMI_SH_POLICY; -+typedef TPM_HANDLE TPMI_DH_PCR; -+typedef TPM_HANDLE TPMI_RH_NV_AUTH; -+typedef TPM_HANDLE TPMI_RH_NV_INDEX; -+ -+/* TPM_HT Constants */ -+typedef grub_uint8_t TPM_HT; -+#define TPM_HT_PERMANENT ((TPM_HT) 0x40) -+#define TPM_HT_PERSISTENT ((TPM_HT) 0x81) -+ -+/* TPM_RH Constants */ -+typedef TPM_HANDLE TPM_RH; -+ -+#define TPM_RH_FIRST ((TPM_RH) 0x40000000) -+#define TPM_RH_SRK ((TPM_RH) 0x40000000) -+#define TPM_RH_OWNER ((TPM_RH) 0x40000001) -+#define TPM_RH_REVOKE ((TPM_RH) 0x40000002) -+#define TPM_RH_TRANSPORT ((TPM_RH) 0x40000003) -+#define TPM_RH_OPERATOR ((TPM_RH) 0x40000004) -+#define TPM_RH_ADMIN ((TPM_RH) 0x40000005) -+#define TPM_RH_EK ((TPM_RH) 0x40000006) -+#define TPM_RH_NULL ((TPM_RH) 0x40000007) -+#define TPM_RH_UNASSIGNED ((TPM_RH) 0x40000008) -+#define TPM_RS_PW ((TPM_RH) 0x40000009) -+#define TPM_RH_LOCKOUT ((TPM_RH) 0x4000000A) -+#define TPM_RH_ENDORSEMENT ((TPM_RH) 0x4000000B) -+#define TPM_RH_PLATFORM ((TPM_RH) 0x4000000C) -+#define TPM_RH_PLATFORM_NV ((TPM_RH) 0x4000000D) -+#define TPM_RH_AUTH_00 ((TPM_RH) 0x40000010) -+#define TPM_RH_AUTH_FF ((TPM_RH) 0x4000010F) -+#define TPM_RH_LAST ((TPM_RH) 0x4000010F) -+ -+/* TPM_HC Constants */ -+typedef TPM_HANDLE TPM_HC; -+#define TPM_HR_HANDLE_MASK ((TPM_HC) 0x00FFFFFF) -+#define TPM_HR_RANGE_MASK ((TPM_HC) 0xFF000000) -+#define TPM_HR_SHIFT ((TPM_HC) 24) -+#define TPM_HR_PERSISTENT ((TPM_HC) (TPM_HT_PERSISTENT << TPM_HR_SHIFT)) -+#define TPM_HR_PERMANENT ((TPM_HC) (TPM_HT_PERMANENT << TPM_HR_SHIFT)) -+#define TPM_PERSISTENT_FIRST ((TPM_HC) (TPM_HR_PERSISTENT + 0)) -+#define TPM_PERSISTENT_LAST ((TPM_HC) (TPM_PERSISTENT_FIRST + 0x00FFFFFF)) -+#define TPM_PERMANENT_FIRST ((TPM_HC) TPM_RH_FIRST) -+#define TPM_PERMANENT_LAST ((TPM_HC) TPM_RH_LAST) -+ -+/* TPM Handle Type Checks */ -+#define TPM_HT_IS_PERMANENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERMANENT) -+#define TPM_HT_IS_PERSISTENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERSISTENT) -+ -+/* TPM_ECC_CURVE Constants */ -+typedef grub_uint16_t TPM_ECC_CURVE; -+ -+#define TPM_ECC_NONE ((TPM_ECC_CURVE) 0x0000) -+#define TPM_ECC_NIST_P192 ((TPM_ECC_CURVE) 0x0001) -+#define TPM_ECC_NIST_P224 ((TPM_ECC_CURVE) 0x0002) -+#define TPM_ECC_NIST_P256 ((TPM_ECC_CURVE) 0x0003) -+#define TPM_ECC_NIST_P384 ((TPM_ECC_CURVE) 0x0004) -+#define TPM_ECC_NIST_P521 ((TPM_ECC_CURVE) 0x0005) -+#define TPM_ECC_BN_P256 ((TPM_ECC_CURVE) 0x0010) -+#define TPM_ECC_BN_P638 ((TPM_ECC_CURVE) 0x0011) -+#define TPM_ECC_SM2_P256 ((TPM_ECC_CURVE) 0x0020) -+ -+/* TPM_CC Constants */ -+typedef grub_uint32_t TPM_CC; -+ -+#define TPM_CC_EvictControl ((TPM_CC) 0x00000120) -+#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131) -+#define TPM_CC_Create ((TPM_CC) 0x00000153) -+#define TPM_CC_FlushContext ((TPM_CC) 0x00000165) -+#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173) -+#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176) -+#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f) -+#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e) -+#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169) -+#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a) -+#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e) -+#define TPM_CC_Load ((TPM_CC) 0x00000157) -+#define TPM_CC_LoadExternal ((TPM_CC) 0x00000167) -+#define TPM_CC_Unseal ((TPM_CC) 0x0000015e) -+#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) -+#define TPM_CC_Hash ((TPM_CC) 0x0000017d) -+#define TPM_CC_VerifySignature ((TPM_CC) 0x00000177) -+#define TPM_CC_PolicyAuthorize ((TPM_CC) 0x0000016a) -+#define TPM_CC_TestParms ((TPM_CC) 0x0000018a) -+ -+/* Hash algorithm sizes */ -+#define TPM_SHA1_DIGEST_SIZE 20 -+#define TPM_SHA256_DIGEST_SIZE 32 -+#define TPM_SM3_256_DIGEST_SIZE 32 -+#define TPM_SHA384_DIGEST_SIZE 48 -+#define TPM_SHA512_DIGEST_SIZE 64 -+ -+/* Encryption algorithm sizes */ -+#define TPM_MAX_SYM_BLOCK_SIZE 16 -+#define TPM_MAX_SYM_DATA 256 -+#define TPM_MAX_ECC_KEY_BYTES 128 -+#define TPM_MAX_SYM_KEY_BYTES 32 -+#define TPM_MAX_RSA_KEY_BYTES 512 -+ -+/* Buffer Size Constants */ -+#define TPM_MAX_PCRS 32 -+#define TPM_NUM_PCR_BANKS 16 -+#define TPM_PCR_SELECT_MAX ((TPM_MAX_PCRS + 7) / 8) -+#define TPM_MAX_DIGEST_BUFFER 1024 -+#define TPM_MAX_TPM_PROPERTIES 8 -+#define TPM_MAX_NV_BUFFER_SIZE 2048 -+#define TPM_PRIVATE_VENDOR_SPECIFIC_BYTES 1280 -+ -+/* TPM_GENERATED Constants */ -+typedef grub_uint32_t TPM_GENERATED; -+ -+#define TPM_GENERATED_VALUE ((TPM_GENERATED) 0xff544347) -+ -+/* TPM_ALG_ID Types */ -+typedef TPM_ALG_ID TPMI_ALG_PUBLIC; -+typedef TPM_ALG_ID TPMI_ALG_HASH; -+typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME; -+typedef TPM_ALG_ID TPMI_ALG_KDF; -+typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT; -+typedef TPM_ALG_ID TPMI_ALG_SYM_MODE; -+typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT; -+typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; -+typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; -+typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; -+typedef TPM_ALG_ID TPMI_ALG_SYM; -+typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME; -+ -+/* TPM_KEY_BITS Type */ -+typedef grub_uint16_t TPM_KEY_BITS; -+ -+/* TPM_ECC_CURVE Types */ -+typedef TPM_ECC_CURVE TPMI_ECC_CURVE; -+ -+/* TPMI_RH_PROVISION Type */ -+typedef TPM_HANDLE TPMI_RH_PROVISION; -+ -+/* TPMI_RH_PROVISION Type */ -+typedef TPM_HANDLE TPMI_DH_PERSISTENT; -+ -+#endif /* ! GRUB_TPM2_INTERNAL_TYPES_HEADER */ -diff --git a/include/grub/tpm2/mu.h b/include/grub/tpm2/mu.h -new file mode 100644 -index 000000000..0970b5c70 ---- /dev/null -+++ b/include/grub/tpm2/mu.h -@@ -0,0 +1,396 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_MU_HEADER -+#define GRUB_TPM2_MU_HEADER 1 -+ -+#include -+#include -+ -+void -+grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_AUTH_COMMAND* authCommand); -+ -+void -+grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer, -+ const grub_uint16_t size, -+ const grub_uint8_t* b); -+ -+void -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_SYM_OBJECT algorithm, -+ const TPMU_SYM_KEY_BITS *p); -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_SYM_OBJECT algorithm, -+ const TPMU_SYM_MODE *p); -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_SYM_DEF *p); -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, -+ const TPML_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMA_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SCHEME_XOR *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SCHEME_HMAC *p); -+ -+void -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ const TPMU_SCHEME_KEYEDHASH *p); -+ -+void -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_KEYEDHASH_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_KEYEDHASH_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_SYM_DEF_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_RSA_DECRYPT scheme, -+ const TPMU_ASYM_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_RSA_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_RSA_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SYMCIPHER_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_ECC_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_KDF scheme, -+ const TPMU_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_ECC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const grub_uint32_t type, -+ const TPMU_PUBLIC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_ECC_POINT *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_PUBLIC type, -+ const TPMU_PUBLIC_ID *p); -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_PUBLIC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPM2B_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SENSITIVE_CREATE *p); -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPM2B_SENSITIVE_CREATE *sensitiveCreate); -+ -+void -+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_PUBLIC type, -+ const TPMU_SENSITIVE_COMPOSITE *p); -+void -+grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_SENSITIVE *p); -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPM2B_SENSITIVE *p); -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SIGNATURE_RSA *p); -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMS_SIGNATURE_ECC *p); -+ -+void -+grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_HASH hashAlg, -+ const TPMU_HA *p); -+ -+void -+grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_HA *p); -+ -+void -+grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMI_ALG_SIG_SCHEME sigAlg, -+ const TPMU_SIGNATURE *p); -+ -+void -+grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_SIGNATURE *p); -+ -+void -+grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, -+ const TPMT_TK_VERIFIED *p); -+ -+void -+grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_AUTH_RESPONSE* p); -+ -+void -+grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_DIGEST* digest); -+ -+void -+grub_tpm2_mu_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_NONCE* nonce); -+ -+void -+grub_tpm2_mu_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_DATA* data); -+ -+void -+grub_tpm2_mu_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_CREATION_DATA *data); -+ -+void -+grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_CREATION_DATA *data); -+ -+void -+grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_PRIVATE* private); -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_SENSITIVE_DATA *data); -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_PUBLIC_KEY_RSA *rsa); -+ -+void -+grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_ECC_PARAMETER *param); -+ -+void -+grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMA_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SCHEME_HMAC *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SCHEME_XOR *p); -+ -+void -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ TPMU_SCHEME_KEYEDHASH *p); -+ -+void -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_KEYEDHASH_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_KEYEDHASH_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_KEY_BITS *p); -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_MODE *p); -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_SYM_DEF_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SYMCIPHER_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_RSA_DECRYPT scheme, -+ TPMU_ASYM_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_RSA_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_RSA_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_ECC_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_KDF scheme, -+ TPMU_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_ECC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, -+ grub_uint32_t type, -+ TPMU_PUBLIC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_ECC_POINT *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_PUBLIC type, -+ TPMU_PUBLIC_ID *p); -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_NV_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_NV_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B_NAME *n); -+ -+void -+grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_TAGGED_PROPERTY* property); -+ -+void -+grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_TK_CREATION *p); -+ -+void -+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_TK_HASHCHECK *p); -+ -+void -+grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_TK_VERIFIED *p); -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPML_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPML_DIGEST* digest); -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SIGNATURE_RSA *p); -+ -+void -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_SIGNATURE_ECC *p); -+ -+void -+grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_HASH hashAlg, -+ TPMU_HA *p); -+ -+void -+grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_HA *p); -+ -+void -+grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_SIG_SCHEME sigAlg, -+ TPMU_SIGNATURE *p); -+ -+void -+grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMT_SIGNATURE *p); -+ -+#endif /* ! GRUB_TPM2_MU_HEADER */ -diff --git a/include/grub/tpm2/tcg2.h b/include/grub/tpm2/tcg2.h -new file mode 100644 -index 000000000..553b3fd93 ---- /dev/null -+++ b/include/grub/tpm2/tcg2.h -@@ -0,0 +1,34 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_TCG2_HEADER -+#define GRUB_TPM2_TCG2_HEADER 1 -+ -+#include -+#include -+ -+grub_err_t -+grub_tcg2_get_max_output_size (grub_size_t *size); -+ -+grub_err_t -+grub_tcg2_submit_command (grub_size_t input_size, -+ grub_uint8_t *input, -+ grub_size_t output_size, -+ grub_uint8_t *output); -+ -+#endif /* ! GRUB_TPM2_TCG2_HEADER */ -diff --git a/include/grub/tpm2/tpm2.h b/include/grub/tpm2/tpm2.h -new file mode 100644 -index 000000000..cfdc9edcd ---- /dev/null -+++ b/include/grub/tpm2/tpm2.h -@@ -0,0 +1,34 @@ -+/* -+ * 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 . -+ */ -+ -+#ifndef GRUB_TPM2_TPM2_HEADER -+#define GRUB_TPM2_TPM2_HEADER 1 -+ -+#include -+#include -+#include -+ -+/* Well-Known Windows SRK handle */ -+#define TPM2_SRK_HANDLE 0x81000001 -+ -+typedef struct TPM2_SEALED_KEY { -+ TPM2B_PUBLIC public; -+ TPM2B_PRIVATE private; -+} TPM2_SEALED_KEY; -+ -+#endif /* ! GRUB_TPM2_TPM2_HEADER */ --- -2.35.3 - diff --git a/0003-Add-grub2-switch-to-blscfg.patch b/0003-Add-grub2-switch-to-blscfg.patch deleted file mode 100644 index f96ebf4..0000000 --- a/0003-Add-grub2-switch-to-blscfg.patch +++ /dev/null @@ -1,385 +0,0 @@ -From 90153f1c9631498723450d84e014e25865fecc1b Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 15 Mar 2018 14:12:40 -0400 -Subject: [PATCH 3/9] Add grub2-switch-to-blscfg - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub] -Signed-off-by: Jan Hlavac -[rharwood: skip on ostree installations, migrate man to h2m] -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 7 + - docs/man/grub-switch-to-blscfg.h2m | 2 + - util/grub-switch-to-blscfg.in | 317 +++++++++++++++++++++++++++++ - util/grub.d/10_linux.in | 2 +- - 4 files changed, 327 insertions(+), 1 deletion(-) - create mode 100644 docs/man/grub-switch-to-blscfg.h2m - create mode 100644 util/grub-switch-to-blscfg.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 6bb30c165..ffedea24a 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -1460,6 +1460,13 @@ program = { - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; - -+script = { -+ name = grub-switch-to-blscfg; -+ common = util/grub-switch-to-blscfg.in; -+ mansection = 8; -+ installdir = sbin; -+}; -+ - program = { - name = grub-glue-efi; - mansection = 1; -diff --git a/docs/man/grub-switch-to-blscfg.h2m b/docs/man/grub-switch-to-blscfg.h2m -new file mode 100644 -index 000000000..fa341426a ---- /dev/null -+++ b/docs/man/grub-switch-to-blscfg.h2m -@@ -0,0 +1,2 @@ -+[NAME] -+grub-switch-to-blscfg \- switch to using BLS config files -diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in -new file mode 100644 -index 000000000..a851424be ---- /dev/null -+++ b/util/grub-switch-to-blscfg.in -@@ -0,0 +1,317 @@ -+#! /bin/sh -+# -+# Set a default boot entry for GRUB. -+# Copyright (C) 2004,2009 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 . -+ -+#set -eu -+ -+# Initialize some variables. -+prefix=@prefix@ -+exec_prefix=@exec_prefix@ -+sbindir=@sbindir@ -+bindir=@bindir@ -+sysconfdir="@sysconfdir@" -+PACKAGE_NAME=@PACKAGE_NAME@ -+PACKAGE_VERSION=@PACKAGE_VERSION@ -+datarootdir="@datarootdir@" -+datadir="@datadir@" -+if [ ! -v pkgdatadir ]; then -+ pkgdatadir="${datadir}/@PACKAGE@" -+fi -+ -+self=`basename $0` -+ -+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" -+grub_editenv=${bindir}/@grub_editenv@ -+etcdefaultgrub=/etc/default/grub -+ -+eval "$("${grub_get_kernel_settings}")" || true -+ -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') -+if [ -d /sys/firmware/efi/efivars/ ]; then -+ startlink=/etc/grub2-efi.cfg -+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` -+else -+ startlink=/etc/grub2.cfg -+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+fi -+ -+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'` -+ -+backupsuffix=.bak -+ -+arch="$(uname -m)" -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR="@localedir@" -+ -+. "${pkgdatadir}/grub-mkconfig_lib" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ gettext_printf "Usage: %s\n" "$self" -+ gettext "Switch to BLS config files.\n"; echo -+ echo -+ print_option_help "-h, --help" "$(gettext "print this message and exit")" -+ print_option_help "-V, --version" "$(gettext "print the version information and exit")" -+ echo -+ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix" -+ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir" -+ print_option_help "--config-file=$(gettext "FILE")" "$startlink" -+ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub" -+ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir" -+ # echo -+ # gettext "Report bugs to ."; echo -+} -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -V | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -+ --backup-suffix) -+ backupsuffix=`argument $option "$@"` -+ shift -+ ;; -+ --backup-suffix=*) -+ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'` -+ ;; -+ -+ --bls-directory) -+ blsdir=`argument $option "$@"` -+ shift -+ ;; -+ --bls-directory=*) -+ blsdir=`echo "$option" | sed 's/--bls-directory=//'` -+ ;; -+ -+ --config-file) -+ startlink=`argument $option "$@"` -+ shift -+ ;; -+ --config-file=*) -+ startlink=`echo "$option" | sed 's/--config-file=//'` -+ ;; -+ -+ --grub-defaults) -+ etcdefaultgrub=`argument $option "$@"` -+ shift -+ ;; -+ --grub-defaults=*) -+ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'` -+ ;; -+ -+ --grub-directory) -+ grubdir=`argument $option "$@"` -+ shift -+ ;; -+ --grub-directory=*) -+ grubdir=`echo "$option" | sed 's/--grub-directory=//'` -+ ;; -+ -+ *) -+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 -+ usage -+ exit 1 -+ ;; -+ esac -+done -+ -+find_grub_cfg() { -+ local candidate="" -+ while [ -e "${candidate}" -o $# -gt 0 ] -+ do -+ if [ ! -e "${candidate}" ] ; then -+ candidate="$1" -+ shift -+ fi -+ -+ if [ -L "${candidate}" ]; then -+ candidate="$(realpath "${candidate}")" -+ fi -+ -+ if [ -f "${candidate}" ]; then -+ export GRUB_CONFIG_FILE="${candidate}" -+ return 0 -+ fi -+ done -+ return 1 -+} -+ -+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then -+ gettext_printf "Couldn't find config file\n" 1>&2 -+ exit 1 -+fi -+ -+if [ ! -d "${blsdir}" ]; then -+ install -m 700 -d "${blsdir}" -+fi -+ -+if [ -f /etc/machine-id ]; then -+ MACHINE_ID=$(cat /etc/machine-id) -+else -+ MACHINE_ID=$(dmesg | sha256sum) -+fi -+ -+mkbls() { -+ local kernelver=$1 && shift -+ local datetime=$1 && shift -+ local kernelopts=$1 && shift -+ -+ local debugname="" -+ local debugid="" -+ local flavor="" -+ -+ if [ "$kernelver" == *\+* ] ; then -+ local flavor=-"${kernelver##*+}" -+ if [ "${flavor}" == "-debug" ]; then -+ local debugname=" with debugging" -+ local debugid="-debug" -+ fi -+ fi -+ ( -+ source /etc/os-release -+ -+ cat <"${bls_target}" -+ -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")" -+ cp -aT "${bls_target}" "${bls_debug}" -+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')" -+ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')" -+ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}" -+ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}" -+ fi -+ done -+ -+ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then -+ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf" -+ fi -+} -+ -+# The grub2 EFI binary is not copied to the ESP as a part of an ostree -+# transaction. Make sure a grub2 version with BLS support is installed -+# but only do this if the blsdir is not set, to make sure that the BLS -+# parsing module will search for the BLS snippets in the default path. -+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \ -+ ! ${grub_editenv} - list | grep -q blsdir && \ -+ mountpoint -q /boot; then -+ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)" -+ install -m 700 ${grub_binary} ${grubdir} || exit 1 -+ # Create a hidden file to indicate that grub2 now has BLS support. -+ touch /boot/grub2/.grub2-blscfg-supported -+fi -+ -+GENERATE=0 -+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ -+ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then -+ if ! sed -i"${backupsuffix}" \ -+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \ -+ "${etcdefaultgrub}" ; then -+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" -+ exit 1 -+ fi -+ GENERATE=1 -+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then -+ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then -+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" -+ exit 1 -+ fi -+ GENERATE=1 -+fi -+ -+if [ "${GENERATE}" -eq 1 ] ; then -+ copy_bls -+ -+ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then -+ mod_dir="i386-pc" -+ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then -+ mod_dir="powerpc-ieee1275" -+ fi -+ -+ if [ -n "${mod_dir}" ]; then -+ for mod in blscfg increment; do -+ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1 -+ done -+ fi -+ -+ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}" -+ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then -+ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}" -+ sed -i"${backupsuffix}" \ -+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \ -+ "${etcdefaultgrub}" -+ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}" -+ exit 1 -+ fi -+fi -+ -+# Bye. -+exit 0 -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 49eccbeaf..45eefb332 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -147,7 +147,7 @@ blsdir="/boot/loader/entries" - - get_sorted_bls() - { -- if ! [ -d "${blsdir}" ]; then -+ if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ] || [ -d /ostree/repo ]; then - return - fi - --- -2.44.0 - diff --git a/0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch b/0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch deleted file mode 100644 index 0f56012..0000000 --- a/0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 6c8d390809956d355fed8bc830f64e86838e3e82 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Sat, 18 Nov 2023 21:42:00 +0800 -Subject: [PATCH 3/4] Restrict 'ls' and auto file completion on cryptodisk - print - -The 'ls' command allows file listing, while file completion assists in -providing matched file names by partially inputting via the TAB key. -Both functionalities should be restricted when the disk is automatically -unlocked for the same reasons as highlighted in the previous patch -addressing the limitation on file access to the cryptodisk. - -Given that no file is explicitly opened for listing, employing file -filters becomes impractical. Consequently, this patch focuses on -modifying relevant routines separately to incorporate necessary checks. -The objective is to introduce measures that prevent 'ls' and auto file -completion from accessing encrypted data when the disk is automatically -unlocked. - -By implementing these modifications, any attempt to utilize 'ls' or file -completion on the cryptodisk will result in an "Access Denied: -prohibited to browse encrypted data" error message, thus effectively -alerting the user about the restricted access. - -While protecting content within disk files from viewing is essential, -it's equally crucial to restrict access to in-memory content. This -includes prohibiting access to the decrypted in-memory copies of disk -files. - -This enhancement aims to fortify security protocols by extending -restrictions to additional functionalities beyond direct file access. - -Signed-Off-by Michael Chang ---- - grub-core/commands/ls.c | 8 ++++++++ - grub-core/commands/minicmd.c | 6 ++++++ - grub-core/kern/corecmd.c | 8 ++++++++ - grub-core/normal/completion.c | 8 ++++++++ - 4 files changed, 30 insertions(+) - -diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c -index 8e98c73cc..aeb336a73 100644 ---- a/grub-core/commands/ls.c -+++ b/grub-core/commands/ls.c -@@ -183,6 +183,14 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) - if (! dev) - goto fail; - -+ if (dev->disk && -+ grub_disk_is_crypto (dev->disk) && -+ grub_file_filters[GRUB_FILE_FILTER_NOCAT]) -+ { -+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content")); -+ goto fail; -+ } -+ - fs = grub_fs_probe (dev); - path = grub_strchr (dirname, ')'); - if (! path) -diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c -index fa498931e..8f2ac0539 100644 ---- a/grub-core/commands/minicmd.c -+++ b/grub-core/commands/minicmd.c -@@ -101,6 +101,12 @@ grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)), - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified"); - -+ /* NOCAT filter is applied to prevent cat alike command from revealing file -+ * content, the dump command should also be prohibited to revealing memory -+ * content as well */ -+ if (grub_file_filters[GRUB_FILE_FILTER_NOCAT]) -+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by security policy")); -+ - #if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG - #define grub_strtoaddr grub_strtoul - #else -diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c -index 62d434ba9..b639bc3ae 100644 ---- a/grub-core/kern/corecmd.c -+++ b/grub-core/kern/corecmd.c -@@ -135,6 +135,14 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), - if (! dev) - goto fail; - -+ if (dev->disk && -+ grub_disk_is_crypto (dev->disk) && -+ grub_file_filters[GRUB_FILE_FILTER_NOCAT]) -+ { -+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content")); -+ goto fail; -+ } -+ - fs = grub_fs_probe (dev); - path = grub_strchr (argv[0], ')'); - if (! path) -diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c -index 18cadfa85..d003ec37d 100644 ---- a/grub-core/normal/completion.c -+++ b/grub-core/normal/completion.c -@@ -259,6 +259,14 @@ complete_file (void) - goto fail; - } - -+ if (dev->disk && -+ grub_disk_is_crypto (dev->disk) && -+ grub_file_filters[GRUB_FILE_FILTER_NOCAT]) -+ { -+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content")); -+ goto fail; -+ } -+ - fs = grub_fs_probe (dev); - if (! fs) - { --- -2.42.1 - diff --git a/0004-Key-revocation-on-out-of-bound-file-access.patch b/0004-Key-revocation-on-out-of-bound-file-access.patch index 2a85d8d..4241991 100644 --- a/0004-Key-revocation-on-out-of-bound-file-access.patch +++ b/0004-Key-revocation-on-out-of-bound-file-access.patch @@ -20,11 +20,17 @@ Signed-Off-by Michael Chang include/grub/file.h | 1 + 2 files changed, 37 insertions(+) -diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c -index d3acc4b59..e09296c57 100644 --- a/grub-core/commands/crypttab.c +++ b/grub-core/commands/crypttab.c -@@ -121,6 +121,41 @@ grub_cryptokey_tpmkey_discard (void) +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -89,6 +90,41 @@ grub_cryptokey_discard(); } @@ -66,26 +72,97 @@ index d3acc4b59..e09296c57 100644 static grub_err_t grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv) -@@ -153,6 +188,7 @@ GRUB_MOD_INIT(crypttab) +@@ -121,6 +157,8 @@ { cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry, N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description")); + grub_file_filter_register (GRUB_FILE_FILTER_DISTRUST, grub_distrust_open); - grub_dl_set_persistent (mod); ++ grub_dl_set_persistent (mod); } -diff --git a/include/grub/file.h b/include/grub/file.h -index fcfd32ce2..daf23a9c9 100644 + GRUB_MOD_FINI(crypttab) --- a/include/grub/file.h +++ b/include/grub/file.h -@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); +@@ -185,6 +185,7 @@ /* Filters with lower ID are executed first. */ typedef enum grub_file_filter_id { + GRUB_FILE_FILTER_DISTRUST, - GRUB_FILE_FILTER_NOCAT, GRUB_FILE_FILTER_VERIFY, GRUB_FILE_FILTER_GZIO, --- -2.42.1 - + GRUB_FILE_FILTER_XZIO, +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -558,6 +558,39 @@ + return NULL; + } + ++static int ++grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv) ++{ ++ struct grub_diskfilter_pv *pv; ++ ++ if (!lv) ++ return 0; ++ ++ if (lv->vg->pvs) ++ for (pv = lv->vg->pvs; pv; pv = pv->next) ++ { ++ if (!pv->disk) ++ { ++ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'." ++ " Some modules may be missing from core image."), ++ pv->name); ++ continue; ++ } ++ ++ switch (pv->disk->dev->id) ++ { ++ case GRUB_DISK_DEVICE_CRYPTODISK_ID: ++ return 1; ++ case GRUB_DISK_DEVICE_DISKFILTER_ID: ++ return grub_diskfilter_has_cryptodisk (pv->disk->data); ++ default: ++ break; ++ } ++ } ++ ++ return 0; ++} ++ + static grub_err_t + grub_diskfilter_open (const char *name, grub_disk_t disk) + { +@@ -589,6 +622,8 @@ + + disk->total_sectors = lv->size; + disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; ++ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv); ++ + return 0; + } + +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -147,6 +147,8 @@ + + /* Device-specific data. */ + void *data; ++ ++ int is_crypto_diskfilter; + }; + typedef struct grub_disk *grub_disk_t; + +@@ -317,4 +319,12 @@ + void grub_diskfilter_fini (void); + #endif + ++static inline int ++grub_disk_is_crypto (grub_disk_t disk) ++{ ++ return ((disk->is_crypto_diskfilter || ++ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ? ++ 1 : 0); ++} ++ + #endif /* ! GRUB_DISK_HEADER */ diff --git a/0007-mkimage-create-new-ELF-Note-for-SBAT.patch b/0007-grub-mkimage-Create-new-ELF-note-for-SBAT.patch similarity index 78% rename from 0007-mkimage-create-new-ELF-Note-for-SBAT.patch rename to 0007-grub-mkimage-Create-new-ELF-note-for-SBAT.patch index a161a77..4c15cd1 100644 --- a/0007-mkimage-create-new-ELF-Note-for-SBAT.patch +++ b/0007-grub-mkimage-Create-new-ELF-note-for-SBAT.patch @@ -1,19 +1,21 @@ -From 77316f09f133e9c7c5e1026b2b4f5749daac644a Mon Sep 17 00:00:00 2001 +From 6701b4a9e1994c8a05c87a7167694bc3dd71e7d6 Mon Sep 17 00:00:00 2001 From: Sudhakar Kuppusamy -Date: Wed, 17 Apr 2024 23:48:51 +0530 -Subject: [PATCH 7/8] mkimage: create new ELF Note for SBAT +Date: Wed, 23 Oct 2024 17:54:32 +0530 +Subject: [PATCH 7/8] grub-mkimage: Create new ELF note for SBAT -we add a new ELF note for SBAT which store the SBAT data. -The name field of shall be the string "Secure-Boot-Advanced-Targeting", zero-padded -to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values -for the string "sbat"). +In order to store the SBAT data we create a new ELF note. The string +".sbat", zero-padded to 4 byte alignment, shall be entered in the name +field. The string "SBAT"'s ASCII values, 0x53424154, should be entered +in the type field. +Signed-off-by: Daniel Axtens Signed-off-by: Sudhakar Kuppusamy -Co-authored-by: Daniel Axtens +Reviewed-by: Daniel Kiper --- include/grub/util/mkimage.h | 4 +- util/grub-mkimagexx.c | 92 +++++++++++++++++++++++++++---------- - 2 files changed, 71 insertions(+), 25 deletions(-) + util/mkimage.c | 5 +- + 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h index 6f1da89b9..881e3031f 100644 @@ -35,24 +37,24 @@ index 6f1da89b9..881e3031f 100644 struct grub_mkimage_layout *layout); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index 9488f0525..0041b2d0b 100644 +index 9488f0525..b507d4ade 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c -@@ -85,6 +85,14 @@ struct grub_ieee1275_note - struct grub_ieee1275_note_desc descriptor; +@@ -116,6 +116,14 @@ struct section_metadata + const char *strtab; }; -+#define GRUB_SBAT_NOTE_NAME "Secure-Boot-Advanced-Targeting" -+#define GRUB_SBAT_NOTE_TYPE 0x73626174 /* "sbat" */ ++#define GRUB_SBAT_NOTE_NAME ".sbat" ++#define GRUB_SBAT_NOTE_TYPE 0x53424154 /* "SBAT" */ + +struct grub_sbat_note { + Elf32_Nhdr header; + char name[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME), 4)]; +}; + - #define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature" - #define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */ - + static int + is_relocatable (const struct grub_install_image_target_desc *image_target) + { @@ -217,7 +225,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) void @@ -138,8 +140,8 @@ index 9488f0525..0041b2d0b 100644 - } + if (sbat) + { -+ int note_size = ALIGN_UP(sizeof (struct grub_sbat_note) + layout->sbat_size, 4); -+ struct grub_sbat_note *note_ptr = (struct grub_sbat_note *)footer; ++ int note_size = ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4); ++ struct grub_sbat_note *note_ptr = (struct grub_sbat_note *) footer; + + note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_SBAT_NOTE_NAME)); + note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(layout->sbat_size, 4)); @@ -184,6 +186,31 @@ index 9488f0525..0041b2d0b 100644 { char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr) +diff --git a/util/mkimage.c b/util/mkimage.c +index 0737935fd..be7f02c5c 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1835,6 +1835,7 @@ grub_install_generate_image (const char *dir, const char *prefix, + case IMAGE_I386_IEEE1275: + { + grub_uint64_t target_addr; ++ char *sbat = NULL; + if (image_target->id == IMAGE_LOONGSON_ELF) + { + if (comp == GRUB_COMPRESSION_NONE) +@@ -1846,10 +1847,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + else + target_addr = image_target->link_addr; + if (image_target->voidp_sizeof == 4) +- grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img, ++ grub_mkimage_generate_elf32 (image_target, note, appsig_size, sbat, &core_img, + &core_size, target_addr, &layout); + else +- grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img, ++ grub_mkimage_generate_elf64 (image_target, note, appsig_size, sbat, &core_img, + &core_size, target_addr, &layout); + } + break; -- -2.47.0 +2.47.1 diff --git a/0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch b/0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch deleted file mode 100644 index a2ed343..0000000 --- a/0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch +++ /dev/null @@ -1,279 +0,0 @@ -From 96e5a28d120856057fe7fc9b281f11f8933063b7 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Fri, 30 Jun 2023 14:37:41 +0800 -Subject: [PATCH 7/9] grub-switch-to-blscfg: adapt to openSUSE - -A few tweaks to make it 'just works' for openSUSE: - -- remove RHEL specific $grub_get_kernel_settings and all reference to it. -- make $grubdir and $startlink to the path in openSUSE -- change the bls template to openSUSE -- make $cmdline account for btrfs subvolumes, among others -- remove RHEL specific $GRUB_LINUX_MAKE_DEBUG and all related code -- remove ostree specific hack -- ignore increment.mod -- fix error in dash shell script -- fix kernel flavor parsing in openSUSE - -Signed-off-by: Michael Chang ---- - util/grub-switch-to-blscfg.in | 156 ++++++++++++++++++++-------------- - 1 file changed, 94 insertions(+), 62 deletions(-) - -diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in -index a851424be..145c22add 100644 ---- a/util/grub-switch-to-blscfg.in -+++ b/util/grub-switch-to-blscfg.in -@@ -28,27 +28,24 @@ PACKAGE_NAME=@PACKAGE_NAME@ - PACKAGE_VERSION=@PACKAGE_VERSION@ - datarootdir="@datarootdir@" - datadir="@datadir@" --if [ ! -v pkgdatadir ]; then -+if [ -z "${pkgdatadir+x}" ]; then - pkgdatadir="${datadir}/@PACKAGE@" - fi - - self=`basename $0` - --grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" - grub_editenv=${bindir}/@grub_editenv@ --etcdefaultgrub=/etc/default/grub -+grub_probe="${sbindir}/@grub_probe@" -+etcdefaultgrub=${sysconfdir}/default/grub - --eval "$("${grub_get_kernel_settings}")" || true -- --EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') --if [ -d /sys/firmware/efi/efivars/ ]; then -- startlink=/etc/grub2-efi.cfg -- grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` --else -- startlink=/etc/grub2.cfg -- grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+if test -f "$etcdefaultgrub" ; then -+ # shellcheck source=/etc/default/grub -+ . "$etcdefaultgrub" - fi - -+grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+startlink="${grubdir}/grub.cfg" -+ - blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'` - - backupsuffix=.bak -@@ -58,19 +55,80 @@ arch="$(uname -m)" - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" - -+# shellcheck source=/usr/share/grub2/grub-mkconfig_lib - . "${pkgdatadir}/grub-mkconfig_lib" - -+# FIXME: Abort if grub_probe fails -+ -+GRUB_DEVICE="`${grub_probe} --target=device /`" -+GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true -+GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true -+GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" -+ -+# loop-AES arranges things so that /dev/loop/X can be our root device, but -+# the initrds that Linux uses don't like that. -+case ${GRUB_DEVICE} in -+ /dev/loop/*|/dev/loop[0-9]) -+ GRUB_DEVICE=$(losetup "${GRUB_DEVICE}" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/") -+ ;; -+esac -+ -+# Default to disabling partition uuid support to maintian compatibility with -+# older kernels. -+GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true} -+ -+# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter -+# and mounting btrfs requires user space scanning, so force UUID in this case. -+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \ -+ || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ -+ && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \ -+ || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ -+ && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \ -+ || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then -+ LINUX_ROOT_DEVICE=${GRUB_DEVICE} -+elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \ -+ || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then -+ LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID} -+else -+ LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} -+fi -+ -+if [ "x$GRUB_CONMODE" != "x" ]; then -+ GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}" -+fi -+ -+case x"$GRUB_FS" in -+ xbtrfs) -+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" != "xtrue" ]; then -+ rootsubvol="`make_system_path_relative_to_its_root /`" -+ rootsubvol="${rootsubvol#/}" -+ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then -+ GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" -+ fi -+ fi -+ ;; -+ xzfs) -+ rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true` -+ bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`" -+ LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}" -+ ;; -+esac -+ -+if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then -+ LINUX_ROOT_DEVICE="" -+fi -+ - # Usage: usage - # Print the usage. - usage () { - gettext_printf "Usage: %s\n" "$self" -- gettext "Switch to BLS config files.\n"; echo -+ gettext "Switch to BLS config files. Only for testing purpose !!!\n"; echo - echo - print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-V, --version" "$(gettext "print the version information and exit")" - echo - print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix" -- print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir" -+ print_option_help "--bls-directory=$(gettext "DIR")" "Noop, always $blsdir" - print_option_help "--config-file=$(gettext "FILE")" "$startlink" - print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub" - print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir" -@@ -112,11 +170,15 @@ do - ;; - - --bls-directory) -- blsdir=`argument $option "$@"` -+ # blsdir=`argument $option "$@"` -+ gettext_printf "WARN: --bls-directory is currently disabled, it's always $blsdir !!!\n" -+ gettext_printf "WARN: use kernel-install instead if you want to test bls directory on ESP !!!\n" - shift - ;; - --bls-directory=*) -- blsdir=`echo "$option" | sed 's/--bls-directory=//'` -+ # blsdir=`echo "$option" | sed 's/--bls-directory=//'` -+ gettext_printf "WARN: --bls-directory is currently disabled, it's always $blsdir !!!\n" -+ gettext_printf "WARN: use kernel-install instead if you want to test bls directory on ESP !!!\n" - ;; - - --config-file) -@@ -172,7 +234,7 @@ find_grub_cfg() { - return 1 - } - --if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then -+if ! find_grub_cfg "${startlink}" ; then - gettext_printf "Couldn't find config file\n" 1>&2 - exit 1 - fi -@@ -190,27 +252,24 @@ fi - mkbls() { - local kernelver=$1 && shift - local datetime=$1 && shift -+ local prefix=$1 && shift - local kernelopts=$1 && shift - -- local debugname="" -- local debugid="" - local flavor="" - -- if [ "$kernelver" == *\+* ] ; then -- local flavor=-"${kernelver##*+}" -- if [ "${flavor}" == "-debug" ]; then -- local debugname=" with debugging" -- local debugid="-debug" -- fi -- fi -+ case "$kernelver" in -+ *-*-*) -+ flavor=-"${kernelver##*-}" -+ ;; -+ esac - ( -- source /etc/os-release -+ . /etc/os-release - - cat <"${bls_target}" -- -- if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -- bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")" -- cp -aT "${bls_target}" "${bls_debug}" -- title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')" -- options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')" -- sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}" -- sed -i -e "s/^options.*/options ${options}/" "${bls_debug}" -- fi - done -- -- if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then -- mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf" -- fi - } - --# The grub2 EFI binary is not copied to the ESP as a part of an ostree --# transaction. Make sure a grub2 version with BLS support is installed --# but only do this if the blsdir is not set, to make sure that the BLS --# parsing module will search for the BLS snippets in the default path. --if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \ -- ! ${grub_editenv} - list | grep -q blsdir && \ -- mountpoint -q /boot; then -- grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)" -- install -m 700 ${grub_binary} ${grubdir} || exit 1 -- # Create a hidden file to indicate that grub2 now has BLS support. -- touch /boot/grub2/.grub2-blscfg-supported --fi -- - GENERATE=0 - if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ - | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then -@@ -297,9 +329,7 @@ if [ "${GENERATE}" -eq 1 ] ; then - fi - - if [ -n "${mod_dir}" ]; then -- for mod in blscfg increment; do -- install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1 -- done -+ install -m 700 "${pkgdatadir}/${mod_dir}/blscfg.mod" "${grubdir}/$mod_dir/" || exit 1 - fi - - cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}" -@@ -311,6 +341,8 @@ if [ "${GENERATE}" -eq 1 ] ; then - gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}" - exit 1 - fi -+else -+ gettext_printf "Do nothing because \$GRUB_ENABLE_BLSCFG is already true in %s\n" "${GRUB_CONFIG_FILE}" - fi - - # Bye. --- -2.45.2 - diff --git a/0008-blscfg-reading-bls-fragments-if-boot-present.patch b/0008-blscfg-reading-bls-fragments-if-boot-present.patch deleted file mode 100644 index 70738a2..0000000 --- a/0008-blscfg-reading-bls-fragments-if-boot-present.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 2b0e6effc31ec166bbbe35a3cd2b4c73051f38bb Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Fri, 16 Jun 2023 15:54:50 +0800 -Subject: [PATCH 8/9] blscfg: reading bls fragments if boot present - -The Boot Loader Specification (BLS) designates the EFI System Partition -(ESP) as a primary location for $BOOT, where boot menu entries can be -stored. The specification encourages boot loaders to retrieve menu -entries from the ESP, even when XBOOTLDR is present. - -This commit aligns with the BLS specification by introducing the -capability to search for the ESP in addition to the default root -partition or any specified location via blscfg's command line. The $boot -environment variable is utilized as a reference to the ESP device for -the blscfg command. Initialization of $boot in grub.cfg is demonstrated -as follows: - - insmod part_gpt - insmod fat - search --no-floppy --fs-uuid --set=boot F414-5A9F - -If $boot is unset, no additional search for the BLS location will be -performed. - -Signed-off-by: Michael Chang ---- - grub-core/commands/blscfg.c | 10 ++++++++++ - util/grub.d/10_linux.in | 3 ++- - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c -index c872bcef0..cbe2a289e 100644 ---- a/grub-core/commands/blscfg.c -+++ b/grub-core/commands/blscfg.c -@@ -1186,6 +1186,7 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, - char *entry_id = NULL; - bool show_default = true; - bool show_non_default = true; -+ const char *boot = NULL; - - if (argc == 1) { - if (grub_strcmp (args[0], "default") == 0) { -@@ -1205,6 +1206,15 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, - if (r) - return r; - -+ boot = grub_env_get("boot"); -+ path = (boot) ? grub_xasprintf("(%s)" GRUB_BLS_CONFIG_PATH, boot) : NULL; -+ if (path) -+ { -+ bls_load_entries(path); -+ grub_print_error(); -+ } -+ grub_free(path); -+ - return bls_create_entries(show_default, show_non_default, entry_id); - } - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 45eefb332..edf0fca55 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -201,7 +201,8 @@ populate_menu() - } - - # Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. --if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then -+# FIXME: The test should be aligned to openSUSE, grubby is not our default tool -+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && false; then - GRUB_ENABLE_BLSCFG="true" - fi - --- -2.44.0 - diff --git a/0008-grub-mkimage-Add-SBAT-metadata-into-ELF-note-for-Pow.patch b/0008-grub-mkimage-Add-SBAT-metadata-into-ELF-note-for-Pow.patch new file mode 100644 index 0000000..eb51e64 --- /dev/null +++ b/0008-grub-mkimage-Add-SBAT-metadata-into-ELF-note-for-Pow.patch @@ -0,0 +1,48 @@ +From 312edf1f0ebaebba72e348ae88d95b29fa24c09c Mon Sep 17 00:00:00 2001 +From: Sudhakar Kuppusamy +Date: Wed, 23 Oct 2024 17:54:33 +0530 +Subject: [PATCH 8/8] grub-mkimage: Add SBAT metadata into ELF note for PowerPC + targets + +The SBAT metadata is read from CSV file and transformed into an ELF note +with the -s option. + +Signed-off-by: Daniel Axtens +Signed-off-by: Sudhakar Kuppusamy +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index be7f02c5c..d3948937b 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -958,8 +958,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + total_module_size += dtb_size + sizeof (struct grub_module_header); + } + +- if (sbat_path != NULL && image_target->id != IMAGE_EFI) +- grub_util_error (_(".sbat section can be embedded into EFI images only")); ++ if (sbat_path != NULL && (image_target->id != IMAGE_EFI && image_target->id != IMAGE_PPC)) ++ grub_util_error (_("SBAT data can be added only to EFI or powerpc-ieee1275 images")); + + if (disable_shim_lock) + total_module_size += sizeof (struct grub_module_header); +@@ -1836,6 +1836,13 @@ grub_install_generate_image (const char *dir, const char *prefix, + { + grub_uint64_t target_addr; + char *sbat = NULL; ++ if (sbat_path != NULL) ++ { ++ sbat_size = grub_util_get_image_size (sbat_path); ++ sbat = xmalloc (sbat_size); ++ grub_util_load_image (sbat_path, sbat); ++ layout.sbat_size = sbat_size; ++ } + if (image_target->id == IMAGE_LOONGSON_ELF) + { + if (comp == GRUB_COMPRESSION_NONE) +-- +2.47.1 + diff --git a/0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch b/0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch deleted file mode 100644 index 106fc16..0000000 --- a/0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 32d4823762e5a0e7f8bfc5a878d39e1a019392fe Mon Sep 17 00:00:00 2001 -From: Sudhakar Kuppusamy -Date: Thu, 18 Apr 2024 00:00:55 +0530 -Subject: [PATCH 8/8] mkimage: adding sbat data into sbat ELF Note on powerpc - -it reads the SBAT data from sbat.csv and create the ELF Note for it then -store the SBAT data on it while generate image with -s option - -Signed-off-by: Sudhakar Kuppusamy -Co-authored-by: Daniel Axtens ---- - util/mkimage.c | 23 +++++++++++++++++------ - 1 file changed, 17 insertions(+), 6 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index 0737935fd..136e4a90c 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -958,8 +958,9 @@ grub_install_generate_image (const char *dir, const char *prefix, - total_module_size += dtb_size + sizeof (struct grub_module_header); - } - -- if (sbat_path != NULL && image_target->id != IMAGE_EFI) -- grub_util_error (_(".sbat section can be embedded into EFI images only")); -+ if (sbat_path != NULL && (image_target->id != IMAGE_EFI && image_target->id != IMAGE_PPC)) -+ grub_util_error (_(".sbat section can be embedded into EFI images/" -+ "sbat ELF Note cab be added into powerpc-ieee1275 images only")); - - if (disable_shim_lock) - total_module_size += sizeof (struct grub_module_header); -@@ -1835,6 +1836,16 @@ grub_install_generate_image (const char *dir, const char *prefix, - case IMAGE_I386_IEEE1275: - { - grub_uint64_t target_addr; -+ char *sbat = NULL; -+ -+ if (sbat_path != NULL) -+ { -+ sbat_size = grub_util_get_image_size (sbat_path); -+ sbat = xmalloc (sbat_size); -+ grub_util_load_image (sbat_path, sbat); -+ layout.sbat_size = sbat_size; -+ } -+ - if (image_target->id == IMAGE_LOONGSON_ELF) - { - if (comp == GRUB_COMPRESSION_NONE) -@@ -1846,11 +1857,11 @@ grub_install_generate_image (const char *dir, const char *prefix, - else - target_addr = image_target->link_addr; - if (image_target->voidp_sizeof == 4) -- grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img, -- &core_size, target_addr, &layout); -+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, sbat, &core_img, &core_size, -+ target_addr, &layout); - else -- grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img, -- &core_size, target_addr, &layout); -+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, sbat, &core_img, &core_size, -+ target_addr, &layout); - } - break; - } --- -2.47.0 - diff --git a/0009-10_linux-Some-refinement-for-BLS.patch b/0009-10_linux-Some-refinement-for-BLS.patch deleted file mode 100644 index 65ac314..0000000 --- a/0009-10_linux-Some-refinement-for-BLS.patch +++ /dev/null @@ -1,252 +0,0 @@ -From abd8b83cdc6398c52c7d2b71b378938cf51872fd Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 13 Mar 2024 15:26:42 +0800 -Subject: [PATCH 9/9] 10_linux: Some refinement for BLS - -Remove BLS_POPULATE_MENU as it is not being used currently and removing -kernelopts assignment in the grub boot config itself to fully delegate -the responsibility of generating kernel options to a functioning BLS -generator. - -Additionally, removing unused dead code, which is often blamed for -causing errors in the dash shell script. - -Signed-off-by: Michael Chang ---- - util/grub.d/10_linux.in | 194 ---------------------------------------- - 1 file changed, 194 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index edf0fca55..666eae995 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -93,11 +93,7 @@ fi - - populate_header_warn() - { --if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -- bls_parser="10_linux script" --else - bls_parser="blscfg command" --fi - cat </dev/null | tac)) || : -- -- echo "${files[@]}" --} -- --update_bls_cmdline() --{ -- local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -- local -a files=($(get_sorted_bls)) -- -- for bls in "${files[@]}"; do -- local options="${cmdline}" -- if [ -z "${bls##*debug*}" ]; then -- options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}" -- fi -- options="$(echo "${options}" | sed -e 's/\//\\\//g')" -- sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf" -- done --} -- --populate_menu() --{ -- local -a files=($(get_sorted_bls)) -- -- gettext_printf "Generating boot entries from BLS files...\n" >&2 -- -- for bls in "${files[@]}"; do -- read_config "${blsdir}/${bls}.conf" -- -- menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n" -- menu="${menu}\t linux ${linux} ${options}\n" -- if [ -n "${initrd}" ] ; then -- menu="${menu}\t initrd ${boot_prefix}${initrd}\n" -- fi -- menu="${menu}}\n\n" -- done -- # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation -- printf "$menu" --} -- --# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. --# FIXME: The test should be aligned to openSUSE, grubby is not our default tool --if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && false; then -- GRUB_ENABLE_BLSCFG="true" --fi -- - if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then - if [ x$dirname = x/ ]; then - if [ -z "${prepare_root_cache}" ]; then -@@ -225,111 +125,17 @@ if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then - prepare_grub_to_access_device_with_variable boot ${boot_device} - fi - -- arch="$(uname -m)" -- if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then -- -- BLS_POPULATE_MENU="true" -- petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" -- -- if test -e ${petitboot_path}; then -- read -r -d '' petitboot_version < ${petitboot_path} -- petitboot_version="$(echo ${petitboot_version//v})" -- -- if test -n ${petitboot_version}; then -- major_version="$(echo ${petitboot_version} | cut -d . -f1)" -- minor_version="$(echo ${petitboot_version} | cut -d . -f2)" -- -- re='^[0-9]+$' -- if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && -- ([[ ${major_version} -gt 1 ]] || -- [[ ${major_version} -eq 1 && -- ${minor_version} -ge 8 ]]); then -- BLS_POPULATE_MENU="false" -- fi -- fi -- fi -- fi -- - populate_header_warn - -- cat << EOF --# The kernelopts variable should be defined in the grubenv file. But to ensure that menu --# entries populated from BootLoaderSpec files that use this variable work correctly even --# without a grubenv file, define a fallback kernelopts variable if this has not been set. --# --# The kernelopts variable in the grubenv file can be modified using the grubby tool or by --# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX --# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both --# the kernelopts variable in the grubenv file and the fallback kernelopts variable. --if [ -z "\${kernelopts}" ]; then -- set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" --fi --EOF -- -- update_bls_cmdline -- -- if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -- populate_menu -- else - cat << EOF - - insmod blscfg - blscfg - EOF -- fi -- -- if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then -- blsdir="/boot/loader/entries" -- [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})" -- if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then -- blsdir=$(make_system_path_relative_to_its_root "${blsdir}") -- if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then -- ${grub_editenv} - set blsdir="${blsdir}" -- fi -- fi -- -- if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then -- ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}" -- fi -- -- if [ -n "${GRUB_DEFAULT_DTB}" ]; then -- ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}" -- fi -- -- if [ -n "${GRUB_SAVEDEFAULT}" ]; then -- ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}" -- fi -- fi - - exit 0 - fi - --mktitle () --{ -- local title_type -- local version -- local OS_NAME -- local OS_VERS -- -- title_type=$1 && shift -- version=$1 && shift -- -- OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" -- OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" -- -- case $title_type in -- recovery) -- title=$(printf '%s (%s) %s (recovery mode)' \ -- "${OS_NAME}" "${version}" "${OS_VERS}") -- ;; -- *) -- title=$(printf '%s (%s) %s' \ -- "${OS_NAME}" "${version}" "${OS_VERS}") -- ;; -- esac -- echo -n ${title} --} -- - title_correction_code= - - hotkey=1 --- -2.45.2 - diff --git a/grub-read-pcr.patch b/grub-read-pcr.patch index faf72e5..bf421b0 100644 --- a/grub-read-pcr.patch +++ b/grub-read-pcr.patch @@ -1,5 +1,7 @@ ---- a/include/grub/tpm.h -+++ b/include/grub/tpm.h +Index: grub-2.12/include/grub/tpm.h +=================================================================== +--- grub-2.12.orig/include/grub/tpm.h ++++ grub-2.12/include/grub/tpm.h @@ -36,6 +36,12 @@ #define EV_IPL 0x0d @@ -13,7 +15,7 @@ grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description); int grub_tpm_present (void); -@@ -45,5 +51,7 @@ +@@ -45,5 +51,7 @@ grub_is_tpm_fail_fatal (void) { return grub_env_get_bool ("tpm_fail_fatal", false); } @@ -21,29 +23,32 @@ +void grub_tpm_digest_free (struct grub_tpm_digest *d); #endif ---- a/grub-core/commands/efi/tpm.c -+++ b/grub-core/commands/efi/tpm.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include +Index: grub-2.12/grub-core/commands/efi/tpm.c +=================================================================== +--- grub-2.12.orig/grub-core/commands/efi/tpm.c ++++ grub-2.12/grub-core/commands/efi/tpm.c +@@ -28,6 +28,8 @@ #include #include -@@ -186,6 +187,91 @@ + ++#include ++ + typedef TCG_PCR_EVENT grub_tpm_event_t; + + static grub_guid_t tpm_guid = EFI_TPM_GUID; +@@ -186,6 +188,91 @@ grub_tpm1_log_event (grub_efi_handle_t t return grub_efi_log_event_status (status); } +static void -+grub_tpm2_select_pcr(TPML_PCR_SELECTION *o, unsigned int pcrIndex, unsigned int algo) ++grub_tpm2_select_pcr (TPML_PCR_SELECTION_t *o, unsigned int pcrIndex, unsigned int algo) +{ -+ TPMS_PCR_SELECTION *pcr; ++ TPMS_PCR_SELECTION_t *pcr; + + pcr = &o->pcrSelections[o->count++]; + pcr->hash = algo; + pcr->sizeOfSelect = 3; -+ pcr->pcrSelect[TPM2_PCR_TO_SELECT(pcrIndex)] |= TPM2_PCR_TO_BIT(pcrIndex); ++ TPMS_PCR_SELECTION_SelectPCR (pcr, pcrIndex); +} + +struct grub_tpm_hash_info { @@ -77,10 +82,10 @@ +grub_tpm2_read_pcr (grub_int8_t pcrIndex, const char *algo, struct grub_tpm_digest **ret) +{ + const struct grub_tpm_hash_info *info; -+ TPML_PCR_SELECTION inSelection, outSelection; ++ TPML_PCR_SELECTION_t inSelection, outSelection; + grub_uint32_t pcrUpdateCounter; -+ TPML_DIGEST digests = { 0 }; -+ TPM2B_DIGEST *d; ++ TPML_DIGEST_t digests = { 0 }; ++ TPM2B_DIGEST_t *d; + struct grub_tpm_digest *result; + int rc; + @@ -92,7 +97,7 @@ + grub_memset(&outSelection, 0, sizeof(outSelection)); + grub_tpm2_select_pcr(&inSelection, pcrIndex, info->id); + -+ rc = TPM2_PCR_Read( ++ rc = grub_tpm2_pcr_read( + NULL, + &inSelection, + &pcrUpdateCounter, @@ -123,7 +128,7 @@ static grub_err_t grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, grub_size_t size, grub_uint8_t pcr, -@@ -323,3 +409,26 @@ +@@ -323,3 +410,26 @@ grub_tpm_present (void) return grub_tpm2_present (tpm); } } @@ -150,16 +155,15 @@ + + return result; +} ---- a/include/grub/tpm2/tpm2.h -+++ b/include/grub/tpm2/tpm2.h -@@ -23,6 +23,10 @@ - #include - #include - -+/* Defined in: TCG TPM Specification, v1.59, Part 2, Section 10.6.1. */ -+#define TPM2_PCR_TO_SELECT(x) ((x) / 8) -+#define TPM2_PCR_TO_BIT(x) (1 << ((x) % 8)) -+ - /* Well-Known Windows SRK handle */ - #define TPM2_SRK_HANDLE 0x81000001 +Index: grub-2.12/grub-core/Makefile.core.def +=================================================================== +--- grub-2.12.orig/grub-core/Makefile.core.def ++++ grub-2.12/grub-core/Makefile.core.def +@@ -2606,6 +2606,7 @@ module = { + common = commands/tpm.c; + efi = commands/efi/tpm.c; + enable = efi; ++ cppflags = '-I$(srcdir)/lib/tss2'; + }; + module = { diff --git a/grub2-add-tss2-support.patch b/grub2-add-tss2-support.patch new file mode 100644 index 0000000..c4d4aed --- /dev/null +++ b/grub2-add-tss2-support.patch @@ -0,0 +1,4586 @@ +From b1a31f22ec895bf231a527500f5d3d0599ccec82 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Mon, 24 Jun 2024 14:03:05 +0800 +Subject: [PATCH 1/3] tss2: Add TPM2 buffer handling functions + +As the prepartion to support TPM2 Software Stack (TSS2), this commit +implements the TPM2 buffer handling functions to pack data for the TPM2 +commands and unpack the data from the response. + +Cc: Stefan Berger +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +Reviewed-by: Daniel Kiper +--- + grub-core/lib/tss2/buffer.c | 147 +++++++++++++++++++++++++++++++ + grub-core/lib/tss2/tss2_buffer.h | 64 ++++++++++++++ + 2 files changed, 211 insertions(+) + create mode 100644 grub-core/lib/tss2/buffer.c + create mode 100644 grub-core/lib/tss2/tss2_buffer.h + +diff --git a/grub-core/lib/tss2/buffer.c b/grub-core/lib/tss2/buffer.c +new file mode 100644 +index 000000000..16d59a8f5 +--- /dev/null ++++ b/grub-core/lib/tss2/buffer.c +@@ -0,0 +1,147 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 . ++ */ ++ ++#include ++ ++#include ++ ++void grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer) ++{ ++ grub_memset (buffer->data, 0, 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 void *) &value, sizeof (value)); ++} ++ ++void ++grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value) ++{ ++ grub_uint16_t tmp = grub_cpu_to_be16 (value); ++ ++ grub_tpm2_buffer_pack (buffer, (const void *) &tmp, sizeof (tmp)); ++} ++ ++void ++grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value) ++{ ++ grub_uint32_t tmp = grub_cpu_to_be32 (value); ++ ++ grub_tpm2_buffer_pack (buffer, (const void *) &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; ++ return; ++ } ++ ++ grub_memcpy (data, &buffer->data[buffer->offset], size); ++ buffer->offset += size; ++} ++ ++void ++grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t *value) ++{ ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (sizeof (*value) > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (value, &buffer->data[buffer->offset], sizeof (*value)); ++ buffer->offset += sizeof (*value); ++} ++ ++void ++grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t *value) ++{ ++ grub_uint16_t tmp; ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (sizeof (tmp) > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); ++ buffer->offset += sizeof (tmp); ++ *value = grub_be_to_cpu16 (tmp); ++} ++ ++void ++grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t *value) ++{ ++ grub_uint32_t tmp; ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (sizeof (tmp) > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); ++ buffer->offset += sizeof (tmp); ++ *value = grub_be_to_cpu32 (tmp); ++} +diff --git a/grub-core/lib/tss2/tss2_buffer.h b/grub-core/lib/tss2/tss2_buffer.h +new file mode 100644 +index 000000000..fb9db1aed +--- /dev/null ++++ b/grub-core/lib/tss2/tss2_buffer.h +@@ -0,0 +1,64 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_BUFFER_HEADER ++#define GRUB_TPM2_BUFFER_HEADER 1 ++ ++#include ++ ++#define GRUB_TPM2_BUFFER_CAPACITY 4096 ++ ++struct grub_tpm2_buffer ++{ ++ grub_uint8_t data[GRUB_TPM2_BUFFER_CAPACITY]; ++ grub_size_t size; ++ grub_size_t offset; ++ grub_size_t cap; ++ bool error; ++}; ++typedef struct grub_tpm2_buffer *grub_tpm2_buffer_t; ++ ++extern void ++grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer); ++ ++extern void ++grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void *data, grub_size_t size); ++ ++extern void ++grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value); ++ ++extern void ++grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value); ++ ++extern void ++grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value); ++ ++extern void ++grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void *data, grub_size_t size); ++ ++extern void ++grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t *value); ++ ++extern void ++grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t *value); ++ ++extern void ++grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t *value); ++ ++#endif /* ! GRUB_TPM2_BUFFER_HEADER */ +-- +2.43.0 + + +From 47f0b938daac250dedbe2a3b126ca6090babb4c9 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Mon, 24 Jun 2024 14:04:56 +0800 +Subject: [PATCH 2/3] tss2: Add TPM2 types and Marshal/Unmarshal functions + +This commit adds the necessary TPM2 types and structs as the preparation +for the TPM2 Software Stack (TSS2) support. The Marshal/Unmarshal +functions are also added to handle the data structure to be submitted to +TPM2 commands and to be received from the response. + +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +Reviewed-by: Daniel Kiper +Reviewed-by: Stefan Berger +--- + grub-core/lib/tss2/tss2_mu.c | 1174 +++++++++++++++++++++++++++++ + grub-core/lib/tss2/tss2_mu.h | 397 ++++++++++ + grub-core/lib/tss2/tss2_structs.h | 796 +++++++++++++++++++ + grub-core/lib/tss2/tss2_types.h | 404 ++++++++++ + 4 files changed, 2771 insertions(+) + create mode 100644 grub-core/lib/tss2/tss2_mu.c + create mode 100644 grub-core/lib/tss2/tss2_mu.h + create mode 100644 grub-core/lib/tss2/tss2_structs.h + create mode 100644 grub-core/lib/tss2/tss2_types.h + +diff --git a/grub-core/lib/tss2/tss2_mu.c b/grub-core/lib/tss2/tss2_mu.c +new file mode 100644 +index 000000000..86134cc0a +--- /dev/null ++++ b/grub-core/lib/tss2/tss2_mu.c +@@ -0,0 +1,1174 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 . ++ */ ++ ++#include ++ ++#include ++ ++void ++grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_AUTH_COMMAND_t *authCommand) ++{ ++ grub_uint32_t start; ++ grub_uint32_t tmp; ++ ++ grub_tpm2_buffer_pack_u32 (buffer, 0); ++ start = buffer->size; ++ ++ grub_tpm2_buffer_pack_u32 (buffer, authCommand->sessionHandle); ++ ++ grub_tpm2_buffer_pack_u16 (buffer, authCommand->nonce.size); ++ grub_tpm2_buffer_pack (buffer, authCommand->nonce.buffer, authCommand->nonce.size); ++ ++ grub_tpm2_buffer_pack_u8 (buffer, *((const grub_uint8_t *) &authCommand->sessionAttributes)); ++ ++ grub_tpm2_buffer_pack_u16 (buffer, authCommand->hmac.size); ++ grub_tpm2_buffer_pack (buffer, authCommand->hmac.buffer, authCommand->hmac.size); ++ ++ tmp = grub_cpu_to_be32 (buffer->size - start); ++ grub_memcpy (&buffer->data[start - sizeof (grub_uint32_t)], &tmp, sizeof (tmp)); ++} ++ ++void ++grub_Tss2_MU_TPM2B_Marshal (grub_tpm2_buffer_t buffer, ++ const grub_uint16_t size, ++ const grub_uint8_t *b) ++{ ++ grub_uint16_t i; ++ ++ grub_tpm2_buffer_pack_u16 (buffer, size); ++ ++ for (i = 0; i < size; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, b[i]); ++} ++ ++void ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SYM_OBJECT_t algorithm, ++ const TPMU_SYM_KEY_BITS_t *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ case TPM_ALG_XOR: ++ grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t *) p)); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SYM_OBJECT_t algorithm, ++ const TPMU_SYM_MODE_t *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t *) p)); ++ break; ++ case TPM_ALG_XOR: ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SYM_DEF_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->algorithm); ++ grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits); ++ grub_Tss2_MU_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); ++} ++ ++void ++grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_PCR_SELECTION_t *pcrSelection) ++{ ++ grub_uint32_t i; ++ ++ grub_tpm2_buffer_pack_u16 (buffer, pcrSelection->hash); ++ grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->sizeOfSelect); ++ ++ for (i = 0; i < pcrSelection->sizeOfSelect; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->pcrSelect[i]); ++} ++ ++void ++grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, ++ const TPML_PCR_SELECTION_t *pcrSelection) ++{ ++ grub_uint32_t i; ++ ++ grub_tpm2_buffer_pack_u32 (buffer, pcrSelection->count); ++ ++ for (i = 0; i < pcrSelection->count; i++) ++ grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (buffer, &pcrSelection->pcrSelections[i]); ++} ++ ++void ++grub_Tss2_MU_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMA_OBJECT_t *p) ++{ ++ grub_tpm2_buffer_pack_u32 (buffer, *((const grub_uint32_t *) p)); ++} ++ ++void ++grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SCHEME_XOR_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf); ++} ++ ++void ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SCHEME_HMAC_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); ++} ++ ++void ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_KEYEDHASH_SCHEME_t scheme, ++ const TPMU_SCHEME_KEYEDHASH_t *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_HMAC: ++ grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_XOR: ++ grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (buffer, &p->exclusiveOr); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_KEYEDHASH_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_KEYEDHASH_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme); ++} ++ ++void ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SYM_DEF_OBJECT_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->algorithm); ++ grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits); ++ grub_Tss2_MU_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); ++} ++ ++void ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_RSA_DECRYPT_t scheme, ++ const TPMU_ASYM_SCHEME_t *p __attribute__ ((unused))) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_NULL: ++ break; ++ default: ++ /* Unsupported */ ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_RSA_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_RSA_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); ++ grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme); ++ grub_tpm2_buffer_pack_u16 (buffer, p->keyBits); ++ grub_tpm2_buffer_pack_u32 (buffer, p->exponent); ++} ++ ++void ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SYMCIPHER_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym); ++} ++ ++void ++grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_ECC_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_KDF_t scheme, ++ const TPMU_KDF_SCHEME_t *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_MGF1: ++ grub_tpm2_buffer_pack_u16 (buffer, p->mgf1.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_56A: ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_56a.hashAlg); ++ break; ++ case TPM_ALG_KDF2: ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf2.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_108: ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_108.hashAlg); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_KDF_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_ECC_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); ++ grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme); ++ grub_tpm2_buffer_pack_u16 (buffer, p->curveID); ++ grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (buffer, &p->kdf); ++} ++ ++void ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const grub_uint32_t type, ++ const TPMU_PUBLIC_PARMS_t *p) ++{ ++ switch (type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (buffer, &p->keyedHashDetail); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (buffer, &p->symDetail); ++ break; ++ case TPM_ALG_RSA: ++ grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (buffer, &p->rsaDetail); ++ break; ++ case TPM_ALG_ECC: ++ grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (buffer, &p->eccDetail); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_ECC_POINT_t *p) ++{ ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->x.size, p->x.buffer); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->y.size, p->y.buffer); ++} ++ ++void ++grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_PUBLIC_t type, ++ const TPMU_PUBLIC_ID_t *p) ++{ ++ switch(type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->keyedHash.size, p->keyedHash.buffer); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); ++ break; ++ case TPM_ALG_RSA: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); ++ break; ++ case TPM_ALG_ECC: ++ grub_Tss2_MU_TPMS_ECC_POINT_Marshal (buffer, &p->ecc); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_PUBLIC_PARMS_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->type); ++ grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); ++} ++ ++void ++grub_Tss2_MU_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_PUBLIC_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->type); ++ grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg); ++ grub_Tss2_MU_TPMA_OBJECT_Marshal (buffer, &p->objectAttributes); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->authPolicy.size, p->authPolicy.buffer); ++ grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); ++ grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (buffer, p->type, &p->unique); ++} ++ ++void ++grub_Tss2_MU_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_PUBLIC_t *p) ++{ ++ grub_uint32_t start; ++ grub_uint16_t size; ++ ++ if (p) ++ { ++ grub_tpm2_buffer_pack_u16 (buffer, p->size); ++ ++ start = buffer->size; ++ grub_Tss2_MU_TPMT_PUBLIC_Marshal (buffer, &p->publicArea); ++ size = grub_cpu_to_be16 (buffer->size - start); ++ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, sizeof (size)); ++ } ++ else ++ grub_tpm2_buffer_pack_u16 (buffer, 0); ++} ++ ++void ++grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SENSITIVE_CREATE_t *p) ++{ ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->userAuth.size, p->userAuth.buffer); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->data.size, p->data.buffer); ++} ++ ++void ++grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_PUBLIC_t type, ++ const TPMU_SENSITIVE_COMPOSITE_t *p) ++{ ++ switch(type) ++ { ++ case TPM_ALG_RSA: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); ++ break; ++ case TPM_ALG_ECC: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer); ++ break; ++ case TPM_ALG_KEYEDHASH: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); ++ break; ++ default: ++ buffer->error = 1; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SENSITIVE_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->authValue.size, p->authValue.buffer); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->seedValue.size, p->seedValue.buffer); ++ grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType, &p->sensitive); ++} ++ ++void ++grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_SENSITIVE_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->size); ++ grub_Tss2_MU_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea); ++} ++ ++void ++grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_SENSITIVE_CREATE_t *sensitiveCreate) ++{ ++ grub_uint32_t start; ++ grub_uint16_t size; ++ ++ if (sensitiveCreate) ++ { ++ grub_tpm2_buffer_pack_u16 (buffer, sensitiveCreate->size); ++ start = buffer->size; ++ grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (buffer, &sensitiveCreate->sensitive); ++ size = grub_cpu_to_be16 (buffer->size - start); ++ ++ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, sizeof (size)); ++ } ++ else ++ grub_tpm2_buffer_pack_u16 (buffer, 0); ++} ++ ++void ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SIGNATURE_RSA_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hash); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer); ++} ++ ++void ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SIGNATURE_ECC_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hash); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->signatureR.size, p->signatureR.buffer); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->signatureS.size, p->signatureS.buffer); ++} ++ ++void ++grub_Tss2_MU_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_HASH_t hashAlg, ++ const TPMU_HA_t *p) ++{ ++ grub_uint16_t i; ++ ++ switch (hashAlg) ++ { ++ case TPM_ALG_SHA1: ++ for (i = 0; i < TPM_SHA1_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha1[i]); ++ break; ++ case TPM_ALG_SHA256: ++ for (i = 0; i < TPM_SHA256_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha256[i]); ++ break; ++ case TPM_ALG_SHA384: ++ for (i = 0; i < TPM_SHA384_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha384[i]); ++ break; ++ case TPM_ALG_SHA512: ++ for (i = 0; i < TPM_SHA512_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha512[i]); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_HA_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); ++ grub_Tss2_MU_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest); ++} ++ ++void ++grub_Tss2_MU_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SIG_SCHEME_t sigAlg, ++ const TPMU_SIGNATURE_t *p) ++{ ++ switch (sigAlg) ++ { ++ case TPM_ALG_RSASSA: ++ grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA_t *) &p->rsassa); ++ break; ++ case TPM_ALG_RSAPSS: ++ grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA_t *) &p->rsapss); ++ break; ++ case TPM_ALG_ECDSA: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->ecdsa); ++ break; ++ case TPM_ALG_ECDAA: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->ecdaa); ++ break; ++ case TPM_ALG_SM2: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->sm2); ++ break; ++ case TPM_ALG_ECSCHNORR: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->ecschnorr); ++ break; ++ case TPM_ALG_HMAC: ++ grub_Tss2_MU_TPMT_HA_Marshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SIGNATURE_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg); ++ grub_Tss2_MU_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature); ++} ++ ++void ++grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_TK_VERIFIED_t *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->tag); ++ grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy); ++ grub_Tss2_MU_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer); ++} ++ ++static void ++__Tss2_MU_TPM2B_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_t *p, grub_uint16_t bound) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); ++ ++ if (p->size > bound) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_tpm2_buffer_unpack (buffer, &p->buffer, p->size); ++} ++ ++#define TPM2B_BUFFER_UNMARSHAL(buffer, type, data) \ ++ __Tss2_MU_TPM2B_BUFFER_Unmarshal(buffer, (TPM2B_t *)data, sizeof(type) - sizeof(grub_uint16_t)) ++ ++void ++grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_AUTH_RESPONSE_t *p) ++{ ++ grub_uint8_t tmp; ++ grub_uint32_t tmp32; ++ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->nonce.size); ++ ++ if (p->nonce.size) ++ grub_tpm2_buffer_unpack (buffer, &p->nonce.buffer, p->nonce.size); ++ ++ grub_tpm2_buffer_unpack_u8 (buffer, &tmp); ++ tmp32 = tmp; ++ grub_memcpy (&p->sessionAttributes, &tmp32, sizeof (grub_uint32_t)); ++ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hmac.size); ++ ++ if (p->hmac.size) ++ grub_tpm2_buffer_unpack (buffer, &p->hmac.buffer, p->hmac.size); ++} ++ ++void ++grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_DIGEST_t *digest) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DIGEST_t, digest); ++} ++ ++void ++grub_Tss2_MU_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NONCE_t *nonce) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NONCE_t, nonce); ++} ++ ++void ++grub_Tss2_MU_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_DATA_t *data) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DATA_t, data); ++} ++ ++void ++grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_CREATION_DATA_t *data) ++{ ++ grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (buffer, &data->pcrSelect); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &data->pcrDigest); ++ grub_tpm2_buffer_unpack_u8 (buffer, (grub_uint8_t *)&data->locality); ++ grub_tpm2_buffer_unpack_u16 (buffer, &data->parentNameAlg); ++ grub_Tss2_MU_TPM2B_NAME_Unmarshal (buffer, &data->parentName); ++ grub_Tss2_MU_TPM2B_NAME_Unmarshal (buffer, &data->parentQualifiedName); ++ grub_Tss2_MU_TPM2B_DATA_Unmarshal (buffer, &data->outsideInfo); ++} ++ ++void ++grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_CREATION_DATA_t *data) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &data->size); ++ grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (buffer, &data->creationData); ++} ++ ++void ++grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PRIVATE_t *private) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PRIVATE_t, private); ++} ++ ++void ++grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_SENSITIVE_DATA_t *data) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_SENSITIVE_DATA_t, data); ++} ++ ++void ++grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PUBLIC_KEY_RSA_t *rsa) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PUBLIC_KEY_RSA_t, rsa); ++} ++ ++void ++grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_ECC_PARAMETER_t *param) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_ECC_PARAMETER_t, param); ++} ++ ++void ++grub_Tss2_MU_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMA_OBJECT_t *p) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, (grub_uint32_t *) p); ++} ++ ++void ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SCHEME_HMAC_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); ++} ++ ++void ++grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SCHEME_XOR_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf); ++} ++ ++void ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_KEYEDHASH_SCHEME_t scheme, ++ TPMU_SCHEME_KEYEDHASH_t *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_HMAC: ++ grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_XOR: ++ grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (buffer, &p->exclusiveOr); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_KEYEDHASH_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_KEYEDHASH_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (buffer, &p->scheme); ++} ++ ++void ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SYM_OBJECT_t algorithm, ++ TPMU_SYM_KEY_BITS_t *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ case TPM_ALG_XOR: ++ grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t *) p); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SYM_OBJECT_t algorithm, ++ TPMU_SYM_MODE_t *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t *) p); ++ break; ++ case TPM_ALG_XOR: ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_SYM_DEF_OBJECT_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->algorithm); ++ grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (buffer, p->algorithm, &p->keyBits); ++ grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (buffer, p->algorithm, &p->mode); ++} ++ ++void ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SYMCIPHER_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->sym); ++} ++ ++void ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_RSA_DECRYPT_t scheme, ++ TPMU_ASYM_SCHEME_t *p __attribute__((unused))) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_NULL: ++ break; ++ default: ++ /* Unsupported */ ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_RSA_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_RSA_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); ++ grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (buffer, &p->scheme); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->keyBits); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->exponent); ++} ++ ++void ++grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_ECC_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_KDF_t scheme, ++ TPMU_KDF_SCHEME_t *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_MGF1: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->mgf1.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_56A: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_56a.hashAlg); ++ break; ++ case TPM_ALG_KDF2: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf2.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_108: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_108.hashAlg); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_KDF_SCHEME_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_ECC_PARMS_t *p) ++{ ++ grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); ++ grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (buffer, &p->scheme ); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->curveID); ++ grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (buffer, &p->kdf); ++} ++ ++void ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ grub_uint32_t type, ++ TPMU_PUBLIC_PARMS_t *p) ++{ ++ switch (type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (buffer, &p->keyedHashDetail); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (buffer, &p->symDetail); ++ break; ++ case TPM_ALG_RSA: ++ grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (buffer, &p->rsaDetail); ++ break; ++ case TPM_ALG_ECC: ++ grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (buffer, &p->eccDetail); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_ECC_POINT_t *p) ++{ ++ grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->x); ++ grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->y); ++} ++ ++void ++grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_PUBLIC_t type, ++ TPMU_PUBLIC_ID_t *p) ++{ ++ switch(type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->keyedHash); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->sym); ++ break; ++ case TPM_ALG_RSA: ++ grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &p->rsa); ++ break; ++ case TPM_ALG_ECC: ++ grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_PUBLIC_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->type); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); ++ grub_Tss2_MU_TPMA_OBJECT_Unmarshal (buffer, &p->objectAttributes); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); ++ grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (buffer, p->type, &p->parameters); ++ grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (buffer, p->type, &p->unique); ++} ++ ++void ++grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PUBLIC_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); ++ grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (buffer, &p->publicArea); ++} ++ ++void ++grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_NV_PUBLIC_t *p) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->nvIndex); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->attributes); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->dataSize); ++} ++ ++void ++grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NV_PUBLIC_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); ++ grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic); ++} ++ ++void ++grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NAME_t *n) ++{ ++ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NAME_t, n); ++} ++ ++void ++grub_Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_TAGGED_PROPERTY_t *property) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, &property->property); ++ grub_tpm2_buffer_unpack_u32 (buffer, &property->value); ++} ++ ++void ++grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_CREATION_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); ++} ++ ++void ++grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_HASHCHECK_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); ++} ++ ++void ++grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_VERIFIED_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); ++} ++ ++void ++grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_PCR_SELECTION_t *pcrSelection) ++{ ++ grub_uint32_t i; ++ ++ grub_tpm2_buffer_unpack_u16 (buffer, &pcrSelection->hash); ++ grub_tpm2_buffer_unpack_u8 (buffer, &pcrSelection->sizeOfSelect); ++ ++ if (pcrSelection->sizeOfSelect > TPM_PCR_SELECT_MAX) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ for (i = 0; i < pcrSelection->sizeOfSelect; i++) ++ grub_tpm2_buffer_unpack_u8 (buffer, &pcrSelection->pcrSelect[i]); ++} ++ ++void ++grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPML_PCR_SELECTION_t *pcrSelection) ++{ ++ grub_uint32_t i; ++ ++ grub_tpm2_buffer_unpack_u32 (buffer, &pcrSelection->count); ++ ++ if (pcrSelection->count > TPM_NUM_PCR_BANKS) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ for (i = 0; i < pcrSelection->count; i++) ++ grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (buffer, &pcrSelection->pcrSelections[i]); ++} ++ ++void ++grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPML_DIGEST_t *digest) ++{ ++ grub_uint32_t i; ++ ++ grub_tpm2_buffer_unpack_u32 (buffer, &digest->count); ++ ++ if (digest->count > 8) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ for (i = 0; i < digest->count; i++) ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &digest->digests[i]); ++} ++ ++void ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SIGNATURE_RSA_t *rsa) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash); ++ grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &rsa->sig); ++} ++ ++void ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SIGNATURE_ECC_t *ecc) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash); ++ grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureR); ++ grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureS); ++} ++ ++void ++grub_Tss2_MU_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_HASH_t hashAlg, ++ TPMU_HA_t *p) ++{ ++ switch (hashAlg) ++ { ++ case TPM_ALG_SHA1: ++ grub_tpm2_buffer_unpack (buffer, &p->sha1, TPM_SHA1_DIGEST_SIZE); ++ break; ++ case TPM_ALG_SHA256: ++ grub_tpm2_buffer_unpack (buffer, &p->sha256, TPM_SHA256_DIGEST_SIZE); ++ break; ++ case TPM_ALG_SHA384: ++ grub_tpm2_buffer_unpack (buffer, &p->sha384, TPM_SHA384_DIGEST_SIZE); ++ break; ++ case TPM_ALG_SHA512: ++ grub_tpm2_buffer_unpack (buffer, &p->sha512, TPM_SHA512_DIGEST_SIZE); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_HA_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); ++ grub_Tss2_MU_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest); ++} ++ ++void ++grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SIG_SCHEME_t sigAlg, ++ TPMU_SIGNATURE_t *p) ++{ ++ switch (sigAlg) ++ { ++ case TPM_ALG_RSASSA: ++ grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA_t *)&p->rsassa); ++ break; ++ case TPM_ALG_RSAPSS: ++ grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA_t *)&p->rsapss); ++ break; ++ case TPM_ALG_ECDSA: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->ecdsa); ++ break; ++ case TPM_ALG_ECDAA: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->ecdaa); ++ break; ++ case TPM_ALG_SM2: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->sm2); ++ break; ++ case TPM_ALG_ECSCHNORR: ++ grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->ecschnorr); ++ break; ++ case TPM_ALG_HMAC: ++ grub_Tss2_MU_TPMT_HA_Unmarshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_SIGNATURE_t *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg); ++ grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, &p->signature); ++} +diff --git a/grub-core/lib/tss2/tss2_mu.h b/grub-core/lib/tss2/tss2_mu.h +new file mode 100644 +index 000000000..8f82126e1 +--- /dev/null ++++ b/grub-core/lib/tss2/tss2_mu.h +@@ -0,0 +1,397 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_MU_HEADER ++#define GRUB_TPM2_MU_HEADER 1 ++ ++#include ++#include ++ ++extern void ++grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_AUTH_COMMAND_t *authCommand); ++ ++extern void ++grub_Tss2_MU_TPM2B_Marshal (grub_tpm2_buffer_t buffer, ++ const grub_uint16_t size, ++ const grub_uint8_t *b); ++ ++extern void ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SYM_OBJECT_t algorithm, ++ const TPMU_SYM_KEY_BITS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SYM_OBJECT_t algorithm, ++ const TPMU_SYM_MODE_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SYM_DEF_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_PCR_SELECTION_t *pcrSelection); ++ ++extern void ++grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, ++ const TPML_PCR_SELECTION_t *pcrSelection); ++ ++extern void ++grub_Tss2_MU_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMA_OBJECT_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SCHEME_XOR_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SCHEME_HMAC_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_KEYEDHASH_SCHEME_t scheme, ++ const TPMU_SCHEME_KEYEDHASH_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_KEYEDHASH_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_KEYEDHASH_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SYM_DEF_OBJECT_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_RSA_DECRYPT_t scheme, ++ const TPMU_ASYM_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_RSA_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_RSA_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SYMCIPHER_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_ECC_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_KDF_t scheme, ++ const TPMU_KDF_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_KDF_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_ECC_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const grub_uint32_t type, ++ const TPMU_PUBLIC_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_ECC_POINT_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_PUBLIC_t type, ++ const TPMU_PUBLIC_ID_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_PUBLIC_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_PUBLIC_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_PUBLIC_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SENSITIVE_CREATE_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_SENSITIVE_CREATE_t *sensitiveCreate); ++ ++extern void ++grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_PUBLIC_t type, ++ const TPMU_SENSITIVE_COMPOSITE_t *p); ++extern void ++grub_Tss2_MU_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SENSITIVE_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_SENSITIVE_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SIGNATURE_RSA_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SIGNATURE_ECC_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_HASH_t hashAlg, ++ const TPMU_HA_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_HA_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SIG_SCHEME_t sigAlg, ++ const TPMU_SIGNATURE_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SIGNATURE_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_TK_VERIFIED_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_AUTH_RESPONSE_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_DIGEST_t *digest); ++ ++extern void ++grub_Tss2_MU_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NONCE_t *nonce); ++ ++extern void ++grub_Tss2_MU_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_DATA_t *data); ++ ++extern void ++grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_CREATION_DATA_t *data); ++ ++extern void ++grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_CREATION_DATA_t *data); ++ ++extern void ++grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PRIVATE_t *private); ++ ++extern void ++grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_SENSITIVE_DATA_t *data); ++ ++extern void ++grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PUBLIC_KEY_RSA_t *rsa); ++ ++extern void ++grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_ECC_PARAMETER_t *param); ++ ++extern void ++grub_Tss2_MU_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMA_OBJECT_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SCHEME_HMAC_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SCHEME_XOR_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_KEYEDHASH_SCHEME_t scheme, ++ TPMU_SCHEME_KEYEDHASH_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_KEYEDHASH_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_KEYEDHASH_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SYM_OBJECT_t algorithm, ++ TPMU_SYM_KEY_BITS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SYM_OBJECT_t algorithm, ++ TPMU_SYM_MODE_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_SYM_DEF_OBJECT_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SYMCIPHER_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_RSA_DECRYPT_t scheme, ++ TPMU_ASYM_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_RSA_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_RSA_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_ECC_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_KDF_t scheme, ++ TPMU_KDF_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_KDF_SCHEME_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_ECC_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ grub_uint32_t type, ++ TPMU_PUBLIC_PARMS_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_ECC_POINT_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_PUBLIC_t type, ++ TPMU_PUBLIC_ID_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_PUBLIC_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PUBLIC_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_NV_PUBLIC_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NV_PUBLIC_t *p); ++ ++extern void ++grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NAME_t *n); ++ ++extern void ++grub_Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_TAGGED_PROPERTY_t *property); ++ ++extern void ++grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_CREATION_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_HASHCHECK_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_VERIFIED_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_PCR_SELECTION_t *pcrSelection); ++ ++extern void ++grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPML_PCR_SELECTION_t *pcrSelection); ++ ++extern void ++grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPML_DIGEST_t *digest); ++ ++extern void ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SIGNATURE_RSA_t *p); ++ ++extern void ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SIGNATURE_ECC_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_HASH_t hashAlg, ++ TPMU_HA_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_HA_t *p); ++ ++extern void ++grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SIG_SCHEME_t sigAlg, ++ TPMU_SIGNATURE_t *p); ++ ++extern void ++grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_SIGNATURE_t *p); ++ ++#endif /* ! GRUB_TPM2_MU_HEADER */ +diff --git a/grub-core/lib/tss2/tss2_structs.h b/grub-core/lib/tss2/tss2_structs.h +new file mode 100644 +index 000000000..798cd45df +--- /dev/null ++++ b/grub-core/lib/tss2/tss2_structs.h +@@ -0,0 +1,796 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_INTERNAL_STRUCTS_HEADER ++#define GRUB_TPM2_INTERNAL_STRUCTS_HEADER 1 ++ ++#include ++ ++/* ++ * TPM response header ++ * This struct is used to calculate the minimum size of the TPM 2.0 response. ++ * The format of the response: ++ * ++ * +----------------------+ ++ * | UINT16 tag | ++ * +----------------------+ ++ * | UINT32 repsonse_size | ++ * +----------------------+ ++ * | UINT32 response_code | ++ * +======================+ ++ * | response_data | (optional) ++ * +======================+ ++ */ ++struct __attribute__ ((__packed__)) TPM_RESPONSE_HEADER ++{ ++ grub_uint16_t tag; ++ grub_uint32_t response_size; ++ TPM_RC_t response_code; ++}; ++typedef struct TPM_RESPONSE_HEADER TPM_RESPONSE_HEADER_t; ++ ++/* TPMS_TAGGED_PROPERTY Structure */ ++struct TPMS_TAGGED_PROPERTY ++{ ++ TPM_PT_t property; ++ grub_uint32_t value; ++}; ++typedef struct TPMS_TAGGED_PROPERTY TPMS_TAGGED_PROPERTY_t; ++ ++/* TPML_TAGGED_TPM_PROPERTY Structure */ ++struct TPML_TAGGED_TPM_PROPERTY ++{ ++ grub_uint32_t count; ++ TPMS_TAGGED_PROPERTY_t tpmProperty[TPM_MAX_TPM_PROPERTIES]; ++}; ++typedef struct TPML_TAGGED_TPM_PROPERTY TPML_TAGGED_TPM_PROPERTY_t; ++ ++/* TPMU_CAPABILITIES Structure */ ++union TPMU_CAPABILITIES ++{ ++ TPML_TAGGED_TPM_PROPERTY_t tpmProperties; ++}; ++typedef union TPMU_CAPABILITIES TPMU_CAPABILITIES_t; ++ ++/* TPMS_CAPABILITY_DATA Structure */ ++struct TPMS_CAPABILITY_DATA ++{ ++ TPM_CAP_t capability; ++ TPMU_CAPABILITIES_t data; ++}; ++typedef struct TPMS_CAPABILITY_DATA TPMS_CAPABILITY_DATA_t; ++ ++/* TPMS_PCR_SELECT Structure */ ++struct TPMS_PCR_SELECT ++{ ++ grub_uint8_t sizeOfSelect; ++ grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; ++}; ++typedef struct TPMS_PCR_SELECT TPMS_PCR_SELECT_t; ++ ++/* TPMS_PCR_SELECTION Structure */ ++struct TPMS_PCR_SELECTION ++{ ++ TPMI_ALG_HASH_t hash; ++ grub_uint8_t sizeOfSelect; ++ grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; ++}; ++typedef struct TPMS_PCR_SELECTION TPMS_PCR_SELECTION_t; ++ ++static inline void TPMS_PCR_SELECTION_SelectPCR(TPMS_PCR_SELECTION_t *self, grub_uint32_t n) ++{ ++ self->pcrSelect[(n / 8)] |= (1 << (n % 8)); ++} ++ ++/* TPML_PCR_SELECTION Structure */ ++struct TPML_PCR_SELECTION ++{ ++ grub_uint32_t count; ++ TPMS_PCR_SELECTION_t pcrSelections[TPM_NUM_PCR_BANKS]; ++}; ++typedef struct TPML_PCR_SELECTION TPML_PCR_SELECTION_t; ++ ++/* TPMU_HA Structure */ ++union TPMU_HA ++{ ++ grub_uint8_t sha1[TPM_SHA1_DIGEST_SIZE]; ++ grub_uint8_t sha256[TPM_SHA256_DIGEST_SIZE]; ++ grub_uint8_t sha384[TPM_SHA384_DIGEST_SIZE]; ++ grub_uint8_t sha512[TPM_SHA512_DIGEST_SIZE]; ++ grub_uint8_t sm3_256[TPM_SM3_256_DIGEST_SIZE]; ++}; ++typedef union TPMU_HA TPMU_HA_t; ++ ++/* TPM2B Structure */ ++struct TPM2B ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[1]; ++}; ++typedef struct TPM2B TPM2B_t; ++ ++/* TPM2B_DIGEST Structure */ ++struct TPM2B_DIGEST ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[sizeof(TPMU_HA_t)]; ++}; ++typedef struct TPM2B_DIGEST TPM2B_DIGEST_t; ++ ++/* TPML_DIGEST Structure */ ++struct TPML_DIGEST ++{ ++ grub_uint32_t count; ++ TPM2B_DIGEST_t digests[8]; ++}; ++typedef struct TPML_DIGEST TPML_DIGEST_t; ++ ++/* TPM2B_NONCE Type */ ++typedef TPM2B_DIGEST_t TPM2B_NONCE_t; ++ ++/* TPMA_SESSION Structure */ ++struct TPMA_SESSION ++{ ++ grub_uint8_t continueSession:1; ++ grub_uint8_t auditExclusive:1; ++ grub_uint8_t auditReset:1; ++ grub_uint8_t reserved:2; ++ grub_uint8_t decrypt:1; ++ grub_uint8_t encrypt:1; ++ grub_uint8_t audit:1; ++}; ++typedef struct TPMA_SESSION TPMA_SESSION_t; ++ ++/* TPM2B_AUTH Type */ ++typedef TPM2B_DIGEST_t TPM2B_AUTH_t; ++ ++/* TPMS_AUTH_COMMAND Structure */ ++struct TPMS_AUTH_COMMAND ++{ ++ TPMI_SH_AUTH_SESSION_t sessionHandle; ++ TPM2B_NONCE_t nonce; ++ TPMA_SESSION_t sessionAttributes; ++ TPM2B_AUTH_t hmac; ++}; ++typedef struct TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND_t; ++ ++/* TPMS_AUTH_RESPONSE Structure */ ++struct TPMS_AUTH_RESPONSE ++{ ++ TPM2B_NONCE_t nonce; ++ TPMA_SESSION_t sessionAttributes; ++ TPM2B_AUTH_t hmac; ++}; ++typedef struct TPMS_AUTH_RESPONSE TPMS_AUTH_RESPONSE_t; ++ ++/* TPM2B_SENSITIVE_DATA Structure */ ++struct TPM2B_SENSITIVE_DATA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_SYM_DATA]; ++}; ++typedef struct TPM2B_SENSITIVE_DATA TPM2B_SENSITIVE_DATA_t; ++ ++/* TPMS_SENSITIVE_CREATE Structure */ ++struct TPMS_SENSITIVE_CREATE ++{ ++ TPM2B_AUTH_t userAuth; ++ TPM2B_SENSITIVE_DATA_t data; ++}; ++typedef struct TPMS_SENSITIVE_CREATE TPMS_SENSITIVE_CREATE_t; ++ ++/* TPM2B_SENSITIVE_CREATE Structure */ ++struct TPM2B_SENSITIVE_CREATE ++{ ++ grub_uint16_t size; ++ TPMS_SENSITIVE_CREATE_t sensitive; ++}; ++typedef struct TPM2B_SENSITIVE_CREATE TPM2B_SENSITIVE_CREATE_t; ++ ++/* TPMA_OBJECT Structure */ ++struct TPMA_OBJECT ++{ ++ grub_uint32_t reserved1:1; ++ grub_uint32_t fixedTPM:1; ++ grub_uint32_t stClear:1; ++ grub_uint32_t reserved2:1; ++ grub_uint32_t fixedParent:1; ++ grub_uint32_t sensitiveDataOrigin:1; ++ grub_uint32_t userWithAuth:1; ++ grub_uint32_t adminWithPolicy:1; ++ grub_uint32_t reserved3:2; ++ grub_uint32_t noDA:1; ++ grub_uint32_t encryptedDuplication:1; ++ grub_uint32_t reserved4:4; ++ grub_uint32_t restricted:1; ++ grub_uint32_t decrypt:1; ++ grub_uint32_t sign:1; ++ grub_uint32_t reserved5:13; ++}; ++typedef struct TPMA_OBJECT TPMA_OBJECT_t; ++ ++/* TPMS_SCHEME_HASH Structure */ ++struct TPMS_SCHEME_HASH ++{ ++ TPMI_ALG_HASH_t hashAlg; ++}; ++typedef struct TPMS_SCHEME_HASH TPMS_SCHEME_HASH_t; ++ ++/* TPMS_SCHEME_HASH Types */ ++typedef TPMS_SCHEME_HASH_t TPMS_KEY_SCHEME_ECDH_t; ++typedef TPMS_SCHEME_HASH_t TPMS_KEY_SCHEME_ECMQV_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_RSASSA_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_RSAPSS_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_ECDSA_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_ECDAA_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_SM2_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_ECSCHNORR_t; ++typedef TPMS_SCHEME_HASH_t TPMS_ENC_SCHEME_RSAES_t; ++typedef TPMS_SCHEME_HASH_t TPMS_ENC_SCHEME_OAEP_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF2_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_MGF1_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF1_SP800_56A_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF2_t; ++typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF1_SP800_108_t; ++ ++/* TPMS_SCHEME_HMAC Type */ ++typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_HMAC_t; ++ ++/* TPMS_SCHEME_XOR Structure */ ++struct TPMS_SCHEME_XOR ++{ ++ TPMI_ALG_HASH_t hashAlg; ++ TPMI_ALG_KDF_t kdf; ++}; ++typedef struct TPMS_SCHEME_XOR TPMS_SCHEME_XOR_t; ++ ++/* TPMU_SCHEME_KEYEDHASH Union */ ++union TPMU_SCHEME_KEYEDHASH ++{ ++ TPMS_SCHEME_HMAC_t hmac; ++ TPMS_SCHEME_XOR_t exclusiveOr; ++}; ++typedef union TPMU_SCHEME_KEYEDHASH TPMU_SCHEME_KEYEDHASH_t; ++ ++/* TPMT_KEYEDHASH_SCHEME Structure */ ++struct TPMT_KEYEDHASH_SCHEME ++{ ++ TPMI_ALG_KEYEDHASH_SCHEME_t scheme; ++ TPMU_SCHEME_KEYEDHASH_t details; ++}; ++typedef struct TPMT_KEYEDHASH_SCHEME TPMT_KEYEDHASH_SCHEME_t; ++ ++/* TPMS_KEYEDHASH_PARMS Structure */ ++struct TPMS_KEYEDHASH_PARMS ++{ ++ TPMT_KEYEDHASH_SCHEME_t scheme; ++}; ++typedef struct TPMS_KEYEDHASH_PARMS TPMS_KEYEDHASH_PARMS_t; ++ ++/* TPMU_SYM_KEY_BITS Union */ ++union TPMU_SYM_KEY_BITS ++{ ++ TPM_KEY_BITS_t aes; ++ TPM_KEY_BITS_t exclusiveOr; ++ TPM_KEY_BITS_t sm4; ++ TPM_KEY_BITS_t camellia; ++}; ++typedef union TPMU_SYM_KEY_BITS TPMU_SYM_KEY_BITS_t; ++ ++/* TPMU_SYM_MODE Union */ ++union TPMU_SYM_MODE ++{ ++ TPMI_ALG_SYM_MODE_t aes; ++ TPMI_ALG_SYM_MODE_t sm4; ++ TPMI_ALG_SYM_MODE_t camellia; ++ TPMI_ALG_SYM_MODE_t sym; ++}; ++typedef union TPMU_SYM_MODE TPMU_SYM_MODE_t; ++ ++/* TPMT_SYM_DEF_OBJECT Structure */ ++struct TPMT_SYM_DEF_OBJECT ++{ ++ TPMI_ALG_SYM_OBJECT_t algorithm; ++ TPMU_SYM_KEY_BITS_t keyBits; ++ TPMU_SYM_MODE_t mode; ++}; ++typedef struct TPMT_SYM_DEF_OBJECT TPMT_SYM_DEF_OBJECT_t; ++ ++/* TPMS_SYMCIPHER_PARMS Structure */ ++struct TPMS_SYMCIPHER_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT_t sym; ++}; ++typedef struct TPMS_SYMCIPHER_PARMS TPMS_SYMCIPHER_PARMS_t; ++ ++/* TPMU_ASYM_SCHEME Union */ ++union TPMU_ASYM_SCHEME ++{ ++ TPMS_KEY_SCHEME_ECDH_t ecdh; ++ TPMS_KEY_SCHEME_ECMQV_t ecmqv; ++ TPMS_SIG_SCHEME_RSASSA_t rsassa; ++ TPMS_SIG_SCHEME_RSAPSS_t rsapss; ++ TPMS_SIG_SCHEME_ECDSA_t ecdsa; ++ TPMS_SIG_SCHEME_ECDAA_t ecdaa; ++ TPMS_SIG_SCHEME_SM2_t sm2; ++ TPMS_SIG_SCHEME_ECSCHNORR_t ecschnorr; ++ TPMS_ENC_SCHEME_RSAES_t rsaes; ++ TPMS_ENC_SCHEME_OAEP_t oaep; ++ TPMS_SCHEME_HASH_t anySig; ++ unsigned char padding[4]; ++}; ++typedef union TPMU_ASYM_SCHEME TPMU_ASYM_SCHEME_t; ++ ++/* TPMT_RSA_SCHEME Structure */ ++struct TPMT_RSA_SCHEME ++{ ++ TPMI_ALG_RSA_SCHEME_t scheme; ++ TPMU_ASYM_SCHEME_t details; ++}; ++typedef struct TPMT_RSA_SCHEME TPMT_RSA_SCHEME_t; ++ ++/* TPMS_RSA_PARMS Structure */ ++struct TPMS_RSA_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT_t symmetric; ++ TPMT_RSA_SCHEME_t scheme; ++ TPM_KEY_BITS_t keyBits; ++ grub_uint32_t exponent; ++}; ++typedef struct TPMS_RSA_PARMS TPMS_RSA_PARMS_t; ++ ++/* TPMT_ECC_SCHEME Structure */ ++struct TPMT_ECC_SCHEME ++{ ++ TPMI_ALG_ECC_SCHEME_t scheme; ++ TPMU_ASYM_SCHEME_t details; ++}; ++typedef struct TPMT_ECC_SCHEME TPMT_ECC_SCHEME_t; ++ ++/* TPMU_KDF_SCHEME Union */ ++union TPMU_KDF_SCHEME ++{ ++ TPMS_SCHEME_MGF1_t mgf1; ++ TPMS_SCHEME_KDF1_SP800_56A_t kdf1_sp800_56a; ++ TPMS_SCHEME_KDF2_t kdf2; ++ TPMS_SCHEME_KDF1_SP800_108_t kdf1_sp800_108; ++}; ++typedef union TPMU_KDF_SCHEME TPMU_KDF_SCHEME_t; ++ ++/* TPMT_KDF_SCHEME Structure */ ++struct TPMT_KDF_SCHEME ++{ ++ TPMI_ALG_KDF_t scheme; ++ TPMU_KDF_SCHEME_t details; ++}; ++typedef struct TPMT_KDF_SCHEME TPMT_KDF_SCHEME_t; ++ ++/* TPMS_ECC_PARMS Structure */ ++struct TPMS_ECC_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT_t symmetric; ++ TPMT_ECC_SCHEME_t scheme; ++ TPMI_ECC_CURVE_t curveID; ++ TPMT_KDF_SCHEME_t kdf; ++}; ++typedef struct TPMS_ECC_PARMS TPMS_ECC_PARMS_t; ++ ++/* TPMT_ASYM_SCHEME Structure */ ++struct TPMT_ASYM_SCHEME ++{ ++ TPMI_ALG_ASYM_SCHEME_t scheme; ++ TPMU_ASYM_SCHEME_t details; ++}; ++typedef struct TPMT_ASYM_SCHEME TPMT_ASYM_SCHEME_t; ++ ++/* TPMS_ASYM_PARMS Structure */ ++struct TPMS_ASYM_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT_t symmetric; ++ TPMT_ASYM_SCHEME_t scheme; ++}; ++typedef struct TPMS_ASYM_PARMS TPMS_ASYM_PARMS_t; ++ ++/* TPMU_PUBLIC_PARMS Union */ ++union TPMU_PUBLIC_PARMS ++{ ++ TPMS_KEYEDHASH_PARMS_t keyedHashDetail; ++ TPMS_SYMCIPHER_PARMS_t symDetail; ++ TPMS_RSA_PARMS_t rsaDetail; ++ TPMS_ECC_PARMS_t eccDetail; ++ TPMS_ASYM_PARMS_t asymDetail; ++}; ++typedef union TPMU_PUBLIC_PARMS TPMU_PUBLIC_PARMS_t; ++ ++/* TPMT_PUBLIC_PARMS Structure */ ++struct TPMT_PUBLIC_PARMS { ++ TPMI_ALG_PUBLIC_t type; ++ TPMU_PUBLIC_PARMS_t parameters; ++}; ++typedef struct TPMT_PUBLIC_PARMS TPMT_PUBLIC_PARMS_t; ++ ++/* TPM2B_PUBLIC_KEY_RSA Structure */ ++struct TPM2B_PUBLIC_KEY_RSA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES]; ++}; ++typedef struct TPM2B_PUBLIC_KEY_RSA TPM2B_PUBLIC_KEY_RSA_t; ++ ++/* TPM2B_ECC_PARAMETER Structure */ ++struct TPM2B_ECC_PARAMETER ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_ECC_KEY_BYTES]; ++}; ++typedef struct TPM2B_ECC_PARAMETER TPM2B_ECC_PARAMETER_t; ++ ++/* TPMS_ECC_POINT Structure */ ++struct TPMS_ECC_POINT ++{ ++ TPM2B_ECC_PARAMETER_t x; ++ TPM2B_ECC_PARAMETER_t y; ++}; ++typedef struct TPMS_ECC_POINT TPMS_ECC_POINT_t; ++ ++/* TPMU_ENCRYPTED_SECRET Union */ ++union TPMU_ENCRYPTED_SECRET ++{ ++ grub_uint8_t ecc[sizeof(TPMS_ECC_POINT_t)]; ++ grub_uint8_t rsa[TPM_MAX_RSA_KEY_BYTES]; ++ grub_uint8_t symmetric[sizeof(TPM2B_DIGEST_t)]; ++ grub_uint8_t keyedHash[sizeof(TPM2B_DIGEST_t)]; ++}; ++typedef union TPMU_ENCRYPTED_SECRET TPMU_ENCRYPTED_SECRET_t; ++ ++/* TPM2B_ENCRYPTED_SECRET Structure */ ++struct TPM2B_ENCRYPTED_SECRET ++{ ++ grub_uint16_t size; ++ grub_uint8_t secret[sizeof(TPMU_ENCRYPTED_SECRET_t)]; ++}; ++typedef struct TPM2B_ENCRYPTED_SECRET TPM2B_ENCRYPTED_SECRET_t; ++ ++/* TPMU_PUBLIC_ID Union */ ++union TPMU_PUBLIC_ID ++{ ++ TPM2B_DIGEST_t keyedHash; ++ TPM2B_DIGEST_t sym; ++ TPM2B_PUBLIC_KEY_RSA_t rsa; ++ TPMS_ECC_POINT_t ecc; ++}; ++typedef union TPMU_PUBLIC_ID TPMU_PUBLIC_ID_t; ++ ++/* TPMT_PUBLIC Structure */ ++struct TPMT_PUBLIC ++{ ++ TPMI_ALG_PUBLIC_t type; ++ TPMI_ALG_HASH_t nameAlg; ++ TPMA_OBJECT_t objectAttributes; ++ TPM2B_DIGEST_t authPolicy; ++ TPMU_PUBLIC_PARMS_t parameters; ++ TPMU_PUBLIC_ID_t unique; ++}; ++typedef struct TPMT_PUBLIC TPMT_PUBLIC_t; ++ ++/* TPM2B_PUBLIC Structure */ ++struct TPM2B_PUBLIC ++{ ++ grub_uint16_t size; ++ TPMT_PUBLIC_t publicArea; ++}; ++typedef struct TPM2B_PUBLIC TPM2B_PUBLIC_t; ++ ++/* TPMT_HA Structure */ ++struct TPMT_HA ++{ ++ TPMI_ALG_HASH_t hashAlg; ++ TPMU_HA_t digest; ++}; ++typedef struct TPMT_HA TPMT_HA_t; ++ ++/* TPM2B_DATA Structure */ ++struct TPM2B_DATA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[sizeof(TPMT_HA_t)]; ++}; ++typedef struct TPM2B_DATA TPM2B_DATA_t; ++ ++/* TPMA_LOCALITY Structure */ ++struct TPMA_LOCALITY ++{ ++ grub_uint8_t TPM_LOC_ZERO:1; ++ grub_uint8_t TPM_LOC_ONE:1; ++ grub_uint8_t TPM_LOC_TWO:1; ++ grub_uint8_t TPM_LOC_THREE:1; ++ grub_uint8_t TPM_LOC_FOUR:1; ++ grub_uint8_t Extended:3; ++}; ++typedef struct TPMA_LOCALITY TPMA_LOCALITY_t; ++ ++/* TPMU_NAME Union */ ++union TPMU_NAME ++{ ++ TPMT_HA_t digest; ++ TPM_HANDLE_t handle; ++}; ++typedef union TPMU_NAME TPMU_NAME_t; ++ ++/* TPM2B_NAME Structure */ ++struct TPM2B_NAME ++{ ++ grub_uint16_t size; ++ grub_uint8_t name[sizeof(TPMU_NAME_t)]; ++}; ++typedef struct TPM2B_NAME TPM2B_NAME_t; ++ ++/* TPMS_CREATION_DATA Structure */ ++struct TPMS_CREATION_DATA ++{ ++ TPML_PCR_SELECTION_t pcrSelect; ++ TPM2B_DIGEST_t pcrDigest; ++ TPMA_LOCALITY_t locality; ++ TPM_ALG_ID_t parentNameAlg; ++ TPM2B_NAME_t parentName; ++ TPM2B_NAME_t parentQualifiedName; ++ TPM2B_DATA_t outsideInfo; ++}; ++typedef struct TPMS_CREATION_DATA TPMS_CREATION_DATA_t; ++ ++/* TPM2B_CREATION_DATA Structure */ ++struct TPM2B_CREATION_DATA ++{ ++ grub_uint16_t size; ++ TPMS_CREATION_DATA_t creationData; ++}; ++typedef struct TPM2B_CREATION_DATA TPM2B_CREATION_DATA_t; ++ ++/* TPMT_SYM_DEF Structure */ ++struct TPMT_SYM_DEF ++{ ++ TPMI_ALG_SYM_t algorithm; ++ TPMU_SYM_KEY_BITS_t keyBits; ++ TPMU_SYM_MODE_t mode; ++}; ++typedef struct TPMT_SYM_DEF TPMT_SYM_DEF_t; ++ ++/* TPM2B_MAX_BUFFER Structure */ ++struct TPM2B_MAX_BUFFER ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_DIGEST_BUFFER]; ++}; ++typedef struct TPM2B_MAX_BUFFER TPM2B_MAX_BUFFER_t; ++ ++/* TPMT_TK_HASHCHECK Structure */ ++struct TPMT_TK_HASHCHECK ++{ ++ TPM_ST_t tag; ++ TPMI_RH_HIERARCHY_t hierarchy; ++ TPM2B_DIGEST_t digest; ++}; ++typedef struct TPMT_TK_HASHCHECK TPMT_TK_HASHCHECK_t; ++ ++/* TPM2B_SYM_KEY Structure */ ++struct TPM2B_SYM_KEY ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_SYM_KEY_BYTES]; ++}; ++typedef struct TPM2B_SYM_KEY TPM2B_SYM_KEY_t; ++ ++/* TPM2B_PRIVATE_KEY_RSA Structure */ ++struct TPM2B_PRIVATE_KEY_RSA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES/2]; ++}; ++typedef struct TPM2B_PRIVATE_KEY_RSA TPM2B_PRIVATE_KEY_RSA_t; ++ ++/* TPM2B_PRIVATE_VENDOR_SPECIFIC Structure */ ++struct TPM2B_PRIVATE_VENDOR_SPECIFIC ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_PRIVATE_VENDOR_SPECIFIC_BYTES]; ++}; ++typedef struct TPM2B_PRIVATE_VENDOR_SPECIFIC TPM2B_PRIVATE_VENDOR_SPECIFIC_t; ++ ++/* TPM2B_PRIVATE_VENDOR_SPECIFIC Union */ ++union TPMU_SENSITIVE_COMPOSITE ++{ ++ TPM2B_PRIVATE_KEY_RSA_t rsa; ++ TPM2B_ECC_PARAMETER_t ecc; ++ TPM2B_SENSITIVE_DATA_t bits; ++ TPM2B_SYM_KEY_t sym; ++ TPM2B_PRIVATE_VENDOR_SPECIFIC_t any; ++}; ++typedef union TPMU_SENSITIVE_COMPOSITE TPMU_SENSITIVE_COMPOSITE_t; ++ ++/* TPMT_SENSITIVE Structure */ ++struct TPMT_SENSITIVE ++{ ++ TPMI_ALG_PUBLIC_t sensitiveType; ++ TPM2B_AUTH_t authValue; ++ TPM2B_DIGEST_t seedValue; ++ TPMU_SENSITIVE_COMPOSITE_t sensitive; ++}; ++typedef struct TPMT_SENSITIVE TPMT_SENSITIVE_t; ++ ++/* TPM2B_SENSITIVE Structure */ ++struct TPM2B_SENSITIVE ++{ ++ grub_uint16_t size; ++ TPMT_SENSITIVE_t sensitiveArea; ++}; ++typedef struct TPM2B_SENSITIVE TPM2B_SENSITIVE_t; ++ ++/* ++ * _PRIVATE Structure ++ * ++ * Although '_PRIVATE' is the name defined in the TPM2 SPEC, it is too generic, ++ * so here we add the '__TPM2B' prefix to make the struct specific for 'TPM2B_PRIVATE'. ++ */ ++struct __TPM2B_PRIVATE ++{ ++ TPM2B_DIGEST_t integrityOuter; ++ TPM2B_DIGEST_t integrityInner; ++ TPM2B_SENSITIVE_t sensitive; ++}; ++typedef struct __TPM2B_PRIVATE __TPM2B_PRIVATE_t; ++ ++/* TPM2B_PRIVATE Structure */ ++struct TPM2B_PRIVATE ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[sizeof(__TPM2B_PRIVATE_t)]; ++}; ++typedef struct TPM2B_PRIVATE TPM2B_PRIVATE_t; ++ ++/* TPML_DIGEST_VALUES Structure */ ++struct TPML_DIGEST_VALUES ++{ ++ grub_uint16_t count; ++ TPMT_HA_t digests[TPM_NUM_PCR_BANKS]; ++}; ++typedef struct TPML_DIGEST_VALUES TPML_DIGEST_VALUES_t; ++ ++/* TPM2B_MAX_NV_BUFFER Structure */ ++struct TPM2B_MAX_NV_BUFFER ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_NV_BUFFER_SIZE]; ++}; ++typedef struct TPM2B_MAX_NV_BUFFER TPM2B_MAX_NV_BUFFER_t; ++ ++/* TPMS_NV_PUBLIC Structure */ ++struct TPMS_NV_PUBLIC ++{ ++ TPMI_RH_NV_INDEX_t nvIndex; ++ TPMI_ALG_HASH_t nameAlg; ++ TPMA_NV_t attributes; ++ TPM2B_DIGEST_t authPolicy; ++ grub_uint16_t dataSize; ++}; ++typedef struct TPMS_NV_PUBLIC TPMS_NV_PUBLIC_t; ++ ++/* TPM2B_NV_PUBLIC Structure */ ++struct TPM2B_NV_PUBLIC ++{ ++ grub_uint16_t size; ++ TPMS_NV_PUBLIC_t nvPublic; ++}; ++typedef struct TPM2B_NV_PUBLIC TPM2B_NV_PUBLIC_t; ++ ++/* TPMT_TK_CREATION Structure */ ++struct TPMT_TK_CREATION ++{ ++ TPM_ST_t tag; ++ TPMI_RH_HIERARCHY_t hierarchy; ++ TPM2B_DIGEST_t digest; ++}; ++typedef struct TPMT_TK_CREATION TPMT_TK_CREATION_t; ++ ++/* TPMS_EMPTY Structure */ ++struct TPMS_EMPTY { ++ grub_uint8_t empty[1]; /* a structure with no member */ ++}; ++typedef struct TPMS_EMPTY TPMS_EMPTY_t; ++ ++/* TPMS_SIGNATURE_RSA Structure */ ++struct TPMS_SIGNATURE_RSA { ++ TPMI_ALG_HASH_t hash; ++ TPM2B_PUBLIC_KEY_RSA_t sig; ++}; ++typedef struct TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSA_t; ++ ++/* Definition of Types for RSA Signature */ ++typedef TPMS_SIGNATURE_RSA_t TPMS_SIGNATURE_RSASSA_t; ++typedef TPMS_SIGNATURE_RSA_t TPMS_SIGNATURE_RSAPSS_t; ++ ++/* TPMS_SIGNATURE_ECC Structure */ ++struct TPMS_SIGNATURE_ECC { ++ TPMI_ALG_HASH_t hash; ++ TPM2B_ECC_PARAMETER_t signatureR; ++ TPM2B_ECC_PARAMETER_t signatureS; ++}; ++typedef struct TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECC_t; ++ ++/* Definition of Types for ECC TPMS_SIGNATURE_ECC */ ++typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_ECDSA_t; ++typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_ECDAA_t; ++typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_SM2_t; ++typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_ECSCHNORR_t; ++ ++/* TPMU_SIGNATURE Structure */ ++union TPMU_SIGNATURE { ++ TPMS_SIGNATURE_RSASSA_t rsassa; ++ TPMS_SIGNATURE_RSAPSS_t rsapss; ++ TPMS_SIGNATURE_ECDSA_t ecdsa; ++ TPMS_SIGNATURE_ECDAA_t ecdaa; ++ TPMS_SIGNATURE_SM2_t sm2; ++ TPMS_SIGNATURE_ECSCHNORR_t ecschnorr; ++ TPMT_HA_t hmac; ++ TPMS_SCHEME_HASH_t any; ++ TPMS_EMPTY_t null; ++}; ++typedef union TPMU_SIGNATURE TPMU_SIGNATURE_t; ++ ++/* TPMT_SIGNATURE Structure */ ++struct TPMT_SIGNATURE { ++ TPMI_ALG_SIG_SCHEME_t sigAlg; ++ TPMU_SIGNATURE_t signature; ++}; ++typedef struct TPMT_SIGNATURE TPMT_SIGNATURE_t; ++ ++static inline TPMI_ALG_HASH_t ++TPMT_SIGNATURE_get_hash_alg (TPMT_SIGNATURE_t *sig) ++{ ++ switch (sig->sigAlg) ++ { ++ case TPM_ALG_RSASSA: ++ return sig->signature.rsassa.hash; ++ case TPM_ALG_RSAPSS: ++ return sig->signature.rsapss.hash; ++ case TPM_ALG_ECDSA: ++ return sig->signature.ecdsa.hash; ++ case TPM_ALG_ECDAA: ++ return sig->signature.ecdaa.hash; ++ case TPM_ALG_SM2: ++ return sig->signature.sm2.hash; ++ case TPM_ALG_ECSCHNORR: ++ return sig->signature.ecschnorr.hash; ++ case TPM_ALG_HMAC: ++ return sig->signature.hmac.hashAlg; ++ default: ++ break; ++ } ++ ++ return TPM_ALG_NULL; ++} ++ ++/* TPMT_TK_VERIFIED Structure */ ++struct TPMT_TK_VERIFIED { ++ TPM_ST_t tag; ++ TPMI_RH_HIERARCHY_t hierarchy; ++ TPM2B_DIGEST_t digest; ++}; ++typedef struct TPMT_TK_VERIFIED TPMT_TK_VERIFIED_t; ++ ++#endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */ +diff --git a/grub-core/lib/tss2/tss2_types.h b/grub-core/lib/tss2/tss2_types.h +new file mode 100644 +index 000000000..5b1a7947d +--- /dev/null ++++ b/grub-core/lib/tss2/tss2_types.h +@@ -0,0 +1,404 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_INTERNAL_TYPES_HEADER ++#define GRUB_TPM2_INTERNAL_TYPES_HEADER 1 ++ ++#include ++ ++/* TPM2_RC Constants */ ++typedef grub_uint32_t TPM_RC_t; ++ ++#define TPM_RC_1 ((TPM_RC_t) 0x100) ++#define TPM_RC_2 ((TPM_RC_t) 0x200) ++#define TPM_RC_3 ((TPM_RC_t) 0x300) ++#define TPM_RC_4 ((TPM_RC_t) 0x400) ++#define TPM_RC_5 ((TPM_RC_t) 0x500) ++#define TPM_RC_6 ((TPM_RC_t) 0x600) ++#define TPM_RC_7 ((TPM_RC_t) 0x700) ++#define TPM_RC_8 ((TPM_RC_t) 0x800) ++#define TPM_RC_9 ((TPM_RC_t) 0x900) ++#define TPM_RC_A ((TPM_RC_t) 0xA00) ++#define TPM_RC_ASYMMETRIC ((TPM_RC_t) 0x081) ++#define TPM_RC_ATTRIBUTES ((TPM_RC_t) 0x082) ++#define TPM_RC_AUTH_CONTEXT ((TPM_RC_t) 0x145) ++#define TPM_RC_AUTH_FAIL ((TPM_RC_t) 0x08E) ++#define TPM_RC_AUTH_MISSING ((TPM_RC_t) 0x125) ++#define TPM_RC_AUTHSIZE ((TPM_RC_t) 0x144) ++#define TPM_RC_AUTH_TYPE ((TPM_RC_t) 0x124) ++#define TPM_RC_AUTH_UNAVAILABLE ((TPM_RC_t) 0x12F) ++#define TPM_RC_B ((TPM_RC_t) 0xB00) ++#define TPM_RC_BAD_AUTH ((TPM_RC_t) 0x0A2) ++#define TPM_RC_BAD_CONTEXT ((TPM_RC_t) 0x150) ++#define TPM_RC_BAD_TAG ((TPM_RC_t) 0x01E) ++#define TPM_RC_BINDING ((TPM_RC_t) 0x0A5) ++#define TPM_RC_C ((TPM_RC_t) 0xC00) ++#define TPM_RC_CANCELED ((TPM_RC_t) 0x909) ++#define TPM_RC_COMMAND_CODE ((TPM_RC_t) 0x143) ++#define TPM_RC_COMMAND_SIZE ((TPM_RC_t) 0x142) ++#define TPM_RC_CONTEXT_GAP ((TPM_RC_t) 0x901) ++#define TPM_RC_CPHASH ((TPM_RC_t) 0x151) ++#define TPM_RC_CURVE ((TPM_RC_t) 0x0A6) ++#define TPM_RC_D ((TPM_RC_t) 0xD00) ++#define TPM_RC_DISABLED ((TPM_RC_t) 0x120) ++#define TPM_RC_E ((TPM_RC_t) 0xE00) ++#define TPM_RC_ECC_POINT ((TPM_RC_t) 0x0A7) ++#define TPM_RC_EXCLUSIVE ((TPM_RC_t) 0x121) ++#define TPM_RC_EXPIRED ((TPM_RC_t) 0x0A3) ++#define TPM_RC_F ((TPM_RC_t) 0xF00) ++#define TPM_RC_FAILURE ((TPM_RC_t) 0x101) ++#define TPM_RC_H ((TPM_RC_t) 0x000) ++#define TPM_RC_HANDLE ((TPM_RC_t) 0x08B) ++#define TPM_RC_HASH ((TPM_RC_t) 0x083) ++#define TPM_RC_HIERARCHY ((TPM_RC_t) 0x085) ++#define TPM_RC_HMAC ((TPM_RC_t) 0x119) ++#define TPM_RC_INITIALIZE ((TPM_RC_t) 0x100) ++#define TPM_RC_INSUFFICIENT ((TPM_RC_t) 0x09A) ++#define TPM_RC_INTEGRITY ((TPM_RC_t) 0x09F) ++#define TPM_RC_KDF ((TPM_RC_t) 0x08C) ++#define TPM_RC_KEY ((TPM_RC_t) 0x09C) ++#define TPM_RC_KEY_SIZE ((TPM_RC_t) 0x087) ++#define TPM_RC_LOCALITY ((TPM_RC_t) 0x907) ++#define TPM_RC_LOCKOUT ((TPM_RC_t) 0x921) ++#define TPM_RC_MEMORY ((TPM_RC_t) 0x904) ++#define TPM_RC_MGF ((TPM_RC_t) 0x088) ++#define TPM_RC_MODE ((TPM_RC_t) 0x089) ++#define TPM_RC_NEEDS_TEST ((TPM_RC_t) 0x153) ++#define TPM_RC_N_MASK ((TPM_RC_t) 0xF00) ++#define TPM_RC_NONCE ((TPM_RC_t) 0x08F) ++#define TPM_RC_NO_RESULT ((TPM_RC_t) 0x154) ++#define TPM_RC_NOT_USED ((TPM_RC_t) 0x97F) ++#define TPM_RC_NV_AUTHORIZATION ((TPM_RC_t) 0x149) ++#define TPM_RC_NV_DEFINED ((TPM_RC_t) 0x14C) ++#define TPM_RC_NV_LOCKED ((TPM_RC_t) 0x148) ++#define TPM_RC_NV_RANGE ((TPM_RC_t) 0x146) ++#define TPM_RC_NV_RATE ((TPM_RC_t) 0x920) ++#define TPM_RC_NV_SIZE ((TPM_RC_t) 0x147) ++#define TPM_RC_NV_SPACE ((TPM_RC_t) 0x14B) ++#define TPM_RC_NV_UNAVAILABLE ((TPM_RC_t) 0x923) ++#define TPM_RC_NV_UNINITIALIZED ((TPM_RC_t) 0x14A) ++#define TPM_RC_OBJECT_HANDLES ((TPM_RC_t) 0x906) ++#define TPM_RC_OBJECT_MEMORY ((TPM_RC_t) 0x902) ++#define TPM_RC_P ((TPM_RC_t) 0x040) ++#define TPM_RC_PARENT ((TPM_RC_t) 0x152) ++#define TPM_RC_PCR ((TPM_RC_t) 0x127) ++#define TPM_RC_PCR_CHANGED ((TPM_RC_t) 0x128) ++#define TPM_RC_POLICY ((TPM_RC_t) 0x126) ++#define TPM_RC_POLICY_CC ((TPM_RC_t) 0x0A4) ++#define TPM_RC_POLICY_FAIL ((TPM_RC_t) 0x09D) ++#define TPM_RC_PP ((TPM_RC_t) 0x090) ++#define TPM_RC_PRIVATE ((TPM_RC_t) 0x10B) ++#define TPM_RC_RANGE ((TPM_RC_t) 0x08D) ++#define TPM_RC_REBOOT ((TPM_RC_t) 0x130) ++#define TPM_RC_REFERENCE_H0 ((TPM_RC_t) 0x910) ++#define TPM_RC_REFERENCE_H1 ((TPM_RC_t) 0x911) ++#define TPM_RC_REFERENCE_H2 ((TPM_RC_t) 0x912) ++#define TPM_RC_REFERENCE_H3 ((TPM_RC_t) 0x913) ++#define TPM_RC_REFERENCE_H4 ((TPM_RC_t) 0x914) ++#define TPM_RC_REFERENCE_H5 ((TPM_RC_t) 0x915) ++#define TPM_RC_REFERENCE_H6 ((TPM_RC_t) 0x916) ++#define TPM_RC_REFERENCE_S0 ((TPM_RC_t) 0x918) ++#define TPM_RC_REFERENCE_S1 ((TPM_RC_t) 0x919) ++#define TPM_RC_REFERENCE_S2 ((TPM_RC_t) 0x91A) ++#define TPM_RC_REFERENCE_S3 ((TPM_RC_t) 0x91B) ++#define TPM_RC_REFERENCE_S4 ((TPM_RC_t) 0x91C) ++#define TPM_RC_REFERENCE_S5 ((TPM_RC_t) 0x91D) ++#define TPM_RC_REFERENCE_S6 ((TPM_RC_t) 0x91E) ++#define TPM_RC_RESERVED_BITS ((TPM_RC_t) 0x0A1) ++#define TPM_RC_RETRY ((TPM_RC_t) 0x922) ++#define TPM_RC_S ((TPM_RC_t) 0x800) ++#define TPM_RC_SCHEME ((TPM_RC_t) 0x092) ++#define TPM_RC_SELECTOR ((TPM_RC_t) 0x098) ++#define TPM_RC_SENSITIVE ((TPM_RC_t) 0x155) ++#define TPM_RC_SEQUENCE ((TPM_RC_t) 0x103) ++#define TPM_RC_SESSION_HANDLES ((TPM_RC_t) 0x905) ++#define TPM_RC_SESSION_MEMORY ((TPM_RC_t) 0x903) ++#define TPM_RC_SIGNATURE ((TPM_RC_t) 0x09B) ++#define TPM_RC_SIZE ((TPM_RC_t) 0x095) ++#define TPM_RC_SUCCESS ((TPM_RC_t) 0x000) ++#define TPM_RC_SYMMETRIC ((TPM_RC_t) 0x096) ++#define TPM_RC_TAG ((TPM_RC_t) 0x097) ++#define TPM_RC_TESTING ((TPM_RC_t) 0x90A) ++#define TPM_RC_TICKET ((TPM_RC_t) 0x0A0) ++#define TPM_RC_TOO_MANY_CONTEXTS ((TPM_RC_t) 0x12E) ++#define TPM_RC_TYPE ((TPM_RC_t) 0x08A) ++#define TPM_RC_UNBALANCED ((TPM_RC_t) 0x131) ++#define TPM_RC_UPGRADE ((TPM_RC_t) 0x12D) ++#define TPM_RC_VALUE ((TPM_RC_t) 0x084) ++#define TPM_RC_YIELDED ((TPM_RC_t) 0x908) ++ ++/* TPMA_NV_t Constants */ ++typedef grub_uint32_t TPMA_NV_t; ++ ++#define TPMA_NV_PPWRITE ((TPMA_NV_t) 0x00000001) ++#define TPMA_NV_OWNERWRITE ((TPMA_NV_t) 0x00000002) ++#define TPMA_NV_AUTHWRITE ((TPMA_NV_t) 0x00000004) ++#define TPMA_NV_POLICYWRITE ((TPMA_NV_t) 0x00000008) ++#define TPMA_NV_TPM2_NT_MASK ((TPMA_NV_t) 0x000000F0) ++#define TPMA_NV_TPM2_NT_SHIFT (4) ++#define TPMA_NV_RESERVED1_MASK ((TPMA_NV_t) 0x00000300) ++#define TPMA_NV_POLICY_DELETE ((TPMA_NV_t) 0x00000400) ++#define TPMA_NV_WRITELOCKED ((TPMA_NV_t) 0x00000800) ++#define TPMA_NV_WRITEALL ((TPMA_NV_t) 0x00001000) ++#define TPMA_NV_WRITEDEFINE ((TPMA_NV_t) 0x00002000) ++#define TPMA_NV_WRITE_STCLEAR ((TPMA_NV_t) 0x00004000) ++#define TPMA_NV_GLOBALLOCK ((TPMA_NV_t) 0x00008000) ++#define TPMA_NV_PPREAD ((TPMA_NV_t) 0x00010000) ++#define TPMA_NV_OWNERREAD ((TPMA_NV_t) 0x00020000) ++#define TPMA_NV_AUTHREAD ((TPMA_NV_t) 0x00040000) ++#define TPMA_NV_POLICYREAD ((TPMA_NV_t) 0x00080000) ++#define TPMA_NV_RESERVED2_MASK ((TPMA_NV_t) 0x01F00000) ++#define TPMA_NV_NO_DA ((TPMA_NV_t) 0x02000000) ++#define TPMA_NV_ORDERLY ((TPMA_NV_t) 0x04000000) ++#define TPMA_NV_CLEAR_STCLEAR ((TPMA_NV_t) 0x08000000) ++#define TPMA_NV_READLOCKED ((TPMA_NV_t) 0x10000000) ++#define TPMA_NV_WRITTEN ((TPMA_NV_t) 0x20000000) ++#define TPMA_NV_PLATFORMCREATE ((TPMA_NV_t) 0x40000000) ++#define TPMA_NV_READ_STCLEAR ((TPMA_NV_t) 0x80000000) ++ ++/* TPM_ALG_ID_t Constants */ ++typedef grub_uint16_t TPM_ALG_ID_t; ++ ++#define TPM_ALG_ERROR ((TPM_ALG_ID_t) 0x0000) ++#define TPM_ALG_AES ((TPM_ALG_ID_t) 0x0006) ++#define TPM_ALG_CAMELLIA ((TPM_ALG_ID_t) 0x0026) ++#define TPM_ALG_CBC ((TPM_ALG_ID_t) 0x0042) ++#define TPM_ALG_CFB ((TPM_ALG_ID_t) 0x0043) ++#define TPM_ALG_ECB ((TPM_ALG_ID_t) 0x0044) ++#define TPM_ALG_ECC ((TPM_ALG_ID_t) 0x0023) ++#define TPM_ALG_ECDAA ((TPM_ALG_ID_t) 0x001A) ++#define TPM_ALG_ECDSA ((TPM_ALG_ID_t) 0x0018) ++#define TPM_ALG_ECSCHNORR ((TPM_ALG_ID_t) 0x001C) ++#define TPM_ALG_HMAC ((TPM_ALG_ID_t) 0x0005) ++#define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID_t) 0x0022) ++#define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID_t) 0x0020) ++#define TPM_ALG_KDF2 ((TPM_ALG_ID_t) 0x0021) ++#define TPM_ALG_KEYEDHASH ((TPM_ALG_ID_t) 0x0008) ++#define TPM_ALG_MGF1 ((TPM_ALG_ID_t) 0x0007) ++#define TPM_ALG_NULL ((TPM_ALG_ID_t) 0x0010) ++#define TPM_ALG_RSA ((TPM_ALG_ID_t) 0x0001) ++#define TPM_ALG_RSASSA ((TPM_ALG_ID_t) 0x0014) ++#define TPM_ALG_RSAPSS ((TPM_ALG_ID_t) 0x0016) ++#define TPM_ALG_SHA1 ((TPM_ALG_ID_t) 0x0004) ++#define TPM_ALG_SHA256 ((TPM_ALG_ID_t) 0x000B) ++#define TPM_ALG_SHA384 ((TPM_ALG_ID_t) 0x000C) ++#define TPM_ALG_SHA512 ((TPM_ALG_ID_t) 0x000D) ++#define TPM_ALG_SM2 ((TPM_ALG_ID_t) 0x001B) ++#define TPM_ALG_SM3_256 ((TPM_ALG_ID_t) 0x0012) ++#define TPM_ALG_SM4 ((TPM_ALG_ID_t) 0x0013) ++#define TPM_ALG_SYMCIPHER ((TPM_ALG_ID_t) 0x0025) ++#define TPM_ALG_XOR ((TPM_ALG_ID_t) 0x000A) ++ ++/* TPM_CAP_t Constants */ ++typedef grub_uint32_t TPM_CAP_t; ++ ++#define TPM_CAP_FIRST ((TPM_CAP_t) 0x00000000) ++#define TPM_CAP_ALGS ((TPM_CAP_t) 0x00000000) ++#define TPM_CAP_HANDLES ((TPM_CAP_t) 0x00000001) ++#define TPM_CAP_COMMANDS ((TPM_CAP_t) 0x00000002) ++#define TPM_CAP_PP_COMMANDS ((TPM_CAP_t) 0x00000003) ++#define TPM_CAP_AUDIT_COMMANDS ((TPM_CAP_t) 0x00000004) ++#define TPM_CAP_PCRS ((TPM_CAP_t) 0x00000005) ++#define TPM_CAP_TPM_PROPERTIES ((TPM_CAP_t) 0x00000006) ++#define TPM_CAP_PCR_PROPERTIES ((TPM_CAP_t) 0x00000007) ++#define TPM_CAP_ECC_CURVES ((TPM_CAP_t) 0x00000008) ++#define TPM_CAP_LAST ((TPM_CAP_t) 0x00000008) ++#define TPM_CAP_VENDOR_PROPERTY ((TPM_CAP_t) 0x00000100) ++ ++/* TPM_PT_t Constants */ ++typedef grub_uint32_t TPM_PT_t; ++ ++#define TPM_PT_NONE ((TPM_PT_t) 0x00000000) ++#define PT_GROUP ((TPM_PT_t) 0x00000100) ++#define PT_FIXED ((TPM_PT_t) (PT_GROUP * 1)) ++#define TPM_PT_FAMILY_INDICATOR ((TPM_PT_t) (PT_FIXED + 0)) ++#define TPM_PT_LEVEL ((TPM_PT_t) (PT_FIXED + 1)) ++#define TPM_PT_REVISION ((TPM_PT_t) (PT_FIXED + 2)) ++#define TPM_PT_DAY_OF_YEAR ((TPM_PT_t) (PT_FIXED + 3)) ++#define TPM_PT_YEAR ((TPM_PT_t) (PT_FIXED + 4)) ++#define TPM_PT_PCR_COUNT ((TPM_PT_t) (PT_FIXED + 18)) ++ ++/* TPM_SE_t Constants */ ++typedef grub_uint8_t TPM_SE_t; ++ ++#define TPM_SE_HMAC ((TPM_SE_t) 0x00) ++#define TPM_SE_POLICY ((TPM_SE_t) 0x01) ++#define TPM_SE_TRIAL ((TPM_SE_t) 0x03) ++ ++/* TPMI_YES_NO_t Constants */ ++typedef grub_uint8_t TPMI_YES_NO_t; ++ ++#define TPM_NO ((TPMI_YES_NO_t)0) ++#define TPM_YES ((TPMI_YES_NO_t)1) ++ ++/* TPM_ST_t Constants */ ++typedef grub_uint16_t TPM_ST_t; ++typedef TPM_ST_t TPMI_ST_COMMAND_TAG_t; ++ ++#define TPM_ST_NO_SESSIONS ((TPMI_ST_COMMAND_TAG_t) 0x8001) ++#define TPM_ST_SESSIONS ((TPMI_ST_COMMAND_TAG_t) 0x8002) ++ ++/* TPM_HANDLE_t Types */ ++typedef grub_uint32_t TPM_HANDLE_t; ++ ++typedef TPM_HANDLE_t TPMI_RH_HIERARCHY_t; ++typedef TPM_HANDLE_t TPMI_RH_LOCKOUT_t; ++typedef TPM_HANDLE_t TPMI_SH_AUTH_SESSION_t; ++typedef TPM_HANDLE_t TPMI_DH_CONTEXT_t; ++typedef TPM_HANDLE_t TPMI_DH_OBJECT_t; ++typedef TPM_HANDLE_t TPMI_DH_ENTITY_t; ++typedef TPM_HANDLE_t TPMI_SH_POLICY_t; ++typedef TPM_HANDLE_t TPMI_DH_PCR_t; ++typedef TPM_HANDLE_t TPMI_RH_NV_AUTH_t; ++typedef TPM_HANDLE_t TPMI_RH_NV_INDEX_t; ++ ++/* TPM_HT_t Constants */ ++typedef grub_uint8_t TPM_HT_t; ++#define TPM_HT_PERMANENT ((TPM_HT_t) 0x40) ++#define TPM_HT_PERSISTENT ((TPM_HT_t) 0x81) ++ ++/* TPM_RH_t Constants */ ++typedef TPM_HANDLE_t TPM_RH_t; ++ ++#define TPM_RH_FIRST ((TPM_RH_t) 0x40000000) ++#define TPM_RH_SRK ((TPM_RH_t) 0x40000000) ++#define TPM_RH_OWNER ((TPM_RH_t) 0x40000001) ++#define TPM_RH_REVOKE ((TPM_RH_t) 0x40000002) ++#define TPM_RH_TRANSPORT ((TPM_RH_t) 0x40000003) ++#define TPM_RH_OPERATOR ((TPM_RH_t) 0x40000004) ++#define TPM_RH_ADMIN ((TPM_RH_t) 0x40000005) ++#define TPM_RH_EK ((TPM_RH_t) 0x40000006) ++#define TPM_RH_NULL ((TPM_RH_t) 0x40000007) ++#define TPM_RH_UNASSIGNED ((TPM_RH_t) 0x40000008) ++#define TPM_RS_PW ((TPM_RH_t) 0x40000009) ++#define TPM_RH_LOCKOUT ((TPM_RH_t) 0x4000000A) ++#define TPM_RH_ENDORSEMENT ((TPM_RH_t) 0x4000000B) ++#define TPM_RH_PLATFORM ((TPM_RH_t) 0x4000000C) ++#define TPM_RH_PLATFORM_NV ((TPM_RH_t) 0x4000000D) ++#define TPM_RH_AUTH_00 ((TPM_RH_t) 0x40000010) ++#define TPM_RH_AUTH_FF ((TPM_RH_t) 0x4000010F) ++#define TPM_RH_LAST ((TPM_RH_t) 0x4000010F) ++ ++/* TPM_HC_t Constants */ ++typedef TPM_HANDLE_t TPM_HC_t; ++#define TPM_HR_HANDLE_MASK ((TPM_HC_t) 0x00FFFFFF) ++#define TPM_HR_RANGE_MASK ((TPM_HC_t) 0xFF000000) ++#define TPM_HR_SHIFT ((TPM_HC_t) 24) ++#define TPM_HR_PERSISTENT ((TPM_HC_t) (TPM_HT_PERSISTENT << TPM_HR_SHIFT)) ++#define TPM_HR_PERMANENT ((TPM_HC_t) (TPM_HT_PERMANENT << TPM_HR_SHIFT)) ++#define TPM_PERSISTENT_FIRST ((TPM_HC_t) (TPM_HR_PERSISTENT + 0)) ++#define TPM_PERSISTENT_LAST ((TPM_HC_t) (TPM_PERSISTENT_FIRST + 0x00FFFFFF)) ++#define TPM_PERMANENT_FIRST ((TPM_HC_t) TPM_RH_FIRST) ++#define TPM_PERMANENT_LAST ((TPM_HC_t) TPM_RH_LAST) ++ ++/* TPM Handle Type Checks */ ++#define TPM_HT_IS_PERMANENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERMANENT) ++#define TPM_HT_IS_PERSISTENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERSISTENT) ++ ++/* TPM_ECC_CURVE_t Constants */ ++typedef grub_uint16_t TPM_ECC_CURVE_t; ++ ++#define TPM_ECC_NONE ((TPM_ECC_CURVE_t) 0x0000) ++#define TPM_ECC_NIST_P192 ((TPM_ECC_CURVE_t) 0x0001) ++#define TPM_ECC_NIST_P224 ((TPM_ECC_CURVE_t) 0x0002) ++#define TPM_ECC_NIST_P256 ((TPM_ECC_CURVE_t) 0x0003) ++#define TPM_ECC_NIST_P384 ((TPM_ECC_CURVE_t) 0x0004) ++#define TPM_ECC_NIST_P521 ((TPM_ECC_CURVE_t) 0x0005) ++#define TPM_ECC_BN_P256 ((TPM_ECC_CURVE_t) 0x0010) ++#define TPM_ECC_BN_P638 ((TPM_ECC_CURVE_t) 0x0011) ++#define TPM_ECC_SM2_P256 ((TPM_ECC_CURVE_t) 0x0020) ++ ++/* TPM_CC_t Constants */ ++typedef grub_uint32_t TPM_CC_t; ++ ++#define TPM_CC_EvictControl ((TPM_CC_t) 0x00000120) ++#define TPM_CC_CreatePrimary ((TPM_CC_t) 0x00000131) ++#define TPM_CC_Create ((TPM_CC_t) 0x00000153) ++#define TPM_CC_FlushContext ((TPM_CC_t) 0x00000165) ++#define TPM_CC_ReadPublic ((TPM_CC_t) 0x00000173) ++#define TPM_CC_StartAuthSession ((TPM_CC_t) 0x00000176) ++#define TPM_CC_PolicyPCR ((TPM_CC_t) 0x0000017f) ++#define TPM_CC_NV_Read ((TPM_CC_t) 0x0000014e) ++#define TPM_CC_NV_ReadPublic ((TPM_CC_t) 0x00000169) ++#define TPM_CC_GetCapability ((TPM_CC_t) 0x0000017a) ++#define TPM_CC_PCR_Read ((TPM_CC_t) 0x0000017e) ++#define TPM_CC_Load ((TPM_CC_t) 0x00000157) ++#define TPM_CC_LoadExternal ((TPM_CC_t) 0x00000167) ++#define TPM_CC_Unseal ((TPM_CC_t) 0x0000015e) ++#define TPM_CC_PolicyGetDigest ((TPM_CC_t) 0x00000189) ++#define TPM_CC_Hash ((TPM_CC_t) 0x0000017d) ++#define TPM_CC_VerifySignature ((TPM_CC_t) 0x00000177) ++#define TPM_CC_PolicyAuthorize ((TPM_CC_t) 0x0000016a) ++#define TPM_CC_TestParms ((TPM_CC_t) 0x0000018a) ++ ++/* Hash algorithm sizes */ ++#define TPM_SHA1_DIGEST_SIZE 20 ++#define TPM_SHA256_DIGEST_SIZE 32 ++#define TPM_SM3_256_DIGEST_SIZE 32 ++#define TPM_SHA384_DIGEST_SIZE 48 ++#define TPM_SHA512_DIGEST_SIZE 64 ++ ++/* Encryption algorithm sizes */ ++#define TPM_MAX_SYM_BLOCK_SIZE 16 ++#define TPM_MAX_SYM_DATA 256 ++#define TPM_MAX_ECC_KEY_BYTES 128 ++#define TPM_MAX_SYM_KEY_BYTES 32 ++#define TPM_MAX_RSA_KEY_BYTES 512 ++ ++/* Buffer Size Constants */ ++#define TPM_MAX_PCRS 24 ++#define TPM_NUM_PCR_BANKS 16 ++#define TPM_PCR_SELECT_MAX ((TPM_MAX_PCRS + 7) / 8) ++#define TPM_MAX_DIGEST_BUFFER 1024 ++#define TPM_MAX_TPM_PROPERTIES 8 ++#define TPM_MAX_NV_BUFFER_SIZE 2048 ++#define TPM_PRIVATE_VENDOR_SPECIFIC_BYTES 1280 ++ ++/* TPM_GENERATED_t Constants */ ++typedef grub_uint32_t TPM_GENERATED_t; ++ ++#define TPM_GENERATED_VALUE ((TPM_GENERATED_t) 0xff544347) ++ ++/* TPM_ALG_ID_t Types */ ++typedef TPM_ALG_ID_t TPMI_ALG_PUBLIC_t; ++typedef TPM_ALG_ID_t TPMI_ALG_HASH_t; ++typedef TPM_ALG_ID_t TPMI_ALG_KEYEDHASH_SCHEME_t; ++typedef TPM_ALG_ID_t TPMI_ALG_KDF_t; ++typedef TPM_ALG_ID_t TPMI_ALG_SYM_OBJECT_t; ++typedef TPM_ALG_ID_t TPMI_ALG_SYM_MODE_t; ++typedef TPM_ALG_ID_t TPMI_ALG_RSA_DECRYPT_t; ++typedef TPM_ALG_ID_t TPMI_ALG_ECC_SCHEME_t; ++typedef TPM_ALG_ID_t TPMI_ALG_ASYM_SCHEME_t; ++typedef TPM_ALG_ID_t TPMI_ALG_RSA_SCHEME_t; ++typedef TPM_ALG_ID_t TPMI_ALG_SYM_t; ++typedef TPM_ALG_ID_t TPMI_ALG_SIG_SCHEME_t; ++ ++/* TPM_KEY_BITS_t Type */ ++typedef grub_uint16_t TPM_KEY_BITS_t; ++ ++/* TPMI_ECC_CURVE_t Types */ ++typedef TPM_ECC_CURVE_t TPMI_ECC_CURVE_t; ++ ++/* TPMI_RH_PROVISION_t Type */ ++typedef TPM_HANDLE_t TPMI_RH_PROVISION_t; ++ ++/* TPMI_RH_PROVISION_t Type */ ++typedef TPM_HANDLE_t TPMI_DH_PERSISTENT_t; ++ ++#endif /* ! GRUB_TPM2_INTERNAL_TYPES_HEADER */ +-- +2.43.0 + + +From 50a5ff62f0f4ae18936beb66e4751a9dbcc0c80f Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Mon, 24 Jun 2024 14:05:50 +0800 +Subject: [PATCH 3/3] tss2: Add TPM2 Software Stack (TSS2) support + +A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to +compose and submit TPM commands and parse reponses. + +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, +second, of the TPM wire protocol itself. + +As such, this patch includes implementations of various grub_tpm2_* functions +(inventoried below), and logic to write and read command and response +buffers, respectively, using the TPM wire protocol. + +Functions: + * grub_tpm2_create() + * grub_tpm2_createprimary() + * grub_tpm2_evictcontrol() + * grub_tpm2_flushcontext() + * grub_tpm2_load() + * grub_tpm2_pcr_read() + * grub_tpm2_policygetdigest() + * grub_tpm2_policypcr() + * grub_tpm2_readpublic() + * grub_tpm2_startauthsession() + * grub_tpm2_unseal() + * grub_tpm2_loadexternal() + * grub_tpm2_hash() + * grub_tpm2_verifysignature() + * grub_tpm2_policyauthorize() + * grub_tpm2_testparms() + +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +Reviewed-by: Daniel Kiper +Reviewed-by: Stefan Berger +--- + grub-core/Makefile.core.def | 11 + + grub-core/lib/efi/tcg2.c | 143 +++++ + grub-core/lib/tss2/tcg2.h | 35 ++ + grub-core/lib/tss2/tpm2_cmd.c | 1043 +++++++++++++++++++++++++++++++++ + grub-core/lib/tss2/tpm2_cmd.h | 157 +++++ + grub-core/lib/tss2/tss2.c | 21 + + 6 files changed, 1410 insertions(+) + create mode 100644 grub-core/lib/efi/tcg2.c + create mode 100644 grub-core/lib/tss2/tcg2.h + create mode 100644 grub-core/lib/tss2/tpm2_cmd.c + create mode 100644 grub-core/lib/tss2/tpm2_cmd.h + create mode 100644 grub-core/lib/tss2/tss2.c + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 37f131ae2..45b705a34 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2567,6 +2567,17 @@ module = { + enable = efi; + }; + ++module = { ++ name = tss2; ++ common = lib/tss2/buffer.c; ++ common = lib/tss2/tss2_mu.c; ++ common = lib/tss2/tpm2_cmd.c; ++ common = lib/tss2/tss2.c; ++ efi = lib/efi/tcg2.c; ++ enable = efi; ++ cppflags = '-I$(srcdir)/lib/tss2'; ++}; ++ + module = { + name = tr; + common = commands/tr.c; +diff --git a/grub-core/lib/efi/tcg2.c b/grub-core/lib/efi/tcg2.c +new file mode 100644 +index 000000000..841bf50bb +--- /dev/null ++++ b/grub-core/lib/efi/tcg2.c +@@ -0,0 +1,143 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++static grub_err_t ++tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2, grub_size_t *max_output_size) ++{ ++ grub_efi_status_t status; ++ static bool has_caps = 0; ++ static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps = ++ { ++ .Size = (grub_uint8_t) sizeof (caps) ++ }; ++ ++ if (has_caps) ++ goto exit; ++ ++ status = protocol->get_capability (protocol, &caps); ++ if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ has_caps = 1; ++ ++ exit: ++ if (tpm2 != NULL) ++ *tpm2 = caps.TPMPresentFlag; ++ if (max_output_size != NULL) ++ *max_output_size = caps.MaxResponseSize; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol) ++{ ++ static grub_guid_t tpm2_guid = EFI_TPM2_GUID; ++ static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL; ++ int tpm2; ++ grub_efi_handle_t *handles; ++ grub_efi_uintn_t num_handles; ++ grub_efi_handle_t tpm2_handle; ++ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; ++ ++ if (tpm2_protocol != NULL) ++ { ++ *protocol = tpm2_protocol; ++ return GRUB_ERR_NONE; ++ } ++ ++ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, ++ &num_handles); ++ if (handles == NULL || num_handles == 0) ++ return err; ++ ++ tpm2_handle = handles[0]; ++ ++ tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (tpm2_protocol == NULL) ++ goto exit; ++ ++ err = tcg2_get_caps (tpm2_protocol, &tpm2, NULL); ++ if (err != GRUB_ERR_NONE || tpm2 == 0) ++ goto exit; ++ ++ *protocol = tpm2_protocol; ++ err = GRUB_ERR_NONE; ++ ++ exit: ++ grub_free (handles); ++ return err; ++} ++ ++grub_err_t ++grub_tcg2_get_max_output_size (grub_size_t *size) ++{ ++ grub_err_t err; ++ grub_size_t max; ++ grub_efi_tpm2_protocol_t *protocol; ++ ++ if (size == NULL) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ err = tcg2_get_protocol (&protocol); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ err = tcg2_get_caps (protocol, NULL, &max); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ *size = max; ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tcg2_submit_command (grub_size_t input_size, ++ grub_uint8_t *input, ++ grub_size_t output_size, ++ grub_uint8_t *output) ++{ ++ grub_err_t err; ++ grub_efi_status_t status; ++ grub_efi_tpm2_protocol_t *protocol; ++ ++ if (input_size == 0 || input == NULL || ++ output_size == 0 || output == NULL) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ err = tcg2_get_protocol (&protocol); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ status = protocol->submit_command (protocol, input_size, input, ++ output_size, output); ++ if (status != GRUB_EFI_SUCCESS) ++ return GRUB_ERR_INVALID_COMMAND; ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/lib/tss2/tcg2.h b/grub-core/lib/tss2/tcg2.h +new file mode 100644 +index 000000000..3d26373dd +--- /dev/null ++++ b/grub-core/lib/tss2/tcg2.h +@@ -0,0 +1,35 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_TCG2_HEADER ++#define GRUB_TPM2_TCG2_HEADER 1 ++ ++#include ++#include ++ ++extern grub_err_t ++grub_tcg2_get_max_output_size (grub_size_t *size); ++ ++extern grub_err_t ++grub_tcg2_submit_command (grub_size_t input_size, ++ grub_uint8_t *input, ++ grub_size_t output_size, ++ grub_uint8_t *output); ++ ++#endif /* ! GRUB_TPM2_TCG2_HEADER */ +diff --git a/grub-core/lib/tss2/tpm2_cmd.c b/grub-core/lib/tss2/tpm2_cmd.c +new file mode 100644 +index 000000000..cd0c6fd31 +--- /dev/null ++++ b/grub-core/lib/tss2/tpm2_cmd.c +@@ -0,0 +1,1043 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static TPM_RC_t ++tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG_t tag, ++ const TPM_CC_t commandCode, ++ TPM_RC_t *responseCode, ++ const struct grub_tpm2_buffer *in, ++ struct grub_tpm2_buffer *out) ++{ ++ grub_err_t err; ++ struct grub_tpm2_buffer buf; ++ TPMI_ST_COMMAND_TAG_t tag_out; ++ grub_uint32_t command_size; ++ grub_size_t max_output_size; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&buf); ++ grub_tpm2_buffer_pack_u16 (&buf, tag); ++ grub_tpm2_buffer_pack_u32 (&buf, 0); ++ grub_tpm2_buffer_pack_u32 (&buf, commandCode); ++ grub_tpm2_buffer_pack (&buf, in->data, in->size); ++ ++ if (buf.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Convert the command size to big endian to fill the u32 buffer below 'tag' */ ++ command_size = grub_cpu_to_be32 (buf.size); ++ grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size, sizeof (command_size)); ++ ++ /* Stay within output block limits */ ++ err = grub_tcg2_get_max_output_size (&max_output_size); ++ if (err != GRUB_ERR_NONE || max_output_size > out->cap) ++ max_output_size = out->cap - 1; ++ ++ /* Submit */ ++ err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size, out->data); ++ if (err != GRUB_ERR_NONE) ++ return TPM_RC_FAILURE; ++ ++ /* Unmarshal */ ++ out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) + sizeof (grub_uint32_t); ++ grub_tpm2_buffer_unpack_u16 (out, &tag_out); ++ grub_tpm2_buffer_unpack_u32 (out, &command_size); ++ grub_tpm2_buffer_unpack_u32 (out, responseCode); ++ out->size = command_size; ++ if (out->error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++static TPM_RC_t ++tpm2_submit_command (const TPMI_ST_COMMAND_TAG_t tag, ++ const TPM_CC_t commandCode, ++ TPM_RC_t *responseCode, ++ const struct grub_tpm2_buffer *in, ++ struct grub_tpm2_buffer *out) ++{ ++ TPM_RC_t err; ++ int retry_cnt = 0; ++ ++ /* Catch TPM_RC_RETRY and send the command again */ ++ do { ++ err = 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_t ++grub_tpm2_createprimary (const TPMI_RH_HIERARCHY_t primaryHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_SENSITIVE_CREATE_t *inSensitive, ++ const TPM2B_PUBLIC_t *inPublic, ++ const TPM2B_DATA_t *outsideInfo, ++ const TPML_PCR_SELECTION_t *creationPCR, ++ TPM_HANDLE_t *objectHandle, ++ TPM2B_PUBLIC_t *outPublic, ++ TPM2B_CREATION_DATA_t *creationData, ++ TPM2B_DIGEST_t *creationHash, ++ TPMT_TK_CREATION_t *creationTicket, ++ TPM2B_NAME_t *name, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_HANDLE_t objectHandleTmp; ++ TPM2B_PUBLIC_t outPublicTmp; ++ TPM2B_CREATION_DATA_t creationDataTmp; ++ TPM2B_DIGEST_t creationHashTmp; ++ TPMT_TK_CREATION_t creationTicketTmp; ++ TPM2B_NAME_t nameTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t parameterSize; ++ ++ if (inSensitive == NULL || inPublic == NULL || outsideInfo == NULL || ++ creationPCR == NULL) ++ return TPM_RC_VALUE; ++ ++ if (objectHandle == NULL) ++ objectHandle = &objectHandleTmp; ++ if (outPublic == NULL) ++ outPublic = &outPublicTmp; ++ if (creationData == NULL) ++ creationData = &creationDataTmp; ++ if (creationHash == NULL) ++ creationHash = &creationHashTmp; ++ if (creationTicket == NULL) ++ creationTicket = &creationTicketTmp; ++ if (name == NULL) ++ name = &nameTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outPublic, 0, sizeof (*outPublic)); ++ grub_memset (creationData, 0, sizeof (*creationData)); ++ grub_memset (creationHash, 0, sizeof (*creationHash)); ++ grub_memset (creationTicket, 0, sizeof (*creationTicket)); ++ grub_memset (name, 0, sizeof (*name)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, primaryHandle); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); ++ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ grub_Tss2_MU_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, creationPCR); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_CreatePrimary, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic); ++ grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (&out, creationData); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, creationHash); ++ grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); ++ grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_startauthsession (const TPMI_DH_OBJECT_t tpmKey, ++ const TPMI_DH_ENTITY_t bind, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_NONCE_t *nonceCaller, ++ const TPM2B_ENCRYPTED_SECRET_t *encryptedSalt, ++ const TPM_SE_t sessionType, ++ const TPMT_SYM_DEF_t *symmetric, ++ const TPMI_ALG_HASH_t authHash, ++ TPMI_SH_AUTH_SESSION_t *sessionHandle, ++ TPM2B_NONCE_t *nonceTpm, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMI_SH_AUTH_SESSION_t sessionHandleTmp; ++ TPM2B_NONCE_t nonceTpmTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (nonceCaller == NULL || symmetric == NULL) ++ return TPM_RC_VALUE; ++ ++ if (tpmKey == TPM_RH_NULL && ++ (encryptedSalt && encryptedSalt->size != 0)) ++ return TPM_RC_VALUE; ++ ++ if (sessionHandle == NULL) ++ sessionHandle = &sessionHandleTmp; ++ if (nonceTpm == NULL) ++ nonceTpm = &nonceTpmTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (sessionHandle, 0, sizeof (*sessionHandle)); ++ grub_memset (nonceTpm, 0, sizeof (*nonceTpm)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, tpmKey); ++ grub_tpm2_buffer_pack_u32 (&in, bind); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_Tss2_MU_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer); ++ if (encryptedSalt != NULL) ++ grub_Tss2_MU_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_buffer_pack_u8 (&in, sessionType); ++ grub_Tss2_MU_TPMT_SYM_DEF_Marshal (&in, symmetric); ++ grub_tpm2_buffer_pack_u16 (&in, authHash); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_StartAuthSession, &responseCode, ++ &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, sessionHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPM2B_NONCE_Unmarshal (&out, nonceTpm); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_policypcr (const TPMI_SH_POLICY_t policySessions, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_DIGEST_t *pcrDigest, ++ const TPML_PCR_SELECTION_t *pcrs, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (pcrs == NULL) ++ return TPM_RC_VALUE; ++ ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, policySessions); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (pcrDigest != NULL) ++ grub_Tss2_MU_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, pcrs); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_PolicyPCR, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ TPM2B_PUBLIC_t *outPublic) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t parameterSize; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, objectHandle); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_ReadPublic, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_PRIVATE_t *inPrivate, ++ const TPM2B_PUBLIC_t *inPublic, ++ TPM_HANDLE_t *objectHandle, ++ TPM2B_NAME_t *name, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_HANDLE_t objectHandleTmp; ++ TPM2B_NAME_t nameTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (inPrivate == NULL || inPublic == NULL) ++ return TPM_RC_VALUE; ++ ++ if (objectHandle == NULL) ++ objectHandle = &objectHandleTmp; ++ if (name == NULL) ++ name = &nameTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (objectHandle, 0, sizeof (*objectHandle)); ++ grub_memset (name, 0, sizeof (*name)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, parent_handle); ++ if (authCommand) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_Tss2_MU_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer); ++ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_Load, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_SENSITIVE_t *inPrivate, ++ const TPM2B_PUBLIC_t *inPublic, ++ const TPMI_RH_HIERARCHY_t hierarchy, ++ TPM_HANDLE_t *objectHandle, ++ TPM2B_NAME_t *name, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_HANDLE_t objectHandleTmp; ++ TPM2B_NAME_t nameTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (inPublic == NULL) ++ return TPM_RC_VALUE; ++ ++ if (objectHandle == NULL) ++ objectHandle = &objectHandleTmp; ++ if (name == NULL) ++ name = &nameTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (objectHandle, 0, sizeof (*objectHandle)); ++ grub_memset (name, 0, sizeof (*name)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (inPrivate) ++ grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (&in, inPrivate); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ grub_tpm2_buffer_pack_u32 (&in, hierarchy); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_unseal (const TPMI_DH_OBJECT_t itemHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ TPM2B_SENSITIVE_DATA_t *outData, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM2B_SENSITIVE_DATA_t outDataTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (outData == NULL) ++ outData = &outDataTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outData, 0, sizeof (*outData)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, itemHandle); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_Unseal, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (&out, outData); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_RC_t responseCode; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, handle); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (TPM_ST_NO_SESSIONS, TPM_CC_FlushContext, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPML_PCR_SELECTION_t *pcrSelectionIn, ++ grub_uint32_t *pcrUpdateCounter, ++ TPML_PCR_SELECTION_t *pcrSelectionOut, ++ TPML_DIGEST_t *pcrValues, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ grub_uint32_t pcrUpdateCounterTmp; ++ TPML_PCR_SELECTION_t pcrSelectionOutTmp; ++ TPML_DIGEST_t pcrValuesTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t parameterSize; ++ ++ if (pcrSelectionIn == NULL) ++ return TPM_RC_VALUE; ++ ++ if (pcrUpdateCounter == NULL) ++ pcrUpdateCounter = &pcrUpdateCounterTmp; ++ if (pcrSelectionOut == NULL) ++ pcrSelectionOut = &pcrSelectionOutTmp; ++ if (pcrValues == NULL) ++ pcrValues = &pcrValuesTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_PCR_Read, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_buffer_unpack_u32 (&out, pcrUpdateCounter); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (&out, pcrSelectionOut); ++ grub_Tss2_MU_TPML_DIGEST_Unmarshal (&out, pcrValues); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_policygetdigest (const TPMI_SH_POLICY_t policySession, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ TPM2B_DIGEST_t *policyDigest, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPM2B_DIGEST_t policyDigestTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t parameterSize; ++ ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ if (policyDigest == NULL) ++ policyDigest = &policyDigestTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ grub_memset (policyDigest, 0, sizeof (*policyDigest)); ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, policySession); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_PolicyGetDigest, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, policyDigest); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_create (const TPMI_DH_OBJECT_t parentHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_SENSITIVE_CREATE_t *inSensitive, ++ const TPM2B_PUBLIC_t *inPublic, ++ const TPM2B_DATA_t *outsideInfo, ++ const TPML_PCR_SELECTION_t *creationPCR, ++ TPM2B_PRIVATE_t *outPrivate, ++ TPM2B_PUBLIC_t *outPublic, ++ TPM2B_CREATION_DATA_t *creationData, ++ TPM2B_DIGEST_t *creationHash, ++ TPMT_TK_CREATION_t *creationTicket, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM2B_PUBLIC_t outPublicTmp; ++ TPM2B_PRIVATE_t outPrivateTmp; ++ TPM2B_CREATION_DATA_t creationDataTmp; ++ TPM2B_DIGEST_t creationHashTmp; ++ TPMT_TK_CREATION_t creationTicketTmp; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS:TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ TPM_RC_t rc; ++ grub_uint32_t parameterSize; ++ ++ if (inSensitive == NULL || inPublic == NULL || outsideInfo == NULL || ++ creationPCR == NULL) ++ return TPM_RC_VALUE; ++ ++ if (outPrivate == NULL) ++ outPrivate = &outPrivateTmp; ++ if (outPublic == NULL) ++ outPublic = &outPublicTmp; ++ if (creationData == NULL) ++ creationData = &creationDataTmp; ++ if (creationHash == NULL) ++ creationHash = &creationHashTmp; ++ if (creationTicket == NULL) ++ creationTicket = &creationTicketTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outPrivate, 0, sizeof (*outPrivate)); ++ grub_memset (outPublic, 0, sizeof (*outPublic)); ++ grub_memset (creationData, 0, sizeof (*creationData)); ++ grub_memset (creationHash, 0, sizeof (*creationHash)); ++ grub_memset (creationTicket, 0, sizeof (*creationTicket)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, parentHandle); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); ++ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ grub_Tss2_MU_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); ++ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, creationPCR); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_Create, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&out, outPrivate); ++ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic); ++ grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (&out, creationData); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, creationHash); ++ grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_evictcontrol (const TPMI_RH_PROVISION_t auth, ++ const TPMI_DH_OBJECT_t objectHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPMI_DH_PERSISTENT_t persistentHandle, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ TPM_RC_t rc; ++ grub_uint32_t parameterSize; ++ ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, auth); ++ grub_tpm2_buffer_pack_u32 (&in, objectHandle); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_buffer_pack_u32 (&in, persistentHandle); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_EvictControl, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ { ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ } ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_hash (const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_MAX_BUFFER_t *data, ++ const TPMI_ALG_HASH_t hashAlg, ++ const TPMI_RH_HIERARCHY_t hierarchy, ++ TPM2B_DIGEST_t *outHash, ++ TPMT_TK_HASHCHECK_t *validation, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPM2B_DIGEST_t outHashTmp; ++ TPMT_TK_HASHCHECK_t validationTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (hashAlg == TPM_ALG_NULL) ++ return TPM_RC_VALUE; ++ ++ if (outHash == NULL) ++ outHash = &outHashTmp; ++ if (validation == NULL) ++ validation = &validationTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outHash, 0, sizeof (*outHash)); ++ grub_memset (validation, 0, sizeof (*validation)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (data != NULL) ++ grub_Tss2_MU_TPM2B_Marshal (&in, data->size, data->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_buffer_pack_u16 (&in, hashAlg); ++ grub_tpm2_buffer_pack_u32 (&in, hierarchy); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_Hash, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, outHash); ++ grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_verifysignature (const TPMI_DH_OBJECT_t keyHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_DIGEST_t *digest, ++ const TPMT_SIGNATURE_t *signature, ++ TPMT_TK_VERIFIED_t *validation, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPMT_TK_VERIFIED_t validationTmp; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (digest == NULL || signature == NULL) ++ return TPM_RC_VALUE; ++ ++ if (validation == NULL) ++ validation = &validationTmp; ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (validation, 0, sizeof (*validation)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_buffer_pack_u32 (&in, keyHandle); ++ grub_Tss2_MU_TPM2B_Marshal (&in, digest->size, digest->buffer); ++ grub_Tss2_MU_TPMT_SIGNATURE_Marshal (&in, signature); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_VerifySignature, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (&out, validation); ++ if (tag == TPM_ST_SESSIONS) ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_policyauthorize (const TPMI_SH_POLICY_t policySession, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_DIGEST_t *approvedPolicy, ++ const TPM2B_NONCE_t *policyRef, ++ const TPM2B_NAME_t *keySign, ++ const TPMT_TK_VERIFIED_t *checkTicket, ++ TPMS_AUTH_RESPONSE_t *authResponse) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE_t authResponseTmp; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ grub_uint32_t param_size; ++ ++ if (approvedPolicy == NULL || keySign == NULL || checkTicket == NULL) ++ return TPM_RC_VALUE; ++ ++ if (authResponse == NULL) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, policySession); ++ if (authCommand != NULL) ++ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_Tss2_MU_TPM2B_Marshal (&in, approvedPolicy->size, approvedPolicy->buffer); ++ if (policyRef != NULL) ++ grub_Tss2_MU_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_Tss2_MU_TPM2B_Marshal (&in, keySign->size, keySign->name); ++ grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (&in, checkTicket); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_PolicyAuthorize, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (tag == TPM_ST_SESSIONS) ++ { ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ } ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC_t ++grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms, ++ const TPMS_AUTH_COMMAND_t *authCommand) ++{ ++ TPM_RC_t rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC_t responseCode; ++ ++ if (parms == NULL) ++ return TPM_RC_VALUE; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (&in, parms); ++ if (in.error != 0) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = tpm2_submit_command (tag, TPM_CC_TestParms, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ if (out.error != 0) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} +diff --git a/grub-core/lib/tss2/tpm2_cmd.h b/grub-core/lib/tss2/tpm2_cmd.h +new file mode 100644 +index 000000000..d313cba00 +--- /dev/null ++++ b/grub-core/lib/tss2/tpm2_cmd.h +@@ -0,0 +1,157 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2024 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_TPM2_COMMANDS_HEADER ++#define GRUB_TPM2_COMMANDS_HEADER 1 ++ ++#include ++ ++extern TPM_RC_t ++grub_tpm2_createprimary (const TPMI_RH_HIERARCHY_t primaryHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_SENSITIVE_CREATE_t *inSensitive, ++ const TPM2B_PUBLIC_t *inPublic, ++ const TPM2B_DATA_t *outsideInfo, ++ const TPML_PCR_SELECTION_t *creationPCR, ++ TPM_HANDLE_t *objectHandle, ++ TPM2B_PUBLIC_t *outPublic, ++ TPM2B_CREATION_DATA_t *creationData, ++ TPM2B_DIGEST_t *creationHash, ++ TPMT_TK_CREATION_t *creationTicket, ++ TPM2B_NAME_t *name, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_startauthsession (const TPMI_DH_OBJECT_t tpmKey, ++ const TPMI_DH_ENTITY_t bind, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_NONCE_t *nonceCaller, ++ const TPM2B_ENCRYPTED_SECRET_t *encryptedSalt, ++ const TPM_SE_t sessionType, ++ const TPMT_SYM_DEF_t *symmetric, ++ const TPMI_ALG_HASH_t authHash, ++ TPMI_SH_AUTH_SESSION_t *sessionHandle, ++ TPM2B_NONCE_t *nonceTpm, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_policypcr (const TPMI_SH_POLICY_t policySession, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_DIGEST_t *pcrDigest, ++ const TPML_PCR_SELECTION_t *pcrs, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ TPM2B_PUBLIC_t *outPublic); ++ ++extern TPM_RC_t ++grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_PRIVATE_t *inPrivate, ++ const TPM2B_PUBLIC_t *inPublic, ++ TPM_HANDLE_t *objectHandle, ++ TPM2B_NAME_t *name, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_SENSITIVE_t *inPrivate, ++ const TPM2B_PUBLIC_t *inPublic, ++ const TPMI_RH_HIERARCHY_t hierarchy, ++ TPM_HANDLE_t *objectHandle, ++ TPM2B_NAME_t *name, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_unseal (const TPMI_DH_OBJECT_t item_handle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ TPM2B_SENSITIVE_DATA_t *outData, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle); ++ ++extern TPM_RC_t ++grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPML_PCR_SELECTION_t *pcrSelectionIn, ++ grub_uint32_t *pcrUpdateCounter, ++ TPML_PCR_SELECTION_t *pcrSelectionOut, ++ TPML_DIGEST_t *pcrValues, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_policygetdigest (const TPMI_SH_POLICY_t policySession, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ TPM2B_DIGEST_t *policyDigest, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_create (const TPMI_DH_OBJECT_t parentHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_SENSITIVE_CREATE_t *inSensitive, ++ const TPM2B_PUBLIC_t *inPublic, ++ const TPM2B_DATA_t *outsideInfo, ++ const TPML_PCR_SELECTION_t *creationPCR, ++ TPM2B_PRIVATE_t *outPrivate, ++ TPM2B_PUBLIC_t *outPublic, ++ TPM2B_CREATION_DATA_t *creationData, ++ TPM2B_DIGEST_t *creationHash, ++ TPMT_TK_CREATION_t *creationTicket, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_evictcontrol (const TPMI_RH_PROVISION_t auth, ++ const TPMI_DH_OBJECT_t objectHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPMI_DH_PERSISTENT_t persistentHandle, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_hash (const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_MAX_BUFFER_t *data, ++ const TPMI_ALG_HASH_t hashAlg, ++ const TPMI_RH_HIERARCHY_t hierarchy, ++ TPM2B_DIGEST_t *outHash, ++ TPMT_TK_HASHCHECK_t *validation, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_verifysignature (const TPMI_DH_OBJECT_t keyHandle, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_DIGEST_t *digest, ++ const TPMT_SIGNATURE_t *signature, ++ TPMT_TK_VERIFIED_t *validation, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_policyauthorize (const TPMI_SH_POLICY_t policySession, ++ const TPMS_AUTH_COMMAND_t *authCommand, ++ const TPM2B_DIGEST_t *approvedPolicy, ++ const TPM2B_NONCE_t *policyRef, ++ const TPM2B_NAME_t *keySign, ++ const TPMT_TK_VERIFIED_t *checkTicket, ++ TPMS_AUTH_RESPONSE_t *authResponse); ++ ++extern TPM_RC_t ++grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms, ++ const TPMS_AUTH_COMMAND_t *authCommand); ++ ++#endif /* ! GRUB_TPM2_COMMANDS_HEADER */ +diff --git a/grub-core/lib/tss2/tss2.c b/grub-core/lib/tss2/tss2.c +new file mode 100644 +index 000000000..48251e9b4 +--- /dev/null ++++ b/grub-core/lib/tss2/tss2.c +@@ -0,0 +1,21 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2024 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 . ++ */ ++ ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); +-- +2.43.0 + diff --git a/grub2-bsc1220338-key_protector-implement-the-blocklist.patch b/grub2-bsc1220338-key_protector-implement-the-blocklist.patch index b7345e9..fe8887e 100644 --- a/grub2-bsc1220338-key_protector-implement-the-blocklist.patch +++ b/grub2-bsc1220338-key_protector-implement-the-blocklist.patch @@ -1,4 +1,4 @@ -From beb26b1be325ea55f3f9a230152d170a3faa85d5 Mon Sep 17 00:00:00 2001 +From 32e07f7b99a1dbae933f4d916b0342a82e7ccf35 Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Mon, 18 Mar 2024 14:53:11 +0800 Subject: [PATCH] key_protector: implement the blocklist @@ -15,11 +15,11 @@ Signed-off-by: Gary Lin include/grub/efi/api.h | 5 +++++ 2 files changed, 36 insertions(+) -diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c -index b84afe1c7..3d630ca4f 100644 ---- a/grub-core/disk/key_protector.c -+++ b/grub-core/disk/key_protector.c -@@ -24,6 +24,10 @@ +Index: grub-2.12/grub-core/disk/key_protector.c +=================================================================== +--- grub-2.12.orig/grub-core/disk/key_protector.c ++++ grub-2.12/grub-core/disk/key_protector.c +@@ -25,6 +25,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); @@ -30,7 +30,7 @@ index b84afe1c7..3d630ca4f 100644 struct grub_key_protector *grub_key_protectors = NULL; grub_err_t -@@ -54,11 +58,34 @@ grub_key_protector_unregister (struct grub_key_protector *protector) +@@ -53,11 +57,34 @@ grub_key_protector_unregister (struct gr return GRUB_ERR_NONE; } @@ -64,10 +64,10 @@ index b84afe1c7..3d630ca4f 100644 + grub_err_t err; if (grub_key_protectors == NULL) - return GRUB_ERR_OUT_OF_RANGE; -@@ -74,5 +101,9 @@ grub_key_protector_recover_key (const char *protector, grub_uint8_t **key, - "Is the name spelled correctly and is the " - "corresponding module loaded?"), protector); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered"); +@@ -69,5 +96,9 @@ grub_key_protector_recover_key (const ch + if (kp == NULL) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector); + err = grub_key_protector_check_blocklist (); + if (err != GRUB_ERR_NONE) @@ -75,10 +75,10 @@ index b84afe1c7..3d630ca4f 100644 + return kp->recover_key (key, key_size); } -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 7947cf592..975b90b09 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h +Index: grub-2.12/include/grub/efi/api.h +=================================================================== +--- grub-2.12.orig/include/grub/efi/api.h ++++ grub-2.12/include/grub/efi/api.h @@ -389,6 +389,11 @@ { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ } @@ -91,6 +91,3 @@ index 7947cf592..975b90b09 100644 struct grub_efi_sal_system_table { grub_uint32_t signature; --- -2.35.3 - diff --git a/grub2-s390x-secure-execution-support.patch b/grub2-s390x-secure-execution-support.patch new file mode 100644 index 0000000..b6b4244 --- /dev/null +++ b/grub2-s390x-secure-execution-support.patch @@ -0,0 +1,361 @@ +From 023b569648eece7a7fe2ae38d731185a1f2abeb5 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Fri, 23 Aug 2024 09:57:03 +0800 +Subject: [PATCH] s390x: add Secure Execution support + +To support Secure Execution, 2 extra files and 5 environment variables +are introduced. + +- se-parm.conf.in + The template file for the kernel parameter to be used by 'genprotimg' + +- se-zipl2grub.conf.in + The template file of zipl.conf for secure execution + +- SUSE_S390_SE_ENABLE + The variable to enable s390x Secure Execution + +- SUSE_S390_SE_HOST_KEY + The variable to set the file list to the host key documents + +- SUSE_S390_SE_HOST_KEY_SIGNING_KEY + The variable to set the file list to the signing key certificates + +- SUSE_S390_SE_CA_CERT + The variable to set the file path to the CA certificate + +- SUSE_S390_SE_REVOCATION_LIST + The variable to set the file list of the host key revocation lists + +When enabling Secure Execution, the zipl initrd is generated in +"/dev/shm/zipl-se" instead of "/boot/zipl" because the zipl initrd +may contain the LUKS key for the encrypted root partition. Then, +'genprotimg' stores the encrypted image, a combination of the zipl +kernel, zipl initrd, and the kernel parameters, as +"/boot/secure-linux-$version". To make the image ready for zipl, +it is copied to "/boot/zipl/secure-linux-$version" and linked to +"/boot/zipl/secure-linux" which is expected by the zipl config. +--- + Makefile.util.def | 17 +++ + util/s390x/se-parm.conf.in | 1 + + util/s390x/se-zipl2grub.conf.in | 17 +++ + util/s390x/zipl2grub.pl.in | 202 ++++++++++++++++++++++++++------ + 4 files changed, 198 insertions(+), 39 deletions(-) + create mode 100644 util/s390x/se-parm.conf.in + create mode 100644 util/s390x/se-zipl2grub.conf.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index ffedea24a..722542933 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -796,6 +796,23 @@ data = { + emu_condition = COND_s390x; + }; + ++data = { ++ name = se-parm.conf.in; ++ common = util/s390x/se-parm.conf.in; ++ installdir = grubconf; ++ enable = emu; ++ emu_condition = COND_s390x; ++}; ++ ++data = { ++ name = se-zipl2grub.conf.in; ++ common = util/s390x/se-zipl2grub.conf.in; ++ installdir = grubconf; ++ enable = emu; ++ emu_condition = COND_s390x; ++}; ++ ++ + script = { + name = dracut-module-setup.sh; + common = util/s390x/dracut-module-setup.sh.in; +diff --git a/util/s390x/se-parm.conf.in b/util/s390x/se-parm.conf.in +new file mode 100644 +index 000000000..63959b753 +--- /dev/null ++++ b/util/s390x/se-parm.conf.in +@@ -0,0 +1 @@ ++root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 +diff --git a/util/s390x/se-zipl2grub.conf.in b/util/s390x/se-zipl2grub.conf.in +new file mode 100644 +index 000000000..e9feeb9b6 +--- /dev/null ++++ b/util/s390x/se-zipl2grub.conf.in +@@ -0,0 +1,17 @@ ++## This is the template for '@zipldir@/config' and is subject to ++## rpm's %config file handling in case of grub2-s390x-emu package update. ++ ++[defaultboot] ++defaultmenu = menu ++ ++[grub2-secure] ++ target = @zipldir@ ++ image = @zipldir@/secure-linux ++ ++:menu ++ target = @zipldir@ ++ timeout = 60 ++ default = 1 ++ prompt = 0 ++ secure = @SUSE_SECURE_BOOT@ ++ 1 = grub2-secure +diff --git a/util/s390x/zipl2grub.pl.in b/util/s390x/zipl2grub.pl.in +index 46b902209..930ecc4cd 100644 +--- a/util/s390x/zipl2grub.pl.in ++++ b/util/s390x/zipl2grub.pl.in +@@ -12,10 +12,19 @@ my $definitrd = "/boot/initrd"; + my $Image = "$defimage"; + my $previous = ".prev"; + my $zipldir = ""; ++my $imgdir = ""; + my $running = ""; + my $refresh = 1; # needs to default to "on" until most bugs are shaken out! + my $force = 0; + my $hostonly = 1; ++my $secure_exec = 0; ++my $sehostkey = ""; ++my $sesignkey = ""; ++my $secacert = ""; ++my $serevoke = ""; ++my $separm= ""; ++my $se_zipconf = '@sysconfdir@/default/se-zipl2grub.conf.in'; ++my $se_kernparm = '@sysconfdir@/default/se-parm.conf.in'; + my $verbose = 0; + my $debug = 0; + my $miss = 0; +@@ -183,6 +192,55 @@ sub ChkInitrd($$) { + return $found; + } + ++sub GenSEImage($$$$) { ++ my( $kernel, $initrd, $parm, $out_image) = @_; ++ ++ # genprotimg -i \ ++ # -r > \ ++ # -p \ ++ # --host-key-document \ ++ # --cert ibm-z-host-key-signing.crt \ ++ # --cert DigiCertCA.crt \ ++ # --crl revocation.crl \ ++ # -o /boot/zipl/secure-linux ++ ++ my @C = ( "genprotimg", "-i", $kernel, "-r", $initrd, "-p", $parm, ++ "--cert", $secacert); ++ ++ # Handle the host key document list ++ if ($sehostkey) { ++ my @sehostkey_list = split('[,\s]+', $sehostkey); ++ my $hkd; ++ foreach $hkd (@sehostkey_list) { ++ Panic( 1, "$C: host key document '$hkd' not readable!?\n") unless (-r $hkd); ++ push @C, "--host-key-document", $hkd; ++ } ++ } ++ ++ # Handle the signing key list ++ if ($sesignkey) { ++ my @sesignkey_list = split('[,\s]+', $sesignkey); ++ my $signkey; ++ foreach $signkey (@sesignkey_list) { ++ Panic( 1, "$C: signing key '$signkey' not readable!?\n") unless (-r $signkey); ++ push @C, "--cert", $signkey; ++ } ++ } ++ ++ # Handle the revocation list files ++ if ($serevoke) { ++ my @serevoke_list = split('[,\s]+', $serevoke); ++ my $crl; ++ foreach $crl (@serevoke_list) { ++ Panic( 1, "$C: revocation list '$crl' not readable!?\n") unless (-r $crl); ++ push @C, "--crl", $crl; ++ } ++ } ++ ++ push @C, "-o", "$out_image"; ++ System( @C); ++} ++ + sub Usage($) { + my @cat = ("", + "Parameter error.", +@@ -401,49 +459,91 @@ if ( $debug && $verbose > 2 ) { + } + } + +-open( IN, "< $in") || +- Panic( 1, "$C: Failed to open 'zipl.conf' template: $!.\n"); +-while ( ) { +- Info( 4, "$.. <$_$.. >"); +- if ( $. == 1 && m{^## This} ) { +- $_ = "## This file was written by 'grub2-install/$C'\n" . +- "## filling '$in' as template\n"; +- } elsif ( $. == 2 && m{^## rpm's} ) { +- $_ = "## with values from '$default'.\n" . +- "## In-place modifications will eventually go missing!\n"; ++# ++# s390x Secure Execution variables ++# ++# SUSE_S390_SE_ENABLE: enabling s390x Secure Execution ++# SUSE_S390_SE_HOST_KEY: the host key ++# SUSE_S390_SE_HOST_KEY_SIGNING_KEY: the signing key of the host key ++# SUSE_S390_SE_CA_CERT: the CA certificate ++# SUSE_S390_SE_REVOCATION_LIST: the revocation list ++# ++if ( -r $C{SUSE_S390_SE_HOST_KEY} && -r $C{SUSE_S390_SE_HOST_KEY_SIGNING_KEY} && ++ -r $C{SUSE_S390_SE_CA_CERT}) { ++ ++ $sehostkey = $C{SUSE_S390_SE_HOST_KEY}; ++ $sesignkey = $C{SUSE_S390_SE_HOST_KEY_SIGNING_KEY}; ++ $secacert = $C{SUSE_S390_SE_CA_CERT}; ++ ++ $serevoke = $C{SUSE_S390_SE_REVOCATION_LIST} if $C{SUSE_S390_SE_REVOCATION_LIST}; ++ ++ if ( $C{SUSE_S390_SE_ENABLE} =~ m{^(yes|true|1)$} ) { ++ $secure_exec = 1; + } +- while ( m{\@([^\@\s]+)\@} ) { +- my $k = $1; +- my $v; +- if ( exists( $C{$k}) ) { +- $v = $C{$k}; +- } elsif ( exists( $Mandatory{$k}) ) { +- $v = "$k"; +- $miss++; +- } else { +- $v = ""; ++} ++ ++sub MkConfig($$) { ++ my( $template, $name) = @_; ++ open( IN, "< $template") || ++ Panic( 1, "$C: Failed to open '$name' template: $!.\n"); ++ while ( ) { ++ Info( 4, "$.. <$_$.. >"); ++ if ( $. == 1 && m{^## This} ) { ++ $_ = "## This file was written by 'grub2-install/$C'\n" . ++ "## filling '$template' as template\n"; ++ } elsif ( $. == 2 && m{^## rpm's} ) { ++ $_ = "## with values from '$default'.\n" . ++ "## In-place modifications will eventually go missing!\n"; + } +- if ($k eq "GRUB_DEVICE") { +- if (($v !~ /^UUID/ && ! -e $v) || +- (exists( $C{SUSE_REMOVE_LINUX_ROOT_PARAM}) && +- $C{SUSE_REMOVE_LINUX_ROOT_PARAM} eq "true")) { +- s{root=\@$k\@}{}g; +- next; ++ while ( m{\@([^\@\s]+)\@} ) { ++ my $k = $1; ++ my $v; ++ if ( exists( $C{$k}) ) { ++ $v = $C{$k}; ++ } elsif ( exists( $Mandatory{$k}) ) { ++ $v = "$k"; ++ $miss++; ++ } else { ++ $v = ""; ++ } ++ if ($k eq "GRUB_DEVICE") { ++ if (($v !~ /^UUID/ && ! -e $v) || ++ (exists( $C{SUSE_REMOVE_LINUX_ROOT_PARAM}) && ++ $C{SUSE_REMOVE_LINUX_ROOT_PARAM} eq "true")) { ++ s{root=\@$k\@}{}g; ++ next; ++ } + } ++ s{\@$k\@}{$v}g; + } +- s{\@$k\@}{$v}g; ++ Info( 3, $_); ++ $cfg .= $_; ++ } ++ if ( $miss ) { ++ Info( 1, "Partially filled config:\n===\n$cfg===\n"); ++ Panic( 1, "$C: '$name' template could not be filled. \n"); + } +- Info( 3, $_); +- $cfg .= $_; + } +-if ( $miss ) { +- Info( 1, "Partially filled config:\n===\n$cfg===\n"); +- Panic( 1, "$C: 'zipl.conf' template could not be filled. \n"); ++ ++if ( $secure_exec ) { ++ # create the kernel parameter file ++ MkConfig($se_kernparm, "parm.conf"); ++ $separm = $cfg; ++ ++ # clean up $cfg to reuse the variable for zipl.conf ++ $cfg = ""; ++ MkConfig($se_zipconf, "zipl.conf"); ++ $imgdir = "/dev/shm/zipl-se"; ++ ++ mkdir ($imgdir, 0700) unless (-d $imgdir); ++} else { ++ MkConfig($in, "zipl.conf"); ++ $imgdir = $zipldir; + } + + # copy out kernel and initrd +-my $ziplimage = "$zipldir/image"; +-my $ziplinitrd = "$zipldir/initrd"; ++my $ziplimage = "$imgdir/image"; ++my $ziplinitrd = "$imgdir/initrd"; + + if ( ! $running && ! $force ) { + chomp( $running = qx{uname -r}); +@@ -478,18 +578,42 @@ my $initrd = "initrd-$version"; + $image = "image-$version"; + + if ( ! -r $ziplimage || ! -r $ziplinitrd || $refresh ) { +- BootCopy( $Image, $image, $zipldir, "image"); +- BootCopy( $initrd, $initrd, $zipldir, "initrd") ++ BootCopy( $Image, $image, $imgdir, "image"); ++ BootCopy( $initrd, $initrd, $imgdir, "initrd") + if (-r "/boot/$initrd" && ! exists( $fsdev{"/boot"})); + } +-if ( $refresh || ChkInitrd( $zipldir, "initrd") <= 0 ) { +- MkInitrd( $initrd, $zipldir, $version); ++if ( $refresh || ChkInitrd( $imgdir, "initrd") <= 0 ) { ++ MkInitrd( $initrd, $imgdir, $version); + } +-if ( ChkInitrd( $zipldir, "initrd") == 0 ) { ++if ( ChkInitrd( $imgdir, "initrd") == 0 ) { + Info( 0, "$C: dracut does not work as expected! Help needed!\n"); + $miss++; + } + ++if ( $secure_exec ) { ++ my $seimage = "secure-linux-$version"; ++ my $parmconf = "$imgdir/parm.conf"; ++ my $bootseimg = "/boot/$seimage"; ++ ++ # write parm.conf ++ if ( ! $debug ) { ++ open( OUT, "> $parmconf") || die; ++ print( OUT $separm) || die; ++ close( OUT); ++ } else { ++ print( STDERR $separm); ++ } ++ ++ # Create the secure-execution image in /boot first ++ GenSEImage( $ziplimage, $ziplinitrd, $parmconf, $bootseimg ); ++ ++ # check /boot/$seimage ++ Panic( 1, "$C: Secure Image '$bootseimg' not readable!?\n") unless (-r "$bootseimg"); ++ ++ # copy /boot/$seimage to $zipldir ++ BootCopy($seimage, $seimage, $zipldir, "secure-linux"); ++} ++ + # write zipl config file + my $ziplconf = "$zipldir/config"; + $cfg =~ s{#@}{}g if ( -r "$ziplimage$previous" && -r "$ziplinitrd$previous" ); +-- +2.43.0 + diff --git a/grub2-s390x-set-hostonly.patch b/grub2-s390x-set-hostonly.patch index 63b5679..89b376e 100644 --- a/grub2-s390x-set-hostonly.patch +++ b/grub2-s390x-set-hostonly.patch @@ -1,3 +1,24 @@ +From 2a86e5f9e3abb622d2e16ee5f05b1ba2df1f756d Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Tue, 6 Aug 2024 14:46:17 +0800 +Subject: [PATCH] zipl2grub.pl.in: add the switch for hostonly/no-hostonly + +Since the kiwi build environment could be very different from the real +system environment, it may cause some problem to build the zipl initrd +with '--hostonly' since some critical files could be omitted +accidentally. To avoid the potential issues, this commit introduces a +variable, SUSE_S390_DRACUT_HOSTONLY, as the switch to use hostonly or +no-hostonly for the zipl initrd. By default, it's detected automatically +by tracing the root partition to the root block device. If the root +block device is a loop device, then it's likely to be a build +environment, and then '--no-hostonly' will be used to create the zipl +initrd. + +Signed-off-by: Gary Lin +--- + util/s390x/zipl2grub.pl.in | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + diff --git a/util/s390x/zipl2grub.pl.in b/util/s390x/zipl2grub.pl.in index f4f997100..46b902209 100644 --- a/util/s390x/zipl2grub.pl.in @@ -50,3 +71,6 @@ index f4f997100..46b902209 100644 if ( $debug && $verbose > 2 ) { foreach ( sort( keys( %C)) ) { printf( "%s=\"%s\"\n", $_, $C{$_}); +-- +2.35.3 + diff --git a/grub2.changes b/grub2.changes index 9079f22..6c8b000 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,104 @@ +------------------------------------------------------------------- +Sun Dec 8 10:22:43 UTC 2024 - Michael Chang + +- Update PowerPC SBAT patches to upstream (bsc#1233730) + * 0007-grub-mkimage-Create-new-ELF-note-for-SBAT.patch + * 0008-grub-mkimage-Add-SBAT-metadata-into-ELF-note-for-Pow.patch +- Replaced patches + * 0007-mkimage-create-new-ELF-Note-for-SBAT.patch + * 0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch + +------------------------------------------------------------------- +Fri Dec 6 16:40:54 UTC 2024 - Michael Chang + +- Fix missing requires in SLE package (bsc#1234264) (bsc#1234272) + +------------------------------------------------------------------- +Tue Dec 3 07:18:32 UTC 2024 - Gary Ching-Pang Lin + +- Update the TPM2 patches to the upstream final version + * Update 0001-key_protector-Add-key-protectors-framework.patch + * Replace 0002-tpm2-Add-TPM-Software-Stack-TSS.patch with + grub2-add-tss2-support.patch + * Replace 0003-key_protector-Add-TPM2-Key-Protector.patch with + 0001-key_protector-Add-TPM2-Key-Protector.patch + * Replace 0005-util-grub-protect-Add-new-tool.patch with + 0001-util-grub-protect-Add-new-tool.patch + * Replace 0001-tpm2-Implement-NV-index.patch with + 0001-tpm2_key_protector-Implement-NV-index.patch + * Replace 0001-tpm2-Support-authorized-policy.patch with + 0001-tpm2_key_protector-Support-authorized-policy.patch +- Refresh the TPM2 related patches + * grub-read-pcr.patch + * 0001-tpm2-Add-extra-RSA-SRK-types.patch + * grub2-bsc1220338-key_protector-implement-the-blocklist.patch + * safe_tpm_pcr_snapshot.patch + * tpm-record-pcrs.patch + +------------------------------------------------------------------- +Fri Nov 29 05:56:22 UTC 2024 - Gary Ching-Pang Lin + +- Support s390x Secure Execution (jsc#PED-9531) + * grub2-s390x-secure-execution-support.patch +- Update grub2-s390x-set-hostonly.patch to add the patch header + and the description + +------------------------------------------------------------------- +Wed Nov 13 01:09:47 UTC 2024 - Michael Chang + +- Revert the patches related to BLS support in grub2-mkconfig, as they are not + relevant to the current BLS integration and cause issues in older KIWI + versions, which actively force it to be enabled by default (bsc#1233196) + * 0002-Add-BLS-support-to-grub-mkconfig.patch + * 0003-Add-grub2-switch-to-blscfg.patch + * 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch + * 0008-blscfg-reading-bls-fragments-if-boot-present.patch + * 0009-10_linux-Some-refinement-for-BLS.patch + * 0001-10_linux-Do-not-enable-BLSCFG-on-s390-emu.patch + +------------------------------------------------------------------- +Fri Nov 8 14:42:12 UTC 2024 - Michael Chang + +- Fix previous change as the variable has to be set earlier + * 0001-10_linux-Do-not-enable-BLSCFG-on-s390-emu.patch + +------------------------------------------------------------------- +Fri Nov 8 05:21:47 UTC 2024 - Michael Chang + +- Do not enable blscfg on s390-emu + * 0001-10_linux-Do-not-enable-BLSCFG-on-s390-emu.patch + +------------------------------------------------------------------- +Wed Nov 6 07:45:21 UTC 2024 - Michael Chang + +- Fix xen package contains debug_info files with the .module suffix by moving + them to a separate xen-debug subpackage (bsc#1232573) + +------------------------------------------------------------------- +Fri Nov 1 08:46:36 UTC 2024 - Michael Chang + +- Fix grub.cfg is loaded from an unexpected fallback directory instead of the + root directory during PXE boot when grub is loaded from the tftp root + directory (bsc#1232391) + * 0001-kern-main-Fix-cmdpath-in-root-directory.patch + * grub2.spec: Refine PPC grub.elf early config to derive root from cmdpath + directly, avoiding the unneeded search + +------------------------------------------------------------------- +Wed Oct 30 08:24:15 UTC 2024 - Michael Chang + +- Fix CVE-2024-49504 (bsc#1229163) (bsc#1229164) +- Restrict CLI access if the encrypted root device is automatically unlocked by + the TPM. LUKS password authentication is required for access to be granted + * 0001-cli_lock-Add-build-option-to-block-command-line-inte.patch + * 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch +- Obsolete, as CLI access is now locked and granted access no longer requires + the previous restrictions + * 0002-Restrict-file-access-on-cryptodisk-print.patch + * 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch +- Rediff + * 0004-Key-revocation-on-out-of-bound-file-access.patch + ------------------------------------------------------------------- Wed Oct 30 00:44:41 UTC 2024 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 9c0bc97..aa660fc 100644 --- a/grub2.spec +++ b/grub2.spec @@ -339,10 +339,10 @@ Patch147: 0001-grub-probe-Deduplicate-probed-partmap-output.patch Patch148: 0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch Patch149: 0001-ofdisk-improve-boot-time-by-lookup-boot-disk-first.patch Patch150: 0001-key_protector-Add-key-protectors-framework.patch -Patch151: 0002-tpm2-Add-TPM-Software-Stack-TSS.patch -Patch152: 0003-key_protector-Add-TPM2-Key-Protector.patch +Patch151: grub2-add-tss2-support.patch +Patch152: 0001-key_protector-Add-TPM2-Key-Protector.patch Patch153: 0004-cryptodisk-Support-key-protectors.patch -Patch154: 0005-util-grub-protect-Add-new-tool.patch +Patch154: 0001-util-grub-protect-Add-new-tool.patch Patch155: 0008-linuxefi-Use-common-grub_initrd_load.patch Patch156: 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch Patch157: 0010-templates-import-etc-crypttab-to-grub.cfg.patch @@ -356,7 +356,7 @@ Patch164: 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch Patch165: 0004-ofpath-controller-name-update.patch Patch166: 0002-Mark-environmet-blocks-as-used-for-image-embedding.patch Patch167: grub2-increase-crypttab-path-buffer.patch -Patch170: 0001-tpm2-Support-authorized-policy.patch +Patch170: 0001-tpm2_key_protector-Support-authorized-policy.patch Patch171: 0001-tpm2-Add-extra-RSA-SRK-types.patch Patch174: 0001-clean-up-crypttab-and-linux-modules-dependency.patch Patch175: 0002-discard-cached-key-before-entering-grub-shell-and-ed.patch @@ -368,7 +368,7 @@ Patch180: 0001-xen_boot-add-missing-grub_arch_efi_linux_load_image_.patch Patch181: 0001-font-Try-memdisk-fonts-with-the-same-name.patch Patch182: 0001-Make-grub.cfg-compatible-to-old-binaries.patch Patch183: grub2-change-bash-completion-dir.patch -Patch184: 0001-tpm2-Implement-NV-index.patch +Patch184: 0001-tpm2_key_protector-Implement-NV-index.patch Patch185: 0002-cryptodisk-Fallback-to-passphrase.patch Patch186: 0003-cryptodisk-wipe-out-the-cached-keys-from-protectors.patch Patch187: 0004-diskfilter-look-up-cryptodisk-devices-first.patch @@ -377,8 +377,6 @@ Patch189: arm64-Use-proper-memory-type-for-kernel-allocation.patch Patch190: 0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch Patch191: Fix-the-size-calculation-for-the-synthesized-initrd.patch Patch192: 0001-Improve-TPM-key-protection-on-boot-interruptions.patch -Patch193: 0002-Restrict-file-access-on-cryptodisk-print.patch -Patch194: 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch Patch195: 0004-Key-revocation-on-out-of-bound-file-access.patch # Workaround for 2.12 tarball Patch196: fix_no_extra_deps_in_release_tarball.patch @@ -394,14 +392,9 @@ Patch205: 0001-10_linux-Ensure-persistence-of-root-file-system-moun.patch Patch206: 0001-util-bash-completion-Fix-for-bash-completion-2.12.patch Patch207: 0001-util-enable-grub-protect-only-for-EFI-systems.patch Patch208: 0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch -Patch209: 0002-Add-BLS-support-to-grub-mkconfig.patch -Patch210: 0003-Add-grub2-switch-to-blscfg.patch Patch211: 0004-blscfg-Don-t-root-device-in-emu-builds.patch Patch212: 0005-blscfg-check-for-mounted-boot-in-emu.patch Patch213: 0006-Follow-the-device-where-blscfg-is-discovered.patch -Patch214: 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch -Patch215: 0008-blscfg-reading-bls-fragments-if-boot-present.patch -Patch216: 0009-10_linux-Some-refinement-for-BLS.patch Patch217: 0001-net-drivers-ieee1275-ofnet-Remove-200-ms-timeout-in-.patch Patch218: grub2-s390x-set-hostonly.patch Patch219: 0001-bli-Fix-crash-in-get_part_uuid.patch @@ -415,10 +408,42 @@ Patch226: 0003-appendedsig-The-creation-of-trusted-and-distrusted-l.patch Patch227: 0004-appendedsig-While-verifying-the-kernel-use-trusted-a.patch Patch228: 0005-appendedsig-The-grub-command-s-trusted-and-distruste.patch Patch229: 0006-appendedsig-documentation.patch -Patch230: 0007-mkimage-create-new-ELF-Note-for-SBAT.patch -Patch231: 0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch +Patch230: 0007-grub-mkimage-Create-new-ELF-note-for-SBAT.patch +Patch231: 0008-grub-mkimage-Add-SBAT-metadata-into-ELF-note-for-Pow.patch Patch232: 0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch Patch233: 0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch +Patch234: 0001-cli_lock-Add-build-option-to-block-command-line-inte.patch +Patch235: 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch +Patch236: 0001-kern-main-Fix-cmdpath-in-root-directory.patch +Patch237: grub2-s390x-secure-execution-support.patch + +%if 0%{?suse_version} <= 1600 +Requires: gettext-runtime +%if 0%{?suse_version} >= 1140 +%ifnarch s390x +Recommends: os-prober +%endif +# xorriso not available using grub2-mkrescue (bnc#812681) +# downgrade to suggest as minimal system can't afford pulling in tcl/tk and half of the x11 stack (bsc#1102515) +Suggests: libburnia-tools +Suggests: mtools +%endif +%ifarch s390x +# required utilities by grub2-s390x-04-grub2-install.patch +# use 'showconsole' to determine console device. (bnc#876743) +Requires: kexec-tools +Requires: (/sbin/showconsole or /usr/sbin/showconsole) +# for /sbin/zipl used by grub2-zipl-setup +Requires: s390-tools +%endif +%ifarch ppc64 ppc64le +Requires: powerpc-utils +%endif +%ifarch %{ix86} +# meanwhile, memtest is available as EFI executable +Recommends: memtest86+ +%endif +%endif %if 0%{?suse_version} > 1600 # Always requires a default cpu-platform package @@ -445,9 +470,7 @@ computer architectures and hardware devices. %package common Summary: Utilies to manage grub Group: System/Boot -%endif Requires: gettext-runtime -%if 0%{?suse_version} >= 1140 %ifnarch s390x Recommends: os-prober %endif @@ -455,7 +478,6 @@ Recommends: os-prober # downgrade to suggest as minimal system can't afford pulling in tcl/tk and half of the x11 stack (bsc#1102515) Suggests: libburnia-tools Suggests: mtools -%endif %ifarch s390x # required utilities by grub2-s390x-04-grub2-install.patch # use 'showconsole' to determine console device. (bnc#876743) @@ -472,7 +494,6 @@ Requires: powerpc-utils Recommends: memtest86+ %endif -%if 0%{?suse_version} > 1600 %description common This package includes user space utlities to manage GRUB on your system. %endif @@ -638,6 +659,18 @@ Provides: %{name}-%{grubxenarch}:%{_datadir}/%{name}/%{grubxenarch}/zfsinf %description %{grubxenarch}-extras Unsupported modules for %{name}-%{grubxenarch} +%package %{grubxenarch}-debug +Summary: Debug symbols for %{grubxenarch} +Group: System/Boot +BuildArch: noarch +Requires: %{name}-%{grubxenarch} = %{version} + +%description %{grubxenarch}-debug +Debug symbols for %{name}-%{grubxenarch} + +Information on how to debug grub can be found online: +https://www.cnblogs.com/coryxie/archive/2013/03/12/2956807.html + %endif %package snapper-plugin @@ -770,7 +803,7 @@ CD_MODULES="all_video boot cat configfile echo true \ PXE_MODULES="tftp http" CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 crypttab" %ifarch %{efi} -CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tpm2 memdisk tar squash4 xzio blscfg" +CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blscfg" PXE_MODULES="${PXE_MODULES} efinet" %else CD_MODULES="${CD_MODULES} net ofnet" @@ -868,7 +901,7 @@ mksquashfs ./boot memdisk.sqsh -keep-as-directory -comp xz -quiet -no-progress %{?sbat_generation:--sbat sbat.csv} \ -d grub-core \ all_video boot font gfxmenu gfxterm gzio halt jpeg minicmd normal part_gpt png reboot video \ - fat tpm tpm2 memdisk tar squash4 xzio blscfg linux bli regexp loadenv test echo true sleep + fat tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blscfg linux bli regexp loadenv test echo true sleep %endif %ifarch x86_64 aarch64 @@ -948,8 +981,6 @@ echo "bpath=$bpath" if regexp '^(tftp|http)$' "$bdev"; then if [ -z "$bpath" ]; then echo "network booting via $bdev but firmware didn't provide loaded path from sever root" - bpath="/boot/grub2/powerpc-ieee1275" - echo "using bpath=$bpath as fallback path" fi elif [ -z "$ENV_FS_UUID" ]; then echo "Reading vars from ($bdev)" @@ -994,6 +1025,17 @@ set prefix="" set root="" set cfg="grub.cfg" +if regexp '^(tftp|http)$' "$bdev"; then + cfg_dir="" + root="$bdev$bpart" + if [ -z "$bpath" ]; then + bpath="/boot/grub2/powerpc-ieee1275" + echo "using bpath=$bpath as fallback path" + fi + prefix="($root)$bpath" + cfg="grub.cfg" +fi + for uuid in $ENV_CRYPTO_UUID; do cryptomount -u $uuid done @@ -1176,7 +1218,11 @@ rm -f $R%{_sysconfdir}/grub.d/20_ppc_terminfo %ifarch s390x mv $R%{_sysconfdir}/{grub.d,default}/zipl2grub.conf.in +mv $R%{_sysconfdir}/{grub.d,default}/se-zipl2grub.conf.in +mv $R%{_sysconfdir}/{grub.d,default}/se-parm.conf.in chmod 600 $R%{_sysconfdir}/default/zipl2grub.conf.in +chmod 600 $R%{_sysconfdir}/default/se-zipl2grub.conf.in +chmod 600 $R%{_sysconfdir}/default/se-parm.conf.in %define dracutlibdir %{_prefix}/lib/dracut %define dracutgrubmoddir %{dracutlibdir}/modules.d/99grub2 @@ -1211,9 +1257,9 @@ perl -ni -e ' # EXTRA_PATTERN='pattern1|pattern2|pattern3|...' EXTRA_PATTERN="zfs" %ifarch %{ix86} x86_64 -find %{buildroot}/%{_datadir}/%{name}/%{grubxenarch}/ -type f | sed 's,%{buildroot},,' > %{grubxenarch}-all.lst -grep -v -E ${EXTRA_PATTERN} %{grubxenarch}-all.lst > %{grubxenarch}.lst -grep -E ${EXTRA_PATTERN} %{grubxenarch}-all.lst > %{grubxenarch}-extras.lst +find %{buildroot}/%{_datadir}/%{name}/%{grubxenarch}/ -name '*.mod' | sed 's,%{buildroot},,' > %{grubxenarch}-mod-all.lst +grep -v -E ${EXTRA_PATTERN} %{grubxenarch}-mod-all.lst > %{grubxenarch}-mod.lst +grep -E ${EXTRA_PATTERN} %{grubxenarch}-mod-all.lst > %{grubxenarch}-mod-extras.lst %endif %ifarch %{efi} @@ -1342,6 +1388,8 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst %endif %ifarch s390x %config(noreplace) %{_sysconfdir}/default/zipl2grub.conf.in +%config(noreplace) %{_sysconfdir}/default/se-zipl2grub.conf.in +%config(noreplace) %{_sysconfdir}/default/se-parm.conf.in %{dracutlibdir} %{_sbindir}/%{name}-zipl-setup %{_datadir}/%{name}/zipl-refresh @@ -1352,7 +1400,6 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst %{_sbindir}/%{name}-probe %{_sbindir}/%{name}-reboot %{_sbindir}/%{name}-set-default -%{_sbindir}/%{name}-switch-to-blscfg %{_sbindir}/%{name}-check-default %{_bindir}/%{name}-editenv %{_bindir}/%{name}-file @@ -1405,7 +1452,6 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst %{_mandir}/man8/%{name}-probe.8.* %{_mandir}/man8/%{name}-reboot.8.* %{_mandir}/man8/%{name}-set-default.8.* -%{_mandir}/man8/%{name}-switch-to-blscfg.8.* %if %{emu} %{_bindir}/%{name}-emu %{_mandir}/man1/%{name}-emu.1.* @@ -1526,16 +1572,27 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst %{_libdir}/snapper/plugins/grub %ifarch %{ix86} x86_64 -%files %{grubxenarch} -f %{grubxenarch}.lst +%files %{grubxenarch} -f %{grubxenarch}-mod.lst %defattr(-,root,root,-) %dir %{_datadir}/%{name}/%{grubxenarch} # provide compatibility sym-link for VM definitions pointing to old location %dir %{_libdir}/%{name} %{_libdir}/%{name}/%{grubxenarch} +%{_datadir}/%{name}/%{grubxenarch}/grub.xen +%{_datadir}/%{name}/%{grubxenarch}/*.img +%{_datadir}/%{name}/%{grubxenarch}/*.lst +%{_datadir}/%{name}/%{grubxenarch}/kernel.exec +%{_datadir}/%{name}/%{grubxenarch}/modinfo.sh -%files %{grubxenarch}-extras -f %{grubxenarch}-extras.lst +%files %{grubxenarch}-extras -f %{grubxenarch}-mod-extras.lst %defattr(-,root,root,-) %dir %{_datadir}/%{name}/%{grubxenarch} + +%files %{grubxenarch}-debug +%defattr(-,root,root,-) +%{_datadir}/%{name}/%{grubxenarch}/gdb_grub +%{_datadir}/%{name}/%{grubxenarch}/gdb_helper.py +%{_datadir}/%{name}/%{grubxenarch}/*.module %endif %if 0%{?has_systemd:1} diff --git a/safe_tpm_pcr_snapshot.patch b/safe_tpm_pcr_snapshot.patch index f571aaa..38d8aef 100644 --- a/safe_tpm_pcr_snapshot.patch +++ b/safe_tpm_pcr_snapshot.patch @@ -3,20 +3,21 @@ util/grub-install.c | 6 ++++-- 2 files changed, 40 insertions(+), 12 deletions(-) ---- a/grub-core/commands/tpm.c -+++ b/grub-core/commands/tpm.c -@@ -27,8 +27,10 @@ +Index: grub-2.12/grub-core/commands/tpm.c +=================================================================== +--- grub-2.12.orig/grub-core/commands/tpm.c ++++ grub-2.12/grub-core/commands/tpm.c +@@ -27,7 +27,9 @@ #include #include #include +#ifdef GRUB_MACHINE_EFI - #include #include +#endif GRUB_MOD_LICENSE ("GPLv3+"); -@@ -97,12 +99,6 @@ +@@ -96,12 +98,6 @@ struct grub_file_verifier grub_tpm_verif .verify_string = grub_tpm_verify_string, }; @@ -29,7 +30,7 @@ static const struct grub_arg_option grub_tpm_record_pcrs_options[] = { { -@@ -118,6 +114,14 @@ +@@ -117,6 +113,14 @@ static const struct grub_arg_option grub {0, 0, 0, 0, 0, 0} }; @@ -44,7 +45,7 @@ static grub_err_t grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index) { -@@ -269,6 +273,10 @@ +@@ -268,6 +272,10 @@ grub_tpm_record_pcrs (grub_extcmd_contex grub_size_t size = 0; int n, rv = 1; @@ -55,7 +56,7 @@ if (argc == 0) pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; else -@@ -297,6 +305,18 @@ +@@ -296,6 +304,18 @@ out: return rv; } @@ -74,9 +75,11 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (tpm) ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -1560,8 +1560,9 @@ +Index: grub-2.12/util/grub-install.c +=================================================================== +--- grub-2.12.orig/util/grub-install.c ++++ grub-2.12/util/grub-install.c +@@ -1574,8 +1574,9 @@ main (int argc, char *argv[]) grub_util_unlink (load_cfg); @@ -87,7 +90,7 @@ load_cfg_f = grub_util_fopen (load_cfg, "wb"); have_load_cfg = 1; fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n"); -@@ -1569,7 +1570,8 @@ +@@ -1583,7 +1584,8 @@ main (int argc, char *argv[]) if (debug_image && debug_image[0]) { diff --git a/tpm-record-pcrs.patch b/tpm-record-pcrs.patch index 40bbb71..bcf207a 100644 --- a/tpm-record-pcrs.patch +++ b/tpm-record-pcrs.patch @@ -1,16 +1,17 @@ ---- a/grub-core/commands/tpm.c -+++ b/grub-core/commands/tpm.c -@@ -26,6 +26,9 @@ +Index: grub-2.12/grub-core/commands/tpm.c +=================================================================== +--- grub-2.12.orig/grub-core/commands/tpm.c ++++ grub-2.12/grub-core/commands/tpm.c +@@ -26,6 +26,8 @@ #include #include #include +#include -+#include +#include GRUB_MOD_LICENSE ("GPLv3+"); -@@ -94,8 +97,214 @@ +@@ -94,8 +96,214 @@ struct grub_file_verifier grub_tpm_verif .verify_string = grub_tpm_verify_string, }; @@ -225,7 +226,7 @@ /* * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(), * it does seem to call it late enough in the initialization sequence so -@@ -109,6 +318,7 @@ +@@ -109,6 +317,7 @@ GRUB_MOD_INIT (tpm) GRUB_MOD_FINI (tpm) {