Sakaki's EFI Install Guide/Configuring Secure Boot

From Gentoo Wiki
Jump to: navigation, search


In this section, which has no equivalent in the standard Gentoo handbook, we'll be setting up secure boot on your target machine.

While secure boot has received mixed reviews from the Linux community, it is a useful facility. With it activated, your machine will refuse to boot an executable that has been changed since it was signed (in an 'evil maid attack' for example), thereby closing off an important attack vector.

Windows 10 (and 8)-certified hardware ships with secure boot turned on by default (but only the Windows-sanctioned public keys installed in the machine), which is why, to get things started, we had to turn this feature off in the BIOS earlier in the tutorial. Now, however, we're going to 'take control of the platform' and add our own keys, so that we can use self-signed EFI stub kernels (which our buildkernel utility can create). The original Microsoft keys will be retained as well, so both Windows and our self-signed Gentoo kernels should be able to boot with secure mode on.

Note
Of course, by retaining the Microsoft keys, your kernel binary could technically still be compromised in such an attack by someone with access to the Windows private keys (since they could resign it after making changes). If this bothers you, you can always remove the Windows keys from the machine completely, and fall back to non-secure-boot for Windows operation.

The steps we'll be undertaking are as follows (see below for a brief explanation of the terms used):

  1. We'll begin by saving off the current contents of the PK, KEK, db and dbx variables, as all four will be cleared when we enter setup mode (in step 4).
  2. We will then create three new private / public keypairs, to be used respectively as:
    1. our platform key (this will ultimately be stored in the PK signature database);
    2. our key exchange key (this will ultimately be appended to the KEK signature database); and
    3. our kernel-signing key (this will ultimately be appended to the db signature database).
  3. We'll create a signed signature list for our new PK (more on what this means later).
  4. We will then reboot the machine, and en route use the BIOS GUI to clear the secure variables, thereby entering setup mode.
  5. Then we will re-install our saved values of KEK, db and dbx.
  6. Next, we'll append our own public keys to KEK and db.
  7. Then, we'll set our own key in PK, thereby re-entering user mode. We'll use the signed signature list for this.
  8. We will then run buildkernel, to rebuild our EFI-stub kernel, this time appropriately signed with our new kernel-signing (private) key.
  9. Then we will restart the machine, enable secure boot, and check that our signed kernel is permitted to start up by the BIOS (it should be).
  10. We'll then reboot into Windows, and check that it is also still permitted to start (again, it should be). When in Windows, we'll take the chance to set the clock format to UTC.
  11. Finally, we'll reboot back into our signed kernel, (optionally setting a BIOS password en route) and proceed with the tutorial.
Note
If you are building your target 'PC' as a VirtualBox guest, please be advised that, although VirtualBox does support EFI booting (through the "Enable EFI (special OSes only)" switch on the System/Motherboard configuration tab), it does not currently support emulation of secure boot. If building on VirtualBox rather than a 'real' PC therefore, you can safely skip the setup of this feature.
Note
Users who do not wish to set up secure boot should click here to skip directly to the next relevant section instead ("Verifying Secure Boot with Windows (and Fixing RTC)").

Let's get started!

Introduction

We'll begin with a (very brief) primer on secure boot. (For a more in-depth review, please refer to James Bottomley's article "The Meaning of all the UEFI Keys"[1], Greg Kroah-Hartman's article "Booting a Self-signed Linux Kernel"[2], and of course the UEFI specification itself[3].)

Note
If you're already familiar with secure boot, simply click here to skip directly to the next section.
Note
A brief "meta-primer" on digital signatures may be in order first, since they are central to the operation of secure boot.

To sign a file (for example, an executable EFI-stub kernel), a message digest of that file is first created (a message digest is a cryptographic hash function, which creates a fixed-length summary value from input data of arbitrary size, in a manner that is practically impossible to invert).

Next, this digest is asymmetrically encrypted using a private key known only to the certifier. The resulting ciphertext is a digital signature, which may be appended to the original data to produce a digitally signed file.

To verify the signature, a recipient (or an automated system, such as the UEFI BIOS) splits the target file into the main body and digital signature, produces a digest of the first and compares it with the plaintext produced by decrypting (using a counterpart public key) the second. If the hashes match, the signature is valid (and the recipient can be confident that the payload was not tampered with).

The diagram below illustrates this process:

Applying and Verifying a Digital Signature

