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 print

Legacy 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.