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 0000000000..cdada57e98 Binary files /dev/null and b/data/boot/efi/keys/DB.auth differ diff --git a/data/boot/efi/keys/DB.cer b/data/boot/efi/keys/DB.cer new file mode 100644 index 0000000000..d5be96083f Binary files /dev/null and b/data/boot/efi/keys/DB.cer differ 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