From 31f27c4d39887e0ef393db27279b8c154ccb1e4b Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Sun, 6 Feb 2022 16:24:02 -0600 Subject: [PATCH] boot/efi: Optionally sign our EFI bootloader * The private keys are in possession of Haiku, Inc. Change-Id: I3b5b004e1dce0102f8a65f6d682f7e428845efe8 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4936 Reviewed-by: Alex von Gluck IV Reviewed-by: waddlesplash --- build/jam/ImageRules | 11 ++++++++ configure | 7 +++++ data/boot/efi/keys/DB.auth | Bin 0 -> 2059 bytes data/boot/efi/keys/DB.cer | Bin 0 -> 791 bytes data/boot/efi/keys/DB.crt | 19 ++++++++++++++ data/boot/efi/keys/README.md | 37 +++++++++++++++++++++++++++ src/system/boot/Jamfile | 48 ++++++++++++++++++++++++++++++++++- 7 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 data/boot/efi/keys/DB.auth create mode 100644 data/boot/efi/keys/DB.cer create mode 100644 data/boot/efi/keys/DB.crt create mode 100644 data/boot/efi/keys/README.md diff --git a/build/jam/ImageRules b/build/jam/ImageRules index 8142be43d0..65c6f07b8b 100644 --- a/build/jam/ImageRules +++ b/build/jam/ImageRules @@ -1701,6 +1701,9 @@ rule BuildEfiSystemPartition image : efiLoader Exit "Error: Unknown EFI architecture!" ; } + # public efi keys for efi bios trust + EFIKEYS on $(image) = [ FDirName $(HAIKU_TOP) data boot efi keys ] ; + BuildEfiSystemPartition1 $(image) : $(fatshell) $(macVolumeIcon) $(efiLoader) ; } @@ -1720,7 +1723,15 @@ actions BuildEfiSystemPartition1 ${FATFS} --initialize "$(<)" 'Haiku ESP' echo "mkdir myfs/EFI" | ${FATFS} $(<) + echo "mkdir myfs/KEYS" | ${FATFS} $(<) echo "mkdir myfs/EFI/BOOT" | ${FATFS} $(<) + echo "cp :${LOADER} myfs/EFI/BOOT/$(EFINAME)" | ${FATFS} $(<) echo "cp :${EFIICON} myfs/.VolumeIcon.icns" | ${FATFS} $(<) + + # Copy UEFI signing keys and a README for end users + echo "cp :$(EFIKEYS)/README.md myfs/KEYS/README.md" | ${FATFS} $(<) + for i in auth cer crt; do + echo "cp :$(EFIKEYS)/DB.$i myfs/KEYS/DB.$i" | ${FATFS} $(<) + done } diff --git a/configure b/configure index c72fad1154..53c84d1cbe 100755 --- a/configure +++ b/configure @@ -93,6 +93,7 @@ options: specify the path to a GDB source dir, to build GDB for each arch we build the cross-tools for. --use-stack-protector Build with stack protection enabled + --efi-signing-key Private keyfile to sign any EFI bootloaders environment variables: CC The host compiler. Defaults to "gcc". @@ -804,6 +805,11 @@ while [ $# -gt 0 ] ; do --no-xattr) HAIKU_HOST_USE_XATTR_REF=0; shift 1;; --with-gdb) gdbSources=$2; shift 2;; --use-stack-protector) HAIKU_USE_STACK_PROTECTOR=1; shift 1;; + --efi-signing-key) + assertparam "$1" $# + HAIKU_EFI_SIGNING_KEY="$2" + shift 2 + ;; *) echo Invalid argument: \`$1\'; exit 1;; esac done @@ -1112,6 +1118,7 @@ HAIKU_PORTS ?= ${HAIKU_PORTS} ; HAIKU_PORTS_CROSS ?= ${HAIKU_PORTS_CROSS} ; HAIKU_IS_BOOTSTRAP ?= ${HAIKU_IS_BOOTSTRAP} ; +HAIKU_BOOT_EFI_PRIVATE_KEYFILE ?= ${HAIKU_EFI_SIGNING_KEY} ; EOF for targetArch in $HAIKU_PACKAGING_ARCHS; do diff --git a/data/boot/efi/keys/DB.auth b/data/boot/efi/keys/DB.auth new file mode 100644 index 0000000000000000000000000000000000000000..cdada57e988942f35b9e022ca3962b4cc1d32d46 GIT binary patch literal 2059 zcmaFH&cwzq%+3G?aOpJ_%{06*ioC$3n zjH%2lOpL4y2Hb3%T5TR}-+39?85cA$iyJgC3mY^s{$9Y$#K^=X68~!7?eou)CJ*`+!Po_Wc73NB6ta^k#3Mg~R( zW`>rgh9<^Q;=CrvTzp!a7?nV7g;@l2D{~VgKLgNhTue=jj0`J(dvD3dW%F-d&E(xt?(DJB z`WnkZ6Ro>PuT=7JbjlqSH-0KO@lu$|qB{}unj0s}St_RF9@i;j6M9n5e$wIllO4Oh zF?GhPZ~q+1y-H`UgOj#q-DMAMy^a7WXE)xd$5QUdDAeapJAXi4Tf^knOXd4a%!~|- zi-QdU4P=2~FU!Xw#v*b4ct4U9vHUFyW;j-qo?gla$RD)(DQda z8Z#}Uo|jGg7uq-NiO+kf*Lru#CuN-3(0|6Ti7^J4^df+H$iNU!vc;WakTV@>x@Ku& zWLUcX{PSoZPAzuv|7ogzGvBG^oBZ>tYberOU>X?!<^y@_LPEKm3M5~t6corS zCUX^E-Mf69q-o;B0;Vc&!v&uVHO(9yw{~vdH1*(*ovAsmExf<|b`qZPZ075$u3=Yx zs-_#huL+ku-1@v)rTgL13b|LF4F)GXr<-q`Ry*q)=gR*-gwDFZblF&6_B`lj$GR*n1_vvQ-E4S^lB@4|AgDx(y z6AKShM{>_@9xieTe`PEW}n=!UxlK&^1a{ckDRavHV(_bset?%}i z-d_Bontx{2`f~*fBM&TnGG)0}`_|Q>G1?!BoS7jdnmUlaAu!*it^JMQ4g;1eM?9tl Sj22O&MHEsF8ZDwAMHB!)G&ckQ literal 0 HcmV?d00001 diff --git a/data/boot/efi/keys/DB.cer b/data/boot/efi/keys/DB.cer new file mode 100644 index 0000000000000000000000000000000000000000..d5be96083fa24b97f459ca221f1d7c5cc1906b38 GIT binary patch literal 791 zcmXqLViq=NV*I^;nTe5!NhJQ&zT4-YFF$1;#u|2^Vua>1IjUMiO{_U1f1wX*Am-XZt4?e&WDC;J?k^>f0v z^0#xnIREvwD0f%(g;m|YExydHzfQrT>Hc<>5Y9g9=t^Pdv=e7n&(125eX=lT+nwfj ze`d|lxtDPHY}%_w^RBvv7xoyLcJD3uxNQE-tC_qz%AGw{T3=&XXrguZ=#@%7j!wCw z;>J$}CteCuS#&32UUTDQIZMTq+~YcBY(h`!*-turf3joOH>S>b_3fWSxmW4Tb#T(w zth?;Nt=ADC}B~_#8^ab zNX_X#s<1N8HNfu6w$~;Gl3qrR2J#?jWflnou?Fl4_(2MU85#exuo^G}Ddb=W#xF3~ zfi`V^w>*TUI_17oDtocr`DN9gF3F$IxABahSLM8KUHl%g{+?e;8ehCR*B=@as3_35 z>FBDa;%{OrgjEe={ww?~?L9v8Z{y}`sf-`?u5~cKeEe|dijvrH9tBbJ!1ATMQQK`# z{ro&L(r;yj%?bynj$3CAY`HUMVcf^3sz>eBKAq4rvQgdMWu^D+Oc?)(^8%`NFGU`H zuX0^>>EEBlM+-JDdZyuY;(+EV2VI;`SQ; zpG>9p-Rg5Uh%rtpv$%Nc#skBac~{(?YxJ~zNv=zb7kd7#M`NaC)bp}w|3dqwJ@I)j Q^;+*v`J{|98~V=x0H}mNn*aa+ literal 0 HcmV?d00001 diff --git a/data/boot/efi/keys/DB.crt b/data/boot/efi/keys/DB.crt new file mode 100644 index 0000000000..f84976afd6 --- /dev/null +++ b/data/boot/efi/keys/DB.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAfugAwIBAgIUX+q+28/np8o/Vg64GrIN8CEcEA8wDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOSGFpa3UsIEluYy4gREIwHhcNMjIwMjA2MTk1MTQzWhcN +NDIwMjA2MTk1MTQzWjAZMRcwFQYDVQQDDA5IYWlrdSwgSW5jLiBEQjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKn6b6J60zU5L+UPXhHbJ2epyoQ+YKAo +6L7gmk79nBFOqidX10wfBFijZxdPvBeGHlMpmukjdgGNbOHKqYrYLsJHhrd/IZ+T +TMSa+ZD2d+2dSgn+jYQji3mOVnrb2xemRo9+IDiC37cEVAmOO1t5E0NmyM2rm2p0 +HeShbLbcg+78mpgs3mDTzWbq4p7VRVdxjDI1i7108aaf2dVpDbh3Q0ipO9YEoTQq +3cXUeQ4IiR7FFzPlEZHSViSi3Fieg4GTHjkhZG3HLHYGEuR/B8lA9+S4uvYCiV8n +t/NVC6osnUBCKyl+00gLLohQGkNGDZXGZNwcIH9tls/AHysoNPrpI98CAwEAAaNT +MFEwHQYDVR0OBBYEFNganI/FIKluRVA+9LbrNDAZSjJBMB8GA1UdIwQYMBaAFNga +nI/FIKluRVA+9LbrNDAZSjJBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAAGz7qdUBHtk30JlB3M+z6Z78tIfz288SV+eekO+rl+8Fo+M+qSB6OrO +j1VcUSEQgbLFqoJz9haoEyUxXP8g/XWNx5n9gbPWZQHwva1AN9PHw4modF1XDCAV +N1F3pQ1atz3K+fOZWU6peDyoQEKI2szAtNycoV7x5SXFPybyyC4yPCW3ijou9sxW +D8jPECU+6RTh93pFptL+/KPFcLOi5ihCyMApqjNSvOox6m0LFUxCSpBJIk0QBOPQ +PHDAiSkkQaOHfA/5AnU/iyedsBYBlnY40drY4DGEntRG5yiMhvRjfmFfEufujCiZ +OVrndpb+VY6W5EzvGusu3HeSaMywj8w= +-----END CERTIFICATE----- diff --git a/data/boot/efi/keys/README.md b/data/boot/efi/keys/README.md new file mode 100644 index 0000000000..f7c599cb4f --- /dev/null +++ b/data/boot/efi/keys/README.md @@ -0,0 +1,37 @@ +# Haiku UEFI Keys + +The EFI keys in this directory can be used to boot Haiku in UEFI Secure Mode. +The Haiku, Inc. key must be appended to your EFI BIOS trusted keychain to function. + +> This is only needed when you're booting in EFI Secure Boot mode! It's probably +> easier to disable EFI Secure Boot in most cases. + +## Installing UEFI Keys + +To trust Haiku's EFI bootloader, you'll need to append our DB key to your BIOS's +DB keychain. + +> Ensure the Haiku installation media is inserted / plugged into your computer. + +Real world examples: + +* Dell XPS 13 Laptop (Dell BIOS) + * Boot laptop, press F2 to enter BIOS + * Settings -> Secure Boot -> Secure Boot Enable + * Verify Secure Boot is enabled, otherwise this does nothing. + * Settings -> Secure Boot -> Expert Key Management + * "Enable Custom Mode" checked + * Press "Reset All Keys" + * Choose db, then press "Append from File" + * Navigate to the Haiku USB installation media + * EFI -> KEYS -> DB.auth + +* Framework Laptop (InsydeH20 BIOS) + * Boot laptop, press F2 to enter BIOS + * Security -> Secure Boot + * Enforce Secure Boot enabled + * DB Options -> Enroll Signature -> PKCS7 + * Haiku ESP -> KEYS -> DB.cer + * (you can leave the "Owner_GUID" blank) + * Enroll DB.cer -> Yes + * F10, Save and Exit diff --git a/src/system/boot/Jamfile b/src/system/boot/Jamfile index 663938d16a..a89587598e 100644 --- a/src/system/boot/Jamfile +++ b/src/system/boot/Jamfile @@ -141,6 +141,39 @@ actions BuildEFILoader fi } +# +# Sign our EFI Bootloader if a key has been provided +# SignEFILoader : : : ; +# +rule SignEFILoader +{ + local signedEFILoader = $(1) ; + local unsignedEFILoader = $(2) ; + local publicCert = $(3) ; + local privateKey = $(4) ; + + Depends $(signedEFILoader) : $(unsignedEFILoader) ; + + DB_CERT_FILE on $(signedEFILoader) = $(publicCert) ; + DB_KEY_FILE on $(signedEFILoader) = $(privateKey) ; +} + +actions SignEFILoader +{ + $(RM) -f $(1) + echo "Signing EFI bootloader..." + sbsign --key $(DB_KEY_FILE) --cert $(DB_CERT_FILE) --output $(1) $(2) +} + +# +# Verify our EFI bootloader has been properly signed +# VerifyEFILoader : +# +actions VerifyEFILoader +{ + sbverify --cert $(2) $(1) +} + # # U-boot image creation @@ -352,7 +385,20 @@ for platform in [ MultiBootSubDirSetup ] { switch $(TARGET_BOOT_PLATFORM) { case efi : - BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ; + if $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) { + BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned + : boot_loader_$(TARGET_BOOT_PLATFORM) ; + SignEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM) + : haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned + : [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ] + : $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) ; + VerifyEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM) + : [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ] ; + } else { + BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM) + : boot_loader_$(TARGET_BOOT_PLATFORM) ; + } + if $(TARGET_ARCH) = arm || $(TARGET_ARCH) = riscv64 { # These EFI platforms need u-boot to get them going BuildUImageScript boot.scr