Environmental description
not have
preamble
As long as you have installed a variety of systems are more or less exposed to the concept of UEFI or BIOS. This article will not explain these concepts in detail, this article mainly string these concepts together, and the introduction of MOK (Machine Owner Key).
The reason why MOK is needed is because it is used when working with modern linux systems (e.g. PVE) if we need to install some drivers of our own build (e.g. if we want to implement gpu sr-iov).
UEFI/BIOS
BIOS (Basic Input/Output System) and UEFI (Unified Extensible Firmware Interface) these two names or functions we are very familiar with, the machine boot self-test is completed, generally f2/del, etc. to enter the interface, it is the system in the display of work. If we do not press the f2/del keys, the system will silently run the BIOS or UEFI, and then automatically load the boot program, and then load the OS to run.
UEFI is mainly designed to replace the BIOS system because of its advantages: support for more partitions, faster boot speeds, support for more hardware, more security, easier maintenance (unified standards), etc. One big disadvantage is that sometimes it requires more setup process because of security issues.
For BIOS, after the machine's power-on self-test is completed, it automatically reads the MBR (Master boot record), which is usually at the beginning of the disk's sector, and then loads the OS or other for booting. Note that the MBR partition is an old partition format.
For UEFI, after the machine's boot self-test completes, it automatically reads the EFI partition in the GPT partition (GUID Partition Table) and then loads the OS or other for booting.
Overall, as time has progressed, UEFI is a standard that has been supported and implemented by major vendors. bios its fulfilled its historical role and we shouldn't use it except for compatibility with older machines.
Linux under UEFI, self-built driver installation issues
Here is a background knowledge, that is, the modern linux kernel, when loading the kernel driver, generally will do a series of checks on the kernel driver, one of them is to do the signature check, if the check fails, the kernel refuses to load the driver. For this part of the content, you can refer to "Linux driver loading source code analysis (secure loading, signing, checking)"./Iflyinsky/p/18301894 An article.
In Common Encryption and Its Related Concepts, Introduction (symmetric, AES, asymmetric, RSA, hashing, HASH, message authentication code, HMAC, signature, CA, digital certificate, base64, padding)/Iflyinsky/p/18076852 We introduced the principle of signature, here is a brief mention: first of all, there are asymmetric encryption algorithms to generate the public key, private key. Then the message is digested, the digest is encrypted with the private key to obtain a signature, and finally the public key can be used to verify (decrypt) whether the signature is correct.
Corresponding to the kernel driver signature verification here is: first of all, the driver module using the private key for the signature, and the signature file will be written into the driver module file, when we load the driver module, the kernel will use its public key to verify the signature of the driver module.
Note that an important question here is: where does the kernel carry the public key? In general, there are two channels to increase the kernel's public key, one is when compiling the kernel, and the other is by dynamically writing some public key to the kernel through some methods in the runtime.
Machine Owner Key
In practice, when we test our own driver module, we usually generate a private key and public key pair to sign our driver module. However, on linux systems with UEFI+ Secure Boot enabled, our driver module cannot be loaded properly because our driver cannot pass the signature verification.
From the above description, to successfully load our kernel module then we should pass our public key to the kernel.
Before we tackle how to pass the public key to the kernel, our first step is to take a brief look at the simple process of linux secure boot:
- Machine boot and hardware self-test completed, then enter the uefi firmware, uefi firmware inside the Microsoft public key.
- uefi loads shim firmware (independent of linux distributions, pre-signed by Microsoft private keys, such as this package:/sid/amd64/shim-signed ). In addition shim has major distribution public keys.
- The shim firmware loads the grub firmware (the grub firmware is signed by the private keys of the major distributions).
- grub loads linux signed kernel.
In fact, from the process above, it is a ring of signature checks that ensure the chain of trust is passed.
Going back to our previous question, how do we pass our private and public keys to the kernel? There must be a tool that can pass in the relevant information, and that tool is the mokutil tool.
mokutil
In short, shim maintains a user-accessible key database of Machine Owner Keys in addition to the distribution's public keys, which can be added and deleted with the mokutil utility. In this way we can embed our own module-signed public key into the UEFI boot process, which can then be handed over to the kernel for use according to the appropriate methodology, and be able to load our own key-signed driver.
The process of adding the mokutil tool.
- Importing Public Keys
mokutil --import /var/lib/dkms/
# and enter a one-time password
-
Reboot the system, at this point the new boot process of uefi will start the mok manager and let the user register the new key as required and enter the previous one-time password. (A box pops up, choose your own, and enter the password)
-
After booting the system this way, our key was successfully loaded.
-
Test the system to see if the password is successfully registered
mokutil --test-key /var/lib/dkms/
This allows us to sign our driver with the corresponding private key, and then we can use public key authentication and load the driver as normal.
Also, one more thing to mention here is that there is actually a similar process for android's secure loading, which also has two main points: trust chain passing, and driver signing.
postscript
Knowing more and more about computers, I have to sigh: knowledge is always inadvertently appear in daily life and work.
bibliography
- /UEFI
- /SecureBoot
- /zh_hans/documentation/red_hat_enterprise_linux/7/html/kernel_administration_guide/sect-signing-kernel-modules-for-secure-boot
- /Iflyinsky/p/18301894
- /Iflyinsky/p/18076852