The UEFI specification defines four secure, non-volatile variables, which are used to control the secure boot subsystem. They are:

  1. The Platform Key (PK). The PK variable contains a UEFI (small 's', small 'd') 'signature database' which has at most one entry in it. When PK is emptied (which the user can perform via a BIOS GUI action), the system enters setup mode (and secure boot is turned off). In setup mode, any of the four special variables can be updated without authentication checks. However, immediately a valid platform key is written into PK (in practice, this would be an X.509 public key, using a 2048-bit RSA scheme), the system (aka, 'platform') enters user mode. Once in user mode, updates to any of the four variables must be digitally signed with an acceptable key.
    The private key counterpart to the public key stored in PK may be used to sign user-mode updates to PK or KEK, but not db or dbx (nor can it be used to sign executables).
  2. The Key Exchange Key (KEK). This variable holds a signature database containing one (or more) X.509 / 2048-bit RSA public keys (other formats are possible). In user mode, any db/dbx (see below) updates must be signed by the private key counterpart of one of these keys (the PK cannot be used for this).
    While KEK keys (or, more accurately, their private-key counterparts) may also be used to sign executables, it is uncommon to do so, since that's really what db is for (see below).
  3. The (caps 'S', caps 'D') Signature Database (db). As the name suggests, this variable holds a UEFI signature database which may contain (any mixture of) public keys, signatures and plain hashes. In practice, X.509 / RSA-2048 public keys are most common. It functions essentially as a boot executable whitelist (described in more detail shortly).
  4. The Forbidden Signatures Database (dbx). This variable holds a signature database of similar format to db. It functions essentially as a boot executable blacklist.

Now, here's the key point (excuse the pun): when the system is in user mode, and secure boot is enabled, the machine will only boot EFI executables which:

  • are unsigned, but have a hash (message digest) in db and not in dbx; or
  • are signed, where that signature appears in db but not in dbx; or
  • are signed, where that signature is verifiable by a public key in db, or a public key in KEK, and where neither that key, not the signature itself, appears in dbx.
Note
PK is not consulted when attempting to verify executables.

When you buy a new Windows (10 or 8) machine, it will usually be set up as follows:

  • The PK variable will be loaded with a public key issued by the hardware vendor (for example, Panasonic).
  • The KEK variable will be loaded with a public key issued by Microsoft.
  • The db variable will be loaded with a set of public keys issued by various vendors authorized by Microsoft).
  • The dbx variable will generally contain some revoked signatures (although it may also be empty, it depends on the revision of Windows on your machine).

Saving Current Keystore Values, and Creating New Keys

We begin by re-establishing an ssh connection, as before (as it will make the work of entering commands etc. easier). From the helper PC, issue:

user@pc2 $ssh root@192.168.1.106
Password: <enter root password>
... additional output suppressed ...
Note
Substitute whatever IP address you got back from ifconfig earlier for 192.168.1.106 in the above command. It is possible (although unlikely, with modern DHCP) that the target's IP address will have changed during the reboot for plymouth testing. If so, log in directly at the target machine's keyboard, use ifconfig to find out the new address, then issue the above ssh command citing that address. As before, in such a case you may need to clean out any previous record of ssh connections to (other machines at) that new address (since the fingerprints will not match), using:
user@pc2 $sed -i '/^[^[:digit:]]*192.168.1.106[^[:digit:]]/d' ~/.ssh/known_hosts

obviously substituting the new address for 192.168.1.106 in the above. Then, be sure to check the fingerprint when prompted (by the subsequent ssh command), against those you noted down earlier.

Note
If installing over WiFi, and you had to manually restart wpa_supplicant in the previous chapter, then you'll need to do so again here (directly at the target machine's keyboard) before you'll be able to ssh in.

