forked from pool/grub2
Revert to revision 268, boo#1202438
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=271
This commit is contained in:
parent
ee92804613
commit
1ac59cb02a
@ -1,33 +0,0 @@
|
||||
From 822f71318a69c150da3ad7df5fe8667dfa6e8069 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
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 <mchang@suse.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 8eae4c33a32d9951641e289d2809a92a223b1642 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,187 +0,0 @@
|
||||
From 4ace73cc192bc63a00f4208b34981a6d91947811 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 86fe3bbbf75e62387cc9842654fd6c852e9457a6 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,58 +0,0 @@
|
||||
From f41488d0e361a34f4d3f8fb6c92729a2901a5c76 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 9ef619a7c1d38988f6d91496ea5c59062dcf6013 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,252 +0,0 @@
|
||||
From 0a5619abd170b3ad43e44cb8036062506d8623cc Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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] <SOURCE|-u UUID|-a|-b>"),
|
||||
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
|
||||
|
@ -1,342 +0,0 @@
|
||||
From a3ae3f800f6aa3f6036351133ed69fa47c9fa371 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,248 +0,0 @@
|
||||
From 5323778d84a7289acba0e50d84fb1afd45fff596 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,39 +0,0 @@
|
||||
From b1acd971fa648fa3c6f3a54db4fdf45fae02ce54 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
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 <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -1,189 +0,0 @@
|
||||
From 2d959549857305d5e4d95a19a0850885f85179d6 Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
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 <hegatta@linux.microsoft.com>
|
||||
---
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/list.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/protector.h>
|
||||
+
|
||||
+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 <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_PROTECTOR_HEADER
|
||||
+#define GRUB_PROTECTOR_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,977 +0,0 @@
|
||||
From b173db7537920ee5706e1c961fea3086ada6b6dd Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
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 <hegatta@linux.microsoft.com>
|
||||
---
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/tpm2/internal/args.h>
|
||||
+
|
||||
+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 <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/extcmd.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/protector.h>
|
||||
+#include <grub/tpm2/buffer.h>
|
||||
+#include <grub/tpm2/internal/args.h>
|
||||
+#include <grub/tpm2/mu.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
+
|
||||
+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 <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER
|
||||
+#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
+
|
||||
+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
|
||||
|
@ -1,336 +0,0 @@
|
||||
From 9888bf40d960339a59dc18fb6e1df5f65b4668e3 Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
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: <Hernan Gatta hegatta@linux.microsoft.com>
|
||||
---
|
||||
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 <grub/file.h>
|
||||
#include <grub/procfs.h>
|
||||
#include <grub/partition.h>
|
||||
+#include <grub/protector.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/hostdisk.h>
|
||||
@@ -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] <SOURCE|-u UUID|-a|-b>"),
|
||||
+ N_("[-p password] [-k protector [-k protector ...]] <SOURCE|-u UUID|-a|-b>"),
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
@ -1,45 +1,3 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Aug 18 02:47:28 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
|
30
grub2.spec
30
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
|
||||
|
Loading…
Reference in New Issue
Block a user