Zephyr RTOS: Booting signed image with custom keys for MCUboot

In previous blog we have used sample key available in MCUboot repository for signing the application image. But it is strictly advised to use custom keys for production purposes or else attacker may modify the application image in flash and take control of the device. In this blog we are going to generate the custom keys and build the sample application with generated key.Before building the sample application with custom keys, a few things need to be discussed about cryptography.

Cryptography is broadly classified into two categories:

  • Symmetric Encryption
  • Asymmetric Encryption

Symmetric Encryption:

Symmetric encryption uses single key (private key) to encrypt and decrypt the message. Here sender uses private key to encrypt the message and receiver uses same private key to decrypt the message. Private key is shared between the sender and receiver.

Symmetric Algorithms: AES, Blowfish, Serpent, Twofish, 3DES and RC4.

Asymmetric Encryption

Asymmetric encryption is quite opposite to symmetric encryption, it consists of two different keys. Public and private key. Here sender uses public key to encrypt the message and receiver uses private key to decrypt the message. So public key is available to everyone and private key is kept secret with authenticated receiver.

Asymmetric Algorithms: RSA, DSA, ECC, Diffie-Hellman.

Zephyr support RSA 2048 and RSA 3072 Asymetric encryption. Here we are going to use RSA 2048 Algorithm for signing the image.

Let’s get started

cd $HOME 
cd zephyrproject/mcuboot 
Generate a key using openssl command 
openssl genrsa -out my_key.pem 2048

This command will create a file named my_key.pem which contains both private and public key.

Modify the prj.conf file to include the generated key.

vi boot/zephyr/prj.conf
CONFIG_BOOT_SIGNATURE_KEY_FILE="root-rsa-2048.pem"

change the default key from root-ras-2048.pem to my_key.pem

CONFIG_BOOT_SIGNATURE_KEY_FILE="my_key.pem"

and save the file.

Build and flash MCUboot Bootloader

west build -s boot/zephyr -b disco_l475_iot1
west flash

Once the bootloader is flashed open the device’s serial monitor by following command

minicom -b 115200 -D /dev/ttyACM0

If everyting goes right, it will display the following output.

The above image describes the bootloader is successfully flashed. Since the slot0_partition (primary partition) does not contain’s signed application image, it’s through an error message in last line.

Follow this steps to flash the sample application (signed image) with zephyr.

cd $HOME
cd zephyrproject/zephyr/samples/basic/blinky

Open the prj.conf file

vi prj.conf

And include the following line and save the file

CONFIG_BOOTLOADER_MCUBOOT=y

Build the application

cd $ZEPHYR_BASE
west build -b disco_l475_iot1 samples/basic/blinky/

Generated output can be found in the build directory

ls -l build/zephyr/zephyr.{bin, hex, elf}

Signing the builded Image with generated key

In previous blog we have used imgtool.py python script to sign the image. Here we are going to use west command to sign the image. For this we need imgtool, install the tool with pip3.

pip3 install --user imgtool

Then run the following command to generate the signed image.

west sign -t imgtool -- --key ../mcuboot/my_key.pem

This will generate the signed bin and hex in the build directory.

build/zephyr/zephyr.signed.bin
build/zephyr/zephyr.signed.hex

Flash the image

west flash --hex-file build/zephyr/zephyr.signed.hex

Open the serial monitor to check the output.

Here Bootloader chainload address offset: 0x20000, denotes the starting address of the slot0_partition. Here bootloader transfer it’s control to application image. It will blink the on board LED every second.

To check the functionality of secure booting, sign the application image with different key available in the repository.

west sign -t imgtool -- --key ../mcuboot/root-rsa-2048.pem

flash the image

west flash --hex-file build/zephyr/zephyr.signed.hex

Open the serial monitor to check the output.

MCUboot failed to boot the application image, since we are using different key for signing the application image.

Conclusion

MCUboot uses Asymmetric encryption for secure booting. Here, Bootloader uses public key and application image uses private key for signing the image.