Now proceed as below, using the ssh connection to enter all commands unless otherwise specified (incidentally, there is no need to use screen at this point, since we'll be rebooting again shortly). Issue:

koneko ~ #mkdir -p -v /etc/efikeys
Note
The buildkernel script expects to find its keys in the /etc/efikeys directory, so please don't change the location.

Ensure only the superuser can access this directory, using chmod - issue:

koneko ~ #chmod -v 700 /etc/efikeys
koneko ~ #cd /etc/efikeys

Next, we'll use the efi-readvar tool (from the app-crypt/efitools) to store off the current values of PK, KEK, db and dbx, in machine-readable signature list format. Issue:

koneko efikeys #efi-readvar -v PK -o old_PK.esl
koneko efikeys #efi-readvar -v KEK -o old_KEK.esl
koneko efikeys #efi-readvar -v db -o old_db.esl
koneko efikeys #efi-readvar -v dbx -o old_dbx.esl
Note
If you omit the -o option, the variables will be dumped as text, and you won't be able to reload them, so take care!
Note
If you have problems with the efi-readvar command, make sure that you have symbolically linked /etc/mtab to /proc/self/mounts, as described earlier in the tutorial, because efi-readvar has a problem similar to that described in bug #434090. If you haven't got this symbolic link in place, you should do it now, restart, reconnect ssh, and then rejoin the tutorial from this point, trying the above commands again.

Now we can create a new platform keypair, key-exchange keypair and kernel-signing keypair. We'll use openssl to do this. The requested keys will:

  • use X.509 certificate format for the public key (this allows various additional data fields to be passed with the key if desired, for subsequent identification);
  • utilise the RSA asymmetric cryptosystem, with a 2048 bit key length;
  • have 10 years (3650 days) to run until expiry;
  • use SHA-256 as the public key's message digest.

Issue:

koneko efikeys #openssl req -new -x509 -newkey rsa:2048 -subj "/CN=sakaki's platform key/" -keyout PK.key -out PK.crt -days 3650 -nodes -sha256
koneko efikeys #openssl req -new -x509 -newkey rsa:2048 -subj "/CN=sakaki's key-exchange-key/" -keyout KEK.key -out KEK.crt -days 3650 -nodes -sha256
koneko efikeys #openssl req -new -x509 -newkey rsa:2048 -subj "/CN=sakaki's kernel-signing key/" -keyout db.key -out db.crt -days 3650 -nodes -sha256
Note
You can substitute anything you like for the "common name" (CN) text in the above commands (and you should in any event change the name from 'sakaki'! ^-^ ). Alternatively, if you omit the -subj "/CN=<...>/" text completely, you will be prompted to enter values, in exactly the same manner as when creating a self-signed domain certificate.[4] None of the information fields (CN, C etc.) affect the operation of secure boot. However, putting some meaningful text in there can help when later reviewing the contents of the four secure variables (which you can do by simply issuing efi-readvar, with no arguments).

This will have created three X.509 public-key certificate files (PK.crt, KEK.crt and db.crt), and three counterpart private key files (PK.key, KEK.key and db.key). We'll make the private keys readable only by root (an extra precaution, since they already in a directory readable only by root). Issue:

koneko efikeys #chmod -v 400 *.key

The efi-updatevar tool (also from the app-crypt/efitools), which we'll use shortly, can use raw X.509 certificates and keys to update the KEK, db and dbx secure variables. However, it is more picky (as of the time of writing) about the PK variable, and will only accept this in the 'signed signature list' ('.auth') format. We can create this in a two step process (using two command line tools from app-crypt/efitools). First, we make a signature list (which requires a unique ID, the value of which is essentially unimportant), and then we use our own (private) platform key to sign it. Let's do both now - issue:

koneko efikeys #cert-to-efi-sig-list -g "$(uuidgen)" PK.crt PK.esl
koneko efikeys #sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth

The file we need out of this is PK.auth.

Note
With some machine BIOSes it can be useful to generate a .auth file for your custom db as well. To do this, issue:
koneko efikeys #cert-to-efi-sig-list -g "$(uuidgen)" db.crt db.esl
koneko efikeys #sign-efi-sig-list -a -k KEK.key -c KEK.crt db db.esl db.auth
Most users will not need this db.auth file to successfully setup secure boot, but it is not harmful to generate it. It may come in useful if you plan to use (or are forced to resort to using) KeyTool to install your own keys (as opposed to the default protocol laid out in the main body of the text below). On some BIOSes, KeyTool will only allow the db variable to be set via an append operation (hence the -a option to sign-efi-sig-list) using a db.auth file such as this, even when in setup mode.

Entering Setup Mode, and Installing New Keys

With the preparations completed, we're ready to enter setup mode. Reboot the machine:

koneko efikeys #systemctl reboot

Immediately your target PC starts to come back up again, enter the BIOS setup screen. As mentioned before, the exact method of entering the BIOS varies greatly from machine to machine (as does the BIOS user interface itself). On the Panasonic CF-AX3, press F2 during startup (you may need to press it repeatedly, and you do this directly on the target machine's keyboard).

Once the BIOS setup screen comes up, using the same navigation techniques as before, perform the following steps:

  1. clear the UEFI secure boot variables, thereby entering setup mode; and
  2. restart your machine (saving changes).

It's impossible to be precise about the GUI actions required to achieve the above, as they will vary from BIOS to BIOS. However, to give you some idea, here's how you go about it on the Panasonic CF-AX3 (which has an AMT BIOS).

To achieve step 1, use the arrow keys to navigate across to the 'Security' tab. Then, navigate down to the 'Secure Boot' item, and press Enter. This enters a special 'Security' sub-page. Navigate down to the 'Clear Secure Boot Keys' item, and press Enter. Confirm that you wish to proceed by selecting 'Yes' in the popup which appears, then press Enter. If asked to reconfirm, select 'Yes' and press Enter again:

Clearing Boot Keys (Entering Setup Mode)

Note that on some UEFI implementations it is required to set a supervisor password in order for the option to clear the Secure Boot keys to be available.

Next, ensure that your boot USB key is still inserted, then press F10 to restart (step 2), and confirm if prompted.

The machine should restart, and, just as before, you will see the plymouth passphrase screen. Enter your LUKS keyfile gpg passphrase (the one you created earlier), directly at the target machine keyboard, and wait for the text console login to appear.

Then, re-connect to the machine via ssh. From the helper PC, issue:

user@pc2 $ssh root@192.168.1.106
Password: <enter root password>
... additional output suppressed ...
Note
Substitute whatever IP address you got back from ifconfig earlier for 192.168.1.106 in the above command. It is possible (although unlikely, with modern DHCP) that the target's IP address will have changed during the reboot. If so, log in directly at the target machine's keyboard, use ifconfig to find out the new address, then issue the above ssh command citing that address. As before, in such a case you may need to clean out any previous record of ssh connections to (other machines at) that new address (since the fingerprints will not match), using:
user@pc2 $sed -i '/^[^[:digit:]]*192.168.1.106[^[:digit:]]/d' ~/.ssh/known_hosts

obviously substituting the new address for 192.168.1.106 in the above. Then, be sure to check the fingerprint when prompted (by the subsequent ssh command), against those you noted down earlier.

Note
If installing over WiFi, and you had to manually restart wpa_supplicant in the previous chapter, then you'll need to do so again here (directly at the target machine's keyboard) before you'll be able to ssh in.

Now proceed as below, using the ssh connection to enter all commands unless otherwise specified (again, we will not need screen). Issue:

koneko ~ #cd /etc/efikeys

You can verify that the secure variables have been cleared. To do so, enter:

koneko efikeys #efi-readvar

and review the output.

Note
You may see a fifth variable, MokList, displayed when you do this. This is an EFI "Boot Services Only Variable" which some Linux distributions use to allow their bootloader shims to work under secure boot.[5] We won't need to worry about it.

Next, we'll reload the old contents of KEK, db and dbx, which we saved off above, thereby ensuing that Windows will still be permitted to load under secure boot (if we don't do this, it will be blocked). Issue:

