Skip to content

Commit 4e51340

Browse files
esnowbergvathpela
authored andcommitted
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 <[email protected]>
1 parent 899314b commit 4e51340

File tree

5 files changed

+187
-5
lines changed

5 files changed

+187
-5
lines changed

MokManager.c

Lines changed: 163 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ typedef struct {
4040
CHAR16 Password[SB_PASSWORD_LEN];
4141
} __attribute__ ((packed)) MokDBvar;
4242

43+
typedef struct {
44+
UINT32 MokTMLState;
45+
UINT32 PWLen;
46+
CHAR16 Password[SB_PASSWORD_LEN];
47+
} __attribute__ ((packed)) MokTMLvar;
48+
4349
typedef struct {
4450
INT32 Timeout;
4551
} __attribute__ ((packed)) MokTimeoutvar;
@@ -1678,6 +1684,121 @@ static EFI_STATUS mok_db_prompt(void *MokDB, UINTN MokDBSize)
16781684
return EFI_SUCCESS;
16791685
}
16801686

1687+
static EFI_STATUS mok_tml_prompt(void *MokTML, UINTN MokTMLSize)
1688+
{
1689+
EFI_STATUS efi_status;
1690+
SIMPLE_TEXT_OUTPUT_MODE SavedMode;
1691+
MokTMLvar *var = MokTML;
1692+
CHAR16 *message[4];
1693+
CHAR16 pass1, pass2, pass3;
1694+
CHAR16 *str;
1695+
UINT8 fail_count = 0;
1696+
UINT8 dbval = 1;
1697+
UINT8 pos1, pos2, pos3;
1698+
int ret;
1699+
CHAR16 *untrust_tml[] = { L"Do not trust the MOK list", NULL };
1700+
CHAR16 *trust_tml[] = { L"Trust the MOK list", NULL };
1701+
1702+
if (MokTMLSize != sizeof(MokTMLvar)) {
1703+
console_notify(L"Invalid MokTML variable contents");
1704+
return EFI_INVALID_PARAMETER;
1705+
}
1706+
1707+
clear_screen();
1708+
1709+
message[0] = L"Change Trusted MOK List Keyring state";
1710+
message[1] = NULL;
1711+
1712+
console_save_and_set_mode(&SavedMode);
1713+
console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
1714+
console_restore_mode(&SavedMode);
1715+
1716+
while (fail_count < 3) {
1717+
RandomBytes(&pos1, sizeof(pos1));
1718+
pos1 = (pos1 % var->PWLen);
1719+
1720+
do {
1721+
RandomBytes(&pos2, sizeof(pos2));
1722+
pos2 = (pos2 % var->PWLen);
1723+
} while (pos2 == pos1);
1724+
1725+
do {
1726+
RandomBytes(&pos3, sizeof(pos3));
1727+
pos3 = (pos3 % var->PWLen);
1728+
} while (pos3 == pos2 || pos3 == pos1);
1729+
1730+
str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
1731+
if (!str) {
1732+
console_errorbox(L"Failed to allocate buffer");
1733+
return EFI_OUT_OF_RESOURCES;
1734+
}
1735+
pass1 = get_password_charater(str);
1736+
FreePool(str);
1737+
1738+
str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
1739+
if (!str) {
1740+
console_errorbox(L"Failed to allocate buffer");
1741+
return EFI_OUT_OF_RESOURCES;
1742+
}
1743+
pass2 = get_password_charater(str);
1744+
FreePool(str);
1745+
1746+
str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
1747+
if (!str) {
1748+
console_errorbox(L"Failed to allocate buffer");
1749+
return EFI_OUT_OF_RESOURCES;
1750+
}
1751+
pass3 = get_password_charater(str);
1752+
FreePool(str);
1753+
1754+
if (pass1 != var->Password[pos1] ||
1755+
pass2 != var->Password[pos2] ||
1756+
pass3 != var->Password[pos3]) {
1757+
console_print(L"Invalid character\n");
1758+
fail_count++;
1759+
} else {
1760+
break;
1761+
}
1762+
}
1763+
1764+
if (fail_count >= 3) {
1765+
console_notify(L"Password limit reached");
1766+
return EFI_ACCESS_DENIED;
1767+
}
1768+
1769+
if (var->MokTMLState == 0)
1770+
ret = console_yes_no(trust_tml);
1771+
else
1772+
ret = console_yes_no(untrust_tml);
1773+
1774+
if (ret == 0) {
1775+
LibDeleteVariable(L"MokListTrustedNew", &SHIM_LOCK_GUID);
1776+
return EFI_ABORTED;
1777+
}
1778+
1779+
if (var->MokTMLState == 0) {
1780+
efi_status = RT->SetVariable(L"MokListTrusted", &SHIM_LOCK_GUID,
1781+
EFI_VARIABLE_NON_VOLATILE |
1782+
EFI_VARIABLE_BOOTSERVICE_ACCESS,
1783+
1, &dbval);
1784+
if (EFI_ERROR(efi_status)) {
1785+
console_notify(L"Failed to set MokListTrusted state");
1786+
return efi_status;
1787+
}
1788+
} else {
1789+
efi_status = RT->SetVariable(L"MokListTrusted", &SHIM_LOCK_GUID,
1790+
EFI_VARIABLE_NON_VOLATILE |
1791+
EFI_VARIABLE_BOOTSERVICE_ACCESS,
1792+
0, NULL);
1793+
if (EFI_ERROR(efi_status)) {
1794+
console_notify(L"Failed to delete MokListTrusted state");
1795+
return efi_status;
1796+
}
1797+
}
1798+
1799+
return EFI_SUCCESS;
1800+
}
1801+
16811802
static EFI_STATUS mok_pw_prompt(void *MokPW, UINTN MokPWSize)
16821803
{
16831804
EFI_STATUS efi_status;
@@ -2076,7 +2197,8 @@ typedef enum {
20762197
MOK_SET_PW,
20772198
MOK_CHANGE_DB,
20782199
MOK_KEY_ENROLL,
2079-
MOK_HASH_ENROLL
2200+
MOK_HASH_ENROLL,
2201+
MOK_CHANGE_TML
20802202
} mok_menu_item;
20812203

20822204
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,
20952217
void *MokPW, UINTN MokPWSize,
20962218
void *MokDB, UINTN MokDBSize,
20972219
void *MokXNew, UINTN MokXNewSize,
2098-
void *MokXDel, UINTN MokXDelSize)
2220+
void *MokXDel, UINTN MokXDelSize,
2221+
void *MokTML, UINTN MokTMLSize)
20992222
{
21002223
CHAR16 **menu_strings = NULL;
21012224
mok_menu_item *menu_item = NULL;
@@ -2171,6 +2294,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
21712294
if (MokDB)
21722295
menucount++;
21732296

2297+
if (MokTML)
2298+
menucount++;
2299+
21742300
menu_strings = AllocateZeroPool(sizeof(CHAR16 *) *
21752301
(menucount + 1));
21762302
if (!menu_strings)
@@ -2242,6 +2368,12 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
22422368
i++;
22432369
}
22442370

