Recommendations about the U-boot’s configuration

Very commonly used for embedded uses in 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 Disable the possibility to stop the automatic U-Boot bootflow
CONFIG_DISABLE_CONSOLE y Entirely disable the U-Boot command console *
CONFIG_CMD_CMDLINE n Remove 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 Disable the USB boot or use option
CONFIG_CMD_I2C n Remove the boot through I2C bus communication
CONFIG_CMD_SPI n Remove 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 Disable the ‘booti’ command used to boot Linux images
CONFIG_CMD_BOOTZ n Remove the possibility to directly boot Linux Kernel images
CONFIG_CMD_BOOTEFI n Boot on EFI applications disabled
CONFIG_CMD_ELF n Disable the use, the load, and the boot of ELF format images
CONFIG_CMD_ABOOTIMG n Avoid the launching of Android Boot Images
CONFIG_CMD_ADTIMG n Disable 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 The diag command can run system diagnostics (e.g., on some hardware components such as memory, serial ports…), so it’s better to disable it
CONFIG_CMD_MEMORY n Disable memory-related commands that might expose sensitive information
CONFIG_CMD_IMI n Avoid the dumping image info (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 Disable the SMC (Secure Monitor Call) command for transitioning between different security levels if it’s unused in your configuration
CONFIG_CMD_HVC n Avoid 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 than the latest version (U-Boot 2022.04) so you have to be careful especially environment flags, the configuration updated, 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:

* : (to work, another needed thing is to add the following 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 print

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.