Skip to content

Commit a897ed1

Browse files
committed
Try to detect and add an alert for 'TPM Measured Boot' with BitLocker
* Per https://github.com/microsoft/secureboot_objects/wiki/OEM-Certificate-Key-Rolling#update-factory-defaults-for-oems: "Modifying (PK/KEK/db/dbx) will break full disk encryption because they are key components of SRTM PCR measurements". * As a result, we try to detect the present of a TPM along with BitLocker encrypted partitions, and add a notice that users may need to provide their recovery key for Windows to boot, once the Secure Boot variables have been altered. * Closes #18. * Also improve the alert boxes and prevent the NoPk creation in update mode.
1 parent 2a60d8e commit a897ed1

6 files changed

Lines changed: 91 additions & 12 deletions

File tree

MosbyPkg.inf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,11 @@
6666
gEfiSmbios3TableGuid
6767

6868
[Protocols]
69+
gEfiBlockIoProtocolGuid
6970
gEfiLoadedImageProtocolGuid
7071
gEfiSimpleFileSystemProtocolGuid
7172
gEfiRngProtocolGuid
73+
gEfiTcg2ProtocolGuid
7274

7375
[Pcd]
7476
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang

src/console.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,15 @@ INTN ConsoleOkCancel(
332332
return ConsoleSelect(StrArray, (CONST CHAR16 *[]){ L"OK", L"Cancel", NULL }, 0);
333333
}
334334