koneko efikeys #efi-updatevar -e -f old_KEK.esl KEK
koneko efikeys #efi-updatevar -e -f old_db.esl db
koneko efikeys #efi-updatevar -e -f old_dbx.esl dbx

The -e option specifies that an EFI signature list file is to be loaded (and the -f option precedes the filename itself). Because we are in setup mode, no private key is required for these operations (which it would be, if we were in user mode).

Assuming that completed successfully, we can now append our own key-exchange and kernel-signing public keys, which we created and stored into KEK.crt and db.crt (respectively) earlier. Issue:

koneko efikeys #efi-updatevar -a -c KEK.crt KEK
koneko efikeys #efi-updatevar -a -c db.crt db

Note that here, we are using the -a option to append (rather than replace), and a slightly different format for the input file (since it is a X.509 certificate, rather than a signature list, we drop the -e, and use -c rather than -f to introduce the pathname). More details can be found in the efi-updatevar manpage.

Note
On some machines (with certain AMT, and some other, BIOSes) the above efi-updatevar commands may fail, with an error of "Cannot write to ..., wrong filesystem permissions". This appears to be a known issue,[6] but there is no fix in efi-updatevar as yet. I encountered this problem myself recently, when installing a Librem 13 laptop, and performed the following to work around it.

First, I created DER versions of each of the three certificates, as follows:
koneko efikeys #openssl x509 -outform DER -in PK.crt -out PK.cer
koneko efikeys #openssl x509 -outform DER -in KEK.crt -out KEK.cer
koneko efikeys #openssl x509 -outform DER -in db.crt -out db.cer
I then copied these three DER certificates to the boot USB key, restarted the machine, entered the BIOS and used the available BIOS GUI commands to clear the keystore (as efi-updatevar appeared to have corrupted it). Then, again via the BIOS GUI, I inserted the new .cer certificates directly from the boot USB key, taking care to insert PK.cer last. After this, I enabled secure boot, and all was well (also, efi-updatevar displayed the new variables correctly). The AMT BIOS on the Librem 13 provides options to install new keys and also to append to an existing keystore; however, your BIOS may not offer the same range of options.