2371+
if (MokTML) {
2372+
menu_strings[i] = L"Change MOK List Trusted State";
2373+
menu_item[i] = MOK_CHANGE_TML;
2374+
i++;
2375+
}
2376+
22452377
menu_strings[i] = L"Enroll key from disk";
22462378
menu_item[i] = MOK_KEY_ENROLL;
22472379
i++;
@@ -2352,6 +2484,17 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
23522484
case MOK_HASH_ENROLL:
23532485
efi_status = mok_hash_enroll();
23542486
break;
2487+
case MOK_CHANGE_TML:
2488+
if (!MokTML) {
2489+
console_print(L"MokManager: internal error: %s",
2490+
L"MokListTrusted was ! NULL bs is now NULL\n");
2491+
ret = EFI_ABORTED;
2492+
goto out;
2493+
}
2494+
efi_status = mok_tml_prompt(MokTML, MokTMLSize);
2495+
if (!EFI_ERROR(efi_status))
2496+
MokTML = NULL;
2497+
break;
23552498
}
23562499

23572500
if (!EFI_ERROR(efi_status))
@@ -2376,14 +2519,15 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED,
23762519
static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
23772520
{
23782521
UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0;
2379-
UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0;
2522+
UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0, MokTMLSize = 0;
23802523
void *MokNew = NULL;
23812524
void *MokDel = NULL;
23822525
void *MokSB = NULL;
23832526
void *MokPW = NULL;
23842527
void *MokDB = NULL;
23852528
void *MokXNew = NULL;
23862529
void *MokXDel = NULL;
2530+
void *MokTML = NULL;
23872531
EFI_STATUS efi_status;
23882532

23892533
efi_status = get_variable(L"MokNew", (UINT8 **) & MokNew, &MokNewSize,
@@ -2436,6 +2580,18 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
24362580
console_error(L"Could not retrieve MokDB", efi_status);
24372581
}
24382582

2583+
efi_status = get_variable(L"MokListTrustedNew", (UINT8 **) & MokTML,
2584+
&MokTMLSize, SHIM_LOCK_GUID);
2585+
if (!EFI_ERROR(efi_status)) {
2586+
efi_status = LibDeleteVariable(L"MokListTrustedNew",
2587+
&SHIM_LOCK_GUID);
2588+
if (EFI_ERROR(efi_status))
2589+
console_notify(L"Failed to delete MokListTrustedNew");
2590+
} else if (EFI_ERROR(efi_status) && efi_status != EFI_NOT_FOUND) {
2591+
console_error(L"Could not retrieve MokListTrustedNew",
2592+
efi_status);
2593+
}
2594+
24392595
efi_status = get_variable(L"MokXNew", (UINT8 **) & MokXNew,
24402596
&MokXNewSize, SHIM_LOCK_GUID);
24412597
if (!EFI_ERROR(efi_status)) {
@@ -2458,7 +2614,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
24582614

24592615
enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize,
24602616
MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize,
2461-
MokXNew, MokXNewSize, MokXDel, MokXDelSize);
2617+
MokXNew, MokXNewSize, MokXDel, MokXDelSize, MokTML, MokTMLSize);
24622618

