Skip to content

Instantly share code, notes, and snippets.

@heri16
Last active July 15, 2024 14:03
Show Gist options
  • Save heri16/6df9ae37ae51496fe376debaca45540b to your computer and use it in GitHub Desktop.
Save heri16/6df9ae37ae51496fe376debaca45540b to your computer and use it in GitHub Desktop.
Enable Linux Secure Boot with TPM 2.0 (Manjaro / Archlinux) - rEFInd
--- /usr/share/libalpm/hooks/90-mkinitcpio-install.hook 2020-03-05 12:45:41.000000000 +0800
+++ /etc/pacman.d/hooks/90-mkinitcpio-install.hook 2020-06-13 23:08:32.861202141 +0800
@@ -8,5 +8,7 @@
[Action]
Description = Updating linux initcpios...
When = PostTransaction
-Exec = /usr/share/libalpm/scripts/mkinitcpio-install
+Exec = /usr/local/share/libalpm/scripts/mkinitcpio-install
+Depends = sbsigntools
+Depends = x11-ssh-askpass
NeedsTargets

Required

Hardware

  • TPM module installed in the motherboard (that is set to TPM 2.0 mode from the BIOS).

Packages

  • refind
  • sbsigntools
  • shim-signed
  • tpm2-tss-engine
  • tpm2-tools (optional)

Archlinux / Manjaro: pamac update --download-only --aur && pamac install refind sbsigntools shim-signed tpm2-tss-engine

Usage

sudo -i

# Patch refind-install script
curl -o- https://gist.githubusercontent.com/heri16/6df9ae37ae51496fe376debaca45540b/raw/refind-install.patch | patch /usr/bin/refind-install

# Install reFind EFI Bootloader to ESP partition (encrypted keys without TPM)
# refind-install --shim /usr/share/shim-signed/shimx64.efi --localkeys --encryptkeys --yes

# Install reFind EFI Bootloader to ESP partition (encrypted keys on TPM)
refind-install --shim /usr/share/shim-signed/shimx64.efi --localkeys --encryptkeys --engine tpm2tss --yes
efibootmgr

# Sign Linux kernel
sbsign --engine tpm2tss --key /etc/refind.d/keys/refind_local.key --cert /etc/refind.d/keys/refind_local.crt --output "/boot/vmlinuz-5.6-x86_64" "/boot/vmlinuz-5.6-x86_64"
sbverify --list "/boot/vmlinuz-5.6-x86_64"

# Sign Manjaro's Grub2 EFI Bootloader (optional)
sbsign --engine tpm2tss --key /etc/refind.d/keys/refind_local.key --cert /etc/refind.d/keys/refind_local.crt --output "/boot/efi/EFI/manjaro/grubx64.efi" "/boot/efi/EFI/manjaro/grubx64.efi"
sbverify --list "/boot/efi/EFI/manjaro/grubx64.efi"

# Reboot into BIOS

Then, reboot into BIOS to enable SecureBoot.

Once in MokManager add refind_local.cer to MoKList. refind_local.cer can be found inside a directory called keys in the rEFInd's installation directory, e.g. esp/EFI/refind/keys/refind_local.cer.

Misc

Enable pacman hook

Make pacman sign the kernel automatically on kernel updates.

sudo -i
pamac install x11-ssh-askpass
curl -o- https://gist.githubusercontent.com/heri16/6df9ae37ae51496fe376debaca45540b/raw/90-mkinitcpio-install.hook.patch | patch -o "/etc/pacman.d/hooks/90-mkinitcpio-install.hook" /usr/share/libalpm/hooks/90-mkinitcpio-install.hook
curl -o- https://gist.githubusercontent.com/heri16/6df9ae37ae51496fe376debaca45540b/raw/mkinitcpio-install.patch | patch -o "/usr/local/share/libalpm/scripts/mkinitcpio-install" /usr/share/libalpm/scripts/mkinitcpio-install

Useful Info

