diff --git a/0001-crytodisk-fix-cryptodisk-module-looking-up.patch b/0001-crytodisk-fix-cryptodisk-module-looking-up.patch deleted file mode 100644 index f19c0d0..0000000 --- a/0001-crytodisk-fix-cryptodisk-module-looking-up.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 822f71318a69c150da3ad7df5fe8667dfa6e8069 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 31 Mar 2022 15:45:35 +0800 -Subject: [PATCH] crytodisk: fix cryptodisk module looking up - -The error "no cryptodisk module can handle this device" may happen even -encrypted disk were correctly formatted and required modules were loaded. - -It is casued by missing break to the loop in which cryptodisk modules are -iterated to find the one matching target's disk format. With the break -statement, the loop will be always ended with testing last cryptodisk module on -the list that may not be able to handle the format of encrypted disk's. - -Signed-off-by: Michael Chang ---- - grub-core/disk/cryptodisk.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 00c44773fb..6d22bf871c 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -1021,6 +1021,7 @@ grub_cryptodisk_scan_device_real (const char *name, - if (!dev) - continue; - crd = cr; -+ break; - } - - if (!dev) --- -2.34.1 - diff --git a/0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch b/0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch deleted file mode 100644 index 20d869e..0000000 --- a/0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8eae4c33a32d9951641e289d2809a92a223b1642 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:50 -0600 -Subject: [PATCH 01/14] luks2: Add debug message to align with luks and geli - modules - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/luks2.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c -index 371a53b837..fea196dd4a 100644 ---- a/grub-core/disk/luks2.c -+++ b/grub-core/disk/luks2.c -@@ -370,7 +370,10 @@ luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot) - uuid[j] = '\0'; - - if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) -- return NULL; -+ { -+ grub_dprintf ("luks2", "%s != %s\n", uuid, check_uuid); -+ return NULL; -+ } - - cryptodisk = grub_zalloc (sizeof (*cryptodisk)); - if (!cryptodisk) --- -2.34.1 - diff --git a/0002-cryptodisk-Refactor-to-discard-have_it-global.patch b/0002-cryptodisk-Refactor-to-discard-have_it-global.patch deleted file mode 100644 index a7a0555..0000000 --- a/0002-cryptodisk-Refactor-to-discard-have_it-global.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 4ace73cc192bc63a00f4208b34981a6d91947811 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:51 -0600 -Subject: [PATCH 02/14] cryptodisk: Refactor to discard have_it global - -The global "have_it" was never used by the crypto-backends, but was used to -determine if a crypto-backend successfully mounted a cryptodisk with a given -UUID. This is not needed however, because grub_device_iterate() will return -1 if and only if grub_cryptodisk_scan_device() returns 1. And -grub_cryptodisk_scan_device() will now only return 1 if a search_uuid has -been specified and a cryptodisk was successfully setup by a crypto-backend or -a cryptodisk of the requested UUID is already open. - -To implement this grub_cryptodisk_scan_device_real() is modified to return -a cryptodisk or NULL on failure and having the appropriate grub_errno set to -indicated failure. Note that grub_cryptodisk_scan_device_real() will fail now -with a new errno GRUB_ERR_BAD_MODULE when none of the cryptodisk backend -modules succeed in identifying the source disk. - -With this change grub_device_iterate() will return 1 when a crypto device is -successfully decrypted or when the source device has already been successfully -opened. Prior to this change, trying to mount an already successfully opened -device would trigger an error with the message "no such cryptodisk found", -which is at best misleading. The mount should silently succeed in this case, -which is what happens with this patch. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++-------------- - 1 file changed, 35 insertions(+), 21 deletions(-) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 90f82b2d39..9df3d310fe 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -983,7 +983,7 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) - - #endif - --static int check_boot, have_it; -+static int check_boot; - static char *search_uuid; - - static void -@@ -995,7 +995,7 @@ cryptodisk_close (grub_cryptodisk_t dev) - grub_free (dev); - } - --static grub_err_t -+static grub_cryptodisk_t - grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) - { - grub_err_t err; -@@ -1005,13 +1005,13 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) -- return GRUB_ERR_NONE; -+ return dev; - - FOR_CRYPTODISK_DEVS (cr) - { - dev = cr->scan (source, search_uuid, check_boot); - if (grub_errno) -- return grub_errno; -+ return NULL; - if (!dev) - continue; - -@@ -1019,16 +1019,16 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) - if (err) - { - cryptodisk_close (dev); -- return err; -+ return NULL; - } - - grub_cryptodisk_insert (dev, name, source); - -- have_it = 1; -- -- return GRUB_ERR_NONE; -+ return dev; - } -- return GRUB_ERR_NONE; -+ -+ grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); -+ return NULL; - } - - #ifdef GRUB_UTIL -@@ -1082,8 +1082,10 @@ static int - grub_cryptodisk_scan_device (const char *name, - void *data __attribute__ ((unused))) - { -- grub_err_t err; -+ int ret = 0; - grub_disk_t source; -+ grub_cryptodisk_t dev; -+ grub_errno = GRUB_ERR_NONE; - - /* Try to open disk. */ - source = grub_disk_open (name); -@@ -1093,13 +1095,26 @@ grub_cryptodisk_scan_device (const char *name, - return 0; - } - -- err = grub_cryptodisk_scan_device_real (name, source); -+ dev = grub_cryptodisk_scan_device_real (name, source); -+ if (dev) -+ { -+ ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); -+ goto cleanup; -+ } - -- grub_disk_close (source); -- -- if (err) -+ /* -+ * Do not print error when err is GRUB_ERR_BAD_MODULE to avoid many unhelpful -+ * error messages. -+ */ -+ if (grub_errno == GRUB_ERR_BAD_MODULE) -+ grub_error_pop (); -+ -+ if (grub_errno != GRUB_ERR_NONE) - grub_print_error (); -- return have_it && search_uuid ? 1 : 0; -+ -+ cleanup: -+ grub_disk_close (source); -+ return ret; - } - - static grub_err_t -@@ -1110,9 +1125,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - if (argc < 1 && !state[1].set && !state[2].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - -- have_it = 0; - if (state[0].set) - { -+ int found_uuid; - grub_cryptodisk_t dev; - - dev = grub_cryptodisk_get_by_uuid (args[0]); -@@ -1125,10 +1140,10 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - - check_boot = state[2].set; - search_uuid = args[0]; -- grub_device_iterate (&grub_cryptodisk_scan_device, NULL); -+ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); - search_uuid = NULL; - -- if (!have_it) -+ if (!found_uuid) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); - return GRUB_ERR_NONE; - } -@@ -1142,7 +1157,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - } - else - { -- grub_err_t err; - grub_disk_t disk; - grub_cryptodisk_t dev; - char *diskname; -@@ -1178,13 +1192,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - return GRUB_ERR_NONE; - } - -- err = grub_cryptodisk_scan_device_real (diskname, disk); -+ dev = grub_cryptodisk_scan_device_real (diskname, disk); - - grub_disk_close (disk); - if (disklast) - *disklast = ')'; - -- return err; -+ return (dev == NULL) ? grub_errno : GRUB_ERR_NONE; - } - } - --- -2.34.1 - diff --git a/0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch b/0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch deleted file mode 100644 index a720702..0000000 --- a/0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 86fe3bbbf75e62387cc9842654fd6c852e9457a6 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:52 -0600 -Subject: [PATCH 03/14] cryptodisk: Return failure in cryptomount when no - cryptodisk modules are loaded - -This displays an error notifying the user that they'll want to load -a backend module to make cryptomount useful. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 9df3d310fe..27491871a5 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -1125,6 +1125,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - if (argc < 1 && !state[1].set && !state[2].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - -+ if (grub_cryptodisk_list == NULL) -+ return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); -+ - if (state[0].set) - { - int found_uuid; --- -2.34.1 - diff --git a/0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch b/0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch deleted file mode 100644 index 775368a..0000000 --- a/0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch +++ /dev/null @@ -1,58 +0,0 @@ -From f41488d0e361a34f4d3f8fb6c92729a2901a5c76 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:53 -0600 -Subject: [PATCH 04/14] cryptodisk: Improve error messaging in cryptomount - invocations - -Update such that "cryptomount -u UUID" will not print two error messages -when an invalid passphrase is given and the most relevant error message -will be displayed. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 21 +++++++++++++++++---- - 1 file changed, 17 insertions(+), 4 deletions(-) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 27491871a5..3a896c6634 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -1109,7 +1109,10 @@ grub_cryptodisk_scan_device (const char *name, - if (grub_errno == GRUB_ERR_BAD_MODULE) - grub_error_pop (); - -- if (grub_errno != GRUB_ERR_NONE) -+ if (search_uuid != NULL) -+ /* Push error onto stack to save for cryptomount. */ -+ grub_error_push (); -+ else - grub_print_error (); - - cleanup: -@@ -1146,9 +1149,19 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); - search_uuid = NULL; - -- if (!found_uuid) -- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); -- return GRUB_ERR_NONE; -+ if (found_uuid) -+ return GRUB_ERR_NONE; -+ else if (grub_errno == GRUB_ERR_NONE) -+ { -+ /* -+ * Try to pop the next error on the stack. If there is not one, then -+ * no device matched the given UUID. -+ */ -+ grub_error_pop (); -+ if (grub_errno == GRUB_ERR_NONE) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); -+ } -+ return grub_errno; - } - else if (state[1].set || (argc == 0 && state[2].set)) - { --- -2.34.1 - diff --git a/0005-cryptodisk-Improve-cryptomount-u-error-message.patch b/0005-cryptodisk-Improve-cryptomount-u-error-message.patch deleted file mode 100644 index 64d03c6..0000000 --- a/0005-cryptodisk-Improve-cryptomount-u-error-message.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 9ef619a7c1d38988f6d91496ea5c59062dcf6013 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:54 -0600 -Subject: [PATCH 05/14] cryptodisk: Improve cryptomount -u error message - -When a cryptmount is specified with a UUID, but no cryptodisk backends find -a disk with that UUID, return a more detailed message giving telling the -user that they might not have a needed cryptobackend module loaded. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 3a896c6634..5a9780b14c 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -1159,7 +1159,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - */ - grub_error_pop (); - if (grub_errno == GRUB_ERR_NONE) -- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found, perhaps a needed disk or cryptodisk module is not loaded"); - } - return grub_errno; - } --- -2.34.1 - diff --git a/0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch b/0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch deleted file mode 100644 index 91fb26d..0000000 --- a/0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 0a5619abd170b3ad43e44cb8036062506d8623cc Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:55 -0600 -Subject: [PATCH 06/14] cryptodisk: Add infrastructure to pass data from - cryptomount to cryptodisk modules - -Previously, the cryptomount arguments were passed by global variable and -function call argument, neither of which are ideal. This change passes data -via a grub_cryptomount_args struct, which can be added to over time as -opposed to continually adding arguments to the cryptodisk scan and -recover_key. - -As an example, passing a password as a cryptomount argument is implemented. -However, the backends are not implemented, so testing this will return a not -implemented error. - -Also, add comments to cryptomount argument parsing to make it more obvious -which argument states are being handled. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 31 +++++++++++++++++++++---------- - grub-core/disk/geli.c | 6 +++++- - grub-core/disk/luks.c | 7 ++++++- - grub-core/disk/luks2.c | 7 ++++++- - include/grub/cryptodisk.h | 9 ++++++++- - 5 files changed, 46 insertions(+), 14 deletions(-) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 5a9780b14c..14c661a86e 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] = - /* TRANSLATORS: It's still restricted to cryptodisks only. */ - {"all", 'a', 0, N_("Mount all."), 0, 0}, - {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, -+ {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -@@ -996,7 +997,9 @@ cryptodisk_close (grub_cryptodisk_t dev) - } - - static grub_cryptodisk_t --grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) -+grub_cryptodisk_scan_device_real (const char *name, -+ grub_disk_t source, -+ grub_cryptomount_args_t cargs) - { - grub_err_t err; - grub_cryptodisk_t dev; -@@ -1015,7 +1018,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) - if (!dev) - continue; - -- err = cr->recover_key (source, dev); -+ err = cr->recover_key (source, dev, cargs); - if (err) - { - cryptodisk_close (dev); -@@ -1080,11 +1083,12 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) - - static int - grub_cryptodisk_scan_device (const char *name, -- void *data __attribute__ ((unused))) -+ void *data) - { - int ret = 0; - grub_disk_t source; - grub_cryptodisk_t dev; -+ grub_cryptomount_args_t cargs = data; - grub_errno = GRUB_ERR_NONE; - - /* Try to open disk. */ -@@ -1095,7 +1099,7 @@ grub_cryptodisk_scan_device (const char *name, - return 0; - } - -- dev = grub_cryptodisk_scan_device_real (name, source); -+ dev = grub_cryptodisk_scan_device_real (name, source, cargs); - if (dev) - { - ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); -@@ -1124,6 +1128,7 @@ static grub_err_t - grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - { - struct grub_arg_list *state = ctxt->state; -+ struct grub_cryptomount_args cargs = {0}; - - if (argc < 1 && !state[1].set && !state[2].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); -@@ -1131,7 +1136,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - if (grub_cryptodisk_list == NULL) - return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); - -- if (state[0].set) -+ if (state[3].set) /* password */ -+ { -+ cargs.key_data = (grub_uint8_t *) state[3].arg; -+ cargs.key_len = grub_strlen (state[3].arg); -+ } -+ -+ if (state[0].set) /* uuid */ - { - int found_uuid; - grub_cryptodisk_t dev; -@@ -1146,7 +1157,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - - check_boot = state[2].set; - search_uuid = args[0]; -- found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); -+ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); - search_uuid = NULL; - - if (found_uuid) -@@ -1163,11 +1174,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - } - return grub_errno; - } -- else if (state[1].set || (argc == 0 && state[2].set)) -+ else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */ - { - search_uuid = NULL; - check_boot = state[2].set; -- grub_device_iterate (&grub_cryptodisk_scan_device, NULL); -+ grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); - search_uuid = NULL; - return GRUB_ERR_NONE; - } -@@ -1208,7 +1219,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - return GRUB_ERR_NONE; - } - -- dev = grub_cryptodisk_scan_device_real (diskname, disk); -+ dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); - - grub_disk_close (disk); - if (disklast) -@@ -1347,7 +1358,7 @@ GRUB_MOD_INIT (cryptodisk) - { - grub_disk_dev_register (&grub_cryptodisk_dev); - cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, -- N_("SOURCE|-u UUID|-a|-b"), -+ N_("[-p password] "), - N_("Mount a crypto device."), options); - grub_procfs_register ("luks_script", &luks_script); - } -diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c -index 2f34a35e6b..777da3a055 100644 ---- a/grub-core/disk/geli.c -+++ b/grub-core/disk/geli.c -@@ -398,7 +398,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, - } - - static grub_err_t --recover_key (grub_disk_t source, grub_cryptodisk_t dev) -+recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs) - { - grub_size_t keysize; - grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN]; -@@ -414,6 +414,10 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) - grub_disk_addr_t sector; - grub_err_t err; - -+ /* Keyfiles are not implemented yet */ -+ if (cargs->key_data != NULL || cargs->key_len) -+ return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ - if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return grub_error (GRUB_ERR_BUG, "cipher block is too long"); - -diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c -index 13103ea6a2..c5858fcf8a 100644 ---- a/grub-core/disk/luks.c -+++ b/grub-core/disk/luks.c -@@ -152,7 +152,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, - - static grub_err_t - luks_recover_key (grub_disk_t source, -- grub_cryptodisk_t dev) -+ grub_cryptodisk_t dev, -+ grub_cryptomount_args_t cargs) - { - struct grub_luks_phdr header; - grub_size_t keysize; -@@ -165,6 +166,10 @@ luks_recover_key (grub_disk_t source, - grub_size_t max_stripes = 1; - char *tmp; - -+ /* Keyfiles are not implemented yet */ -+ if (cargs->key_data != NULL || cargs->key_len) -+ return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ - err = grub_disk_read (source, 0, 0, sizeof (header), &header); - if (err) - return err; -diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c -index fea196dd4a..2cbec8acc2 100644 ---- a/grub-core/disk/luks2.c -+++ b/grub-core/disk/luks2.c -@@ -545,7 +545,8 @@ luks2_decrypt_key (grub_uint8_t *out_key, - - static grub_err_t - luks2_recover_key (grub_disk_t source, -- grub_cryptodisk_t crypt) -+ grub_cryptodisk_t crypt, -+ grub_cryptomount_args_t cargs) - { - grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; - char passphrase[MAX_PASSPHRASE], cipher[32]; -@@ -559,6 +560,10 @@ luks2_recover_key (grub_disk_t source, - grub_json_t *json = NULL, keyslots; - grub_err_t ret; - -+ /* Keyfiles are not implemented yet */ -+ if (cargs->key_data != NULL || cargs->key_len) -+ return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ - ret = luks2_read_header (source, &header); - if (ret) - return ret; -diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h -index dcf17fbb3a..282f8ac456 100644 ---- a/include/grub/cryptodisk.h -+++ b/include/grub/cryptodisk.h -@@ -66,6 +66,13 @@ typedef gcry_err_code_t - (*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, - grub_uint64_t zoneno); - -+struct grub_cryptomount_args -+{ -+ grub_uint8_t *key_data; -+ grub_size_t key_len; -+}; -+typedef struct grub_cryptomount_args *grub_cryptomount_args_t; -+ - struct grub_cryptodisk - { - struct grub_cryptodisk *next; -@@ -119,7 +126,7 @@ struct grub_cryptodisk_dev - - grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, - int boot_only); -- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev); -+ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs); - }; - typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; - --- -2.34.1 - diff --git a/0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch b/0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch deleted file mode 100644 index 8f93c9a..0000000 --- a/0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch +++ /dev/null @@ -1,342 +0,0 @@ -From a3ae3f800f6aa3f6036351133ed69fa47c9fa371 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:56 -0600 -Subject: [PATCH 07/14] cryptodisk: Refactor password input out of crypto dev - modules into cryptodisk - -The crypto device modules should only be setting up the crypto devices and -not getting user input. This has the added benefit of simplifying the code -such that three essentially duplicate pieces of code are merged into one. - -Add documentation of passphrase option for cryptomount as it is now usable. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - docs/grub.texi | 8 ++++-- - grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++++++++-------- - grub-core/disk/geli.c | 26 ++++------------- - grub-core/disk/luks.c | 27 +++--------------- - grub-core/disk/luks2.c | 25 +++-------------- - include/grub/cryptodisk.h | 1 + - 6 files changed, 64 insertions(+), 79 deletions(-) - -diff --git a/docs/grub.texi b/docs/grub.texi -index f4794fddac..4504bcabec 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -4310,9 +4310,11 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum} - @node cryptomount - @subsection cryptomount - --@deffn Command cryptomount device|@option{-u} uuid|@option{-a}|@option{-b} --Setup access to encrypted device. If necessary, passphrase --is requested interactively. Option @var{device} configures specific grub device -+@deffn Command cryptomount [@option{-p} password] device|@option{-u} uuid|@option{-a}|@option{-b} -+Setup access to encrypted device. If @option{-p} is not given, a passphrase -+is requested interactively. Otherwise, the given @var{password} will be used and -+no passphrase will be requested interactively. -+Option @var{device} configures specific grub device - (@pxref{Naming convention}); option @option{-u} @var{uuid} configures device - with specified @var{uuid}; option @option{-a} configures all detected encrypted - devices; option @option{-b} configures all geli containers that have boot flag set. -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 14c661a86e..d12368a1f7 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -1001,9 +1001,11 @@ grub_cryptodisk_scan_device_real (const char *name, - grub_disk_t source, - grub_cryptomount_args_t cargs) - { -- grub_err_t err; -+ grub_err_t ret = GRUB_ERR_NONE; - grub_cryptodisk_t dev; - grub_cryptodisk_dev_t cr; -+ int askpass = 0; -+ char *part = NULL; - - dev = grub_cryptodisk_get_by_source_disk (source); - -@@ -1017,21 +1019,53 @@ grub_cryptodisk_scan_device_real (const char *name, - return NULL; - if (!dev) - continue; -- -- err = cr->recover_key (source, dev, cargs); -- if (err) -- { -- cryptodisk_close (dev); -- return NULL; -- } -+ -+ if (!cargs->key_len) -+ { -+ /* Get the passphrase from the user, if no key data. */ -+ askpass = 1; -+ if (source->partition != NULL) -+ 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 : "", -+ dev->uuid); -+ grub_free (part); -+ -+ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); -+ if (cargs->key_data == NULL) -+ return NULL; -+ -+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); -+ goto error; -+ } -+ cargs->key_len = grub_strlen ((char *) cargs->key_data); -+ } -+ -+ ret = cr->recover_key (source, dev, cargs); -+ if (ret != GRUB_ERR_NONE) -+ goto error; - - grub_cryptodisk_insert (dev, name, source); - -- return dev; -+ goto cleanup; - } -- - grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); -- return NULL; -+ goto cleanup; -+ -+ error: -+ cryptodisk_close (dev); -+ dev = NULL; -+ -+ cleanup: -+ if (askpass) -+ { -+ cargs->key_len = 0; -+ grub_free (cargs->key_data); -+ } -+ return dev; - } - - #ifdef GRUB_UTIL -diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c -index 777da3a055..7299a47d19 100644 ---- a/grub-core/disk/geli.c -+++ b/grub-core/disk/geli.c -@@ -135,8 +135,6 @@ const char *algorithms[] = { - [0x16] = "aes" - }; - --#define MAX_PASSPHRASE 256 -- - static gcry_err_code_t - geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) - { -@@ -406,17 +404,14 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t - grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN]; - grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; - grub_uint8_t geli_cipher_key[64]; -- char passphrase[MAX_PASSPHRASE] = ""; - unsigned i; - gcry_err_code_t gcry_err; - struct grub_geli_phdr header; -- char *tmp; - grub_disk_addr_t sector; - grub_err_t err; - -- /* Keyfiles are not implemented yet */ -- if (cargs->key_data != NULL || cargs->key_len) -- return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ if (cargs->key_data == NULL || cargs->key_len == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - - if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return grub_error (GRUB_ERR_BUG, "cipher block is too long"); -@@ -438,23 +433,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t - - grub_puts_ (N_("Attempting to decrypt master key...")); - -- /* Get the passphrase from the user. */ -- tmp = NULL; -- if (source->partition) -- tmp = grub_partition_get_name (source->partition); -- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -- source->partition ? "," : "", tmp ? : "", -- dev->uuid); -- grub_free (tmp); -- if (!grub_password_get (passphrase, MAX_PASSPHRASE)) -- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); -- - /* Calculate the PBKDF2 of the user supplied passphrase. */ - if (grub_le_to_cpu32 (header.niter) != 0) - { - grub_uint8_t pbkdf_key[64]; -- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, -- grub_strlen (passphrase), -+ gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, -+ cargs->key_len, - header.salt, - sizeof (header.salt), - grub_le_to_cpu32 (header.niter), -@@ -477,7 +461,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t - return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY); - - grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt)); -- grub_crypto_hmac_write (hnd, passphrase, grub_strlen (passphrase)); -+ grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len); - - gcry_err = grub_crypto_hmac_fini (hnd, geomkey); - if (gcry_err) -diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c -index c5858fcf8a..39a7af6a43 100644 ---- a/grub-core/disk/luks.c -+++ b/grub-core/disk/luks.c -@@ -29,8 +29,6 @@ - - GRUB_MOD_LICENSE ("GPLv3+"); - --#define MAX_PASSPHRASE 256 -- - #define LUKS_KEY_ENABLED 0x00AC71F3 - - /* On disk LUKS header */ -@@ -158,17 +156,14 @@ luks_recover_key (grub_disk_t source, - struct grub_luks_phdr header; - grub_size_t keysize; - grub_uint8_t *split_key = NULL; -- char passphrase[MAX_PASSPHRASE] = ""; - grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; - unsigned i; - grub_size_t length; - grub_err_t err; - grub_size_t max_stripes = 1; -- char *tmp; - -- /* Keyfiles are not implemented yet */ -- if (cargs->key_data != NULL || cargs->key_len) -- return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ if (cargs->key_data == NULL || cargs->key_len == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - - err = grub_disk_read (source, 0, 0, sizeof (header), &header); - if (err) -@@ -188,20 +183,6 @@ luks_recover_key (grub_disk_t source, - if (!split_key) - return grub_errno; - -- /* Get the passphrase from the user. */ -- tmp = NULL; -- if (source->partition) -- tmp = grub_partition_get_name (source->partition); -- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -- source->partition ? "," : "", tmp ? : "", -- dev->uuid); -- grub_free (tmp); -- if (!grub_password_get (passphrase, MAX_PASSPHRASE)) -- { -- grub_free (split_key); -- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); -- } -- - /* Try to recover master key from each active keyslot. */ - for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) - { -@@ -216,8 +197,8 @@ luks_recover_key (grub_disk_t source, - grub_dprintf ("luks", "Trying keyslot %d\n", i); - - /* Calculate the PBKDF2 of the user supplied passphrase. */ -- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, -- grub_strlen (passphrase), -+ gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, -+ cargs->key_len, - header.keyblock[i].passwordSalt, - sizeof (header.keyblock[i].passwordSalt), - grub_be_to_cpu32 (header.keyblock[i]. -diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c -index 2cbec8acc2..09740b53f9 100644 ---- a/grub-core/disk/luks2.c -+++ b/grub-core/disk/luks2.c -@@ -35,8 +35,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define LUKS_MAGIC_1ST "LUKS\xBA\xBE" - #define LUKS_MAGIC_2ND "SKUL\xBA\xBE" - --#define MAX_PASSPHRASE 256 -- - enum grub_luks2_kdf_type - { - LUKS2_KDF_TYPE_ARGON2I, -@@ -549,8 +547,7 @@ luks2_recover_key (grub_disk_t source, - grub_cryptomount_args_t cargs) - { - grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; -- char passphrase[MAX_PASSPHRASE], cipher[32]; -- char *json_header = NULL, *part = NULL, *ptr; -+ char cipher[32], *json_header = NULL, *ptr; - grub_size_t candidate_key_len = 0, json_idx, size; - grub_luks2_header_t header; - grub_luks2_keyslot_t keyslot; -@@ -560,9 +557,8 @@ luks2_recover_key (grub_disk_t source, - grub_json_t *json = NULL, keyslots; - grub_err_t ret; - -- /* Keyfiles are not implemented yet */ -- if (cargs->key_data != NULL || cargs->key_len) -- return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ if (cargs->key_data == NULL || cargs->key_len == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - - ret = luks2_read_header (source, &header); - if (ret) -@@ -589,18 +585,6 @@ luks2_recover_key (grub_disk_t source, - goto err; - } - -- /* Get the passphrase from the user. */ -- if (source->partition) -- part = grub_partition_get_name (source->partition); -- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -- source->partition ? "," : "", part ? : "", -- crypt->uuid); -- if (!grub_password_get (passphrase, MAX_PASSPHRASE)) -- { -- ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); -- goto err; -- } -- - if (grub_json_getvalue (&keyslots, json, "keyslots") || - grub_json_getsize (&size, &keyslots)) - { -@@ -725,7 +709,7 @@ luks2_recover_key (grub_disk_t source, - } - - ret = luks2_decrypt_key (candidate_key, source, crypt, &keyslot, -- (const grub_uint8_t *) passphrase, grub_strlen (passphrase)); -+ cargs->key_data, cargs->key_len); - if (ret) - { - grub_dprintf ("luks2", "Decryption with keyslot \"%" PRIuGRUB_UINT64_T "\" failed: %s\n", -@@ -777,7 +761,6 @@ luks2_recover_key (grub_disk_t source, - } - - err: -- grub_free (part); - grub_free (json_header); - grub_json_free (json); - return ret; -diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h -index 282f8ac456..5bd970692f 100644 ---- a/include/grub/cryptodisk.h -+++ b/include/grub/cryptodisk.h -@@ -59,6 +59,7 @@ typedef enum - #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) - #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) - #define GRUB_CRYPTODISK_MAX_KEYLEN 128 -+#define GRUB_CRYPTODISK_MAX_PASSPHRASE 256 - - struct grub_cryptodisk; - --- -2.34.1 - diff --git a/0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch b/0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch deleted file mode 100644 index b40f35f..0000000 --- a/0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 5323778d84a7289acba0e50d84fb1afd45fff596 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:57 -0600 -Subject: [PATCH 08/14] cryptodisk: Move global variables into - grub_cryptomount_args struct - -Note that cargs.search_uuid does not need to be initialized in various parts -of the cryptomount argument parsing, just once when cargs is declared with -a struct initializer. The previous code used a global variable which would -retain the value across cryptomount invocations. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 24 +++++++++--------------- - grub-core/disk/geli.c | 9 ++++----- - grub-core/disk/luks.c | 9 ++++----- - grub-core/disk/luks2.c | 8 ++++---- - include/grub/cryptodisk.h | 9 +++++++-- - 5 files changed, 28 insertions(+), 31 deletions(-) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index d12368a1f7..7ca880402d 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -984,9 +984,6 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) - - #endif - --static int check_boot; --static char *search_uuid; -- - static void - cryptodisk_close (grub_cryptodisk_t dev) - { -@@ -1014,7 +1011,7 @@ grub_cryptodisk_scan_device_real (const char *name, - - FOR_CRYPTODISK_DEVS (cr) - { -- dev = cr->scan (source, search_uuid, check_boot); -+ dev = cr->scan (source, cargs); - if (grub_errno) - return NULL; - if (!dev) -@@ -1077,6 +1074,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) - grub_cryptodisk_t dev; - grub_cryptodisk_dev_t cr; - grub_disk_t source; -+ struct grub_cryptomount_args cargs = {0}; - - /* Try to open disk. */ - source = grub_disk_open (sourcedev); -@@ -1093,7 +1091,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) - - FOR_CRYPTODISK_DEVS (cr) - { -- dev = cr->scan (source, search_uuid, check_boot); -+ dev = cr->scan (source, &cargs); - if (grub_errno) - return grub_errno; - if (!dev) -@@ -1136,7 +1134,7 @@ grub_cryptodisk_scan_device (const char *name, - dev = grub_cryptodisk_scan_device_real (name, source, cargs); - if (dev) - { -- ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); -+ ret = (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, dev->uuid) == 0); - goto cleanup; - } - -@@ -1147,7 +1145,7 @@ grub_cryptodisk_scan_device (const char *name, - if (grub_errno == GRUB_ERR_BAD_MODULE) - grub_error_pop (); - -- if (search_uuid != NULL) -+ if (cargs->search_uuid != NULL) - /* Push error onto stack to save for cryptomount. */ - grub_error_push (); - else -@@ -1189,10 +1187,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - return GRUB_ERR_NONE; - } - -- check_boot = state[2].set; -- search_uuid = args[0]; -+ cargs.check_boot = state[2].set; -+ cargs.search_uuid = args[0]; - found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); -- search_uuid = NULL; - - if (found_uuid) - return GRUB_ERR_NONE; -@@ -1210,10 +1207,8 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - } - else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */ - { -- search_uuid = NULL; -- check_boot = state[2].set; -+ cargs.check_boot = state[2].set; - grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); -- search_uuid = NULL; - return GRUB_ERR_NONE; - } - else -@@ -1224,8 +1219,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - char *disklast = NULL; - grub_size_t len; - -- search_uuid = NULL; -- check_boot = state[2].set; -+ cargs.check_boot = state[2].set; - diskname = args[0]; - len = grub_strlen (diskname); - if (len && diskname[0] == '(' && diskname[len - 1] == ')') -diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c -index 7299a47d19..23789c43f3 100644 ---- a/grub-core/disk/geli.c -+++ b/grub-core/disk/geli.c -@@ -240,8 +240,7 @@ grub_util_get_geli_uuid (const char *dev) - #endif - - static grub_cryptodisk_t --configure_ciphers (grub_disk_t disk, const char *check_uuid, -- int boot_only) -+configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) - { - grub_cryptodisk_t newdev; - struct grub_geli_phdr header; -@@ -289,7 +288,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, - return NULL; - } - -- if (boot_only && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) -+ if (cargs->check_boot && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) - { - grub_dprintf ("geli", "not a boot volume\n"); - return NULL; -@@ -302,9 +301,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, - return NULL; - } - -- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) -+ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0) - { -- grub_dprintf ("geli", "%s != %s\n", uuid, check_uuid); -+ grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid); - return NULL; - } - -diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c -index 39a7af6a43..f0feb38447 100644 ---- a/grub-core/disk/luks.c -+++ b/grub-core/disk/luks.c -@@ -63,8 +63,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_size_t blocknumbers); - - static grub_cryptodisk_t --configure_ciphers (grub_disk_t disk, const char *check_uuid, -- int check_boot) -+configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) - { - grub_cryptodisk_t newdev; - const char *iptr; -@@ -76,7 +75,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, - char hashspec[sizeof (header.hashSpec) + 1]; - grub_err_t err; - -- if (check_boot) -+ if (cargs->check_boot) - return NULL; - - /* Read the LUKS header. */ -@@ -103,9 +102,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, - } - *optr = 0; - -- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) -+ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0) - { -- grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid); -+ grub_dprintf ("luks", "%s != %s\n", uuid, cargs->search_uuid); - return NULL; - } - -diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c -index 09740b53f9..ccfacb63a3 100644 ---- a/grub-core/disk/luks2.c -+++ b/grub-core/disk/luks2.c -@@ -346,14 +346,14 @@ luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr) - } - - static grub_cryptodisk_t --luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot) -+luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) - { - grub_cryptodisk_t cryptodisk; - grub_luks2_header_t header; - char uuid[sizeof (header.uuid) + 1]; - grub_size_t i, j; - -- if (check_boot) -+ if (cargs->check_boot) - return NULL; - - if (luks2_read_header (disk, &header)) -@@ -367,9 +367,9 @@ luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot) - uuid[j++] = header.uuid[i]; - uuid[j] = '\0'; - -- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) -+ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0) - { -- grub_dprintf ("luks2", "%s != %s\n", uuid, check_uuid); -+ grub_dprintf ("luks2", "%s != %s\n", uuid, cargs->search_uuid); - return NULL; - } - -diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h -index 5bd970692f..c6524c9ea9 100644 ---- a/include/grub/cryptodisk.h -+++ b/include/grub/cryptodisk.h -@@ -69,7 +69,13 @@ typedef gcry_err_code_t - - struct grub_cryptomount_args - { -+ /* scan: Flag to indicate that only bootable volumes should be decrypted */ -+ grub_uint32_t check_boot : 1; -+ /* scan: Only volumes matching this UUID should be decrpyted */ -+ char *search_uuid; -+ /* recover_key: Key data used to decrypt voume */ - grub_uint8_t *key_data; -+ /* recover_key: Length of key_data */ - grub_size_t key_len; - }; - typedef struct grub_cryptomount_args *grub_cryptomount_args_t; -@@ -125,8 +131,7 @@ struct grub_cryptodisk_dev - struct grub_cryptodisk_dev *next; - struct grub_cryptodisk_dev **prev; - -- grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, -- int boot_only); -+ grub_cryptodisk_t (*scan) (grub_disk_t disk, grub_cryptomount_args_t cargs); - grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs); - }; - typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; --- -2.34.1 - diff --git a/0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch b/0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch deleted file mode 100644 index 834f7e9..0000000 --- a/0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b1acd971fa648fa3c6f3a54db4fdf45fae02ce54 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 9 Dec 2021 11:14:58 -0600 -Subject: [PATCH 09/14] cryptodisk: Improve handling of partition name in - cryptomount password prompt - -Call grub_partition_get_name() unconditionally to initialize the part -variable. Then part will only be NULL when grub_partition_get_name() errors. -Note that when source->partition is NULL, then grub_partition_get_name() -returns an allocated empty string. So no comma or partition will be printed, -as desired. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - grub-core/disk/cryptodisk.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 7ca880402d..497097394f 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -1021,11 +1021,10 @@ grub_cryptodisk_scan_device_real (const char *name, - { - /* Get the passphrase from the user, if no key data. */ - askpass = 1; -- if (source->partition != NULL) -- part = grub_partition_get_name (source->partition); -+ 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 : "", -+ part != NULL ? part : N_("UNKNOWN"), - dev->uuid); - grub_free (part); - --- -2.34.1 - diff --git a/0010-protectors-Add-key-protectors-framework.patch b/0010-protectors-Add-key-protectors-framework.patch deleted file mode 100644 index 84a5612..0000000 --- a/0010-protectors-Add-key-protectors-framework.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 2d959549857305d5e4d95a19a0850885f85179d6 Mon Sep 17 00:00:00 2001 -From: Hernan Gatta -Date: Tue, 1 Feb 2022 05:02:53 -0800 -Subject: [PATCH 10/14] protectors: 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 module registers -itself with the key protectors framework when it is loaded and unregisters when -unloaded. Additionally, a key protector may accept parameters that describe how -it should operate. - -The key protectors framework, besides offering registration and unregistration -functions, also offers a one-stop routine for finding and invoking a key -protector by name. If a key protector with the specified name exists and if an -unlocking key is successfully retrieved by it, the function returns to the -caller the retrieved key and its length. - -Signed-off-by: Hernan Gatta ---- - grub-core/Makefile.am | 1 + - grub-core/Makefile.core.def | 1 + - grub-core/kern/protectors.c | 75 +++++++++++++++++++++++++++++++++++++ - include/grub/protector.h | 48 ++++++++++++++++++++++++ - 4 files changed, 125 insertions(+) - create mode 100644 grub-core/kern/protectors.c - create mode 100644 include/grub/protector.h - -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index de241f0d04..dc07ba6f87 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -90,6 +90,7 @@ endif - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/protector.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index f3140815b8..b0001a33cf 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -138,6 +138,7 @@ kernel = { - common = kern/misc.c; - common = kern/parser.c; - common = kern/partition.c; -+ common = kern/protectors.c; - common = kern/rescue_parser.c; - common = kern/rescue_reader.c; - common = kern/term.c; -diff --git a/grub-core/kern/protectors.c b/grub-core/kern/protectors.c -new file mode 100644 -index 0000000000..21954dfa48 ---- /dev/null -+++ b/grub-core/kern/protectors.c -@@ -0,0 +1,75 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Microsoft Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+struct grub_key_protector *grub_key_protectors = NULL; -+ -+grub_err_t -+grub_key_protector_register (struct grub_key_protector *protector) -+{ -+ if (!protector || !protector->name || !grub_strlen(protector->name)) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ if (grub_key_protectors && -+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), -+ protector->name)) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), -+ GRUB_AS_LIST (protector)); -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_key_protector_unregister (struct grub_key_protector *protector) -+{ -+ if (!protector) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ grub_list_remove (GRUB_AS_LIST (protector)); -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key, -+ grub_size_t *key_size) -+{ -+ struct grub_key_protector *kp = NULL; -+ -+ if (!grub_key_protectors) -+ return GRUB_ERR_OUT_OF_RANGE; -+ -+ if (!protector || !grub_strlen (protector)) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), -+ protector); -+ if (!kp) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("A key protector with name '%s' could not be found. " -+ "Is the name spelled correctly and is the " -+ "corresponding module loaded?"), protector); -+ -+ return kp->recover_key (key, key_size); -+} -diff --git a/include/grub/protector.h b/include/grub/protector.h -new file mode 100644 -index 0000000000..179020a344 ---- /dev/null -+++ b/include/grub/protector.h -@@ -0,0 +1,48 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Microsoft Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under 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_PROTECTOR_HEADER -+#define GRUB_PROTECTOR_HEADER 1 -+ -+#include -+#include -+ -+struct grub_key_protector -+{ -+ struct grub_key_protector *next; -+ struct grub_key_protector **prev; -+ -+ const char *name; -+ -+ grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size); -+}; -+ -+extern struct grub_key_protector *EXPORT_VAR (grub_key_protectors); -+ -+grub_err_t -+EXPORT_FUNC (grub_key_protector_register) (struct grub_key_protector *protector); -+ -+grub_err_t -+EXPORT_FUNC (grub_key_protector_unregister) (struct grub_key_protector *protector); -+ -+grub_err_t -+EXPORT_FUNC (grub_key_protector_recover_key) (const char *protector, -+ grub_uint8_t **key, -+ grub_size_t *key_size); -+ -+#endif /* ! GRUB_PROTECTOR_HEADER */ --- -2.34.1 - diff --git a/0011-tpm2-Add-TPM-Software-Stack-TSS.patch b/0011-tpm2-Add-TPM-Software-Stack-TSS.patch deleted file mode 100644 index 9c0755c..0000000 --- a/0011-tpm2-Add-TPM-Software-Stack-TSS.patch +++ /dev/null @@ -1,3523 +0,0 @@ -From 65f937752d51b81fb830d4c6177975d395be9346 Mon Sep 17 00:00:00 2001 -From: Hernan Gatta -Date: Tue, 1 Feb 2022 05:02:54 -0800 -Subject: [PATCH 11/14] tpm2: Add TPM Software Stack (TSS) - -A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to compose, -submit, and parse TPM commands and responses. - -A limited number of TPM commands may be accessed via the EFI TCG2 protocol. This -protocol exposes functionality that is primarily geared toward TPM usage within -the context of Secure Boot. For all other TPM commands, however, such as sealing -and unsealing, this protocol does not provide any help, with the exception of -passthrough command submission. - -The SubmitCommand method allows a caller to send raw commands to the system's -TPM and to receive the corresponding response. These command/response pairs are -formatted using the TPM wire protocol. To construct commands in this way, and to -parse the TPM's response, it is necessary to, first, possess knowledge of the -various TPM structures, and, two, of the TPM wire protocol itself. - -As such, this patch includes a set of header files that define the necessary TPM -structures and TSS functions, implementations of various TPM2_* functions -(inventoried below), and logic to write and read command and response buffers, -respectively, using the TPM wire protocol. - -Functions: TPM2_Create, TPM2_CreatePrimary, TPM2_EvictControl, -TPM2_FlushContext, TPM2_Load, TPM2_PCR_Read, TPM2_PolicyGetDigest, -TPM2_PolicyPCR, TPM2_ReadPublic, TPM2_StartAuthSession, TPM2_Unseal. - -Signed-off-by: Hernan Gatta ---- - grub-core/tpm2/buffer.c | 145 +++++ - grub-core/tpm2/mu.c | 807 +++++++++++++++++++++++++ - grub-core/tpm2/tcg2.c | 143 +++++ - grub-core/tpm2/tpm2.c | 711 ++++++++++++++++++++++ - include/grub/tpm2/buffer.h | 65 ++ - include/grub/tpm2/internal/functions.h | 117 ++++ - include/grub/tpm2/internal/structs.h | 675 +++++++++++++++++++++ - include/grub/tpm2/internal/types.h | 372 ++++++++++++ - include/grub/tpm2/mu.h | 292 +++++++++ - include/grub/tpm2/tcg2.h | 34 ++ - include/grub/tpm2/tpm2.h | 38 ++ - 11 files changed, 3399 insertions(+) - create mode 100644 grub-core/tpm2/buffer.c - create mode 100644 grub-core/tpm2/mu.c - create mode 100644 grub-core/tpm2/tcg2.c - create mode 100644 grub-core/tpm2/tpm2.c - create mode 100644 include/grub/tpm2/buffer.h - create mode 100644 include/grub/tpm2/internal/functions.h - create mode 100644 include/grub/tpm2/internal/structs.h - create mode 100644 include/grub/tpm2/internal/types.h - create mode 100644 include/grub/tpm2/mu.h - create mode 100644 include/grub/tpm2/tcg2.h - create mode 100644 include/grub/tpm2/tpm2.h - -diff --git a/grub-core/tpm2/buffer.c b/grub-core/tpm2/buffer.c -new file mode 100644 -index 0000000000..fee42d5a9e ---- /dev/null -+++ b/grub-core/tpm2/buffer.c -@@ -0,0 +1,145 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Microsoft Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+ -+void grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer) -+{ -+ grub_memset (buffer->data, 0xDD, sizeof (buffer->data)); -+ buffer->size = 0; -+ buffer->offset = 0; -+ buffer->cap = sizeof (buffer->data); -+ buffer->error = 0; -+} -+ -+void -+grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data, -+ grub_size_t size) -+{ -+ grub_uint32_t r = buffer->cap - buffer->size; -+ -+ if (buffer->error) -+ return; -+ -+ if (size > r) -+ { -+ buffer->error = 1; -+ return; -+ } -+ -+ grub_memcpy (&buffer->data[buffer->size], (void*) data, size); -+ buffer->size += size; -+} -+ -+void -+grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value) -+{ -+ grub_tpm2_buffer_pack (buffer, (const char*) &value, sizeof (value)); -+} -+ -+void -+grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value) -+{ -+ grub_uint16_t tmp = grub_swap_bytes16 (value); -+ grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp)); -+} -+ -+void -+grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value) -+{ -+ grub_uint32_t tmp = grub_swap_bytes32 (value); -+ grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp)); -+} -+ -+void -+grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data, -+ grub_size_t size) -+{ -+ grub_uint32_t r = buffer->size - buffer->offset; -+ -+ if (buffer->error) -+ return; -+ -+ if (size > r) -+ { -+ buffer->error = 1; -+ 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_swap_bytes16 (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_swap_bytes32 (tmp); -+} -diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c -new file mode 100644 -index 0000000000..c5f5c7b5f8 ---- /dev/null -+++ b/grub-core/tpm2/mu.c -@@ -0,0 +1,807 @@ -+/* -+ * 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_swap_bytes32 (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, -+ 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, -+ 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_pack_u16 (buffer, *((const grub_uint16_t*) p)); -+ break; -+ case TPM_ALG_NULL: -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Marshal (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_pack_u16 (buffer, *((const grub_uint16_t*) p)); -+ break; -+ case TPM_ALG_XOR: -+ case TPM_ALG_NULL: -+ break; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, -+ 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, -+ 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, -+ TPMS_SCHEME_HMAC *p) -+{ -+ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); -+} -+ -+void -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, -+ TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ TPMU_SCHEME_KEYEDHASH *p) -+{ -+ 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, -+ 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, -+ TPMS_KEYEDHASH_PARMS *p) -+{ -+ grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme); -+} -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, -+ TPMT_SYM_DEF_OBJECT *p) -+{ -+ 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, -+ 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_Marshal (grub_tpm2_buffer_t buffer, -+ 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, -+ 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, -+ 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, -+ 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, -+ TPMI_ALG_KDF scheme, -+ 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, -+ 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, -+ 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, -+ grub_uint32_t type, -+ 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, -+ 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, -+ TPMI_ALG_PUBLIC type, -+ 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; -+ } -+} -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, -+ 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, -+ 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_swap_bytes16 (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, -+ 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_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, -+ 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_swap_bytes16 (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_TPM2B_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPM2B* p) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); -+ -+ for (grub_uint16_t i = 0; i < p->size; i++) -+ grub_tpm2_buffer_unpack_u8 (buffer, &p->buffer[i]); -+} -+ -+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) -+{ -+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)digest); -+} -+ -+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; -+ } -+} -+ -+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; -+ } -+} -+ -+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_Unmarshal (buffer, (TPM2B*) &p->x); -+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &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_Unmarshal (buffer, (TPM2B*) &p->keyedHash); -+ break; -+ case TPM_ALG_SYMCIPHER: -+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->sym); -+ break; -+ case TPM_ALG_RSA: -+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->rsa); -+ break; -+ case TPM_ALG_ECC: -+ grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc); -+ 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_Unmarshal (buffer, (TPM2B*) &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) -+{ -+ grub_tpm2_buffer_unpack_u16 (buffer, &n->size); -+ grub_tpm2_buffer_unpack (buffer, n->name, n->size); -+} -+ -+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_TPMS_CAPABILITY_DATA_tpmProperties_Unmarshal (grub_tpm2_buffer_t buffer, -+ TPMS_CAPABILITY_DATA* capabilityData) -+{ -+ grub_tpm2_buffer_unpack_u32 (buffer, -+ &capabilityData->data.tpmProperties.count); -+ -+ if (buffer->error) -+ return; -+ -+ for (grub_uint32_t i = 0; i < capabilityData->data.tpmProperties.count; i++) -+ grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (buffer, -+ &capabilityData->data.tpmProperties.tpmProperty[i]); -+} -+ -+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_Unmarshal (buffer, (TPM2B*) &p->digest); -+} -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_PCR_SELECTION* pcrSelection) -+{ -+ grub_tpm2_buffer_unpack_u16 (buf, &pcrSelection->hash); -+ grub_tpm2_buffer_unpack_u8 (buf, &pcrSelection->sizeOfSelect); -+ -+ for (grub_uint32_t i = 0; i < pcrSelection->sizeOfSelect; i++) -+ grub_tpm2_buffer_unpack_u8 (buf, &pcrSelection->pcrSelect[i]); -+} -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, -+ TPML_PCR_SELECTION* pcrSelection) -+{ -+ grub_tpm2_buffer_unpack_u32 (buf, &pcrSelection->count); -+ -+ for (grub_uint32_t i = 0; i < pcrSelection->count; i++) -+ grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (buf, &pcrSelection->pcrSelections[i]); -+} -+ -+void -+grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, -+ TPML_DIGEST* digest) -+{ -+ grub_tpm2_buffer_unpack_u32 (buf, &digest->count); -+ -+ for (grub_uint32_t i = 0; i < digest->count; i++) -+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buf, &digest->digests[i]); -+} -diff --git a/grub-core/tpm2/tcg2.c b/grub-core/tpm2/tcg2.c -new file mode 100644 -index 0000000000..44837218a2 ---- /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 = efi_call_2 (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_efi_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 = efi_call_5 (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 0000000000..2407a844d2 ---- /dev/null -+++ b/grub-core/tpm2/tpm2.c -@@ -0,0 +1,711 @@ -+/* -+ * 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 (TPMI_ST_COMMAND_TAG tag, -+ 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; -+} -+ -+TPM_RC -+TPM2_CreatePrimary (TPMI_RH_HIERARCHY primaryHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_CREATE *inSensitive, -+ TPM2B_PUBLIC *inPublic, -+ TPM2B_DATA *outsideInfo, -+ 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 (!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_Unmarshal (&out, (TPM2B*)creationData); -+ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)creationHash); -+ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); -+ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)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 (TPMI_DH_OBJECT tpmKey, -+ TPMI_DH_ENTITY bind, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_NONCE *nonceCaller, -+ TPM2B_ENCRYPTED_SECRET *encryptedSalt, -+ TPM_SE sessionType, -+ TPMT_SYM_DEF *symmetric, -+ 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 (!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); -+ grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret); -+ 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_Unmarshal (&out, (TPM2B*)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 (TPMI_SH_POLICY policySessions, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_DIGEST *pcrDigest, -+ 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 (!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); -+ grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer); -+ 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 (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 (TPMI_DH_OBJECT parent_handle, -+ TPMS_AUTH_COMMAND const *authCommand, -+ TPM2B_PRIVATE *inPrivate, -+ 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 (!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_Unmarshal (&out, (TPM2B*)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 (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; -+ -+ // Unmarhsal -+ if (tag == TPM_ST_SESSIONS) -+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); -+ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)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 (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, -+ 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_FAILURE; -+ -+ if (!pcrUpdateCounter) -+ pcrUpdateCounter = &pcrUpdateCounterTmp; -+ if (!pcrSelectionOut) -+ pcrSelectionOut = &pcrSelectionOutTmp; -+ if (!pcrValues) -+ pcrValues = &pcrValuesTmp; -+ if (!authResponse) -+ authResponse = &authResponseTmp; -+ -+ /* Marshal */ -+ grub_tpm2_buffer_init (&in); -+ 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 (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_Unmarshal (&out, (TPM2B*)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 (TPMI_DH_OBJECT parentHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_CREATE *inSensitive, -+ TPM2B_PUBLIC *inPublic, -+ TPM2B_DATA *outsideInfo, -+ 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 (!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_Unmarshal (&out, (TPM2B*)outPrivate); -+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); -+ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)creationData); -+ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)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 (TPMI_RH_PROVISION auth, -+ TPMI_DH_OBJECT objectHandle, -+ TPMI_DH_PERSISTENT persistentHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ 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; -+} -diff --git a/include/grub/tpm2/buffer.h b/include/grub/tpm2/buffer.h -new file mode 100644 -index 0000000000..ad05393add ---- /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 0000000000..a1c71fae51 ---- /dev/null -+++ b/include/grub/tpm2/internal/functions.h -@@ -0,0 +1,117 @@ -+/* -+ * 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 (TPMI_RH_HIERARCHY primaryHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_CREATE *inSensitive, -+ TPM2B_PUBLIC *inPublic, -+ TPM2B_DATA *outsideInfo, -+ 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 (TPMI_DH_OBJECT tpmKey, -+ TPMI_DH_ENTITY bind, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_NONCE *nonceCaller, -+ TPM2B_ENCRYPTED_SECRET *encryptedSalt, -+ TPM_SE sessionType, -+ TPMT_SYM_DEF *symmetric, -+ TPMI_ALG_HASH authHash, -+ TPMI_SH_AUTH_SESSION *sessionHandle, -+ TPM2B_NONCE *nonceTpm, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_PolicyPCR (TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_DIGEST *pcrDigest, -+ TPML_PCR_SELECTION *pcrs, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_ReadPublic (TPMI_DH_OBJECT objectHandle, -+ const TPMS_AUTH_COMMAND* authCommand, -+ TPM2B_PUBLIC *outPublic); -+ -+TPM_RC -+TPM2_Load (TPMI_DH_OBJECT parent_handle, -+ TPMS_AUTH_COMMAND const *authCommand, -+ TPM2B_PRIVATE *inPrivate, -+ TPM2B_PUBLIC *inPublic, -+ TPM_HANDLE *objectHandle, -+ TPM2B_NAME *name, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_Unseal (TPMI_DH_OBJECT item_handle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_DATA *outData, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_FlushContext (TPMI_DH_CONTEXT handle); -+ -+TPM_RC -+TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand, -+ TPML_PCR_SELECTION *pcrSelectionIn, -+ grub_uint32_t *pcrUpdateCounter, -+ TPML_PCR_SELECTION *pcrSelectionOut, -+ TPML_DIGEST *pcrValues, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_PolicyGetDigest (TPMI_SH_POLICY policySession, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_DIGEST *policyDigest, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+TPM_RC -+TPM2_Create (TPMI_DH_OBJECT parentHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPM2B_SENSITIVE_CREATE *inSensitive, -+ TPM2B_PUBLIC *inPublic, -+ TPM2B_DATA *outsideInfo, -+ 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 (TPMI_RH_PROVISION auth, -+ TPMI_DH_OBJECT objectHandle, -+ TPMI_DH_PERSISTENT persistentHandle, -+ const TPMS_AUTH_COMMAND *authCommand, -+ TPMS_AUTH_RESPONSE *authResponse); -+ -+#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 0000000000..75bf99ec8a ---- /dev/null -+++ b/include/grub/tpm2/internal/structs.h -@@ -0,0 +1,675 @@ -+/* -+ * 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; -+ -+/* 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; -+ -+#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 0000000000..9714f75d4f ---- /dev/null -+++ b/include/grub/tpm2/internal/types.h -@@ -0,0 +1,372 @@ -+/* -+ * 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_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_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_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_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) -+ -+/* TPM2_ECC_CURVE Constants */ -+typedef grub_uint16_t TPM2_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_Unseal ((TPM_CC) 0x0000015e) -+#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) -+ -+/* 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; -+ -+/* TPM_KEY_BITS Type */ -+typedef grub_uint16_t TPM_KEY_BITS; -+ -+/* TPM_ECC_CURVE Types */ -+typedef grub_uint16_t TPM_ECC_CURVE; -+ -+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 0000000000..4f4058f9d6 ---- /dev/null -+++ b/include/grub/tpm2/mu.h -@@ -0,0 +1,292 @@ -+/* -+ * 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 buf, -+ const TPMS_AUTH_COMMAND* authCommand); -+ -+void -+grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buf, -+ grub_uint16_t size, -+ const grub_uint8_t* buffer); -+ -+void -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_KEY_BITS *p); -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_MODE *p); -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_SYM_DEF *p); -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buf, -+ const TPMS_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buf, -+ const TPML_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buf, -+ const TPMA_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_SCHEME_XOR *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_SCHEME_HMAC *p); -+ -+void -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ TPMU_SCHEME_KEYEDHASH *p); -+ -+void -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_KEYEDHASH_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_KEYEDHASH_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_SYM_DEF_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_RSA_DECRYPT scheme, -+ TPMU_ASYM_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_RSA_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_RSA_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_SYMCIPHER_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_ECC_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_KDF scheme, -+ TPMU_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_ECC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buf, -+ grub_uint32_t type, -+ TPMU_PUBLIC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_ECC_POINT *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_PUBLIC type, -+ TPMU_PUBLIC_ID *p); -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buf, -+ TPMT_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buf, -+ TPM2B_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf, -+ TPMS_SENSITIVE_CREATE *p); -+ -+void -+grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf, -+ TPM2B_SENSITIVE_CREATE *sensitiveCreate); -+ -+void -+grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf, -+ TPM2B* p); -+ -+void -+grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_AUTH_RESPONSE* p); -+ -+void -+grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, -+ TPM2B_DIGEST* digest); -+ -+void -+grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMA_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_SCHEME_HMAC *p); -+ -+void -+grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_SCHEME_XOR *p); -+ -+void -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_KEYEDHASH_SCHEME scheme, -+ TPMU_SCHEME_KEYEDHASH *p); -+ -+void -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_KEYEDHASH_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_KEYEDHASH_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_KEY_BITS *p); -+ -+void -+grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_SYM_OBJECT algorithm, -+ TPMU_SYM_MODE *p); -+ -+void -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_SYM_DEF_OBJECT *p); -+ -+void -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_SYMCIPHER_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_RSA_DECRYPT scheme, -+ TPMU_ASYM_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_RSA_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_RSA_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_ECC_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_KDF scheme, -+ TPMU_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_KDF_SCHEME *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_ECC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buf, -+ grub_uint32_t type, -+ TPMU_PUBLIC_PARMS *p); -+ -+void -+grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_ECC_POINT *p); -+ -+void -+grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMI_ALG_PUBLIC type, -+ TPMU_PUBLIC_ID *p); -+ -+void -+grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, -+ TPM2B_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_NV_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, -+ TPM2B_NV_PUBLIC *p); -+ -+void -+grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buf, -+ TPM2B_NAME *n); -+ -+void -+grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_TAGGED_PROPERTY* property); -+ -+void -+grub_tpm2_mu_TPMS_CAPABILITY_DATA_tpmProperties_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_CAPABILITY_DATA* capabilityData); -+ -+void -+grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMT_TK_CREATION *p); -+ -+void -+grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, -+ TPMS_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, -+ TPML_PCR_SELECTION* pcrSelection); -+ -+void -+grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, -+ TPML_DIGEST* digest); -+ -+#endif /* ! GRUB_TPM2_MU_HEADER */ -diff --git a/include/grub/tpm2/tcg2.h b/include/grub/tpm2/tcg2.h -new file mode 100644 -index 0000000000..99f2fdd3b9 ---- /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 0000000000..4b7a9fbb57 ---- /dev/null -+++ b/include/grub/tpm2/tpm2.h -@@ -0,0 +1,38 @@ -+/* -+ * 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 -+ -+/* 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 -+ -+typedef struct TPM2_SEALED_KEY { -+ TPM2B_PUBLIC public; -+ TPM2B_PRIVATE private; -+} TPM2_SEALED_KEY; -+ -+#endif /* ! GRUB_TPM2_TPM2_HEADER */ --- -2.34.1 - diff --git a/0012-protectors-Add-TPM2-Key-Protector.patch b/0012-protectors-Add-TPM2-Key-Protector.patch deleted file mode 100644 index e18bc68..0000000 --- a/0012-protectors-Add-TPM2-Key-Protector.patch +++ /dev/null @@ -1,977 +0,0 @@ -From b173db7537920ee5706e1c961fea3086ada6b6dd Mon Sep 17 00:00:00 2001 -From: Hernan Gatta -Date: Tue, 1 Feb 2022 05:02:55 -0800 -Subject: [PATCH 12/14] protectors: 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. - -The theory of operation is such that the module accepts various arguments, most -of which are optional and therefore possess reasonable defaults. One of these -arguments is the keyfile parameter, which is mandatory. - -The value of this parameter must be a path to a sealed key file (e.g., -(hd0,gpt1)/boot/grub2/sealed_key). This sealed key file is created via the -grub-protect tool. The tool utilizes the TPM's sealing functionality to seal -(i.e., encrypt) an unlocking key using a Storage Root Key (SRK) to the values of -various Platform Configuration Registers (PCRs). These PCRs reflect the state of -the system as it boots. If the values are as expected, the system may be -considered trustworthy, at which point the TPM allows for a caller to utilize -the private component of the SRK to unseal (i.e., decrypt) the sealed key file. -The caller, in this case, is this key protector. - -The TPM2 key protector registers two commands: - -- tpm2_key_protector_init: Initializes the state of the TPM2 key protector for - later usage, clearing any previous state, too, if - any. - -- tpm2_key_protector_clear: Clears any state set by tpm2_key_protector_init. - -The way this is expected to be used requires the user to, either interactively -or, normally, via a boot script, initialize (i.e., configure) the key protector -and then specify that it be used by the cryptomount command (modifications to -this command are in a different patch). - -For instance: - -tpm2_key_protector_init --keyfile=KEYFILE1 -cryptomount DISK1 -k tpm2 - -tpm2_key_protector_init --keyfile=KEYFILE2 --pcrs=7,11 -cryptomount DISK2 -k tpm2 - -If a user does not initialize the key protector and attempts to use it anyway, -the protector returns an error. - -Signed-off-by: Hernan Gatta ---- - grub-core/Makefile.core.def | 10 + - grub-core/tpm2/args.c | 129 ++++++ - grub-core/tpm2/module.c | 710 ++++++++++++++++++++++++++++++ - include/grub/tpm2/internal/args.h | 39 ++ - 4 files changed, 888 insertions(+) - create mode 100644 grub-core/tpm2/args.c - create mode 100644 grub-core/tpm2/module.c - create mode 100644 include/grub/tpm2/internal/args.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index b0001a33cf..850cee2b13 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2561,6 +2561,16 @@ module = { - enable = efi; - }; - -+module = { -+ name = tpm2; -+ common = tpm2/args.c; -+ common = tpm2/buffer.c; -+ common = tpm2/module.c; -+ common = tpm2/mu.c; -+ common = tpm2/tpm2.c; -+ efi = tpm2/tcg2.c; -+}; -+ - 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 0000000000..90c7cd8991 ---- /dev/null -+++ b/grub-core/tpm2/args.c -@@ -0,0 +1,129 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Microsoft Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+grub_err_t -+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, -+ grub_uint8_t *pcr_count) -+{ -+ char *current_pcr = value; -+ char *next_pcr; -+ unsigned long pcr; -+ grub_uint8_t i; -+ -+ if (grub_strlen (value) == 0) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ *pcr_count = 0; -+ for (i = 0; i < TPM_MAX_PCRS; i++) -+ { -+ next_pcr = grub_strchr (current_pcr, ','); -+ if (next_pcr == current_pcr) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Empty entry in PCR list")); -+ if (next_pcr) -+ *next_pcr = '\0'; -+ -+ grub_errno = GRUB_ERR_NONE; -+ pcr = grub_strtoul (current_pcr, NULL, 10); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_error (grub_errno, -+ N_("Entry '%s' in PCR list is not a number"), -+ current_pcr); -+ -+ if (pcr > TPM_MAX_PCRS) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("Entry %lu in PCR list is too large to be a PCR " -+ "number, PCR numbers range from 0 to %u"), -+ pcr, TPM_MAX_PCRS); -+ -+ pcrs[i] = (grub_uint8_t)pcr; -+ *pcr_count += 1; -+ -+ if (!next_pcr) -+ 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")); -+ } -+ -+ 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_ERR_NONE; -+} -+ -+grub_err_t -+grub_tpm2_protector_parse_asymmetric (const char *value, TPM_ALG_ID *asymmetric) -+{ -+ if (grub_strcasecmp (value, "ECC") == 0) -+ *asymmetric = TPM_ALG_ECC; -+ else if (grub_strcasecmp (value, "RSA") == 0) -+ *asymmetric = TPM_ALG_RSA; -+ else -+ 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) -+{ -+ if (grub_strcasecmp (value, "SHA1") == 0) -+ *bank = TPM_ALG_SHA1; -+ else if (grub_strcasecmp (value, "SHA256") == 0) -+ *bank = TPM_ALG_SHA256; -+ else if (grub_strcasecmp (value, "SHA384") == 0) -+ *bank = TPM_ALG_SHA384; -+ else -+ 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) -+{ -+ unsigned long num; -+ -+ 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); -+ -+ 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); -+ -+ *handle = (TPM_HANDLE)num; -+ -+ return GRUB_ERR_NONE; -+} -diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c -new file mode 100644 -index 0000000000..3f2f386f7e ---- /dev/null -+++ b/grub-core/tpm2/module.c -@@ -0,0 +1,710 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Microsoft Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+typedef enum grub_tpm2_protector_mode -+{ -+ GRUB_TPM2_PROTECTOR_MODE_UNSET, -+ GRUB_TPM2_PROTECTOR_MODE_SRK, -+ GRUB_TPM2_PROTECTOR_MODE_NV -+} grub_tpm2_protector_mode_t; -+ -+struct grub_tpm2_protector_context -+{ -+ grub_tpm2_protector_mode_t mode; -+ grub_uint8_t pcrs[TPM_MAX_PCRS]; -+ grub_uint8_t pcr_count; -+ TPM_ALG_ID asymmetric; -+ TPM_ALG_ID bank; -+ const char *keyfile; -+ TPM_HANDLE srk; -+ TPM_HANDLE nv; -+}; -+ -+static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] = -+ { -+ /* Options for all modes */ -+ { -+ .longarg = "mode", -+ .shortarg = 'm', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("Unseal key using SRK ('srk') (default) or retrieve it from an NV " -+ "Index ('nv')."), -+ }, -+ { -+ .longarg = "pcrs", -+ .shortarg = 'p', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("Comma-separated list of PCRs used to authorize key release " -+ "(e.g., '7,11', default is 7."), -+ }, -+ { -+ .longarg = "bank", -+ .shortarg = 'b', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("Bank of PCRs used to authorize key release: " -+ "SHA1, SHA256 (default), or SHA384."), -+ }, -+ /* SRK-mode options */ -+ { -+ .longarg = "keyfile", -+ .shortarg = 'k', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("Required in SRK mode, path to the sealed key file to unseal using " -+ "the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed_key)."), -+ }, -+ { -+ .longarg = "srk", -+ .shortarg = 's', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("In SRK mode, the SRK handle if the SRK is persistent " -+ "(default is 0x81000001)."), -+ }, -+ { -+ .longarg = "asymmetric", -+ .shortarg = 'a', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("In SRK mode, the type of SRK: RSA (default) or ECC."), -+ }, -+ /* NV Index-mode options */ -+ { -+ .longarg = "nvindex", -+ .shortarg = 'n', -+ .flags = 0, -+ .arg = NULL, -+ .type = ARG_TYPE_STRING, -+ .doc = -+ N_("Required in NV Index mode, the NV handle to read which must " -+ "readily exist on the TPM and which contains the key."), -+ }, -+ /* End of list */ -+ {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_err_t -+grub_tpm2_protector_srk_read_keyfile (const char *filepath, void **buffer, -+ grub_size_t *buffer_size) -+{ -+ grub_file_t sealed_key_file; -+ grub_off_t sealed_key_size; -+ void *sealed_key_buffer; -+ grub_off_t sealed_key_read; -+ -+ sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE); -+ if (!sealed_key_file) -+ { -+ grub_dprintf ("tpm2", "Could not open sealed key file.\n"); -+ /* grub_file_open sets grub_errno on error, and if we do no unset it, -+ * future calls to grub_file_open will fail (and so will anybody up the -+ * stack who checks the value, if any). */ -+ grub_errno = GRUB_ERR_NONE; -+ return GRUB_ERR_FILE_NOT_FOUND; -+ } -+ -+ sealed_key_size = grub_file_size (sealed_key_file); -+ if (!sealed_key_size) -+ { -+ grub_dprintf ("tpm2", "Could not read sealed key file size.\n"); -+ grub_file_close (sealed_key_file); -+ return GRUB_ERR_OUT_OF_RANGE; -+ } -+ -+ sealed_key_buffer = grub_malloc (sealed_key_size); -+ if (!sealed_key_buffer) -+ { -+ grub_dprintf ("tpm2", "Could not allocate buffer for sealed key.\n"); -+ grub_file_close (sealed_key_file); -+ return GRUB_ERR_OUT_OF_MEMORY; -+ } -+ -+ sealed_key_read = grub_file_read (sealed_key_file, sealed_key_buffer, -+ sealed_key_size); -+ if (sealed_key_read != sealed_key_size) -+ { -+ grub_dprintf ("tpm2", "Could not retrieve sealed key file contents.\n"); -+ grub_free (sealed_key_buffer); -+ grub_file_close (sealed_key_file); -+ return GRUB_ERR_FILE_READ_ERROR; -+ } -+ -+ grub_file_close (sealed_key_file); -+ -+ *buffer = sealed_key_buffer; -+ *buffer_size = sealed_key_size; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key, -+ grub_size_t sealed_key_size, -+ TPM2_SEALED_KEY *sk) -+{ -+ struct grub_tpm2_buffer buf; -+ -+ grub_tpm2_buffer_init (&buf); -+ if (sealed_key_size > buf.cap) -+ { -+ grub_dprintf ("tpm2", "Sealed key file is larger than decode buffer " -+ "(%lu vs %lu bytes).\n", sealed_key_size, buf.cap); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ 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_Unmarshal (&buf, (TPM2B *)&sk->private); -+ -+ if (buf.error) -+ { -+ grub_dprintf ("tpm2", "Could not unmarshal sealed key file, it is likely " -+ "malformed.\n"); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_tpm2_protector_srk_get (const struct grub_tpm2_protector_context *ctx, -+ TPM_HANDLE *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; -+ -+ /* Find SRK */ -+ rc = TPM2_ReadPublic (ctx->srk, NULL, &public); -+ if (rc == TPM_RC_SUCCESS) -+ { -+ *srk = ctx->srk; -+ return GRUB_ERR_NONE; -+ } -+ -+ /* The handle exists but its public area could not be read. */ -+ if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE) -+ { -+ grub_dprintf ("tpm2", "The SRK handle (0x%x) exists on the TPM but its " -+ "public area could not be read (TPM2_ReadPublic " -+ "failed with TSS/TPM error %u).\n", ctx->srk, rc); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ /* Create SRK */ -+ authCommand.sessionHandle = TPM_RS_PW; -+ inPublic.publicArea.type = ctx->asymmetric; -+ inPublic.publicArea.nameAlg = TPM_ALG_SHA256; -+ inPublic.publicArea.objectAttributes.restricted = 1; -+ inPublic.publicArea.objectAttributes.userWithAuth = 1; -+ inPublic.publicArea.objectAttributes.decrypt = 1; -+ inPublic.publicArea.objectAttributes.fixedTPM = 1; -+ inPublic.publicArea.objectAttributes.fixedParent = 1; -+ inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1; -+ inPublic.publicArea.objectAttributes.noDA = 1; -+ -+ if (ctx->asymmetric == TPM_ALG_RSA) -+ { -+ inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES; -+ inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128; -+ inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB; -+ inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; -+ inPublic.publicArea.parameters.rsaDetail.keyBits = 2048; -+ inPublic.publicArea.parameters.rsaDetail.exponent = 0; -+ } -+ else if (ctx->asymmetric == TPM_ALG_ECC) -+ { -+ inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES; -+ inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128; -+ inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB; -+ inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL; -+ inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256; -+ inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; -+ } -+ else -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ rc = TPM2_CreatePrimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic, -+ &outsideInfo, &creationPcr, &srkHandle, &outPublic, -+ &creationData, &creationHash, &creationTicket, -+ &srkName, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ grub_dprintf ("tpm2", "Could not create SRK (TPM2_CreatePrimary failed " -+ "with TSS/TPM error %u).\n", rc); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ *srk = srkHandle; -+ -+ return GRUB_ERR_NONE; -+} -+ -+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) -+{ -+ TPM_RC rc; -+ TPM2_SEALED_KEY sealed_key; -+ void *sealed_key_bytes; -+ grub_size_t sealed_key_size; -+ TPM_HANDLE srk_handle; -+ TPM2B_NONCE nonceCaller = { 0 }; -+ TPM2B_ENCRYPTED_SECRET salt = { 0 }; -+ TPMT_SYM_DEF symmetric = { 0 }; -+ TPM2B_NONCE nonceTPM = { 0 }; -+ TPMI_SH_AUTH_SESSION session; -+ TPML_PCR_SELECTION pcrSel = { -+ .count = 1, -+ .pcrSelections = { -+ { -+ .hash = ctx->bank, -+ .sizeOfSelect = 3, -+ .pcrSelect = { 0 } -+ }, -+ } -+ }; -+ TPMS_AUTH_COMMAND authCmd = { 0 }; -+ TPM_HANDLE sealed_key_handle; -+ TPM2B_NAME name; -+ TPMS_AUTH_RESPONSE authResponse; -+ TPM2B_SENSITIVE_DATA data; -+ grub_uint8_t *key_out; -+ grub_uint8_t i; -+ grub_err_t err; -+ -+ /* Retrieve Sealed Key */ -+ err = grub_tpm2_protector_srk_read_keyfile (ctx->keyfile, &sealed_key_bytes, -+ &sealed_key_size); -+ if (err) -+ return grub_error (err, N_("Failed to read key file %s"), ctx->keyfile); -+ -+ err = grub_tpm2_protector_srk_unmarshal_keyfile (sealed_key_bytes, -+ sealed_key_size, -+ &sealed_key); -+ if (err) -+ { -+ grub_error (err, N_("Failed to unmarshal key, ensure the key file is in " -+ "TPM wire format")); -+ goto exit1; -+ } -+ -+ /* Get SRK */ -+ err = grub_tpm2_protector_srk_get (ctx, &srk_handle); -+ if (err) -+ { -+ grub_error (err, N_("Failed to retrieve the SRK")); -+ goto exit1; -+ } -+ -+ err = GRUB_ERR_BAD_DEVICE; -+ -+ /* Start Auth Session */ -+ nonceCaller.size = TPM_SHA256_DIGEST_SIZE; -+ symmetric.algorithm = TPM_ALG_NULL; -+ -+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonceCaller, &salt, -+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256, -+ &session, &nonceTPM, 0); -+ if (rc) -+ { -+ grub_error (err, N_("Failed to start auth session (TPM2_StartAuthSession " -+ "failed with TSS/TPM error %u)"), rc); -+ goto exit2; -+ } -+ -+ /* Policy PCR */ -+ for (i = 0; i < ctx->pcr_count; i++) -+ pcrSel -+ .pcrSelections[0] -+ .pcrSelect[TPM2_PCR_TO_SELECT(ctx->pcrs[i])] -+ |= TPM2_PCR_TO_BIT(ctx->pcrs[i]); -+ -+ rc = TPM2_PolicyPCR (session, NULL, NULL, &pcrSel, NULL); -+ if (rc) -+ { -+ grub_error (err, N_("Failed to submit PCR policy (TPM2_PolicyPCR failed " -+ "with TSS/TPM error %u)"), rc); -+ goto exit3; -+ } -+ -+ /* Load Sealed Key */ -+ authCmd.sessionHandle = TPM_RS_PW; -+ rc = TPM2_Load (srk_handle, &authCmd, &sealed_key.private, &sealed_key.public, -+ &sealed_key_handle, &name, &authResponse); -+ if (rc) -+ { -+ grub_error (err, N_("Failed to load sealed key (TPM2_Load failed with " -+ "TSS/TPM error %u)"), rc); -+ goto exit3; -+ } -+ -+ /* Unseal Sealed Key */ -+ authCmd.sessionHandle = session; -+ grub_memset (&authResponse, 0, sizeof (authResponse)); -+ -+ rc = TPM2_Unseal (sealed_key_handle, &authCmd, &data, &authResponse); -+ if (rc) -+ { -+ grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed " -+ "with TSS/TPM error %u)"), rc); -+ goto exit4; -+ } -+ -+ /* Epilogue */ -+ key_out = grub_malloc (data.size); -+ if (!key_out) -+ { -+ err = GRUB_ERR_OUT_OF_MEMORY; -+ grub_error (err, N_("No memory left to allocate unlock key buffer")); -+ goto exit4; -+ } -+ -+ grub_memcpy (key_out, data.buffer, data.size); -+ -+ *key = key_out; -+ *key_size = data.size; -+ -+ err = GRUB_ERR_NONE; -+ -+exit4: -+ TPM2_FlushContext (sealed_key_handle); -+ -+exit3: -+ TPM2_FlushContext (session); -+ -+exit2: -+ TPM2_FlushContext (srk_handle); -+ -+exit1: -+ grub_free (sealed_key_bytes); -+ return err; -+} -+ -+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) -+{ -+ (void)ctx; -+ (void)key; -+ (void)key_size; -+ -+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ N_("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) -+{ -+ 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); -+ default: -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+} -+ -+static grub_err_t -+grub_tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size) -+{ -+ grub_err_t err; -+ -+ /* 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 (!key) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ err = grub_tpm2_protector_recover (&grub_tpm2_protector_ctx, key, key_size); -+ if (err) -+ return err; -+ -+ return GRUB_ERR_NONE; -+} -+ -+ -+static grub_err_t -+grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx) -+{ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET) -+ ctx->mode = GRUB_TPM2_PROTECTOR_MODE_SRK; -+ -+ /* Checks for SRK mode */ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && !ctx->keyfile) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In SRK mode, a key file must be specified: " -+ "--keyfile or -k")); -+ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->nv) -+ 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) -+ 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 && ctx->keyfile) -+ 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) -+ 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 && ctx->asymmetric) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("In NV Index mode, an asymmetric key type cannot be " -+ "specified")); -+ -+ /* Defaults assignment */ -+ if (!ctx->bank) -+ ctx->bank = TPM_ALG_SHA256; -+ -+ if (!ctx->pcr_count) -+ { -+ ctx->pcrs[0] = 7; -+ ctx->pcr_count = 1; -+ } -+ -+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK) -+ { -+ if (!ctx->srk) -+ ctx->srk = TPM2_SRK_HANDLE; -+ -+ if (!ctx->asymmetric) -+ ctx->asymmetric = TPM_ALG_RSA; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile) -+{ -+ if (grub_strlen (value) == 0) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ *keyfile = grub_strdup (value); -+ if (!*keyfile) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("No memory to duplicate keyfile path")); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_tpm2_protector_parse_mode (const char *value, -+ grub_tpm2_protector_mode_t *mode) -+{ -+ if (grub_strcmp (value, "srk") == 0) -+ *mode = GRUB_TPM2_PROTECTOR_MODE_SRK; -+ else if (grub_strcmp (value, "nv") == 0) -+ *mode = GRUB_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_ERR_NONE; -+} -+ -+static grub_err_t -+grub_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)")); -+ -+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); -+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); -+ -+ if (state[0].set) /* mode */ -+ { -+ err = grub_tpm2_protector_parse_mode (state[0].arg, -+ &grub_tpm2_protector_ctx.mode); -+ if (err) -+ return err; -+ } -+ -+ if (state[1].set) /* pcrs */ -+ { -+ err = grub_tpm2_protector_parse_pcrs (state[1].arg, -+ grub_tpm2_protector_ctx.pcrs, -+ &grub_tpm2_protector_ctx.pcr_count); -+ if (err) -+ return err; -+ } -+ -+ if (state[2].set) /* bank */ -+ { -+ err = grub_tpm2_protector_parse_bank (state[2].arg, -+ &grub_tpm2_protector_ctx.bank); -+ if (err) -+ return err; -+ } -+ -+ if (state[3].set) /* keyfile */ -+ { -+ err = grub_tpm2_protector_parse_keyfile (state[3].arg, -+ &grub_tpm2_protector_ctx.keyfile); -+ if (err) -+ return err; -+ } -+ -+ if (state[4].set) /* srk */ -+ { -+ err = grub_tpm2_protector_parse_tpm_handle (state[4].arg, -+ &grub_tpm2_protector_ctx.srk); -+ if (err) -+ return err; -+ } -+ -+ if (state[5].set) /* asymmetric */ -+ { -+ err = grub_tpm2_protector_parse_asymmetric (state[5].arg, -+ &grub_tpm2_protector_ctx.asymmetric); -+ if (err) -+ return err; -+ } -+ -+ if (state[6].set) /* nvindex */ -+ { -+ err = grub_tpm2_protector_parse_tpm_handle (state[6].arg, -+ &grub_tpm2_protector_ctx.nv); -+ if (err) -+ return err; -+ } -+ -+ err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx); -+ -+ /* This command only initializes the protector, so nothing else to do. */ -+ -+ return err; -+} -+ -+static grub_err_t -+grub_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")); -+ -+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); -+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static struct grub_key_protector grub_tpm2_key_protector = -+ { -+ .name = "tpm2", -+ .recover_key = grub_tpm2_protector_recover_key -+ }; -+ -+GRUB_MOD_INIT (tpm2) -+{ -+ grub_tpm2_protector_init_cmd = -+ grub_register_extcmd ("tpm2_key_protector_init", -+ grub_tpm2_protector_init_cmd_handler, 0, -+ N_("[-m mode] " -+ "[-p pcr_list] " -+ "[-b pcr_bank] " -+ "[-k sealed_key_file_path] " -+ "[-s srk_handle] " -+ "[-a asymmetric_key_type] " -+ "[-n nv_index]"), -+ N_("Initialize the TPM2 key protector."), -+ grub_tpm2_protector_init_cmd_options); -+ grub_tpm2_protector_clear_cmd = -+ grub_register_extcmd ("tpm2_key_protector_clear", -+ grub_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_MOD_FINI (tpm2) -+{ -+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); -+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); -+ -+ grub_key_protector_unregister (&grub_tpm2_key_protector); -+ grub_unregister_extcmd (grub_tpm2_protector_clear_cmd); -+ grub_unregister_extcmd (grub_tpm2_protector_init_cmd); -+} -diff --git a/include/grub/tpm2/internal/args.h b/include/grub/tpm2/internal/args.h -new file mode 100644 -index 0000000000..6341fce1c5 ---- /dev/null -+++ b/include/grub/tpm2/internal/args.h -@@ -0,0 +1,39 @@ -+/* -+ * 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 -+ -+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, -+ TPM_ALG_ID *asymmetric); -+ -+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 */ --- -2.34.1 - diff --git a/0013-cryptodisk-Support-key-protectors.patch b/0013-cryptodisk-Support-key-protectors.patch deleted file mode 100644 index 4884875..0000000 --- a/0013-cryptodisk-Support-key-protectors.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 9888bf40d960339a59dc18fb6e1df5f65b4668e3 Mon Sep 17 00:00:00 2001 -From: Hernan Gatta -Date: Tue, 1 Feb 2022 05:02:56 -0800 -Subject: [PATCH 13/14] cryptodisk: Support key protectors - -Add a new parameter to cryptomount to support the key protectors framework: -k. -The parameter is used to automatically retrieve a key from specified key -protectors. The parameter may be repeated to specify any number of key -protectors. These are tried in order until one provides a usable key for any -given disk. - -Signed-off-by: ---- - Makefile.util.def | 1 + - grub-core/disk/cryptodisk.c | 166 +++++++++++++++++++++++++++++------- - include/grub/cryptodisk.h | 14 +++ - 3 files changed, 151 insertions(+), 30 deletions(-) - -diff --git a/Makefile.util.def b/Makefile.util.def -index ef5c818e0e..b3ec2a4bb6 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -35,6 +35,7 @@ library = { - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/kern/partition.c; -+ common = grub-core/kern/protectors.c; - common = grub-core/lib/crypto.c; - common = grub-core/lib/json/json.c; - common = grub-core/disk/luks.c; -diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index 497097394f..00c44773fb 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #ifdef GRUB_UTIL - #include -@@ -42,6 +43,8 @@ static const struct grub_arg_option options[] = - {"all", 'a', 0, N_("Mount all."), 0, 0}, - {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, - {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING}, -+ {"protector", 'k', GRUB_ARG_OPTION_REPEATABLE, -+ N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -@@ -1000,7 +1003,8 @@ grub_cryptodisk_scan_device_real (const char *name, - { - grub_err_t ret = GRUB_ERR_NONE; - grub_cryptodisk_t dev; -- grub_cryptodisk_dev_t cr; -+ grub_cryptodisk_dev_t cr, crd = NULL; -+ int i; - int askpass = 0; - char *part = NULL; - -@@ -1016,39 +1020,108 @@ grub_cryptodisk_scan_device_real (const char *name, - return NULL; - if (!dev) - continue; -+ crd = cr; -+ } - -- if (!cargs->key_len) -- { -- /* Get the passphrase from the user, if no key data. */ -- askpass = 1; -- part = grub_partition_get_name (source->partition); -- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -- source->partition != NULL ? "," : "", -- part != NULL ? part : N_("UNKNOWN"), -- dev->uuid); -- grub_free (part); -- -- cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); -- if (cargs->key_data == NULL) -- return NULL; -- -- if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) -- { -- grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); -- goto error; -- } -- cargs->key_len = grub_strlen ((char *) cargs->key_data); -- } -+ if (!dev) -+ { -+ grub_error (GRUB_ERR_BAD_MODULE, -+ "no cryptodisk module can handle this device"); -+ return NULL; -+ } - -- ret = cr->recover_key (source, dev, cargs); -- if (ret != GRUB_ERR_NONE) -+ if (cargs->protectors) -+ { -+ for (i = 0; cargs->protectors[i]; i++) -+ { -+ if (cargs->key_cache[i].invalid) -+ continue; -+ -+ if (!cargs->key_cache[i].key) -+ { -+ ret = grub_key_protector_recover_key (cargs->protectors[i], -+ &cargs->key_cache[i].key, -+ &cargs->key_cache[i].key_len); -+ if (ret) -+ { -+ if (grub_errno) -+ { -+ grub_print_error (); -+ grub_errno = GRUB_ERR_NONE; -+ } -+ -+ grub_dprintf ("cryptodisk", -+ "failed to recover a key from key protector " -+ "%s, will not try it again for any other " -+ "disks, if any, during this invocation of " -+ "cryptomount\n", -+ cargs->protectors[i]); -+ -+ cargs->key_cache[i].invalid = 1; -+ continue; -+ } -+ } -+ -+ cargs->key_data = cargs->key_cache[i].key; -+ cargs->key_len = cargs->key_cache[i].key_len; -+ -+ ret = crd->recover_key (source, dev, cargs); -+ if (ret) -+ { -+ part = grub_partition_get_name (source->partition); -+ grub_dprintf ("cryptodisk", -+ "recovered a key from key protector %s but it " -+ "failed to unlock %s%s%s (%s)\n", -+ cargs->protectors[i], source->name, -+ source->partition != NULL ? "," : "", -+ part != NULL ? part : N_("UNKNOWN"), dev->uuid); -+ grub_free (part); -+ continue; -+ } -+ else -+ { -+ grub_cryptodisk_insert (dev, name, source); -+ goto cleanup; -+ }; -+ } -+ -+ part = grub_partition_get_name (source->partition); -+ grub_error (GRUB_ERR_ACCESS_DENIED, -+ N_("no key protector provided a usable key for %s%s%s (%s)"), -+ source->name, source->partition != NULL ? "," : "", -+ part != NULL ? part : N_("UNKNOWN"), dev->uuid); -+ grub_free (part); - goto error; -+ } - -- grub_cryptodisk_insert (dev, name, source); -+ if (!cargs->key_len) -+ { -+ /* Get the passphrase from the user, if no key data. */ -+ askpass = 1; -+ part = grub_partition_get_name (source->partition); -+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -+ source->partition != NULL ? "," : "", -+ part != NULL ? part : N_("UNKNOWN"), dev->uuid); -+ grub_free (part); -+ -+ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); -+ if (cargs->key_data == NULL) -+ goto error; -+ -+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); -+ goto error; -+ } -+ cargs->key_len = grub_strlen ((char *) cargs->key_data); -+ } -+ -+ ret = crd->recover_key (source, dev, cargs); -+ if (ret != GRUB_ERR_NONE) -+ goto error; -+ -+ grub_cryptodisk_insert (dev, name, source); - -- goto cleanup; -- } -- grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); - goto cleanup; - - error: -@@ -1155,6 +1228,20 @@ grub_cryptodisk_scan_device (const char *name, - return ret; - } - -+static void -+grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs) -+{ -+ int i; -+ -+ if (!cargs->key_cache) -+ return; -+ -+ for (i = 0; cargs->protectors[i]; i++) -+ grub_free (cargs->key_cache[i].key); -+ -+ grub_free (cargs->key_cache); -+} -+ - static grub_err_t - grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - { -@@ -1167,12 +1254,25 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - if (grub_cryptodisk_list == NULL) - return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); - -+ if (state[3].set && state[4].set) /* password and key protector */ -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "a password and a key protector cannot both be set"); -+ - if (state[3].set) /* password */ - { - cargs.key_data = (grub_uint8_t *) state[3].arg; - cargs.key_len = grub_strlen (state[3].arg); - } - -+ if (state[4].set) /* key protector(s) */ -+ { -+ cargs.key_cache = grub_zalloc (state[4].set * sizeof (*cargs.key_cache)); -+ if (!cargs.key_cache) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "no memory for key protector key cache"); -+ cargs.protectors = state[4].args; -+ } -+ - if (state[0].set) /* uuid */ - { - int found_uuid; -@@ -1181,6 +1281,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - dev = grub_cryptodisk_get_by_uuid (args[0]); - if (dev) - { -+ grub_cryptodisk_clear_key_cache (&cargs); - grub_dprintf ("cryptodisk", - "already mounted as crypto%lu\n", dev->id); - return GRUB_ERR_NONE; -@@ -1189,6 +1290,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - cargs.check_boot = state[2].set; - cargs.search_uuid = args[0]; - found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); -+ grub_cryptodisk_clear_key_cache (&cargs); - - if (found_uuid) - return GRUB_ERR_NONE; -@@ -1208,6 +1310,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - { - cargs.check_boot = state[2].set; - grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); -+ grub_cryptodisk_clear_key_cache (&cargs); - return GRUB_ERR_NONE; - } - else -@@ -1231,6 +1334,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - disk = grub_disk_open (diskname); - if (!disk) - { -+ grub_cryptodisk_clear_key_cache (&cargs); - if (disklast) - *disklast = ')'; - return grub_errno; -@@ -1241,12 +1345,14 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) - { - grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id); - grub_disk_close (disk); -+ grub_cryptodisk_clear_key_cache (&cargs); - if (disklast) - *disklast = ')'; - return GRUB_ERR_NONE; - } - - dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); -+ grub_cryptodisk_clear_key_cache (&cargs); - - grub_disk_close (disk); - if (disklast) -@@ -1385,7 +1491,7 @@ GRUB_MOD_INIT (cryptodisk) - { - grub_disk_dev_register (&grub_cryptodisk_dev); - cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, -- N_("[-p password] "), -+ N_("[-p password] [-k protector [-k protector ...]] "), - N_("Mount a crypto device."), options); - grub_procfs_register ("luks_script", &luks_script); - } -diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h -index c6524c9ea9..b556498fba 100644 ---- a/include/grub/cryptodisk.h -+++ b/include/grub/cryptodisk.h -@@ -67,6 +67,16 @@ typedef gcry_err_code_t - (*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, - grub_uint64_t zoneno); - -+struct grub_cryptomount_cached_key -+{ -+ grub_uint8_t *key; -+ grub_size_t key_len; -+ -+ /* The key protector associated with this cache entry failed, so avoid it -+ * even if the cached entry (an instance of this structure) is empty. */ -+ int invalid; -+}; -+ - struct grub_cryptomount_args - { - /* scan: Flag to indicate that only bootable volumes should be decrypted */ -@@ -77,6 +87,10 @@ struct grub_cryptomount_args - grub_uint8_t *key_data; - /* recover_key: Length of key_data */ - grub_size_t key_len; -+ /* recover_key: Names of the key protectors to use (NULL-terminated) */ -+ char **protectors; -+ /* recover_key: Key cache to avoid invoking the same key protector twice */ -+ struct grub_cryptomount_cached_key *key_cache; - }; - typedef struct grub_cryptomount_args *grub_cryptomount_args_t; - --- -2.34.1 - diff --git a/0014-util-grub-protect-Add-new-tool.patch b/0014-util-grub-protect-Add-new-tool.patch deleted file mode 100644 index c423a60..0000000 --- a/0014-util-grub-protect-Add-new-tool.patch +++ /dev/null @@ -1,1408 +0,0 @@ -From a913983cb75594e08b425e3c099185b2f4187663 Mon Sep 17 00:00:00 2001 -From: Hernan Gatta -Date: Tue, 1 Feb 2022 05:02:57 -0800 -Subject: [PATCH 14/14] 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 includes -support for the TPM2 key protector but other protectors that require setup ahead -of time can be supported in the future. - -For the TPM2 key protector, the intended flow is for a user to have a LUKS 1 or -LUKS 2-protected fully-encrypted disk. The user then creates a new key file, say -by reading /dev/urandom into a file, and creates a new LUKS key slot for this -key. Then, the user invokes the grub-protect tool to seal this key file to a set -of PCRs using the system's TPM 2.0. The resulting sealed key file is stored in -an unencrypted partition such as the EFI System Partition (ESP) so that GRUB may -read it. The user also ensures the cryptomount command is included in GRUB's -boot script and that it carries the requisite key protector (-k) parameter. - -Sample usage: - -$ dd if=/dev/urandom of=key bs=1 count=32 -$ sudo cryptsetup luksAddKey /dev/sdb1 key --pbkdf=pbkdf2 --hash=sha512 - -$ sudo grub-protect --action=add - --protector=tpm2 - --tpm2-keyfile=key - --tpm2-outfile=/boot/efi/boot/grub2/sealed_key - -Then, in the boot script: - -tpm2_key_protector_init -k (hd0,gpt1)/boot/grub2/sealed_key -cryptomount -u b20f95d0834842bc9197bd78b36732f8 -k tpm2 - -where the UUID corresponds to /dev/sdb1. - -Signed-off-by: Hernan Gatta ---- - Makefile.util.def | 18 + - configure.ac | 1 + - util/grub-protect.c | 1314 +++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 1334 insertions(+) - create mode 100644 util/grub-protect.c - -diff --git a/Makefile.util.def b/Makefile.util.def -index b3ec2a4bb6..08f681cd8b 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -207,6 +207,24 @@ program = { - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; - -+program = { -+ name = grub-protect; -+ -+ common = grub-core/osdep/init.c; -+ common = grub-core/tpm2/args.c; -+ common = grub-core/tpm2/buffer.c; -+ common = grub-core/tpm2/mu.c; -+ common = grub-core/tpm2/tpm2.c; -+ common = util/grub-protect.c; -+ common = util/probe.c; -+ -+ ldadd = libgrubmods.a; -+ ldadd = libgrubgcry.a; -+ ldadd = libgrubkern.a; -+ ldadd = grub-core/lib/gnulib/libgnu.a; -+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -+}; -+ - program = { - name = grub-mkrelpath; - mansection = 1; -diff --git a/configure.ac b/configure.ac -index 906eb1cedc..ba717a9600 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -71,6 +71,7 @@ grub_TRANSFORM([grub-mkpasswd-pbkdf2]) - grub_TRANSFORM([grub-mkrelpath]) - grub_TRANSFORM([grub-mkrescue]) - grub_TRANSFORM([grub-probe]) -+grub_TRANSFORM([grub-protect]) - grub_TRANSFORM([grub-reboot]) - grub_TRANSFORM([grub-script-check]) - grub_TRANSFORM([grub-set-default]) -diff --git a/util/grub-protect.c b/util/grub-protect.c -new file mode 100644 -index 0000000000..23ee78d32a ---- /dev/null -+++ b/util/grub-protect.c -@@ -0,0 +1,1314 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Microsoft Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#pragma GCC diagnostic ignored "-Wmissing-prototypes" -+#pragma GCC diagnostic ignored "-Wmissing-declarations" -+#include -+#pragma GCC diagnostic error "-Wmissing-prototypes" -+#pragma GCC diagnostic error "-Wmissing-declarations" -+ -+#include "progname.h" -+ -+/* Unprintable option keys for argp */ -+typedef enum grub_protect_opt -+{ -+ /* General */ -+ GRUB_PROTECT_OPT_ACTION = 'a', -+ GRUB_PROTECT_OPT_PROTECTOR = 'p', -+ /* TPM2 */ -+ GRUB_PROTECT_OPT_TPM2_DEVICE = 0x100, -+ GRUB_PROTECT_OPT_TPM2_PCRS, -+ GRUB_PROTECT_OPT_TPM2_ASYMMETRIC, -+ GRUB_PROTECT_OPT_TPM2_BANK, -+ GRUB_PROTECT_OPT_TPM2_SRK, -+ GRUB_PROTECT_OPT_TPM2_KEYFILE, -+ GRUB_PROTECT_OPT_TPM2_OUTFILE, -+ GRUB_PROTECT_OPT_TPM2_PERSIST, -+ GRUB_PROTECT_OPT_TPM2_EVICT -+} grub_protect_opt; -+ -+/* Option flags to keep track of specified arguments */ -+typedef enum grub_protect_arg -+{ -+ /* General */ -+ GRUB_PROTECT_ARG_ACTION = 1 << 0, -+ GRUB_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_PERSIST = 1 << 9, -+ GRUB_PROTECT_ARG_TPM2_EVICT = 1 << 10 -+} grub_protect_arg_t; -+ -+typedef enum grub_protect_protector -+{ -+ GRUB_PROTECT_TYPE_ERROR, -+ GRUB_PROTECT_TYPE_TPM2 -+} grub_protect_protector_t; -+ -+typedef enum grub_protect_action -+{ -+ GRUB_PROTECT_ACTION_ERROR, -+ GRUB_PROTECT_ACTION_ADD, -+ GRUB_PROTECT_ACTION_REMOVE -+} grub_protect_action_t; -+ -+struct grub_protect_args -+{ -+ grub_protect_arg_t args; -+ grub_protect_action_t action; -+ grub_protect_protector_t protector; -+ -+ const char *tpm2_device; -+ grub_uint8_t tpm2_pcrs[TPM_MAX_PCRS]; -+ grub_uint8_t tpm2_pcr_count; -+ TPM_ALG_ID tpm2_asymmetric; -+ TPM_ALG_ID tpm2_bank; -+ TPM_HANDLE tpm2_srk; -+ const char *tpm2_keyfile; -+ const char *tpm2_outfile; -+ int tpm2_persist; -+ int tpm2_evict; -+}; -+ -+static struct argp_option grub_protect_options[] = -+ { -+ /* Top-level options */ -+ { -+ .name = "action", -+ .key = 'a', -+ .arg = "ADD|REMOVE", -+ .flags = 0, -+ .doc = -+ N_("Add or remove a key protector to or from a key."), -+ .group = 0 -+ }, -+ { -+ .name = "protector", -+ .key = 'p', -+ .arg = "TPM2", -+ .flags = 0, -+ .doc = -+ N_("Key protector to use (only TPM2 is currently supported)."), -+ .group = 0 -+ }, -+ /* TPM2 key protector options */ -+ { -+ .name = "tpm2-device", -+ .key = GRUB_PROTECT_OPT_TPM2_DEVICE, -+ .arg = "FILE", -+ .flags = 0, -+ .doc = -+ N_("Path to the TPM2 device (default is /dev/tpm0)."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-pcrs", -+ .key = GRUB_PROTECT_OPT_TPM2_PCRS, -+ .arg = "0[,1]...", -+ .flags = 0, -+ .doc = -+ N_("Comma-separated list of PCRs used to authorize key release " -+ "(e.g., '7,11', default is 7."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-bank", -+ .key = GRUB_PROTECT_OPT_TPM2_BANK, -+ .arg = "SHA1|SHA256|SHA384", -+ .flags = 0, -+ .doc = -+ N_("Bank of PCRs used to authorize key release: " -+ "SHA1, SHA256 (default), or SHA384."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-keyfile", -+ .key = GRUB_PROTECT_OPT_TPM2_KEYFILE, -+ .arg = "FILE", -+ .flags = 0, -+ .doc = -+ N_("Path to a file that contains the cleartext key to protect."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-outfile", -+ .key = GRUB_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)."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-srk", -+ .key = GRUB_PROTECT_OPT_TPM2_SRK, -+ .arg = "NUM", -+ .flags = 0, -+ .doc = -+ N_("The SRK handle if the SRK is to be made persistent " -+ "(default is 0x81000001)."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-asymmetric", -+ .key = GRUB_PROTECT_OPT_TPM2_ASYMMETRIC, -+ .arg = "RSA|ECC", -+ .flags = 0, -+ .doc = -+ N_("The type of SRK: RSA (default) or ECC."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-persist", -+ .key = GRUB_PROTECT_OPT_TPM2_PERSIST, -+ .arg = NULL, -+ .flags = 0, -+ .doc = -+ N_("Whether to persist the SRK onto the TPM, otherwise it is recreated " -+ "ephemerally during boot (default is to not persist it)."), -+ .group = 0 -+ }, -+ { -+ .name = "tpm2-evict", -+ .key = GRUB_PROTECT_OPT_TPM2_EVICT, -+ .arg = NULL, -+ .flags = 0, -+ .doc = -+ N_("Evict a previously persisted SRK from the TPM, if any."), -+ .group = 0 -+ }, -+ /* End of list */ -+ { 0, 0, 0, 0, 0, 0 } -+ }; -+ -+static int grub_protector_tpm2_fd = -1; -+ -+static grub_err_t -+grub_protect_read_file (const char *filepath, void **buffer, -+ size_t *buffer_size) -+{ -+ grub_err_t err; -+ FILE *f; -+ long len; -+ void *buf; -+ -+ f = fopen (filepath, "rb"); -+ if (!f) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ if (fseek (f, 0, SEEK_END)) -+ { -+ err = GRUB_ERR_FILE_READ_ERROR; -+ goto exit1; -+ } -+ -+ len = ftell (f); -+ if (!len) -+ { -+ err = GRUB_ERR_FILE_READ_ERROR; -+ goto exit1; -+ } -+ -+ rewind (f); -+ -+ buf = grub_malloc (len); -+ if (!buf) -+ { -+ err = GRUB_ERR_OUT_OF_MEMORY; -+ goto exit1; -+ } -+ -+ if (fread (buf, len, 1, f) != 1) -+ { -+ err = GRUB_ERR_FILE_READ_ERROR; -+ goto exit2; -+ } -+ -+ *buffer = buf; -+ *buffer_size = len; -+ -+ buf = NULL; -+ err = GRUB_ERR_NONE; -+ -+exit2: -+ grub_free (buf); -+ -+exit1: -+ fclose (f); -+ -+ return err; -+} -+ -+static grub_err_t -+grub_protect_write_file (const char *filepath, void *buffer, size_t buffer_size) -+{ -+ grub_err_t err; -+ FILE *f; -+ -+ f = fopen (filepath, "wb"); -+ if (!f) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ if (fwrite (buffer, buffer_size, 1, f) != 1) -+ { -+ err = GRUB_ERR_WRITE_ERROR; -+ goto exit1; -+ } -+ -+ err = GRUB_ERR_NONE; -+ -+exit1: -+ fclose (f); -+ -+ return err; -+} -+ -+static grub_err_t -+grub_protect_get_grub_drive_for_file (const char *filepath, char **drive) -+{ -+ grub_err_t err = GRUB_ERR_IO; -+ char *disk; -+ char **devices; -+ char *grub_dev; -+ char *grub_path; -+ char *efi_drive; -+ char *partition; -+ char *grub_drive; -+ grub_device_t dev; -+ grub_size_t grub_drive_len; -+ int n; -+ -+ grub_path = grub_canonicalize_file_name (filepath); -+ if (!grub_path) -+ goto exit1; -+ -+ devices = grub_guess_root_devices (grub_path); -+ if (!devices || !devices[0]) -+ goto exit2; -+ -+ disk = devices[0]; -+ -+ grub_util_pull_device (disk); -+ -+ grub_dev = grub_util_get_grub_dev (disk); -+ if (!grub_dev) -+ goto exit3; -+ -+ dev = grub_device_open (grub_dev); -+ if (!dev) -+ goto exit4; -+ -+ efi_drive = grub_util_guess_efi_drive (disk); -+ if (!efi_drive) -+ goto exit5; -+ -+ partition = grub_partition_get_name (dev->disk->partition); -+ if (!partition) -+ goto exit6; -+ -+ grub_drive_len = grub_strlen (efi_drive) + grub_strlen (partition) + 3; -+ grub_drive = grub_malloc (grub_drive_len + 1); -+ if (!grub_drive) -+ goto exit7; -+ -+ n = grub_snprintf (grub_drive, grub_drive_len + 1, "(%s,%s)", efi_drive, -+ partition); -+ if (n != grub_drive_len) -+ goto exit8; -+ -+ *drive = grub_drive; -+ grub_drive = NULL; -+ err = GRUB_ERR_NONE; -+ -+exit8: -+ grub_free (grub_drive); -+ -+exit7: -+ grub_free (partition); -+ -+exit6: -+ grub_free (efi_drive); -+ -+exit5: -+ grub_device_close (dev); -+ -+exit4: -+ grub_free (grub_dev); -+ -+exit3: -+ grub_free (devices); -+ -+exit2: -+ grub_free (grub_path); -+ -+exit1: -+ return err; -+} -+ -+grub_err_t -+grub_tcg2_get_max_output_size (grub_size_t *size) -+{ -+ if (!size) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ *size = GRUB_TPM2_BUFFER_CAPACITY; -+ -+ 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) -+{ -+ static const grub_size_t header_size = sizeof (grub_uint16_t) + -+ (2 * sizeof(grub_uint32_t)); -+ -+ 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; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_protect_tpm2_open_device (const char *dev_node) -+{ -+ if (grub_protector_tpm2_fd != -1) -+ return GRUB_ERR_NONE; -+ -+ grub_protector_tpm2_fd = open (dev_node, O_RDWR); -+ if (grub_protector_tpm2_fd == -1) -+ { -+ fprintf (stderr, _("Could not open TPM device (Error: %u).\n"), errno); -+ return GRUB_ERR_FILE_NOT_FOUND; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_protect_tpm2_close_device (void) -+{ -+ int err; -+ -+ if (grub_protector_tpm2_fd == -1) -+ return GRUB_ERR_NONE; -+ -+ err = close (grub_protector_tpm2_fd); -+ if (err) -+ { -+ fprintf (stderr, _("Could not close TPM device (Error: %u).\n"), errno); -+ return GRUB_ERR_IO; -+ } -+ -+ grub_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) -+{ -+ TPM_RC rc; -+ TPML_PCR_SELECTION pcr_sel = { -+ .count = 1, -+ .pcrSelections = { -+ { -+ .hash = args->tpm2_bank, -+ .sizeOfSelect = 3, -+ .pcrSelect = { 0 } -+ }, -+ } -+ }; -+ TPML_PCR_SELECTION pcr_sel_out = { 0 }; -+ TPML_DIGEST pcr_values = { 0 }; -+ grub_uint8_t *pcr_digest; -+ grub_size_t pcr_digest_len; -+ grub_uint8_t *pcr_concat; -+ grub_size_t pcr_concat_len; -+ grub_uint8_t *pcr_cursor; -+ const gcry_md_spec_t *hash_spec; -+ TPM2B_NONCE nonce = { 0 }; -+ TPM2B_ENCRYPTED_SECRET salt = { 0 }; -+ TPMT_SYM_DEF symmetric = { 0 }; -+ TPMI_SH_AUTH_SESSION session = 0; -+ TPM2B_DIGEST pcr_digest_in = { -+ .size = TPM_SHA256_DIGEST_SIZE, -+ .buffer = { 0 } -+ }; -+ TPM2B_DIGEST policy_digest = { 0 }; -+ grub_uint8_t i; -+ grub_err_t err; -+ -+ /* PCR Read */ -+ for (i = 0; i < args->tpm2_pcr_count; i++) -+ pcr_sel -+ .pcrSelections[0] -+ .pcrSelect[TPM2_PCR_TO_SELECT(args->tpm2_pcrs[i])] -+ |= TPM2_PCR_TO_BIT(args->tpm2_pcrs[i]); -+ -+ rc = TPM2_PCR_Read (NULL, &pcr_sel, NULL, &pcr_sel_out, &pcr_values, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ fprintf (stderr, _("Failed to read PCRs (TPM error: 0x%x).\n"), rc); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ if ((pcr_sel_out.count != pcr_sel.count) || -+ (pcr_sel.pcrSelections[0].sizeOfSelect != -+ pcr_sel_out.pcrSelections[0].sizeOfSelect)) -+ { -+ fprintf (stderr, _("Could not read all the specified PCRs.\n")); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ /* Compute PCR Digest */ -+ switch (args->tpm2_bank) -+ { -+ case TPM_ALG_SHA1: -+ pcr_digest_len = TPM_SHA1_DIGEST_SIZE; -+ hash_spec = GRUB_MD_SHA1; -+ break; -+ case TPM_ALG_SHA256: -+ pcr_digest_len = TPM_SHA256_DIGEST_SIZE; -+ hash_spec = GRUB_MD_SHA256; -+ break; -+ default: -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ pcr_digest = grub_malloc (pcr_digest_len); -+ if (!pcr_digest) -+ { -+ fprintf (stderr, _("Failed to allocate PCR digest buffer.\n")); -+ return GRUB_ERR_OUT_OF_MEMORY; -+ } -+ -+ pcr_concat_len = pcr_digest_len * args->tpm2_pcr_count; -+ pcr_concat = grub_malloc (pcr_concat_len); -+ if (!pcr_concat) -+ { -+ err = GRUB_ERR_OUT_OF_MEMORY; -+ fprintf (stderr, _("Failed to allocate PCR concatenation buffer.\n")); -+ goto exit1; -+ } -+ -+ pcr_cursor = pcr_concat; -+ for (i = 0; i < args->tpm2_pcr_count; i++) -+ { -+ if (pcr_values.digests[i].size != pcr_digest_len) -+ { -+ fprintf (stderr, -+ _("Bad PCR value size: expected %lu bytes but got %u bytes.\n"), -+ pcr_digest_len, pcr_values.digests[i].size); -+ goto exit2; -+ } -+ -+ grub_memcpy (pcr_cursor, pcr_values.digests[i].buffer, pcr_digest_len); -+ pcr_cursor += pcr_digest_len; -+ } -+ -+ grub_crypto_hash (hash_spec, pcr_digest, pcr_concat, pcr_concat_len); -+ -+ /* Start Trial Session */ -+ 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); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ fprintf (stderr, -+ _("Failed to start trial policy session (TPM error: 0x%x).\n"), -+ rc); -+ err = GRUB_ERR_BAD_DEVICE; -+ goto exit2; -+ } -+ -+ /* PCR Policy */ -+ memcpy (pcr_digest_in.buffer, pcr_digest, TPM_SHA256_DIGEST_SIZE); -+ -+ rc = TPM2_PolicyPCR (session, NULL, &pcr_digest_in, &pcr_sel, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ fprintf (stderr, _("Failed to submit PCR policy (TPM error: 0x%x).\n"), -+ rc); -+ err = GRUB_ERR_BAD_DEVICE; -+ goto exit3; -+ } -+ -+ /* Retrieve Policy Digest */ -+ rc = TPM2_PolicyGetDigest (session, NULL, &policy_digest, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ fprintf (stderr, _("Failed to get policy digest (TPM error: 0x%x).\n"), -+ rc); -+ err = GRUB_ERR_BAD_DEVICE; -+ goto exit3; -+ } -+ -+ /* Epilogue */ -+ *digest = policy_digest; -+ err = GRUB_ERR_NONE; -+ -+exit3: -+ TPM2_FlushContext (session); -+ -+exit2: -+ grub_free (pcr_concat); -+ -+exit1: -+ grub_free (pcr_digest); -+ -+ return err; -+} -+ -+static grub_err_t -+grub_protect_tpm2_get_srk (struct grub_protect_args *args, TPM_HANDLE *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; -+ -+ /* Find SRK */ -+ rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public); -+ if (rc == TPM_RC_SUCCESS) -+ { -+ if (args->tpm2_persist) -+ fprintf (stderr, -+ _("Warning: --tpm2-persist was specified but the SRK already " -+ "exists on the TPM. Continuing anyway...\n")); -+ -+ *srk = TPM2_SRK_HANDLE; -+ return GRUB_ERR_NONE; -+ } -+ -+ /* The handle exists but its public area could not be read. */ -+ if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE) -+ { -+ fprintf (stderr, -+ _("The SRK exists on the TPM but its public area cannot be read " -+ "(TPM error: 0x%x).\n"), rc); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ /* Create SRK */ -+ authCommand.sessionHandle = TPM_RS_PW; -+ inPublic.publicArea.type = args->tpm2_asymmetric; -+ inPublic.publicArea.nameAlg = TPM_ALG_SHA256; -+ inPublic.publicArea.objectAttributes.restricted = 1; -+ inPublic.publicArea.objectAttributes.userWithAuth = 1; -+ inPublic.publicArea.objectAttributes.decrypt = 1; -+ inPublic.publicArea.objectAttributes.fixedTPM = 1; -+ inPublic.publicArea.objectAttributes.fixedParent = 1; -+ inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1; -+ inPublic.publicArea.objectAttributes.noDA = 1; -+ -+ switch (args->tpm2_asymmetric) -+ { -+ case TPM_ALG_RSA: -+ inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES; -+ inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128; -+ inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB; -+ inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; -+ inPublic.publicArea.parameters.rsaDetail.keyBits = 2048; -+ inPublic.publicArea.parameters.rsaDetail.exponent = 0; -+ break; -+ -+ case TPM_ALG_ECC: -+ inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES; -+ inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128; -+ inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB; -+ inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL; -+ inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256; -+ inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; -+ break; -+ -+ default: -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ rc = 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 (TPM error: 0x%x).\n"), rc); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ /* Persist SRK */ -+ if (args->tpm2_persist) -+ { -+ rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, args->tpm2_srk, -+ &authCommand, NULL); -+ if (rc == TPM_RC_SUCCESS) -+ { -+ TPM2_FlushContext (srkHandle); -+ srkHandle = args->tpm2_srk; -+ } -+ else -+ fprintf (stderr, -+ _("Warning: Failed to persist SRK (TPM error: 0x%x\n). " -+ "Continuing anyway...\n"), rc); -+ } -+ -+ /* Epilogue */ -+ *srk = srkHandle; -+ -+ return GRUB_ERR_NONE; -+} -+ -+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) -+{ -+ 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 }; -+ -+ /* Seal Data */ -+ authCommand.sessionHandle = TPM_RS_PW; -+ -+ inSensitive.sensitive.data.size = clearTextLength; -+ memcpy(inSensitive.sensitive.data.buffer, clearText, clearTextLength); -+ -+ inPublic.publicArea.type = TPM_ALG_KEYEDHASH; -+ inPublic.publicArea.nameAlg = TPM_ALG_SHA256; -+ 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); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ fprintf (stderr, _("Failed to seal key (TPM error: 0x%x).\n"), rc); -+ return GRUB_ERR_BAD_DEVICE; -+ } -+ -+ /* Epilogue */ -+ sealed_key->public = outPublic; -+ sealed_key->private = outPrivate; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_protect_tpm2_export_sealed_key (const char *filepath, -+ TPM2_SEALED_KEY *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, -+ sealed_key->private.buffer); -+ if (buf.error) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ err = grub_protect_write_file (filepath, buf.data, buf.size); -+ if (err) -+ fprintf (stderr, _("Could not write sealed key file (Error: %u).\n"), -+ errno); -+ -+ return err; -+} -+ -+static grub_err_t -+grub_protect_tpm2_add (struct grub_protect_args *args) -+{ -+ grub_err_t err; -+ grub_uint8_t *key; -+ grub_size_t key_size; -+ TPM_HANDLE srk; -+ TPM2B_DIGEST policy_digest; -+ TPM2_SEALED_KEY sealed_key; -+ char *grub_drive = NULL; -+ -+ grub_protect_get_grub_drive_for_file (args->tpm2_outfile, &grub_drive); -+ -+ err = grub_protect_tpm2_open_device (args->tpm2_device); -+ if (err) -+ return err; -+ -+ err = grub_protect_read_file (args->tpm2_keyfile, (void **)&key, &key_size); -+ if (err) -+ 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); -+ return GRUB_ERR_OUT_OF_RANGE; -+ } -+ -+ err = grub_protect_tpm2_get_srk (args, &srk); -+ if (err) -+ goto exit2; -+ -+ err = grub_protect_tpm2_get_policy_digest (args, &policy_digest); -+ if (err) -+ goto exit3; -+ -+ err = grub_protect_tpm2_seal (&policy_digest, srk, key, key_size, -+ &sealed_key); -+ if (err) -+ goto exit3; -+ -+ err = grub_protect_tpm2_export_sealed_key (args->tpm2_outfile, &sealed_key); -+ if (err) -+ goto exit3; -+ -+ if (grub_drive) -+ { -+ printf (_("GRUB drive for the sealed key file: %s\n"), grub_drive); -+ grub_free (grub_drive); -+ } -+ else -+ { -+ fprintf (stderr, -+ _("Warning: Could not determine GRUB drive for sealed key " -+ "file.\n")); -+ err = GRUB_ERR_NONE; -+ } -+ -+exit3: -+ TPM2_FlushContext (srk); -+ -+exit2: -+ grub_free (key); -+ -+exit1: -+ grub_protect_tpm2_close_device (); -+ -+ return err; -+} -+ -+static grub_err_t -+grub_protect_tpm2_remove (struct grub_protect_args *args) -+{ -+ TPM_RC rc; -+ TPM2B_PUBLIC public; -+ TPMS_AUTH_COMMAND authCommand = { 0 }; -+ grub_err_t err; -+ -+ if (!args->tpm2_evict) -+ { -+ printf (_("--tpm2-evict not specified, nothing to do.\n")); -+ return GRUB_ERR_NONE; -+ } -+ -+ err = grub_protect_tpm2_open_device (args->tpm2_device); -+ if (err) -+ return err; -+ -+ /* Find SRK */ -+ rc = 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); -+ err = GRUB_ERR_BAD_ARGUMENT; -+ goto exit1; -+ } -+ -+ /* Evict SRK */ -+ authCommand.sessionHandle = TPM_RS_PW; -+ -+ rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, args->tpm2_srk, -+ &authCommand, NULL); -+ if (rc != TPM_RC_SUCCESS) -+ { -+ fprintf (stderr, -+ _("Failed to evict SRK with handle 0x%x (TPM Error: 0x%x).\n"), -+ args->tpm2_srk, rc); -+ err = GRUB_ERR_BAD_DEVICE; -+ goto exit2; -+ } -+ -+ err = GRUB_ERR_NONE; -+ -+exit2: -+ TPM2_FlushContext (args->tpm2_srk); -+ -+exit1: -+ grub_protect_tpm2_close_device (); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_protect_tpm2_run (struct grub_protect_args *args) -+{ -+ switch (args->action) -+ { -+ case GRUB_PROTECT_ACTION_ADD: -+ return grub_protect_tpm2_add (args); -+ -+ case GRUB_PROTECT_ACTION_REMOVE: -+ return grub_protect_tpm2_remove (args); -+ -+ default: -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+} -+ -+static grub_err_t -+grub_protect_tpm2_args_verify (struct grub_protect_args *args) -+{ -+ switch (args->action) -+ { -+ case GRUB_PROTECT_ACTION_ADD: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT) -+ { -+ fprintf (stderr, -+ _("--tpm2-evict is invalid when --action is 'add'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (!args->tpm2_keyfile) -+ { -+ fprintf (stderr, _("--tpm2-keyfile must be specified.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (!args->tpm2_outfile) -+ { -+ fprintf (stderr, _("--tpm2-outfile must be specified.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (!args->tpm2_device) -+ args->tpm2_device = "/dev/tpm0"; -+ -+ if (!args->tpm2_pcr_count) -+ { -+ args->tpm2_pcrs[0] = 7; -+ args->tpm2_pcr_count = 1; -+ } -+ -+ if (!args->tpm2_srk) -+ args->tpm2_srk = TPM2_SRK_HANDLE; -+ -+ if (!args->tpm2_asymmetric) -+ args->tpm2_asymmetric = TPM_ALG_RSA; -+ -+ if (!args->tpm2_bank) -+ args->tpm2_bank = TPM_ALG_SHA256; -+ -+ break; -+ -+ case GRUB_PROTECT_ACTION_REMOVE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC) -+ { -+ fprintf (stderr, -+ _("--tpm2-asymmetric is invalid when --action is 'remove'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (args->args & GRUB_PROTECT_ARG_TPM2_BANK) -+ { -+ fprintf (stderr, -+ _("--tpm2-bank is invalid when --action is 'remove'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE) -+ { -+ fprintf (stderr, -+ _("--tpm2-keyfile is invalid when --action is 'remove'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE) -+ { -+ fprintf (stderr, -+ _("--tpm2-outfile is invalid when --action is 'remove'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS) -+ { -+ fprintf (stderr, -+ _("--tpm2-pcrs is invalid when --action is 'remove'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (args->args & GRUB_PROTECT_ARG_TPM2_PERSIST) -+ { -+ fprintf (stderr, -+ _("--tpm2-persist is invalid when --action is 'remove'.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ if (!args->tpm2_device) -+ args->tpm2_device = "/dev/tpm0"; -+ -+ if (!args->tpm2_srk) -+ args->tpm2_srk = TPM2_SRK_HANDLE; -+ -+ break; -+ -+ default: -+ fprintf (stderr, -+ _("The TPM2 key protector only supports the following actions: " -+ "add, remove.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static error_t -+grub_protect_argp_parser (int key, char *arg, struct argp_state *state) -+{ -+ grub_err_t err; -+ struct grub_protect_args *args = state->input; -+ -+ switch (key) -+ { -+ case GRUB_PROTECT_OPT_ACTION: -+ if (args->args & GRUB_PROTECT_ARG_ACTION) -+ { -+ fprintf (stderr, _("--action|-a can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ if (grub_strcmp (arg, "add") == 0) -+ args->action = GRUB_PROTECT_ACTION_ADD; -+ else if (grub_strcmp (arg, "remove") == 0) -+ args->action = GRUB_PROTECT_ACTION_REMOVE; -+ else -+ { -+ fprintf (stderr, _("'%s' is not a valid action.\n"), arg); -+ return EINVAL; -+ } -+ -+ args->args |= GRUB_PROTECT_ARG_ACTION; -+ break; -+ -+ case GRUB_PROTECT_OPT_PROTECTOR: -+ if (args->args & GRUB_PROTECT_ARG_PROTECTOR) -+ { -+ fprintf (stderr, _("--protector|-p can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ if (grub_strcmp (arg, "tpm2") == 0) -+ args->protector = GRUB_PROTECT_TYPE_TPM2; -+ else -+ { -+ fprintf (stderr, _("'%s' is not a valid protector.\n"), arg); -+ return EINVAL; -+ } -+ -+ args->args |= GRUB_PROTECT_ARG_PROTECTOR; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_DEVICE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_DEVICE) -+ { -+ fprintf (stderr, _("--tpm2-device can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ args->tpm2_device = xstrdup(arg); -+ args->args |= GRUB_PROTECT_ARG_TPM2_DEVICE; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_PCRS: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS) -+ { -+ fprintf (stderr, _("--tpm2-pcrs can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ err = grub_tpm2_protector_parse_pcrs (arg, args->tpm2_pcrs, -+ &args->tpm2_pcr_count); -+ if (err) -+ { -+ if (grub_errno) -+ grub_print_error (); -+ return EINVAL; -+ } -+ -+ args->args |= GRUB_PROTECT_ARG_TPM2_PCRS; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_SRK: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_SRK) -+ { -+ fprintf (stderr, _("--tpm2-srk can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ err = grub_tpm2_protector_parse_tpm_handle (arg, &args->tpm2_srk); -+ if (err) -+ { -+ if (grub_errno) -+ grub_print_error (); -+ return EINVAL; -+ } -+ -+ args->args |= GRUB_PROTECT_ARG_TPM2_SRK; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_ASYMMETRIC: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC) -+ { -+ fprintf (stderr, _("--tpm2-asymmetric can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ err = grub_tpm2_protector_parse_asymmetric (arg, &args->tpm2_asymmetric); -+ if (err) -+ { -+ if (grub_errno) -+ grub_print_error (); -+ return EINVAL; -+ } -+ -+ args->args |= GRUB_PROTECT_ARG_TPM2_ASYMMETRIC; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_BANK: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_BANK) -+ { -+ fprintf (stderr, _("--tpm2-bank can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ err = grub_tpm2_protector_parse_bank (arg, &args->tpm2_bank); -+ if (err) -+ { -+ if (grub_errno) -+ grub_print_error (); -+ return EINVAL; -+ } -+ -+ args->args |= GRUB_PROTECT_ARG_TPM2_BANK; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_KEYFILE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE) -+ { -+ fprintf (stderr, _("--tpm2-keyfile can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ args->tpm2_keyfile = xstrdup(arg); -+ args->args |= GRUB_PROTECT_ARG_TPM2_KEYFILE; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_OUTFILE: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE) -+ { -+ fprintf (stderr, _("--tpm2-outfile can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ args->tpm2_outfile = xstrdup(arg); -+ args->args |= GRUB_PROTECT_ARG_TPM2_OUTFILE; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_PERSIST: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_PERSIST) -+ { -+ fprintf (stderr, _("--tpm2-persist can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ args->tpm2_persist = 1; -+ args->args |= GRUB_PROTECT_ARG_TPM2_PERSIST; -+ break; -+ -+ case GRUB_PROTECT_OPT_TPM2_EVICT: -+ if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT) -+ { -+ fprintf (stderr, _("--tpm2-evict can only be specified once.\n")); -+ return EINVAL; -+ } -+ -+ args->tpm2_evict = 1; -+ args->args |= GRUB_PROTECT_ARG_TPM2_EVICT; -+ break; -+ -+ default: -+ return ARGP_ERR_UNKNOWN; -+ } -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_protect_args_verify (struct grub_protect_args *args) -+{ -+ if (args->action == GRUB_PROTECT_ACTION_ERROR) -+ { -+ fprintf (stderr, "--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) -+ { -+ fprintf (stderr, -+ _("--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); -+ default: -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_protect_dispatch (struct grub_protect_args *args) -+{ -+ switch (args->protector) -+ { -+ case GRUB_PROTECT_TYPE_TPM2: -+ return grub_protect_tpm2_run (args); -+ default: -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+} -+ -+static void -+grub_protect_init (int *argc, char **argv[]) -+{ -+ grub_util_host_init (argc, argv); -+ -+ grub_util_biosdisk_init (NULL); -+ -+ grub_init_all (); -+ grub_gcry_init_all (); -+ -+ grub_lvm_fini (); -+ grub_mdraid09_fini (); -+ grub_mdraid1x_fini (); -+ grub_diskfilter_fini (); -+ grub_diskfilter_init (); -+ grub_mdraid09_init (); -+ grub_mdraid1x_init (); -+ grub_lvm_init (); -+} -+ -+static void -+grub_protect_fini (void) -+{ -+ grub_gcry_fini_all (); -+ grub_fini_all (); -+ grub_util_biosdisk_fini (); -+} -+ -+static struct argp grub_protect_argp = -+{ -+ .options = grub_protect_options, -+ .parser = grub_protect_argp_parser, -+ .args_doc = NULL, -+ .doc = -+ N_("Protect a cleartext key using a GRUB key protector that can retrieve " -+ "the key during boot to unlock fully-encrypted disks automatically."), -+ .children = NULL, -+ .help_filter = NULL, -+ .argp_domain = NULL -+}; -+ -+int -+main (int argc, char *argv[]) -+{ -+ grub_err_t err; -+ struct grub_protect_args args = { 0 }; -+ -+ if (argp_parse (&grub_protect_argp, argc, argv, 0, 0, &args) != 0) -+ { -+ fprintf (stderr, _("Could not parse arguments.\n")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ grub_protect_init (&argc, &argv); -+ -+ err = grub_protect_args_verify (&args); -+ if (err) -+ goto exit; -+ -+ err = grub_protect_dispatch (&args); -+ if (err) -+ goto exit; -+ -+exit: -+ grub_protect_fini (); -+ -+ return err; -+} --- -2.34.1 - diff --git a/fix-tpm2-build.patch b/fix-tpm2-build.patch deleted file mode 100644 index 2a4fc24..0000000 --- a/fix-tpm2-build.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- - grub-core/Makefile.core.def | 1 + - grub-core/tpm2/module.c | 2 +- - util/grub-protect.c | 2 +- - 3 files changed, 3 insertions(+), 2 deletions(-) - ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2569,6 +2569,7 @@ - common = tpm2/mu.c; - common = tpm2/tpm2.c; - efi = tpm2/tcg2.c; -+ enable = efi; - }; - - module = { ---- a/util/grub-protect.c -+++ b/util/grub-protect.c -@@ -542,7 +542,7 @@ - if (pcr_values.digests[i].size != pcr_digest_len) - { - fprintf (stderr, -- _("Bad PCR value size: expected %lu bytes but got %u bytes.\n"), -+ _("Bad PCR value size: expected %" PRIuGRUB_SIZE " bytes but got %u bytes.\n"), - pcr_digest_len, pcr_values.digests[i].size); - goto exit2; - } ---- a/grub-core/tpm2/module.c -+++ b/grub-core/tpm2/module.c -@@ -195,7 +195,7 @@ - if (sealed_key_size > buf.cap) - { - grub_dprintf ("tpm2", "Sealed key file is larger than decode buffer " -- "(%lu vs %lu bytes).\n", sealed_key_size, buf.cap); -+ "(%" PRIuGRUB_SIZE " vs %" PRIuGRUB_SIZE " bytes).\n", sealed_key_size, buf.cap); - return GRUB_ERR_BAD_ARGUMENT; - } - diff --git a/grub2.changes b/grub2.changes index f07f217..c7b5a0f 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,45 +1,3 @@ -------------------------------------------------------------------- -Thu Aug 18 02:47:28 UTC 2022 - Michael Chang - -- Fix tpm error stop tumbleweed from booting (bsc#1202374) - * 0001-tpm-Pass-unknown-error-as-non-fatal-but-debug-print-.patch -- Patch Removed - * 0001-tpm-Log-EFI_VOLUME_FULL-and-continue.patch - -------------------------------------------------------------------- -Wed Jun 8 03:25:26 UTC 2022 - Michael Chang - -- Add tpm, tpm2, luks2 and gcry_sha512 to default grub.efi (bsc#1197625) -- Make grub-tpm.efi a symlink to grub.efi - * grub2.spec -- Log error when tpm event log is full and continue - * 0001-tpm-Log-EFI_VOLUME_FULL-and-continue.patch -- Patch superseded - * 0001-tpm-Pass-unknown-error-as-non-fatal-but-debug-print-.patch - -------------------------------------------------------------------- -Wed Jun 8 03:17:29 UTC 2022 - Michael Chang - -- Add patches for automatic TPM disk unlock (jsc#SLE-24018) (bsc#1196668) - * 0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch - * 0002-cryptodisk-Refactor-to-discard-have_it-global.patch - * 0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch - * 0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch - * 0005-cryptodisk-Improve-cryptomount-u-error-message.patch - * 0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch - * 0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch - * 0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch - * 0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch - * 0010-protectors-Add-key-protectors-framework.patch - * 0011-tpm2-Add-TPM-Software-Stack-TSS.patch - * 0012-protectors-Add-TPM2-Key-Protector.patch - * 0013-cryptodisk-Support-key-protectors.patch - * 0014-util-grub-protect-Add-new-tool.patch -- Fix no disk unlocking happen (bsc#1196668) - * 0001-crytodisk-fix-cryptodisk-module-looking-up.patch -- Fix build error - * fix-tpm2-build.patch - ------------------------------------------------------------------- Tue May 31 04:44:18 UTC 2022 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 80f4f19..613adb7 100644 --- a/grub2.spec +++ b/grub2.spec @@ -407,22 +407,6 @@ Patch881: 0029-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch Patch882: 0030-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch Patch883: 0031-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch Patch884: 0032-Use-grub_loader_set_ex-for-secureboot-chainloader.patch -Patch885: 0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch -Patch886: 0002-cryptodisk-Refactor-to-discard-have_it-global.patch -Patch887: 0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch -Patch888: 0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch -Patch889: 0005-cryptodisk-Improve-cryptomount-u-error-message.patch -Patch890: 0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch -Patch891: 0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch -Patch892: 0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch -Patch893: 0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch -Patch894: 0010-protectors-Add-key-protectors-framework.patch -Patch895: 0011-tpm2-Add-TPM-Software-Stack-TSS.patch -Patch896: 0012-protectors-Add-TPM2-Key-Protector.patch -Patch897: 0013-cryptodisk-Support-key-protectors.patch -Patch898: 0014-util-grub-protect-Add-new-tool.patch -Patch899: fix-tpm2-build.patch -Patch900: 0001-crytodisk-fix-cryptodisk-module-looking-up.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 @@ -691,9 +675,9 @@ CD_MODULES="all_video boot cat configfile echo true \ password password_pbkdf2 png reboot search search_fs_uuid \ search_fs_file search_label sleep test video fat loadenv" PXE_MODULES="tftp http" -CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512" +CRYPTO_MODULES="luks gcry_rijndael gcry_sha1 gcry_sha256" %ifarch %{efi} -CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tpm2" +CD_MODULES="${CD_MODULES} chain efifwsetup efinet read" PXE_MODULES="${PXE_MODULES} efinet" %else CD_MODULES="${CD_MODULES} net" @@ -731,6 +715,10 @@ echo "grub.%{sbat_distro},%{sbat_generation},%{sbat_distro_summary},%{name},%{ve ./grub-mkimage -O %{grubefiarch} -o grub.efi --prefix= %{?sbat_generation:--sbat sbat.csv} \ -d grub-core ${GRUB_MODULES} +%ifarch x86_64 +./grub-mkimage -O %{grubefiarch} -o grub-tpm.efi --prefix= %{?sbat_generation:--sbat sbat.csv} \ + -d grub-core ${GRUB_MODULES} tpm +%endif %ifarch x86_64 aarch64 if test -e %{_sourcedir}/_projectcert.crt ; then @@ -910,7 +898,7 @@ cd build-efi %make_install install -m 644 grub.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/. %ifarch x86_64 -ln -srf %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub-tpm.efi +install -m 644 grub-tpm.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/. %endif # Create grub.efi link to system efi directory @@ -932,6 +920,9 @@ EoM %ifarch x86_64 aarch64 export BRP_PESIGN_FILES="%{_datadir}/%{name}/%{grubefiarch}/grub.efi" +%ifarch x86_64 +BRP_PESIGN_FILES="${BRP_PESIGN_FILES} %{_datadir}/%{name}/%{grubefiarch}/grub-tpm.efi" +%endif install -m 444 grub.der %{buildroot}/%{sysefidir}/ %endif @@ -1258,7 +1249,6 @@ fi %{_bindir}/%{name}-render-label %{_bindir}/%{name}-script-check %{_bindir}/%{name}-syslinux2cfg -%{_bindir}/%{name}-protect %if 0%{?has_systemd:1} %{_unitdir}/grub2-once.service %endif