24632619
if (MokNew)
24642620
FreePool(MokNew);
@@ -2481,6 +2637,9 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
24812637
if (MokXDel)
24822638
FreePool(MokXDel);
24832639

2640+
if (MokTML)
2641+
FreePool(MokTML);
2642+
24842643
LibDeleteVariable(L"MokAuth", &SHIM_LOCK_GUID);
24852644
LibDeleteVariable(L"MokDelAuth", &SHIM_LOCK_GUID);
24862645
LibDeleteVariable(L"MokXAuth", &SHIM_LOCK_GUID);

MokVars.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,9 @@ or not to import DB certs for its own verification purposes.
7777
MokPWStore: A SHA-256 representation of the password set by the user
7878
via MokPW. The user will be prompted to enter this password in order
7979
to interact with MokManager.
80+
81+
MokListTrusted: An 8-bit unsigned integer. If 1, it signifies to Linux
82+
to trust CA keys in the MokList. BS,NV
83+
84+
MokListTrustedRT: A copy of MokListTrusted made available to the kernel
85+
at runtime. RT

globals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ int loader_is_participating;
2525

2626
UINT8 user_insecure_mode;
2727
UINT8 ignore_db;
28+
UINT8 trust_mok_list;
2829

2930
UINT32 verbose = 0;
3031

mok.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
4646
check_var(L"MokPW") || check_var(L"MokAuth") ||
4747
check_var(L"MokDel") || check_var(L"MokDB") ||
4848
check_var(L"MokXNew") || check_var(L"MokXDel") ||
49-
check_var(L"MokXAuth")) {
49+
check_var(L"MokXAuth") || check_var(L"MokListTrustedNew")) {
5050
efi_status = start_image(image_handle, MOK_MANAGER);
5151

5252
if (EFI_ERROR(efi_status)) {
@@ -166,6 +166,20 @@ struct mok_state_variable mok_state_variable_data[] = {
166166
MOK_VARIABLE_MEASURE,
167167
.pcr = 7,
168168
},
169+
{.name = L"MokListTrusted",
170+
.name8 = "MokListTrusted",
171+
.rtname = L"MokListTrustedRT",
172+
.rtname8 = "MokListTrustedRT",
173+
.guid = &SHIM_LOCK_GUID,
174+
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
175+
EFI_VARIABLE_NON_VOLATILE,
176+
.no_attr = EFI_VARIABLE_RUNTIME_ACCESS,
177+
.flags = MOK_MIRROR_DELETE_FIRST |
178+
MOK_VARIABLE_MEASURE |
179+
MOK_VARIABLE_LOG,
180+
.pcr = 14,
181+
.state = &trust_mok_list,
182+
},
169183
{ NULL, }
170184
};
171185
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)
897911

898912
user_insecure_mode = 0;
899913
ignore_db = 0;
914+
trust_mok_list = 0;
900915

901916
UINT64 config_sz = 0;
902917
UINT8 *config_table = NULL;

shim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ extern UINT8 *build_cert;
255255

256256
extern UINT8 user_insecure_mode;
257257
extern UINT8 ignore_db;
258+
extern UINT8 trust_mok_list;
258259
extern UINT8 in_protocol;
259260
extern void *load_options;
260261
extern UINT32 load_options_size;

0 commit comments

Comments
 (0)