--- /usr/share/libalpm/scripts/mkinitcpio-install 2020-03-05 12:45:41.000000000 +0800
+++ /usr/local/share/libalpm/scripts/mkinitcpio-install 2020-06-20 06:09:53.900484682 +0800
@@ -39,8 +39,20 @@
fi
fi
- # always install the kernel
- install -Dm644 "${line}" "/boot/vmlinuz-${kernelbase}"
+ if [[ $DISPLAY ]]; then
+ # always sign & install the kernel for SecureBoot
+ KeyPassphrase=$(/usr/lib/ssh/ssh-askpass "Please enter your SecureBoot Key passphrase:")
+ SbSignCommand=$(printf "%q " /usr/bin/sbsign --engine tpm2tss --key /etc/refind.d/keys/refind_local.key --cert /etc/refind.d/keys/refind_local.crt --output "/boot/vmlinuz-${kernelbase}" "${line}")
+ echo "$KeyPassphrase" |
+ script -qefc "$SbSignCommand" --force /dev/null 2>&1 | ( \
+ head -n 2 >/dev/null # Skip the first two lines (incl. passphrase).
+ grep -v "data remaining.*gaps between PE/COFF sections"
+ )
+ /usr/bin/sbverify --list "/boot/vmlinuz-${kernelbase}"
+ else
+ # always install the kernel
+ install -Dm644 "${line}" "/boot/vmlinuz-${kernelbase}"
+ fi
# compound args for each kernel
args+=(-p "${pkgbase}")
#!/bin/sh
VERSION=5.7
cd /boot/efi/EFI/Linux
cat /boot/amd-ucode.img /boot/initramfs-${VERSION}-x86_64.img > initrd.img
objcopy \
--add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \
--add-section .cmdline="kernel-command-line.txt" --change-section-vma .cmdline=0x30000 \
--add-section .splash="/usr/share/systemd/bootctl/splash-manjaro.bmp" --change-section-vma .splash=0x40000 \
--add-section .linux="/boot/vmlinuz-${VERSION}-x86_64" --change-section-vma .linux=0x2000000 \
--add-section .initrd="initrd.img" --change-section-vma .initrd=0x3000000 \
"/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "linux${VERSION//.}.efi"
sbsign --engine tpm2tss --key /etc/refind.d/keys/refind_local.key --cert /etc/refind.d/keys/refind_local.crt --output "linux${VERSION//.}.efi" "linux${VERSION//.}.efi"
sbverify --list "linux${VERSION//.}.efi"
rm initrd.img
--- /usr/bin/refind-install 2020-04-23 14:10:32.000000000 +0800
+++ ./refind-install 2020-06-12 13:48:27.371630998 +0800
@@ -23,6 +23,7 @@
# only under Linux.
# "--preloader" is synonymous with "--shim". Valid only under Linux.
# "--encryptkeys" password-protects the Secure Boot private key.
+# "--engine" engine that protects the Secure Boot private key.
# "--localkeys" to re-sign x86-64 binaries with a locally-generated key.
# Valid only under Linux.
# "--keepname" to keep refind_x64.efi name as such even when using shim.
@@ -156,6 +157,9 @@
;;
--encryptkeys) EncryptKeys=1
;;
+ --engine) Engine="$2"
+ shift
+ ;;
--shim | --preloader) ShimSource="$2"
ShimType=`basename $ShimSource`
shift
@@ -171,7 +175,7 @@
* ) echo "Usage: $0 [--notesp | --usedefault {device-file} | --root {dir} |"
echo " --ownhfs {device-file} ] [--keepname]"
echo " [--nodrivers | --alldrivers] [--shim {shimfile}]"
- echo " [--localkeys [--encryptkeys]] [--keepname] [--yes]"
+ echo " [--localkeys [--encryptkeys] [--engine {engine}]] [--keepname] [--yes]"
exit 1
esac
shift
@@ -216,6 +220,10 @@
echo "The --encryptkeys option requires the use of --localkeys! Aborting!"
exit 1
fi
+ if [[ $Engine && "$LocalKeys" == 0 ]] ; then
+ echo "The --engine option requires the use of --localkeys! Aborting!"
+ exit 1
+ fi
RLConfFile="$RootDir/boot/refind_linux.conf"
EtcKeysDir="$RootDir/etc/refind.d/keys"
} # GetParams()
@@ -1079,12 +1087,44 @@
cp -f "$DerKey" "$DerKey.backup" 2> /dev/null
fi
if [[ $EncryptKeys == 1 ]]; then
+ ReadKeyPassphrase
KeyEncryptionArgument=""
else
KeyEncryptionArgument="-nodes"
fi
- "$OpenSSL" req -new -x509 -newkey rsa:2048 -keyout "$PrivateKey" -out "$CertKey" \
+ if [[ ! $Engine ]]; then
+ if [[ $EncryptKeys == 1 ]]; then
+ echo "$KeyPassphrase" |
+ "$OpenSSL" req -new -x509 -newkey rsa:2048 -keyout "$PrivateKey" -out "$CertKey" \
+ $KeyEncryptionArgument -days 3650 -subj "/CN=Locally-generated rEFInd key/" -passout stdin
+ echo -e "$KeyPassphrase\n$KeyPassphrase" |
+ "$OpenSSL" pkcs8 -topk8 -iter 1000000 -in "$PrivateKey" -out "${PrivateKey}~" -passin stdin -passout stdin
+ mv "${PrivateKey}~" "$PrivateKey"
+ else
+ "$OpenSSL" req -new -x509 -newkey rsa:2048 -keyout "$PrivateKey" -out "$CertKey" \
$KeyEncryptionArgument -days 3650 -subj "/CN=Locally-generated rEFInd key/"
+ fi
+ else
+ EngineName=$("$OpenSSL" engine "$Engine" | cut -d ' ' -f 2)
+ if [[ "$Engine" == "tpm2tss" ]]; then
+ if [[ $EncryptKeys == 1 ]]; then
+ tpm2tss-genkey -a rsa -p "$KeyPassphrase" "$PrivateKey"
+ else
+ tpm2tss-genkey -a rsa "$PrivateKey"
+ fi
+ KeyReqArguments=(-engine "$Engine" -keyform engine -key "$PrivateKey")
+ else
+ KeyReqArguments=(-keygen_engine "$Engine" -newkey rsa:2048 -keyout "$PrivateKey")
+ fi
+ if [[ $EncryptKeys == 1 ]]; then
+ echo "$KeyPassphrase" |
+ "$OpenSSL" req -new -x509 ${KeyReqArguments[@]} -out "$CertKey" \
+ $KeyEncryptionArgument -days 3650 -subj "/CN=${EngineName}-generated rEFInd key/" -passin stdin
+ else
+ "$OpenSSL" req -new -x509 ${KeyReqArguments[@]} -out "$CertKey" \
+ $KeyEncryptionArgument -days 3650 -subj "/CN=${EngineName}-generated rEFInd key/"
+ fi
+ fi
"$OpenSSL" x509 -in "$CertKey" -out "$DerKey" -outform DER
chmod 0600 "$PrivateKey"
else
@@ -1100,16 +1140,25 @@
SignOneBinary() {
ReadKeyPassphrase --no-confirm
if [[ "$EncryptKeys" == 1 ]] ; then
- SbSignCommand=$(printf "%q " "$SBSign" --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1")
+ if [[ ! $Engine ]]; then
+ SbSignCommand=$(printf "%q " "$SBSign" --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1")
+ else
+ SbSignCommand=$(printf "%q " "$SBSign" --engine "$Engine" --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1")
+ fi
echo "$KeyPassphrase" |
script -qefc "$SbSignCommand" --force /dev/null 2>&1 | ( \
head -n 2 >/dev/null # Skip the first two lines (incl. passphrase).
grep -v "data remaining.*gaps between PE/COFF sections"
)
- local status="${PIPESTATUS[1]}"
+ local status="${PIPESTATUS[1]}"
else
- "$SBSign" --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1" 2>&1 >/dev/null | \
+ if [[ ! $Engine ]]; then
+ "$SBSign" --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1" 2>&1 >/dev/null | \
+ grep -v "data remaining.*gaps between PE/COFF sections"
+ else
+ "$SBSign" --engine "$Engine" --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1" 2>&1 >/dev/null | \
grep -v "data remaining.*gaps between PE/COFF sections"
+ fi
local status="${PIPESTATUS[0]}"
fi
if [[ "$status" != 0 ]] ; then
@heri16
Copy link
Author

heri16 commented Jun 11, 2020

Required

Hardware

  • TPM module installed in the motherboard (that is set to TPM 2.0 mode from the BIOS).

Packages

  • refind
  • sbsigntools
  • shim-signed
  • tpm2-tss-engine
  • tpm2-tools (optional)

Archlinux / Manjaro: pamac update --download-only --aur && pamac install refind sbsigntools shim-signed tpm2-tss-engine

Usage

sudo -i

# Patch refind-install script
curl -o- https://gist.githubusercontent.com/heri16/6df9ae37ae51496fe376debaca45540b/raw/refind-install.patch | patch /usr/bin/refind-install

# Install reFind EFI Bootloader to ESP partition (encrypted keys without TPM)
# refind-install --shim /usr/share/shim-signed/shimx64.efi --localkeys --encryptkeys --yes

# Install reFind EFI Bootloader to ESP partition (encrypted keys on TPM)
refind-install --shim /usr/share/shim-signed/shimx64.efi --localkeys --encryptkeys --engine tpm2tss --yes
efibootmgr

# Sign Linux kernel
sbsign --engine tpm2tss --key /etc/refind.d/keys/refind_local.key --cert /etc/refind.d/keys/refind_local.crt --output "/boot/vmlinuz-5.6-x86_64" "/boot/vmlinuz-5.6-x86_64"
sbverify --list "/boot/vmlinuz-5.6-x86_64"

# Sign Manjaro's Grub2 EFI Bootloader (optional)
sbsign --engine tpm2tss --key /etc/refind.d/keys/refind_local.key --cert /etc/refind.d/keys/refind_local.crt --output "/boot/efi/EFI/manjaro/grubx64.efi" "/boot/efi/EFI/manjaro/grubx64.efi"
sbverify --list "/boot/efi/EFI/manjaro/grubx64.efi"

# Reboot into BIOS

Then, reboot into BIOS to enable SecureBoot.

Once in MokManager add refind_local.cer to MoKList. refind_local.cer can be found inside a directory called keys in the rEFInd's installation directory, e.g. esp/EFI/refind/keys/refind_local.cer.

Misc

Enable pacman hook

Make pacman sign the kernel automatically on kernel updates.

sudo -i
pamac install x11-ssh-askpass
curl -o- https://gist.githubusercontent.com/heri16/6df9ae37ae51496fe376debaca45540b/raw/90-mkinitcpio-install.hook.patch | patch -o "/etc/pacman.d/hooks/90-mkinitcpio-install.hook" /usr/share/libalpm/hooks/90-mkinitcpio-install.hook
curl -o- https://gist.githubusercontent.com/heri16/6df9ae37ae51496fe376debaca45540b/raw/mkinitcpio-install.patch | patch -o "/usr/local/share/libalpm/scripts/mkinitcpio-install" /usr/share/libalpm/scripts/mkinitcpio-install

Useful Info

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment