Tool to manage UEFI Secure Boot MoK Keys
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
6.5 KiB

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
Date: Thu, 21 Apr 2022 17:28:07 -0700
Subject: [PATCH] SBAT revocation update support
Control how shim will apply SBAT revocations:
mokutil --set-sbat-policy latest
applies the latest SBAT revocations
(default behavior)
mokutil --set-sbat-policy previous
applies previous SBAT revocations to
allow falling back to an older release
In both of the above cases shim will only apply SBAT revocations that
are newer than the ones currently installed.
mokutil --set-sbat-policy delete
resets SBAT revocations only if Secure
Boot is disabled. This setting does not
persist.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
(cherry picked from commit 2122b5e4323137509bc38615e269cc352c971815)
[rharwood: renumber, options not added yet]
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
---
src/mokutil.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
man/mokutil.1 | 14 ++++++++++++
2 files changed, 86 insertions(+)
diff --git a/src/mokutil.c b/src/mokutil.c
index 838599c..0327275 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -83,6 +83,8 @@
#define IMPORT_HASH (1 << 21)
#define DELETE_HASH (1 << 22)
#define VERBOSITY (1 << 23)
+#define LIST_SBAT (1 << 27)
+#define SET_SBAT (1 << 28)
#define DEFAULT_CRYPT_METHOD SHA512_BASED
#define DEFAULT_SALT_SIZE SHA512_SALT_MAX
@@ -152,10 +154,12 @@ print_help ()
printf (" --import-hash <hash>\t\t\tImport a hash into MOK or MOKX\n");
printf (" --delete-hash <hash>\t\t\tDelete a hash in MOK or MOKX\n");
printf (" --set-verbosity <true/false>\t\tSet the verbosity bit for shim\n");
+ printf (" --set-sbat-policy <latest/previous/delete>\t\tApply Latest, Previous, or Blank SBAT revocations\n");
printf (" --pk\t\t\t\t\tList the keys in PK\n");
printf (" --kek\t\t\t\t\tList the keys in KEK\n");
printf (" --db\t\t\t\t\tList the keys in db\n");
printf (" --dbx\t\t\t\t\tList the keys in dbx\n");
+ printf (" --list-sbat-revocations\t\t\t\tList the entries in SBAT\n");
printf ("\n");
printf ("Supplimentary Options:\n");
printf (" --hash-file <hash file>\t\tUse the specific password hash\n");
@@ -2115,6 +2119,31 @@ generate_pw_hash (const char *input_pw)
return 0;
}
+static int
+print_var_content (const char *var_name, const efi_guid_t guid)
+{
+ uint8_t *data = NULL;
+ size_t data_size;
+ uint32_t attributes;
+ int ret;
+
+ ret = efi_get_variable (guid, var_name, &data, &data_size, &attributes);
+ if (ret < 0) {
+ if (errno == ENOENT) {
+ printf ("%s is empty\n", var_name);
+ return 0;
+ }
+
+ fprintf (stderr, "Failed to read %s: %m\n", var_name);
+ return -1;
+ }
+
+ printf ("%s", data);
+ free (data);
+
+ return ret;
+}
+
static int
set_verbosity (uint8_t verbosity)
{
@@ -2156,6 +2185,26 @@ list_db (DBName db_name)
return -1;
}
+static int
+manage_sbat (const uint8_t sbat_policy)
+{
+ if (sbat_policy) {
+ uint32_t attributes = EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS;
+ if (efi_set_variable (efi_guid_shim, "SbatPolicy",
+ (uint8_t *)&sbat_policy,
+ sizeof (sbat_policy),
+ attributes, S_IRUSR | S_IWUSR) < 0) {
+ fprintf (stderr, "Failed to set SbatPolicy\n");
+ return -1;
+ }
+ } else {
+ return test_and_delete_var ("SbatPolicy");
+ }
+ return 0;
+}
+
int
main (int argc, char *argv[])
{
@@ -2169,6 +2218,7 @@ main (int argc, char *argv[])
unsigned int command = 0;
int use_root_pw = 0;
uint8_t verbosity = 0;
+ uint8_t sbat_policy = 0;
DBName db_name = MOK_LIST_RT;
int ret = -1;
@@ -2207,10 +2257,12 @@ main (int argc, char *argv[])
{"import-hash", required_argument, 0, 0 },
{"delete-hash", required_argument, 0, 0 },
{"set-verbosity", required_argument, 0, 0 },
+ {"set-sbat-policy", required_argument, 0, 0 },
{"pk", no_argument, 0, 0 },
{"kek", no_argument, 0, 0 },
{"db", no_argument, 0, 0 },
{"dbx", no_argument, 0, 0 },
+ {"list-sbat-revocations", no_argument, 0, 0 },
{0, 0, 0, 0}
};
@@ -2270,6 +2322,16 @@ main (int argc, char *argv[])
verbosity = 0;
else
command |= HELP;
+ } else if (strcmp (option, "set-sbat-policy") == 0) {
+ command |= SET_SBAT;
+ if (strcmp (optarg, "latest") == 0)
+ sbat_policy = 1;
+ else if (strcmp (optarg, "previous") == 0)
+ sbat_policy = 2;
+ else if (strcmp (optarg, "delete") == 0)
+ sbat_policy = 3;
+ else
+ command |= HELP;
} else if (strcmp (option, "pk") == 0) {
if (db_name != MOK_LIST_RT) {
command |= HELP;
@@ -2298,6 +2360,10 @@ main (int argc, char *argv[])
command |= LIST_ENROLLED;
db_name = DBX;
}
+ } else if (strcmp (option, "list-sbat-revocations") == 0) {
+ command |= LIST_SBAT;
+ } else if (strcmp (option, "sbat") == 0) {
+ command |= LIST_SBAT;
}
break;
@@ -2557,6 +2623,12 @@ main (int argc, char *argv[])
case VERBOSITY:
ret = set_verbosity (verbosity);
break;
+ case LIST_SBAT:
+ ret = print_var_content ("SbatLevelRT", efi_guid_shim);
+ break;
+ case SET_SBAT:
+ ret = manage_sbat(sbat_policy);
+ break;
default:
print_help ();
break;
diff --git a/man/mokutil.1 b/man/mokutil.1
index 25fe8b4..f5a0ea3 100644
--- a/man/mokutil.1
+++ b/man/mokutil.1
@@ -73,6 +73,9 @@ mokutil \- utility to manipulate machine owner keys
.br
\fBmokutil\fR [--dbx]
.br
+\fBmokutil\fR [--list-sbat-revocations]
+.br
+\fBmokutil\fR [--set-sbat-policy (\fIlatest\fR | \fIprevious\fR | \fIdelete\fR)]
.SH DESCRIPTION
\fBmokutil\fR is a tool to import or delete the machines owner keys
@@ -173,3 +176,14 @@ List the keys in the secure boot signature store (db)
\fB--dbx\fR
List the keys in the secure boot blacklist signature store (dbx)
.TP
+\fB--list-sbat-revocations\fR
+List the entries in the Secure Boot Advanced Targeting store (SBAT)
+.TP
+\fB--set-sbat-policy (\fIlatest\fR | \fIprevious\fR | \fIdelete\fR)\fR
+Set the SbatPolicy UEFI Variable to have shim apply either the latest
+or the previous SBAT revocations. If UEFI Secure Boot is disabled, then
+delete will reset the SBAT revocations to an empty revocation list.
+While latest and previous are persistent configuration, delete will be
+cleared by shim on the next boot whether or not it succeeds. The default
+behavior is for shim to apply the previous revocations.
+.TP