Skip to content

Commit

Permalink
Introduce a new MOK variable called MokListTrustedRT
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
esnowberg authored and vathpela committed Nov 3, 2021
1 parent 899314b commit 4e51340
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 5 deletions.
167 changes: 163 additions & 4 deletions MokManager.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ typedef struct {
CHAR16 Password[SB_PASSWORD_LEN];
} __attribute__ ((packed)) MokDBvar;

typedef struct {
UINT32 MokTMLState;
UINT32 PWLen;
CHAR16 Password[SB_PASSWORD_LEN];
} __attribute__ ((packed)) MokTMLvar;

typedef struct {
INT32 Timeout;
} __attribute__ ((packed)) MokTimeoutvar;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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))
Expand All @@ -2376,14 +2519,15 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
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;
void *MokPW = NULL;
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,
Expand Down Expand Up @@ -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)) {
Expand All @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions MokVars.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ int loader_is_participating;

UINT8 user_insecure_mode;
UINT8 ignore_db;
UINT8 trust_mok_list;

UINT32 verbose = 0;

Expand Down
17 changes: 16 additions & 1 deletion mok.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 4e51340

Please sign in to comment.