335-
VOID ConsoleAlertBox(
336-
IN CONST CHAR16 *StrArray[]
335+
INTN ConsoleAlertBox(
336+
IN CONST CHAR16 *StrArray[],
337+
IN CONST CHAR16 *Selectors[]
337338
)
338339
{
339340
BackGroundColor = EFI_BACKGROUND_RED;
340-
ConsoleSelect(StrArray, (CONST CHAR16 *[]){ L"OK", 0 }, 0);
341+
INTN Sel = ConsoleSelect(StrArray, Selectors, 100000);
341342
BackGroundColor = DEFAULT_BACKGROUND_COLOR;
343+
return Sel;
342344
}
343345

344346
VOID ConsoleErrorBox(
@@ -355,7 +357,7 @@ VOID ConsoleErrorBox(
355357
ErrArray[2] = Err;
356358

357359
BackGroundColor = EFI_BACKGROUND_RED;
358-
ConsoleAlertBox(ErrArray);
360+
ConsoleAlertBox(ErrArray, (CONST CHAR16 *[]){ L"OK", NULL });
359361
BackGroundColor = DEFAULT_BACKGROUND_COLOR;
360362
}
361363

@@ -377,7 +379,7 @@ VOID ConsoleError(
377379
ErrArray[2] = Str;
378380

379381
BackGroundColor = EFI_BACKGROUND_RED;
380-
ConsoleAlertBox(ErrArray);
382+
ConsoleAlertBox(ErrArray, (CONST CHAR16 *[]){ L"OK", NULL });
381383
BackGroundColor = DEFAULT_BACKGROUND_COLOR;
382384
}
383385

src/console.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ INTN ConsoleOkCancel(
6565
IN CONST CHAR16 *StrArray[]
6666
);
6767

68-
VOID ConsoleAlertBox(
69-
IN CONST CHAR16 *StrArray[]
68+
INTN ConsoleAlertBox(
69+
IN CONST CHAR16 *StrArray[],
70+
IN CONST CHAR16 *Selectors[]
7071
);
7172

7273
VOID ConsoleErrorBox(

src/mosby.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,32 @@ EFI_STATUS EFIAPI efi_main(
361361
RecallPrintRestore();
362362
if (Sel != 0)
363363
goto exit;
364+
365+
/* Display an additional warning for TPM measured boot with BitLocker */
366+
if (SystemHasTpm() && SystemHasBitLocker()) {
367+
RecallPrint(L"Notice: TPM and BitLocker detected.\n");
368+
STATIC CONST CHAR16 *WTF_RISC_COMPILER1[] = {
369+
L"TPM MEASURED BOOT WARNING",
370+
L"",
371+
L"A TPM, along with BitLocker partitions, were detected on this PC.",
372+
L"",
373+
L"Because of a feature called 'TPM Measured Boot', if your system",
374+
L"partition is encrypted, this could result in Windows refusing to",
375+
L"boot after the Secure Boot variables have been updated, until you",
376+
L"provide it with your BitLocker recovery key... ",
377+
L"",
378+
L"If you have your recovery key available, or are sure that your",
379+
L"system partition is not encrypted, you can select 'Proceed' here.",
380+
L"",
381+
L"If you are unsure about the above, and don't have your BitLocker",
382+
L"recovery key, it is recommended that you select 'Abort'. ",
383+
NULL
384+
};
385+
Sel = ConsoleAlertBox(WTF_RISC_COMPILER1, (CONST CHAR16 *[]){ L"PROCEED", L"ABORT", NULL });
386+
RecallPrintRestore();
387+
if (Sel != 0)
388+
goto exit;
389+
}
364390
}
365391

366392
/* If we have an existing cert for a previously generated DB credential, try to reuse it */
@@ -642,7 +668,7 @@ EFI_STATUS EFIAPI efi_main(
642668

643669
// If requested, create a NoPK.auth package, that can be used (with KeyTool or other utilities)
644670
// to delete the PK and set the platform back into Setup Mode.
645-
if (CreateNoPkFile) {
671+
if (CreateNoPkFile && !UpdateMode) {
646672
MOSBY_VARIABLE NoPk = { 0 };
647673
if (SimpleFileExistsByPath(gBaseImageHandle, L"NoPK.auth")) {
648674
RecallPrint(L"WARNING: NOT creating a PK deletion package since 'NoPK.auth' already exists\n");
@@ -667,11 +693,11 @@ EFI_STATUS EFIAPI efi_main(
667693
Reboot = ExitNotice(GenDBCred);
668694

669695
exit:
670-
if (EFI_ERROR(Status) && DisplayErrorNotice && !gOptionSilent) {
696+
if (EFI_ERROR(Status) && DisplayErrorNotice && !gOptionSilent && !UpdateMode) {
671697
// The RISC-V gcc compiler adds implicit memcpy() calls here if you declare the text
672698
// blurb inline, *LIKE WE DO EVERYWHERE ELSE ABOVE WITHOUT ISSUE*, which of course
673699
// breaks UEFI app compilation. So we have to declare a static variable. WTF?!?
674-
STATIC CONST CHAR16 *WTF_RISC_COMPILER[] = {
700+
STATIC CONST CHAR16 *WTF_RISC_COMPILER2[] = {
675701
L"ERROR",
676702
L"",
677703
L"Mosby was NOT able to install your Secure Boot variables. ",
@@ -686,7 +712,7 @@ EFI_STATUS EFIAPI efi_main(
686712
L"",
687713
NULL
688714
};
689-
ConsoleAlertBox(WTF_RISC_COMPILER);
715+
ConsoleAlertBox(WTF_RISC_COMPILER2, (CONST CHAR16 *[]){ L"OK", NULL });
690716
RecallPrintRestore();
691717
}
692718
for (i = 0; i < List.Size; i++)

src/mosby.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,7 @@ EFI_STATUS InitializeList(
158158
);
159159

160160
EFI_STATUS PrintSystemInfo(VOID);
161+
162+
BOOLEAN SystemHasTpm(VOID);
163+
164+
BOOLEAN SystemHasBitLocker(VOID);

src/system.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* MSSB (More Secure Secure Boot -- "Mosby") UEFI system info
3-
* Copyright © 2025 Pete Batard <pete@akeo.ie>
3+
* Copyright © 2025-2026 Pete Batard <pete@akeo.ie>
44
*
55
* This program is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,9 @@
3030

3131
#include <IndustryStandard/SmBios.h>
3232

33+
#include <Protocol/BlockIo.h>
34+
#include <Protocol/Tcg2Protocol.h>
35+
3336
#include <Uefi/UefiBaseType.h>
3437

3538
/*
@@ -139,3 +142,44 @@ EFI_STATUS PrintSystemInfo(VOID)
139142

140143
return EFI_SUCCESS;
141144
}
145+
146+
BOOLEAN SystemHasTpm(VOID)
147+
{
148+
EFI_TCG2_PROTOCOL *Tcg2;
149+
150+
return !EFI_ERROR(gBS->LocateProtocol(&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2));
151+
}
152+
153+
BOOLEAN SystemHasBitLocker(VOID)
154+
{
155+
BOOLEAN Found = FALSE;
156+
EFI_STATUS Status;
157+
EFI_HANDLE *Handles = NULL;
158+
EFI_BLOCK_IO_PROTOCOL *BlockIo = NULL;
159+
UINTN HandleCount, i;
160+
UINT8 *Sector = NULL;
161+
162+
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &Handles);
163+
if (EFI_ERROR(Status))
164+
return FALSE;
165+
166+
for (i = 0; i < HandleCount && !Found; i++) {
167+
Status = gBS->HandleProtocol(Handles[i], &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
168+
if (EFI_ERROR(Status) || !BlockIo->Media->LogicalPartition || !BlockIo->Media->MediaPresent)
169+
continue;
170+
171+
// Read the first sector, and look for the BitLocker "Full Volume Encryption File System" magic
172+
Sector = AllocateZeroPool(BlockIo->Media->BlockSize);
173+
if (Sector == NULL)
174+
continue;
175+
Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 0, BlockIo->Media->BlockSize, Sector);
176+
if (EFI_ERROR(Status))
177+
continue;
178+
if (CompareMem(&Sector[3], "-FVE-FS-", 8) == 0)
179+
Found = TRUE;
180+
FreePool(Sector);
181+
}
182+
183+
FreePool(Handles);
184+
return Found;
185+
}

0 commit comments

Comments
 (0)