Another alternative, if you are experiencing the "wrong filesystem permissions" issue, is to use KeyTool. For more details, please see this short addendum.


For avoidance of doubt, most users will not have to undertake the steps outlined in this note, but should just follow along with the instructions given in the main text.
Note
Additionally, on some BIOSes which exhibit the "you can only set new values, but not append to them" bug, the problem may be worked around by creating compendium (new + old) esl files for the KEK and db (esl files can simply be concatenated[7]), and then (after entering setup mode and clearing the keys) setting these compendium files (in lieu of the "set old, then append new" procedure described in the main body of the text above). To do this, enter setup mode and then proceed as follows:
koneko efikeys #cert-to-efi-sig-list -g "$(uuidgen)" KEK.crt KEK.esl
koneko efikeys #cert-to-efi-sig-list -g "$(uuidgen)" db.crt db.esl
koneko efikeys #cat old_KEK.esl KEK.esl > new_KEK.esl
koneko efikeys #cat old_db.esl db.esl > new_db.esl
koneko efikeys #efi-updatevar -e -f new_KEK.esl KEK
koneko efikeys #efi-updatevar -e -f new_db.esl db
koneko efikeys #efi-updatevar -e -f old_dbx.esl dbx
Then proceed to write the platform key to enter user mode, as described in the main text, below.
Note
This tutorial is primarily aimed at those users wishing to dual-boot, who will, therefore, wish to retain the Microsoft keys (without which, Windows will not secure boot). However, if you do not wish to retain the Microsoft keys, (other than their dbx, which is safe), then you should perform the following three commands, in place of the five just listed in the main body of the text (note that the -a flag is omitted for the KEK and db updates):
koneko efikeys #efi-updatevar -e -f old_dbx.esl dbx
koneko efikeys #efi-updatevar -c KEK.crt KEK
koneko efikeys #efi-updatevar -c db.crt db
For avoidance of doubt, please note that this advice will not apply to most readers of this tutorial (who may safely ignore it, and who should not issue the three commands in this note)!

Having made our changes, we can now write our own platform key into PK, using the signed signature list we created earlier. Issue:

koneko efikeys #efi-updatevar -f PK.auth PK

If this succeeds, the target machine will have been switched back to user mode (although secure boot is not yet enabled).

Display the contents of all the secure variables now. Issue:

koneko efikeys #efi-readvar

and verify that both your new keys, and Microsoft's original set, are present.

Now, let's make a backup (in machine readable signature list format) of the current state of the variables. Issue:

koneko efikeys #efi-readvar -v PK -o new_PK.esl
koneko efikeys #efi-readvar -v KEK -o new_KEK.esl
koneko efikeys #efi-readvar -v db -o new_db.esl
koneko efikeys #efi-readvar -v dbx -o new_dbx.esl

Testing Secure Boot with a Signed Kernel

Our next step is to create an appropriately signed kernel. The buildkernel script will do this automatically for us, provided that the files /etc/efikeys/db.key (the private kernel-signing key) and /etc/efikeys/db.crt (its public key counterpart) exist (which they now do). Ensure that the boot USB key is still inserted, then issue:

koneko efikeys #buildkernel

This should not take long to complete (as by default it does not make clean).

Note
You may see some output similar to the following from buildkernel:
... additional output suppressed ...
* Signing kernel
warning: file-aligned section .text extends beyond end of file
warning: checksum areas are greater than image size. Invalid section table?
... additional output suppressed ...

These warnings may safely be ignored.

Assuming the kernel build completed successfully, we can now restart, turn on secure boot, and try it out! Issue:

koneko efikeys #systemctl reboot

