summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Snowberg <eric.snowberg@oracle.com>2021-10-05 12:06:05 -0400
committerPeter Jones <pjones@redhat.com>2021-11-03 11:30:28 -0400
commit4e513405b4f1641710115780d19dcec130c5208f (patch)
tree57d9202d6155a4e6601acb9fdab1f0fa57e996a6
parent899314b90113abaaa4b22cd1d82a0fcb2a971850 (diff)
downloadefi-boot-shim-4e513405b4f1641710115780d19dcec130c5208f.tar.gz
efi-boot-shim-4e513405b4f1641710115780d19dcec130c5208f.zip
Introduce a new MOK variable called MokListTrustedRT
Introduce a new MOK variable called MokListTrustedRT. It allows an end-user to decide if they want to trust MOKList keys within the soon to be booted Linux kernel. This variable does not change any functionality within shim itself. When Linux boots, if MokListTrustedRT is set and EFI_VARIABLE_NON_VOLATILE is not set, keys in MokListRT are loaded into the .machine keyring instead of the .platform keyring. Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
-rw-r--r--MokManager.c167
-rw-r--r--MokVars.txt6
-rw-r--r--globals.c1
-rw-r--r--mok.c17
-rw-r--r--shim.h1
5 files changed, 187 insertions, 5 deletions
diff --git a/MokManager.c b/MokManager.c
index 08b15d6d..c195cadc 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -41,6 +41,12 @@ typedef struct {
} __attribute__ ((packed)) MokDBvar;
typedef struct {
+ UINT32 MokTMLState;
+ UINT32 PWLen;
+ CHAR16 Password[SB_PASSWORD_LEN];
+} __attribute__ ((packed)) MokTMLvar;
+
+typedef struct {
INT32 Timeout;
} __attribute__ ((packed)) MokTimeoutvar;
@@ -1678,6 +1684,121 @@ static EFI_STATUS mok_db_prompt(void *MokDB, UINTN MokDBSize)
return EFI_SUCCESS;
}
+static EFI_STATUS mok_tml_prompt(void *MokTML, UINTN MokTMLSize)
+{
+ EFI_STATUS efi_status;
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ MokTMLvar *var = MokTML;
+ CHAR16 *message[4];
+ CHAR16 pass1, pass2, pass3;
+ CHAR16 *str;
+ UINT8 fail_count = 0;
+ UINT8 dbval = 1;
+ UINT8 pos1, pos2, pos3;
+ int ret;
+ CHAR16 *untrust_tml[] = { L"Do not trust the MOK list", NULL };
+ CHAR16 *trust_tml[] = { L"Trust the MOK list", NULL };
+
+ if (MokTMLSize != sizeof(MokTMLvar)) {
+ console_notify(L"Invalid MokTML variable contents");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ clear_screen();
+
+ message[0] = L"Change Trusted MOK List Keyring state";
+ message[1] = NULL;
+
+ console_save_and_set_mode(&SavedMode);
+ console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+ console_restore_mode(&SavedMode);
+
+ while (fail_count < 3) {
+ RandomBytes(&pos1, sizeof(pos1));
+ pos1 = (pos1 % var->PWLen);
+
+ do {
+ RandomBytes(&pos2, sizeof(pos2));
+ pos2 = (pos2 % var->PWLen);
+ } while (pos2 == pos1);
+
+ do {
+ RandomBytes(&pos3, sizeof(pos3));
+ pos3 = (pos3 % var->PWLen);
+ } while (pos3 == pos2 || pos3 == pos1);
+
+ str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ pass1 = get_password_charater(str);
+ FreePool(str);
+
+ str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ pass2 = get_password_charater(str);
+ FreePool(str);
+
+ str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ pass3 = get_password_charater(str);
+ FreePool(str);
+
+ if (pass1 != var->Password[pos1] ||
+ pass2 != var->Password[pos2] ||
+ pass3 != var->Password[pos3]) {
+ console_print(L"Invalid character\n");
+ fail_count++;
+ } else {
+ break;
+ }
+ }
+
+ if (fail_count >= 3) {
+ console_notify(L"Password limit reached");
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (var->MokTMLState == 0)
+ ret = console_yes_no(trust_tml);
+ else
+ ret = console_yes_no(untrust_tml);
+
+ if (ret == 0) {
+ LibDeleteVariable(L"MokListTrustedNew", &SHIM_LOCK_GUID);
+ return EFI_ABORTED;
+ }
+
+ if (var->MokTMLState == 0) {
+ efi_status = RT->SetVariable(L"MokListTrusted", &SHIM_LOCK_GUID,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 1, &dbval);
+ if (EFI_ERROR(efi_status)) {
+ console_notify(L"Failed to set MokListTrusted state");
+ return efi_status;
+ }
+ } else {
+ efi_status = RT->SetVariable(L"MokListTrusted", &SHIM_LOCK_GUID,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0, NULL);
+ if (EFI_ERROR(efi_status)) {
+ console_notify(L"Failed to delete MokListTrusted state");
+ return efi_status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
static EFI_STATUS mok_pw_prompt(void *MokPW, UINTN MokPWSize)
{
EFI_STATUS efi_status;
@@ -2076,7 +2197,8 @@ typedef enum {
MOK_SET_PW,
MOK_CHANGE_DB,
MOK_KEY_ENROLL,
- MOK_HASH_ENROLL
+ MOK_HASH_ENROLL,
+ MOK_CHANGE_TML
} mok_menu_item;
static void free_menu(mok_menu_item * menu_item, CHAR16 ** menu_strings)
@@ -2095,7 +2217,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
void *MokPW, UINTN MokPWSize,
void *MokDB, UINTN MokDBSize,
void *MokXNew, UINTN MokXNewSize,
- void *MokXDel, UINTN MokXDelSize)
+ void *MokXDel, UINTN MokXDelSize,
+ void *MokTML, UINTN MokTMLSize)
{
CHAR16 **menu_strings = NULL;
mok_menu_item *menu_item = NULL;
@@ -2171,6 +2294,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
if (MokDB)
menucount++;
+ if (MokTML)
+ menucount++;
+
menu_strings = AllocateZeroPool(sizeof(CHAR16 *) *
(menucount + 1));
if (!menu_strings)
@@ -2242,6 +2368,12 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
i++;
}
+ if (MokTML) {
+ menu_strings[i] = L"Change MOK List Trusted State";
+ menu_item[i] = MOK_CHANGE_TML;
+ i++;
+ }
+
menu_strings[i] = L"Enroll key from disk";
menu_item[i] = MOK_KEY_ENROLL;
i++;
@@ -2352,6 +2484,17 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
case MOK_HASH_ENROLL:
efi_status = mok_hash_enroll();
break;
+ case MOK_CHANGE_TML:
+ if (!MokTML) {
+ console_print(L"MokManager: internal error: %s",
+ L"MokListTrusted was ! NULL bs is now NULL\n");
+ ret = EFI_ABORTED;
+ goto out;
+ }
+ efi_status = mok_tml_prompt(MokTML, MokTMLSize);
+ if (!EFI_ERROR(efi_status))
+ MokTML = NULL;
+ break;
}
if (!EFI_ERROR(efi_status))
@@ -2376,7 +2519,7 @@ out:
static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
{
UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0;
- UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0;
+ UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0, MokTMLSize = 0;
void *MokNew = NULL;
void *MokDel = NULL;
void *MokSB = NULL;
@@ -2384,6 +2527,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
void *MokDB = NULL;
void *MokXNew = NULL;
void *MokXDel = NULL;
+ void *MokTML = NULL;
EFI_STATUS efi_status;
efi_status = get_variable(L"MokNew", (UINT8 **) & MokNew, &MokNewSize,
@@ -2436,6 +2580,18 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
console_error(L"Could not retrieve MokDB", efi_status);
}
+ efi_status = get_variable(L"MokListTrustedNew", (UINT8 **) & MokTML,
+ &MokTMLSize, SHIM_LOCK_GUID);
+ if (!EFI_ERROR(efi_status)) {
+ efi_status = LibDeleteVariable(L"MokListTrustedNew",
+ &SHIM_LOCK_GUID);
+ if (EFI_ERROR(efi_status))
+ console_notify(L"Failed to delete MokListTrustedNew");
+ } else if (EFI_ERROR(efi_status) && efi_status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokListTrustedNew",
+ efi_status);
+ }
+
efi_status = get_variable(L"MokXNew", (UINT8 **) & MokXNew,
&MokXNewSize, SHIM_LOCK_GUID);
if (!EFI_ERROR(efi_status)) {
@@ -2458,7 +2614,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize,
MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize,
- MokXNew, MokXNewSize, MokXDel, MokXDelSize);
+ MokXNew, MokXNewSize, MokXDel, MokXDelSize, MokTML, MokTMLSize);
if (MokNew)
FreePool(MokNew);
@@ -2481,6 +2637,9 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
if (MokXDel)
FreePool(MokXDel);
+ if (MokTML)
+ FreePool(MokTML);
+
LibDeleteVariable(L"MokAuth", &SHIM_LOCK_GUID);
LibDeleteVariable(L"MokDelAuth", &SHIM_LOCK_GUID);
LibDeleteVariable(L"MokXAuth", &SHIM_LOCK_GUID);
diff --git a/MokVars.txt b/MokVars.txt
index 4b80a413..cdfec2c8 100644
--- a/MokVars.txt
+++ b/MokVars.txt
@@ -77,3 +77,9 @@ or not to import DB certs for its own verification purposes.
MokPWStore: A SHA-256 representation of the password set by the user
via MokPW. The user will be prompted to enter this password in order
to interact with MokManager.
+
+MokListTrusted: An 8-bit unsigned integer. If 1, it signifies to Linux
+to trust CA keys in the MokList. BS,NV
+
+MokListTrustedRT: A copy of MokListTrusted made available to the kernel
+at runtime. RT
diff --git a/globals.c b/globals.c
index 476e2e9c..4a1f432f 100644
--- a/globals.c
+++ b/globals.c
@@ -25,6 +25,7 @@ int loader_is_participating;
UINT8 user_insecure_mode;
UINT8 ignore_db;
+UINT8 trust_mok_list;
UINT32 verbose = 0;
diff --git a/mok.c b/mok.c
index 7755eea9..52dffc3e 100644
--- a/mok.c
+++ b/mok.c
@@ -46,7 +46,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
check_var(L"MokPW") || check_var(L"MokAuth") ||
check_var(L"MokDel") || check_var(L"MokDB") ||
check_var(L"MokXNew") || check_var(L"MokXDel") ||
- check_var(L"MokXAuth")) {
+ check_var(L"MokXAuth") || check_var(L"MokListTrustedNew")) {
efi_status = start_image(image_handle, MOK_MANAGER);
if (EFI_ERROR(efi_status)) {
@@ -166,6 +166,20 @@ struct mok_state_variable mok_state_variable_data[] = {
MOK_VARIABLE_MEASURE,
.pcr = 7,
},
+ {.name = L"MokListTrusted",
+ .name8 = "MokListTrusted",
+ .rtname = L"MokListTrustedRT",
+ .rtname8 = "MokListTrustedRT",
+ .guid = &SHIM_LOCK_GUID,
+ .yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE,
+ .no_attr = EFI_VARIABLE_RUNTIME_ACCESS,
+ .flags = MOK_MIRROR_DELETE_FIRST |
+ MOK_VARIABLE_MEASURE |
+ MOK_VARIABLE_LOG,
+ .pcr = 14,
+ .state = &trust_mok_list,
+ },
{ NULL, }
};
size_t n_mok_state_variables = sizeof(mok_state_variable_data) / sizeof(mok_state_variable_data[0]);
@@ -897,6 +911,7 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
user_insecure_mode = 0;
ignore_db = 0;
+ trust_mok_list = 0;
UINT64 config_sz = 0;
UINT8 *config_table = NULL;
diff --git a/shim.h b/shim.h
index 5e1ab36b..69442da3 100644
--- a/shim.h
+++ b/shim.h
@@ -255,6 +255,7 @@ extern UINT8 *build_cert;
extern UINT8 user_insecure_mode;
extern UINT8 ignore_db;
+extern UINT8 trust_mok_list;
extern UINT8 in_protocol;
extern void *load_options;
extern UINT32 load_options_size;