Use shim 15.7 to support Secure Boot

Use shim-signed and shim-helpers-{arch}-signed from Debian:
https://packages.debian.org/bookworm/shim-signed
This commit is contained in:
Lauri Kenttä
2023-11-17 22:16:06 +02:00
parent 14aa79929a
commit 466ab69c48
9 changed files with 400 additions and 17 deletions

View File

@@ -23,7 +23,7 @@ efi-signed: efi-signed/bootx64.efi efi-signed/bootia32.efi
setup: setup.exe
zip: $(ZIP)
$(ZIP): efi-signed certificate.cer config.txt splash.bmp setup.exe README.md CHANGELOG.md README.efilib LICENSE
$(ZIP): efi-signed certificate.cer config.txt splash.bmp setup.exe README.md CHANGELOG.md README.efilib LICENSE shim-signed shim.md
test ! -d "$(ZIPDIR)"
mkdir "$(ZIPDIR)"
cp -a $^ "$(ZIPDIR)" || (rm -rf "$(ZIPDIR)"; exit 1)

View File

@@ -11,26 +11,24 @@ When booting on a UEFI-based computer, Windows may show a vendor-defined logo wh
**Important:** If you mess up the installation, your system may become unbootable! Create a rescue disk before use. This software comes with no warranty. Use at your own risk.
* Make sure that your computer is booting with UEFI.
* Make sure that Secure Boot is disabled, unless you know how to manage certificates.
* Make sure that you have read the Secure Boot instructions.
* Make sure that BitLocker is disabled, or find your recovery key.
### Secure Boot instructions
HackBGRT is not approved by Microsoft. By default, the Secure Boot mechanism will not allow it to run. You will need to either disable Secure Boot (and BitLocker) or enroll the HackBGRT signing certificate `certificate.cer` (also installed in `EFI\HackBGRT\certificate.cer`) into your system. Trusting any self-signed certificates is not recommended, so if you wish to keep your system truly safe with Secure Boot, you should build HackBGRT locally and use your own certificate to sign it.
HackBGRT is not approved by Microsoft. Instead, HackBGRT comes with the *shim* boot loader, which allows to manually select HackBGRT as a trusted program. After installing HackBGRT and rebooting your computer, you have to **follow the instructions in [shim.md](shim.md)** to achieve this. These steps cannot be automated, that's the whole point of Secure Boot. Although HackBGRT is self-signed with a certificate, it's not advisable to enroll foreign certificates directly into your firmware.
Enrolling the certificate cannot be automated, that's the whole point of Secure Boot.
Instructions for enrolling the certificate (if it's possible at all) depend on your computer model. Please refer to your motherboard manual or do a web search on *how to enroll Secure Boot certificate*. No support is provided for this option. Note that enrolling a custom certificate breaks PCR7 Binding and can cause problems with BitLocker Automatic Device Encryption. Make sure you have either disabled BitLocker or have the recovery key available.
The *shim* boot loader is maintained by Red Hat, Inc, and the included signed copy of *shim* is extracted from Debian GNU/Linux many thanks to the maintainers! For copyright information, see [shim-signed/COPYRIGHT](shim-signed/COPYRIGHT).
### Windows installation
* Get the latest release from the Releases page.
* Start `setup.exe` and follow the instructions.
* You may need to manually disable Secure Boot and then retry.
* The installer will launch Paint for editing the image.
* If Windows later restores the original boot loader, just reinstall.
* If you wish to change the image or other configuration, just reinstall.
* For advanced settings, edit `config.txt` before installing. No extra support provided!
* After installing, read the instructions in [shim.md](shim.md) and reboot your computer.
### Quiet (batch) installation
@@ -43,6 +41,7 @@ Instructions for enrolling the certificate (if it's possible at all) depend on y
* `disable-bootmgr` use `bcdedit` to disable the EFI boot entry.
* `enable-overwrite` overwrite the MS boot loader.
* `disable-overwrite` restore the MS boot loader.
* `skip-shim` skip *shim* when installing.
* `allow-secure-boot` ignore Secure Boot in subsequent commands.
* `allow-bitlocker` ignore BitLocker in subsequent commands.
* `allow-bad-loader` ignore bad boot loader configuration in subsequent commands.

55
shim-signed/COPYRIGHT Normal file
View File

@@ -0,0 +1,55 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: shim
Upstream-Contact: Peter Jones <pjones@redhat.com>
Source: https://github.com/rhboot/shim
Files: *
Copyright: 2012 Red Hat, Inc
2009-2012 Intel Corporation
License: BSD-2-Clause
Files: debian/po/cs.po
Copyright: 2018 Michal Simunek <michal.simunek@gmail.com>
License: BSD-2-Clause
Files: debian/po/de.po
Copyright: 2017, 2018 Markus Hiereth <markus.hiereth@freenet.de>
License: BSD-2-Clause
Files: debian/po/fr.po
Copyright: 2017, 2018 Alban Vidal <alban.vidal@zordhak.fr>
License: BSD-2-Clause
Files: debian/po/nl.po
Copyright: 2017, 2018 Frans Spiesschaert <Frans.Spiesschaert@yucom.be>
License: BSD-2-Clause
Files: debian/po/pt.po
Copyright: 2017, 2018 Rui Branco <ruipb@debianpt.org>
License: BSD-2-Clause
License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
.
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

BIN
shim-signed/mmia32.efi Normal file

Binary file not shown.

BIN
shim-signed/mmx64.efi Normal file

Binary file not shown.

BIN
shim-signed/shimia32.efi Normal file

Binary file not shown.

BIN
shim-signed/shimx64.efi Normal file

Binary file not shown.

286
shim.md Normal file
View File

@@ -0,0 +1,286 @@
# Secure Boot and *shim*
Secure Boot accepts only trusted files during boot. The *shim* boot loader is a tool which allows you to select which files to trust. HackBGRT installs *shim* for you, but you need to configure it with these instructions.
On the first boot after installing HackBGRT, you will see an error message saying "Verification failed". You need to press a key to enter the setup tool (MOKManager) where you can choose to trust HackBGRT. After that, use arrow keys to navigate and *Enter* to continue as described below.
## 1. Verification failed
This is the start of *shim* configuration.
```
ERROR
Verification failed: (0x1A) Security Violation
+----+
| OK |
+----+
```
Select `OK`, *Enter*.
```
Shim UEFI key management
Press any key to perform MOK management
Booting in 5 seconds
```
Press a key quickly to enter *MOK management* or the *MOKManager* program.
## 2. MOK management
```
Perform MOK management
Continue to boot
Enroll key from disk
Enroll hash from disk
```
Select `Enroll hash from disk`, *Enter*. This is the safest option where you choose to trust only a specific version of HackBGRT.
You can also choose to `Enroll key from disk`, which means that you choose to trust anything signed with the same certificate. How do you know if it's safe? You don't that's why you should rather use the other option or build your own version of HackBGRT with your own certificate.
## 3a. Enroll hash from disk
```
Select Binary
The Selected Binary will have its hash Enrolled
This means it will subsequently Boot with no prompting
Remember to make sure it is a genuine binary before enrolling its hash
+----------------+
| YOUR DISK NAME |
+----------------+
```
Select the disk, *Enter*.
```
+---------------+
| EFI/ |
| loader/ |
| vmlinuz-linux |
+---------------+
```
Select `EFI/`, *Enter*.
```
+------------+
| ../ |
| Boot/ |
| HackBGRT/ |
| Microsoft/ |
+------------+
```
Select `HackBGRT/`, *Enter*.
```
+-----------------+
| ../ |
| grubx64.efi |
| loader.efi |
| mmx64.efi |
| certificate.cer |
| splash.bmp |
| config.txt |
+-----------------+
```
Select `grubx64.efi`, *Enter*.
```
[Enroll MOK]
+------------+
| View key 0 |
| Continue |
+------------+
```
To verify the key contents, select `View key 0`, *Enter*.
```
SHA256 hash
(some hexadecimal values)
```
Press *Enter* to continue.
```
[Enroll MOK]
+------------+
| View key 0 |
| Continue |
+------------+
```
Select `Continue`, *Enter*.
```
Enroll the key(s)?
+-----+
| No |
| Yes |
+-----+
```
Select `Yes`, *Enter*.
```
Perform MOK management
+-----------------------+
| Reboot |
| Enroll key from disk |
| Enroll hash from disk |
+-----------------------+
```
Select `Reboot`, *Enter*.
You are now ready to boot using HackBGRT.
## 3b. Enroll key from disk
```
Select Key
The selected key will be enrolled into the MOK database
This means any binaries signed with it will be run without prompting
Remember to make sure it is a genuine key before Enrolling it
+----------------+
| YOUR DISK NAME |
+----------------+
```
Select the disk, *Enter*.
```
+---------------+
| EFI/ |
| loader/ |
| vmlinuz-linux |
+---------------+
```
Select `EFI/`, *Enter*.
```
+------------+
| ../ |
| Boot/ |
| HackBGRT/ |
| Microsoft/ |
+------------+
```
Select `HackBGRT/`, *Enter*.
```
+-----------------+
| ../ |
| grubx64.efi |
| loader.efi |
| mmx64.efi |
| certificate.cer |
| splash.bmp |
| config.txt |
+-----------------+
```
Select `certificate.cer`, *Enter*.
```
[Enroll MOK]
+------------+
| View key 0 |
| Continue |
+------------+
```
To verify the key contents, select `View key 0`, *Enter*.
```
[Extended Key Usage]
OID: Code Signing
[Serial Number]
6B:24:52:E9:3B:84:41:73:B0:22:92:E8:BE:8E:38:85:
[Issuer]
CN=HackBGRT Secure Boot Signer, O=Metabolix
[Subject]
CN=HackBGRT Secure Boot Signer, O=Metabolix
[Valid Not Before]
Nov 9 13:43:56 2023 GMT
[Valid Not After]
Jan 19 03:14:07 2037 GMT
[Fingerprint]
79 8E 64 40 D1 D1 F4 53 30 8D
A0 83 A4 77 FE 57 45 30 36 60
```
Press *Enter* to continue.
```
[Enroll MOK]
+------------+
| View key 0 |
| Continue |
+------------+
```
Select `Continue`, *Enter*.
```
Enroll the key(s)?
+-----+
| No |
| Yes |
+-----+
```
Select `Yes`, *Enter*.
```
Perform MOK management
+-----------------------+
| Reboot |
| Enroll key from disk |
| Enroll hash from disk |
+-----------------------+
```
Select `Reboot`, *Enter*.
You are now ready to boot using HackBGRT.
## Tutorial: *shim* for dummies
To install *shim* manually, follow these steps (assuming x64 architecture):
1. Get *shim*, preferably *shim-signed*.
2. Rename your boot loader to `grubx64.efi`.
3. Copy `shimx64.efi` where your loader used to be.
4. Copy `mmx64.efi` to the same folder.
The *shim* boot process is as follows:
1. Your computer starts `your-loader-name.efi`, which is now really *shim*.
2. Next, *shim* tries to load `grubx64.efi`.
3. If `grubx64.efi` is trusted, the boot process continues.
4. Otherwise, *shim* offers to launch *MOKManager* `mmx64.efi`, and you can try again after that.

View File

@@ -53,6 +53,7 @@ public class Setup {
public enum BootLoaderType {
None,
Own,
Shim,
Microsoft,
Other,
}
@@ -63,6 +64,7 @@ public class Setup {
"allow-secure-boot",
"allow-bitlocker",
"allow-bad-loader",
"skip-shim",
"enable-entry", "disable-entry",
"enable-bcdedit", "disable-bcdedit",
"enable-overwrite", "disable-overwrite",
@@ -210,6 +212,8 @@ public class Setup {
string tmp = System.Text.Encoding.ASCII.GetString(data);
if (tmp.IndexOf("HackBGRT") >= 0 || tmp.IndexOf("HackBgrt") >= 0) {
return BootLoaderType.Own;
} else if (tmp.IndexOf("UEFI shim") >= 0) {
return BootLoaderType.Shim;
} else if (tmp.IndexOf("Microsoft Corporation") >= 0) {
return BootLoaderType.Microsoft;
} else {
@@ -313,8 +317,10 @@ public class Setup {
/**
* Install files to ESP.
*
* @param skipShim Whether to skip installing shim.
*/
protected void InstallFiles() {
protected void InstallFiles(bool skipShim) {
var loaderSource = Path.Combine("efi-signed", $"boot{EfiArch}.efi");
LoaderIsSigned = true;
if (!File.Exists(loaderSource)) {
@@ -324,6 +330,16 @@ public class Setup {
throw new SetupException($"Missing boot{EfiArch}.efi, {EfiArch} is not supported!");
}
}
var shimSource = Path.Combine("shim-signed", $"shim{EfiArch}.efi");
var mmSource = Path.Combine("shim-signed", $"mm{EfiArch}.efi");
if (!skipShim) {
if (!File.Exists(shimSource)) {
throw new SetupException($"Missing shim ({shimSource}), can't install shim for {EfiArch}!");
}
if (!File.Exists(mmSource)) {
throw new SetupException($"Missing MokManager ({mmSource}), can't install shim for {EfiArch}!");
}
}
try {
if (!Directory.Exists(InstallPath)) {
Directory.CreateDirectory(InstallPath);
@@ -342,14 +358,32 @@ public class Setup {
InstallImageFile(line.Substring(i + delim.Length));
}
}
InstallFile(loaderSource, "loader.efi");
var loaderDest = "loader.efi";
if (!skipShim) {
InstallFile(shimSource, loaderDest);
InstallFile(mmSource, $"mm{EfiArch}.efi");
loaderDest = $"grub{EfiArch}.efi";
}
InstallFile(loaderSource, loaderDest);
if (LoaderIsSigned) {
InstallFile("certificate.cer");
WriteLine($"Notice: Remember to enroll the certificate.cer in your firmware!");
} else {
WriteLine($"Warning: HackBGRT is not signed, you may need to disable Secure Boot!");
}
WriteLine($"HackBGRT has been copied to {InstallPath}.");
var enrollHashPath = $"EFI\\HackBGRT\\{loaderDest}";
var enrollKeyPath = "EFI\\HackBGRT\\certificate.cer";
if (skipShim) {
if (LoaderIsSigned) {
WriteLine($"Remember to enroll {enrollKeyPath} in your firmware!");
} else {
WriteLine("This HackBGRT build is not signed. You may need to disable Secure Boot.");
}
} else {
WriteLine($"On first boot, select 'Enroll hash from disk' and enroll {enrollHashPath}.");
if (LoaderIsSigned) {
WriteLine($"Alternatively, select 'Enroll key from disk' and enroll {enrollKeyPath}.");
}
}
}
/**
@@ -423,7 +457,6 @@ public class Setup {
protected void OverwriteMsLoader() {
var ms = Esp.MsLoaderPath;
var backup = BackupLoaderPath;
var own = Path.Combine(InstallPath, "loader.efi");
if (DetectLoader(ms) == BootLoaderType.Microsoft) {
InstallFile(ms, backup, false);
@@ -432,8 +465,13 @@ public class Setup {
// Duplicate check, but better to be sure...
throw new SetupException("Missing MS boot loader backup!");
}
var msDir = Path.GetDirectoryName(ms);
var msGrub = Path.Combine(msDir, $"grub{EfiArch}.efi");
var msMm = Path.Combine(msDir, $"mm{EfiArch}.efi");
try {
InstallFile(own, ms, false);
InstallFile(Path.Combine(InstallPath, "loader.efi"), ms, false);
InstallFile(Path.Combine(InstallPath, $"grub{EfiArch}.efi"), msGrub, false);
InstallFile(Path.Combine(InstallPath, $"mm{EfiArch}.efi"), msMm, false);
} catch (SetupException e) {
WriteLine(e.Message);
if (DetectLoader(ms) != BootLoaderType.Microsoft) {
@@ -452,7 +490,7 @@ public class Setup {
*/
protected void RestoreMsLoader() {
var ms = Esp.MsLoaderPath;
if (DetectLoader(ms) == BootLoaderType.Own) {
if (DetectLoader(ms) == BootLoaderType.Own || DetectLoader(ms) == BootLoaderType.Shim) {
WriteLine("Disabling an old version of HackBGRT.");
InstallFile(BackupLoaderPath, ms, false);
WriteLine($"{ms} has been restored.");
@@ -827,6 +865,7 @@ public class Setup {
bool allowSecureBoot = false;
bool allowBitLocker = false;
bool allowBadLoader = false;
bool skipShim = false;
Action<Action> verify = (Action revert) => {
try {
VerifyLoaderConfig();
@@ -842,7 +881,9 @@ public class Setup {
}
};
Action<Action, Action> enable = (Action enable, Action revert) => {
HandleSecureBoot(allowSecureBoot);
if (skipShim) {
HandleSecureBoot(allowSecureBoot);
}
HandleBitLocker(allowBitLocker);
enable();
verify(revert);
@@ -850,13 +891,15 @@ public class Setup {
foreach (var arg in actions) {
Log($"Running action '{arg}'.");
if (arg == "install") {
InstallFiles();
InstallFiles(skipShim);
} else if (arg == "allow-secure-boot") {
allowSecureBoot = true;
} else if (arg == "allow-bitlocker") {
allowBitLocker = true;
} else if (arg == "allow-bad-loader") {
allowBadLoader = true;
} else if (arg == "skip-shim") {
skipShim = true;
} else if (arg == "enable-entry") {
enable(() => EnableEntry(), () => DisableEntry());
} else if (arg == "disable-entry") {