Immediately your target PC starts to come back up again, enter the BIOS setup screen. As mentioned before, the exact method of entering the BIOS varies greatly from machine to machine (as does the BIOS user interface itself). On the Panasonic CF-AX3, press F2 during startup (you may need to press it repeatedly, and you do this directly on the target machine's keyboard).

Once the BIOS setup screen comes up, using the same navigation techniques as before, perform the following steps:

  1. turn on secure boot; and
  2. restart your machine (saving changes).

It's impossible to be precise about the GUI actions required to achieve the above, as they will vary from BIOS to BIOS. However, to give you some idea, here's how you go about it on the Panasonic CF-AX3 (which has an AMT BIOS).

To achieve step 1 on the CF-AX3, use the arrow keys to select the 'Security' tab, then navigate down to the 'Secure Boot' item, and select it by pressing Enter. This enters a 'Security' page; navigate to the 'Secure Boot control' item, and press Enter. In the popup that appears, select 'Enabled' using the arrow keys, and press Enter:

Enabling Secure Boot

Next, ensure that your USB boot key is still inserted, then press F10 to restart (step 2), and confirm if prompted.

The machine should restart, and, if all goes well, you should shortly be prompted with the plymouth passphrase screen. If so, then congratulations, you are running a self-signed kernel under secure boot! Enter your LUKS keyfile gpg passphrase (the one you created earlier), directly at the target machine keyboard, and wait for the text console login to appear, as previously.

Note
If you have problems (for example, the target PC refuses to boot your signed kernel), then simply restart, turn off secure boot again via the BIOS (as described earlier), and then try working through the steps in this section again.

If that still doesn't work, or if you experience difficulties using the efi-readvar or efi-updatevar commands, then you may have more luck by either:

  • using the standalone keytool.efi utility; this is an EFI executable, available as a bootable USB image, which you can use to manipulate the secure variables;[2] or
  • using a UEFI shell to invoke special-purpose binaries from the efitools package.[8]

A short addendum covering the former is available here; the latter approach is currently beyond the scope of this tutorial.

Verifying Secure Boot with Windows (and Fixing RTC)

Having successfully booted our own self-signed kernel, we next have to check that Windows still works. Remove the boot USB key from the target machine, then (while it is still running Gentoo) log in directly at the target machine's keyboard (at the login prompt, enter 'root' as the user (without quotes), and then type the root password you set up earlier). Then issue (directly at the machine's keyboard):

koneko ~ #systemctl reboot

As the boot USB key is not inserted, Windows should start automatically. If it does boot, you have just verified that Windows also starts properly under your modified secure boot settings (and if it does not, follow the troubleshooting hints above).

Now, while Windows is running, let's take the chance to switch its clock to UTC, to match that used by systemd (which we set earlier in the tutorial).

To achieve this, login to your Windows account (which must have administrator rights - the first user created on a new Windows install has these by default), as usual. Next, perform the following steps (I have noted where things differ between Windows 10, 8.1 and 8):[9]

  1. First we'll check the Windows time, date and timezone is correct. Hit the Windows Key, which will bring up the start menu in Windows 10 (or the "start screen" in Windows 8.1 and 8), and type date and time. Then click on the 'Date and Time' item which appears (in Windows 10 and 8.1; Windows 8 users will need to click the 'Settings' icon to see this result; note also that in Windows 8.1 and 8, the item you need to click is entitled 'Date and time settings'). A 'Date and time' dialog appears. Set appropriate values for your locale.
  2. Next, we'll instruct Windows to use UTC (this will require a registry edit). Hit the Windows Key, which will bring up the start menu in Windows 10 (or the "start screen" in Windows 8.1 and 8), and type regedit. Then click on the 'regedit' item that appears. If prompted (via a dialog) whether to allow it to make changes to your computer, click 'Yes'. The regedit program now opens; using the navigation tree-view on the left, select HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation (you need to click on the little arrows to see the lower levels of the tree). Once this item has been selected, various time-zone related information will display on the right-hand pane. Right-click in the white area at the bottom of this pane, and choose New->DWORD (32-bit Value) from the context menu that appears. A fresh DWORD entry is added to the end of the list with its name selected - overtype this with RealTimeIsUniversal then press Enter. Now double-click on the name, and a dialog will appear, in which you can edit the key's value. Type in 1 (the number one) for the value, as shown below:
    Setting UTC Under Windows
    Close the dialog by clicking on 'OK'. Then exit the regedit application (using the menu item File->Exit).
  3. Now we'll disable the Windows Time Service. This is most easily done from the Windows command line. Hit the Windows Key , which will bring up the start menu in Windows 10 (or the "start screen" in Windows 8.1 and 8), and type command. Now right-click on the 'Command Prompt' icon that appears, then click on 'Run as administrator' item in the context menu (in Windows 10 and 8.1; it appears at the bottom of the screen in Windows 8). If asked whether you wish to proceed, click 'Yes'. You will be presented with an open command window. Now enter sc config w32time start= disabled. Hopefully, this should report SUCCESS. Close out the command window (by clicking on the 'x' in its title bar).
  4. Next, we'll force Windows to update the time. Hit the Windows Key, which will bring up the start menu in Windows 10 (or the "start screen" in Windows 8.1 and 8), and type date and time. Then click on the 'Date and Time' item which appears (in Windows 10 and 8.1; Windows 8 users will need to click the 'Settings' icon to see this result; note also that in Windows 8.1 and 8, the item you need to click is entitled 'Date and time settings'). A 'Date and time' dialog (which we used above) appears again. Now, on Windows 10, select the 'Internet Time' tab, click on 'Change settings...' and click 'Update now', then press 'OK'. On Windows 8.1 and 8, instead move the 'Set time automatically' slider to 'Off', and then back to 'On' again. In either case, assuming you have a network connection, the time should immediately update when you do this (and, assuming your locale is set correctly, it should be accurate). Close out the dialog once complete.

