Recommendations about U-Boot’s configuration
Very commonly used in embedded ARM architectures, the bootloader U-Boot isn’t the best for all security aspects. Indeed, the entire boot flow is setup and controlled through environmental parameters. When U-Boot boots, it runs the specified set of commands listed inside the bootcmd parameter. So, by modifying this, anybody can easily boot into alternate images or quickly make modifications to the boot process. When it comes to security, this becomes a huge double-edged sword. In a field-deployed embedded system, we do not want someone to be able to tamper with the environment and arbitrarily execute whatever U-Boot commands they would like.
So, how can we prevent this? Unfortunately, U-Boot does not offer an easy way to sign/authenticate or encrypt the environment. It’s usually easier to disable the other exploitable paths someone may use. That’s why to highly improve the security of the U-Boot’s bootloader system, it is necessary to set the correct flags in the U-Boot environment to disable all unnecessary features that could be an open door to an attacker.
Strengthening the U-Boot console interaction
| U-Boot’s variable name | Value inside the U-Boot environment | Description |
|---|---|---|
| CONFIG_BOOTDELAY | -2 | Disables the possibility to stop the automatic U-Boot bootflow |
| CONFIG_DISABLE_CONSOLE | y | Entirely disables the U-Boot command console * |
| CONFIG_CMD_CMDLINE | n | Removes the U-Boot command line ** |
Enabling the autoboot password protection
| U-Boot’s variable name | Value inside the U-Boot environment | Description |
|---|---|---|
| CONFIG_AUTOBOOT_KEYED | y | The auto-boot is enabled with a key. This means that the automatic boot process is contingent upon the presence of a specific key |
| CONFIG_AUTOBOOT_ENCRYPTION | y | The automatic boot process is secured through an encryption mechanism |
| CONFIG_AUTOBOOT_STOP_STR_SHA256 | “…” | Specify the SHA256 hash value used to verify the stop string for auto-boot |
Reducing the hardware attack surface
| U-Boot’s variable name | Value inside the U-Boot environment | Description |
|---|---|---|
| CONFIG_CMD_USB | n | Disables the USB boot or use option |
| CONFIG_CMD_I2C | n | Removes the boot through I2C bus communication |
| CONFIG_CMD_SPI | n | Removes the boot through SPI bus communication |
| CONFIG_CMD_GO | n | This is the equivalent of an assembly jump/branch operation, so disable it to avoid an attacker changing the U-Boot’s execution to any arbitrary address |
Cleaning some unused alternative boot paths
| U-Boot’s variable name | Value inside the U-Boot environment | Description |
|---|---|---|
| CONFIG_CMD_BOOTI | n | Disables the ‘booti’ command used to boot Linux images |
| CONFIG_CMD_BOOTZ | n | Removes the possibility to directly boot Linux Kernel images |
| CONFIG_CMD_BOOTEFI | n | Disables booting on EFI applications |
| CONFIG_CMD_ELF | n | Disables the use, the load, and the boot of ELF format images |
| CONFIG_CMD_ABOOTIMG | n | Disables the launching of Android Boot Images |
| CONFIG_CMD_ADTIMG | n | Disables the boot of Android Device Tree Images |
Minimizing unnecessary debugging information
| U-Boot’s variable name | Value inside the U-Boot environment | Description |
|---|---|---|
| CONFIG_CMD_DIAG | n | Disables the diag command that can run system diagnostics (e.g., on some hardware components such as memory, serial ports…) |
| CONFIG_CMD_MEMORY | n | Disables memory-related commands that might expose sensitive information |
| CONFIG_CMD_IMI | n | Disables dumping image information (iminfo gives information on your board, the SoC…) |
Removing unused U-Boot options in critical ARM architectures
| U-Boot’s variable name | Value inside the U-Boot environment | Description |
|---|---|---|
| CONFIG_CMD_SMC | n | Disables the SMC (Secure Monitor Call) command for transitioning between different security levels if it’s unused in your configuration |
| CONFIG_CMD_HVC | n | Forbids the use of the HVC (Hypervisor Call) for unnecessary virtualized environments |
This list is obviously not exhaustive. It depends on your needs according to your embedded project, device or architecture. Moreover, your U-Boot version might be different from the latest version (U-Boot 2022.04) so you have to be careful, especially with environment flags, the configuration updates, etc. Please refer to the official U-Boot’s documentation for more details about the security aspects. Each implementation of the Secure Boot could be enforced by the configuration quoted above but don’t forget that your board might have One Time Programmable (OTP) eFuses designed to close some hardware configuration (e.g. at a low-level like the JTAG). Combining both methods improves significantly the security of your embedded system.
NOTES:
*: (in order for this to work, it is required to add the string “gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;” in the arch_cpu_init() of your board SoC configuration)
**: disabling this option is a good idea but it might be more complicated to understand the U-Boot boot process without any printLegacy example: the SolidRun HummingBoard Pulse is no longer an actively maintained redpesk target. The following configuration example is kept as historical U-Boot guidance.
To edit the configuration of your board into the U-Boot directory, you have to change the defconfig in /configs (for example, the /configs/imx8mp_solidrun_defconfig is the config file to change for the Solidrun Hummingboard Pulse).
As an example, we want to disable the autoboot delay for the Solidrun Hummingboard Pulse. This is highly recommended for a production chain. The only thing to do is to set (or add if the variable doesn’t exist depending of the U-Boot version) the variable CONFIG_BOOTDELAY to CONFIG_BOOTDELAY=-2 in the /configs/imx8mp_solidrun_defconfig and compile U-Boot again.