|Summary:||Using own certificates/keys with SecureBoot isn't documented enough|
|Product:||[Fedora] Fedora Documentation||Reporter:||Bruno Cornec <bruno.cornec>|
|Component:||uefi-secure-boot-guide||Assignee:||Peter Jones <pjones>|
|Status:||CLOSED EOL||QA Contact:||Fedora Docs QA <docs-qa>|
|Fixed In Version:||Doc Type:||Bug Fix|
|Doc Text:||Story Points:||---|
|Last Closed:||2019-11-07 15:29:59 UTC||Type:||Bug|
|oVirt Team:||---||RHEL 7.3 requirements from Atomic Host:|
|Cloudforms Team:||---||Target Upstream Version:|
Description Bruno Cornec 2013-09-20 20:45:33 UTC
Description of problem: http://docs.fedoraproject.org/en-US/Fedora/18/html-single/UEFI_Secure_Boot_Guide/index.html#chap-UEFI_Secure_Boot_Guide-Implementation_of_UEFI_Secure_Boot doesn't have descriptions for the chapter 5 which is very useful if you want to use your own keys/certificates. Using what is at http://en.opensuse.org/openSUSE:UEFI could serve as an example.
Comment 1 Eric Christensen 2013-10-01 15:29:34 UTC
Peter, can you can help out here. I suspect you're the only person with enough knowledge to start documenting this.
Comment 2 nicolasoliver03 2019-10-18 22:06:10 UTC
I have some documentation in this area that could serve as a base to solve this (posted in markdown format below). I have tested them in Fedora 30 and 31 (regularly). This snippet documents how to sign a custom kernel with a Machine Owner Key for Secure Boot. ## Secure Boot with custom Linux Kernels In the case that a custom Linux Kernel is used, it is possible to use the Machine Owner Keys (MOK) infrastructure to save a public key to verify a custom Linux Kernel signed with the associated private key. ### MOK Key Generation To start, create an OpenSSL configuration file as follow. Replace the `countryName`, `stateOrProvinceName`, `localityName`, and `0.organizationName` with the correct values, if needed: **NOTE:** There is a 64 character limit for each of the following string values. ```sh cat > openssl.cnf << EOF [ req ] distinguished_name = req_distinguished_name x509_extensions = v3 string_mask = utf8only prompt = no [ req_distinguished_name ] countryName = Country stateOrProvinceName = Province localityName = City 0.organizationName = Organization commonName = Secure Boot Signing emailAddress = firstname.lastname@example.org [ v3 ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical,CA:FALSE extendedKeyUsage = codeSigning,18.104.22.168.4.1.322.214.171.124 nsComment = "OpenSSL Generated Certificate" EOF ``` Create a private key and the associated public key in DER format: ```sh openssl req -config ./openssl.cnf \ -new -x509 -newkey rsa:2048 \ -nodes -days 3650 -outform DER \ -keyout MOK.key \ -out MOK.der ``` Additionally, generate the same associated public key in PEM format. DER format will be used to save the certificate in the MOK infrastructure, and the PEM format will be used to sign the custom Linux Kernel. ```sh openssl x509 -in MOK.der -inform DER -outform PEM -out MOK.pem ``` ### Signing custom Linux Kernel You'll need to have the `pesign` and `sbsigntools` utilities: $if(Fedora)$ ```sh sudo dnf install pesign sudo dnf install sbsigntools ``` $endif$ In the case that the Linux Kernel to be signed contains additional unwanted signatures, use the `pesign` utility to remove them. Repeat this for each signature slot. To list the current signatures in the kernel (`vmlinuz` is used as an example Linux Kernel): ```sh sbverify --list vmlinuz ``` To remove a signature from a slot: ```sh pesign --remove-signature \ --in vmlinuz --out vmlinuz-unsigned \ --signature-number 0 --force ``` Then, we can sign the kernel with our private key generated previously: ```sh sbsign --key MOK.key --cert MOK.pem \ --output vmlinuz-signed vmlinuz-unsigned ``` Install the custom signed Linux Kernel following the distribution recommendations. ### Enrolling Signing Key into MOK Finally, we need to load the public key in DER format into the MOK infrastructure. A password needs to be added, that will be used once the system is rebooted to complete the MOK enrollment: ```sh sudo mokutil --import MOK.der ``` Check the enrollment state: ```sh sudo mokutil --list-new ``` Finally, reboot the system. The first stage bootloader will detect the new key being added, and request the password to complete the enrollment. Once this is done the custom signed Linux Kernel will be validated by the first stage boot loader on every boot. And this snippet explain how to create Custom PK, KEK, DB, and DBX for Secure Boot, how to use them to sign a kernel, and enroll them in the BIOS ## Secure Boot with Custom Keys In the case that Standard Key usage is not desired, it is possible to generate custom PK, KEK, and DB artifacts to be used in the Secure Boot flow. Those artifacts will be then installed into the system using the BIOS Settings. ### Key Generation Generate Platform Key: ```sh openssl req -new -x509 -newkey rsa:2048 -subj "/CN=PK_Key/" \ -keyout Private_PK_Key.key -out Public_PK_Cert.crt \ -days 3650 -nodes -sha384 ``` Generate Key Exchange Key: ```sh openssl req -new -x509 -newkey rsa:2048 -subj "/CN=KEK_Key/" \ -keyout Private_KEK_Key.key -out Public_KEK_Cert.crt \ -days 3650 -nodes -sha384 ``` Generate DB Key: ```sh openssl req -new -x509 -newkey rsa:2048 -subj "/CN=DB_Key/" \ -keyout Private_DB_Key.key -out Public_DB_Cert.crt \ -days 3650 -nodes -sha384 ``` Convert all public parts in DER format ```sh openssl x509 -in Public_PK_Cert.crt -out Public_PK_Cert.der -outform DER openssl x509 -in Public_KEK_Cert.crt -out Public_KEK_Cert.der -outform DER openssl x509 -in Public_DB_Cert.crt -out Public_DB_Cert.der -outform DER ``` The public parts in DER format need to be saved into a USB drive (FAT) to be loaded into the BIOS later. ### Signing EFI binaries with custom keys The artifacts to be signed are: 1. First Stage bootloader (Shim) 2. Second Stage bootloader (Grub 2) 3. Linux Kernel In this example, we use `shimx64.efi`, `grubx64.efi` and `vmlinuz` as example artifacts to be signed. In the case that the artifacts to be signed contains additional unwanted signatures, use the `pesign` utility to remove them. Repeat this for each signature slot. To list the current signatures: ```sh sbverify --list shimx64.efi sbverify --list grubx64.efi sbverify --list vmlinuz ``` To remove a signature from a slot: ```sh pesign --remove-signature --in shimx64.efi \ --out shimx64-unsigned.efi --signature-number 0 \ --force pesign --remove-signature --in grubx64.efi \ --out grubx64-unsigned.efi --signature-number 0 \ --force pesign --remove-signature --in vmlinuz \ --out vmlinuz-unsigned --signature-number 0 \ --force ``` Now, sign the artifacts with the previously generated DB private key: ```sh sbsign --key Private_DB_Key.key \ --cert Public_DB_Cert.crt \ --output shimx64-signed.efi \ shimx64-unsigned.efi sbsign --key Private_DB_Key.key \ --cert Public_DB_Cert.crt \ --output grubx64-signed.efi \ grubx64-unsigned.efi sbsign --key Private_DB_Key.key \ --cert Public_DB_Cert.crt \ --output vmlinuz-signed \ vmlinuz-unsigned ``` Finally, install the signed first stage bootloader, second stage bootloader, and Linux Kernel following the recommended procedure by the Linux Distribution. ### Enabling Custom Keys in the BIOS Restart your system and access the BIOS Configuration. Navigate to the `Security` -> `Secure Boot` screen. Set the Secure Boot mode to `Custom` and open the `Key Management` page. Set the `Default Key Provision` to `Disabled`. Finally, install the new Platform, Key Exchange, and DB keys using each of the corresponding options. **NOTE:** While platform key can only be replaced in the set of keys, the Key Exchange and DB keys can be added to the system. Use the `Append` option to install new keys while keeping the original ones, so you can secure boot to both the new custom kernel and the original ones. I have no instructions on how to sign kernel modules, but this could be taken from the comments of this bug https://bugzilla.redhat.com/show_bug.cgi?id=1615744 Could you please review this instructions?
Comment 3 Petr Bokoc 2019-11-07 15:29:59 UTC
I'm closing this bug as part of a Bugzilla cleanup effort. The most likely reason is that the bug has been opened either against a component we no longer publish, or against Release Notes for an EOL release.
Comment 4 nicolasoliver03 2019-11-07 19:10:50 UTC
Hello, This is still current. The Fedora documentation of secure boot is incomplete and dated (the current one is a draft for Fedora 18) There are some instructions on how to sign kernel modules, but it is also inaccurate per https://bugzilla.redhat.com/show_bug.cgi?id=1615744 Public information found by web search usually recommends nuking PK,KEK,DB,DBX and creating your owns, which is something extreme if the only thing you want to do is to boot a custom kernel. (e.g. http://kroah.com/log/blog/2013/09/02/booting-a-self-signed-linux-kernel/ from 2013). This also invalidates any existing signed kernel and makes you have to sign them with your custom keys. It is not explained how to append a KEK and DB. It is also not clear how kernel modules reacts to secure boot, given that the functionality to force modules to be signed in secure boot mode comes and goes (https://bugzilla.redhat.com/show_bug.cgi?id=1696671)