Setting BIOS Password (Optional), and Restarting Gentoo Linux

Next, we will reboot back into Gentoo. Re-insert the boot USB key into the target PC. Then, in Windows-8, hit CtrlAltDelete, then click on the power icon at the bottom right of the screen, and choose 'Restart' from the pop-up menu.

Immediately your target PC starts to come back up again, enter the BIOS setup screen. As mentioned a number of times now, the exact method of entering the BIOS varies greatly from machine to machine (as does the BIOS user interface itself). On the Panasonic CF-AX3, press F2 during startup (you may need to press it repeatedly, and you do this directly on the target machine's keyboard).

Note
If your target machine is using the 'fast boot' option with Windows, you may not have sufficient time to hit the BIOS-enter key on restart. See this earlier note for a solution.

Once you have the BIOS configuration screen up, you need to perform the following steps:

  1. select the "Gentoo Linux (USB Key)" EFI boot item as top priority;
  2. (optionally) set a BIOS password; then
  3. restart your machine (saving changes).

It's impossible to be precise about the GUI actions required to achieve the above, as they will vary from BIOS to BIOS. However, to give you some idea, here's how you go about it on the Panasonic CF-AX3 (which has an AMT BIOS).

To achieve step 1 on the CF-AX3, use the arrow keys the arrow keys to navigate to the 'Boot' tab, and then down to the 'UEFI Priorities' item. Press Enter, and a sub-page is displayed. Ensure the item 'UEFI Boot from USB' is enabled (if it isn't, enable it now, and then press F10 to restart, and come back to this point). Navigate down to 'Boot Option #1' and press Enter. In the pop-up menu that appears, select the "Gentoo Linux (USB Key)" item (which was added to the boot list when we ran buildkernel earlier):

Reselecting Gentoo as the First Boot Option

Press Enter to set this as the top boot option. Finally, press Esc to exit the subpage.

Note
Some PC UEFI BIOSes may not accept / display a USB boot target unless you:
  • insert the USB device when the BIOS screen is active;
  • then power cycle (e.g., via F10 on the Panasonic CF-AX3); and then
  • come back immediately into the BIOS (via F2 on the CF-AX3).
You'll need to experiment to find what works on your particular machine.
Note
Each time you use Windows, you'll need to go through this BIOS process prior to using your USB key to boot into Linux again, because Windows will generally place itself at the top of the list when it runs.[10] It's a little annoying, but we have avoided the need for a shim bootloader! (Furthermore, you only have to go through this process when switching from Windows to Linux, and not when power cycling Linux, or switching from Linux to Windows (since you simply restart without the USB boot key inserted to do that).)
Note
There is an alternative procedure, but it comes with some complications. When you are running Windows (and want to restart into Linux), hit CtrlAltDelete, then click on the power icon at the bottom right of the screen, and then while holding down Shift, click 'Restart' from the pop-up menu. This will pass you into the Windows boot options menu. Once this comes up (and asks you to 'Choose an option'), click on the 'Use a device' tile. This will show another page, on which you will see a tile entitled 'Gentoo Linux (USB Key)' (and possibly some others). Insert the boot USB key, click the tile, and you should find that the system restarts and that Linux is loaded (and you get the usual plymouth passphrase screen, etc.).

So far, so good, since this way of working avoids going through the BIOS. However, when you do this, Windows has only really set the (one-time) 'boot next' value in EFI, which means that once you restart again from Gentoo (even with the boot USB key still inserted), Windows will start up. To get around this, once you have booted into Gentoo and logged in as root, you need to use the efibootmgr tool (which you already have installed on your system at this point, as it is a dependency of buildkernel), to show (and then re-order) the boot list. As root, issue:

koneko ~ #efibootmgr
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0003,0004,0005,0000
Boot0000* Gentoo Linux (USB Key)
Boot0003* Windows Boot Manager
Boot0004* UEFI: IP4 Intel(R) Ethernet Connection I218-LM
Boot0005* UEFI: IP6 Intel(R) Ethernet Connection I218-LM

Clearly, the above is only an example, and your output would probably differ; but the important point to note is that while you are booted into item X on the list (as shown by BootCurrent, here 0000), the underlying BootOrder has entry Y first on the list (which is Windows, here 0003).

You could then fix this by issuing (for our example here):

koneko ~ #efibootmgr --bootorder 0000,0003,0004,0005
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0003,0004,0005
Boot0000* Gentoo Linux (USB Key)
Boot0003* Windows Boot Manager
Boot0004* UEFI: IP4 Intel(R) Ethernet Connection I218-LM
Boot0005* UEFI: IP6 Intel(R) Ethernet Connection I218-LM

Obviously, it's fairly simple to automate this with a script (which runs each time at Linux startup). This is left as an exercise for the reader ^-^.

The next step (#2, installing a BIOS password) is optional, but it is sensible to ensure that secure boot cannot be switched off by an attacker with temporary access to your machine (to permit a tampered kernel to run without your knowledge, for example). Most machines support some form of BIOS password, but the means of setting it varies widely. On the CF-AX3, use the arrow keys to navigate to the 'Security' tab, and then move down to the 'Set Supervisor Password' item, and press Enter. Type your password into the pop-up that appears:

Setting a BIOS Password

When done, press Enter. Then, when prompted, re-type the password to confirm and press Enter.

Warning
Write this password down in a safe place! If you forget it, you won't be able to access your BIOS, and you'll have to contact your machine's manufacturer to have it reset.

It is then sensible (on the CF-AX3, at any rate) to disable the BIOS's boot password prompt (otherwise, you'll have to type in the BIOS (supervisor) password every time you boot from USB). On the CF-AX3, navigate up to the 'Password On Boot' item, and press Enter. Then, in the pop-up that appears, use the arrow keys to select 'Disabled', and press Enter to select:

Ensuring BIOS Password Not Prompted for on Boot

That's it! Now ensure that the boot USB key is still inserted, then press F10 to restart (step 3), and confirm if prompted.

The machine should restart, and, if all goes well, you should shortly be prompted with the (by now familiar) plymouth passphrase screen. Enter your LUKS keyfile gpg passphrase (the one you created earlier), directly at the target machine keyboard, and wait for the text console login to appear, just as before.

Then, re-connect to the machine via ssh. From the helper PC, issue:

user@pc2 $ssh root@192.168.1.106
Password: <enter root password>
... additional output suppressed ...
Note
Substitute whatever IP address you got back from ifconfig earlier for 192.168.1.106 in the above command. It is possible (although unlikely, with modern DHCP) that the target's IP address will have changed during the reboot. If so, log in directly at the target machine's keyboard, use ifconfig to find out the new address, then issue the above ssh command citing that address. As before, in such a case you may need to clean out any previous record of ssh connections to (other machines at) that new address (since the fingerprints will not match), using:
user@pc2 $sed -i '/^[^[:digit:]]*192.168.1.106[^[:digit:]]/d' ~/.ssh/known_hosts

obviously substituting the new address for 192.168.1.106 in the above. Then, be sure to check the fingerprint when prompted (by the subsequent ssh command), against those you noted down earlier.

Note
If installing over WiFi, and you had to manually restart wpa_supplicant in the previous chapter, then you'll need to do so again here (directly at the target machine's keyboard) before you'll be able to ssh in.

Use the ssh connection to enter all subsequent commands unless otherwise specified (do not start up screen at this point, we'll do so again shortly).

The final thing thing we must do here is to check that our system time details have not been messed up by Windows (which, given the changes we have just made, they should not have been). Issue:

koneko ~ #timedatectl

and make sure the time and date are still correct, and in particular that the "RTC in local TZ" field reports as no.

Next Steps

Congratulations, setup of secure boot is complete! Next, we can install the GNOME 3 graphical environment. Click here to go to the next chapter, "Setting up the GNOME 3 Desktop".

Notes

  1. Bottomley, J. "The Meaning of all the UEFI Keys"
  2. 2.0 2.1 Kroah-Hartman, G. "Booting a Self-signed Linux Kernel"
  3. Unified Extensible Firmware Specification, Version 2.4, April 2014. Download available after registration from UEFI
  4. Stevens, Didier. Blog: "Howto: Make Your Own Cert With OpenSSL"
  5. SUSE Conversations: "SUSE and Secure Boot: The Details"
  6. James Bottomley's random Pages: "UEFI Secure Boot: Comment 73940"
  7. Developers Club: "We subdue UEFI SecureBoot"; see section "We convert public keys into the ESL format"
  8. Smith, Rod. "Managing EFI Boot Loaders for Linux: Controlling Secure Boot"
  9. SuperUser Forum: "Force Windows 8 to use UTC when dealing with BIOS clock"
  10. Watson, J. ZDNet: "UEFI and Windows 8 Update on Windows/Linux dual-boot systems"
< Previous Home Next >