nRF52840 + NCS + MCUBoot, CC310-enabled image encryption?

Hi there,

I am working on a new product iteration that uses the nRF52840. Our existing application is already using nRF52832 + NCS + MCUBoot with image signing.

I would like to take this opportunity to enable image encryption in MCUBoot and use the CC310 crypto hardware accelerator to perform image verification and decryption. However, I cannot find a working KConfig configuration that enables image encryption on MCUBoot with CC310.

Normally I can eventually figure these configuration issues out, but this one is difficult. I cannot find a relevant example project, or similar questions on the devzone.

The main compiler errors I am getting are:

 #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"

Could someone tell me what KConfig options are required, or point me to an existing sample project?

Thanks,

Sean

Parents
  • Hello Sean,

    Encrypted DFU is feature we do not officially support in our SDK, even though it is made available through the mcuboot project. Also be aware that the solution does not utilize a secure key storage for the private key kept on the device. This means we cannot guarantee that the key cannot be extracted.

    That said, the reason you are unable to build the bootloader in its current configuration is that the cc310 runtime library (nrf_cc310_bl crypto library) linked in by the bootloader only provide ECDSA and SHA-256 support. This sufficient to perform signature validation of the FW image, but not encryption/decryption. 

    While it's not really what you want, a simple workaround would be to select the TINYCRYPT SW backend instead (CONFIG_BOOT_ECDSA_TINYCRYPT=y). The other alternative would probably be to integrate the full version of the cc310 library. This will require changes to the bootloader itself. If you end up trying this, then I think a good start is to take a look at the cc310_glue file here (https://github.com/nrfconnect/sdk-mcuboot/blob/main/ext/nrf) /cc310_glue.c and the include headers in https://github.com/nrfconnect/sdk-mcuboot/tree/main/boot/bootutil/include/bootutil/crypto. These files show the functions currently implemented for the cc310 backend.

    You may also edit the imgtool sign command in ncs/nrf/modules/mcuboot/CMakeLists.txt if you want the build to encrypt the update binaries for you.

    e.g.

    diff --git a/modules/mcuboot/CMakeLists.txt b/modules/mcuboot/CMakeLists.txt
    index 6dd442214..dffc07e35 100644
    --- a/modules/mcuboot/CMakeLists.txt
    +++ b/modules/mcuboot/CMakeLists.txt
    @@ -149,6 +149,7 @@ if(CONFIG_BOOTLOADER_MCUBOOT)
           COMMAND
           # Sign the binary version of the input hex file.
           ${sign_cmd}
    +      --encrypt <insert path or symbol here that points to your key file >
           ${sign_dependencies}
           --slot-size ${SIGN_ARG_SLOT_SIZE}
           ${to_sign_bin}

    Best regards,

    Vidar

  • Hi Vidar,

    Thanks for the detailed answer.

    We are aware of the vulnerabilities of storing the keys in FLASH but thank you for noting that - it is important for anyone else reading.

    Ok, I understand why using the CC310 for MCUBoot encryption is currently unsupported. I have opted for the simple option from your suggestions, and I am now able to successfully compile. We can still use the CC310 in our application for signing operations.

    There are two further related questions I would like to ask:

    1. Your last point mentioned manually editing the ncs/nrf/modules/mcuboot/CMakeLists.txt file to automatically include encrypted binaries in the build process. However, I found the KConfig option CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE, that says it's meant to perform this operation automatically? However, this KConfig option is not available unless I also specify CONFIG_MCUBOOT_SIGNATURE_KEY_FILE, and enabling this option results in the warnings below:

    CMake Warning at /Users/FARLY7/workspace/um/catch-firmware-active/nrf/modules/mcuboot/CMakeLists.txt:630 (message):
    CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is set to
    "./bootloader/mcuboot/catch-active-bloodaxe_gen2-sign-p256.pem".

    You are using the NCS Mcuboot signing, which means this option will be
    ignored.

    Image signing in NCS is done via the MCUboot image's
    CONFIG_BOOT_SIGNATURE_KEY_FILE option.

    Consider setting CONFIG_MCUBOOT_SIGNATURE_KEY_FILE in your application
    image back to its default value, the empty string.

    It seems like this feature is not fully implemented or deprecated? I found this related GitHub Issue. We are already only using the CONFIG_BOOT_SIGNATURE_KEY_FILE as suggested, so is our only option to automatically generate the encrypted binaries to use your suggestion? I would rather not edit the CMakeLists.txt file directly, as we use different key files for different board builds, so it seems we will need to perform the encryption/signing separately.

    2.  Not really a question, but I see the issue still exists where if the key file path provided is a relative one, CMake will print the false warning that MCUBoot is using the default key, when it is correctly using the provided key. (see here). I hope this is fixed soon, as it is quite confusing.

    Thanks,

    Sean

  • Hello,

    We have not implemented support for encryption in the signing mechanism because we don't support DFU FW encryption in our SDK. This means we have not evaluated or verified the encryption support offered by the MCUBOOT project. Therefore, if you want the signing function to include encryption, you must patch the cmakelist file as described in my first reply in this thread. You should also consider including the --clear flag (https://github.com/mcu-tools/mcuboot/blob/8724081f9056291023c5d8be3e9df11f91a6bd78/scripts/imgtool/main.py#L291) if use external flash (this will ensure the image is re-encrypted if moved to secondary slot). 

  • Thank you Vidar.  We will attempt to follow that guidance but your comments give us great pause toward continuing this high volume project in the nrfConnect SDK.  I must confirm: is there any other mechanism/infrastructure that Nordic *does* support in the nrfConnect SDK for image encryption?  Please interpret the question broadly, not just in the scope of the NRF52840.

  • We currently do not provide an official solution for encrypted DFU. One of the reasons for this is that the solution provided by MCUBoot does not utilize any secure storage for the encryption key and that the same encryption key will be shared across all devices. 

  • Thank you Vidar. Maybe I'm miss understanding but isn't the encryption key stored in SOC flash which can then be read-back protected and with the latest silicon (at least on NRF52840) that *should* be protected?

  • No, your understanding is correct, but there are potentially other ways the key may be leaked. For instance, if someone gains access to the hex file used in production or exploits unknown software vulnerabilities, etc. But the latest silicon certainly helps limit the risk.

    Here is the threat model defined by MCUBoot: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/encrypted_images.html#threat-model 

Reply Children
  • Thank you for this update. I was able to build the application.

    A lot of the documentation talks about encrypting images on secondary paritions, but to get this to compile, mcuboot requires  CONFIG_SINGLE_APPLICATION_SLOT=y.

    Have you been able to get mcuboot image encryption to work with secondary paritions ? The version of mcuboot bundled in ncs talks about secondary partitions, but it seems to me that only newer versions of mcuboot support it. Is there a way to build a newer version of mcuboot without too much headache ?

  • Hi,

    Please try this sample put together by a coworker of mine: https://github.com/hellesvik-nordic/samples_for_nrf_connect_sdk/tree/main/bootloader_samples/keys_and_signatures/mcuboot_smp_encryption. It has been tested for the 'nrf52840dk_nrf52840' board.

    eb12345 said:
    A lot of the documentation talks about encrypting images on secondary paritions, but to get this to compile, mcuboot requires  CONFIG_SINGLE_APPLICATION_SLOT=y.

    To support encrypted DFU, the image must be stored in a secondary slot. So I'm not sure why the build fails without the CONFIG_SINGLE_APPLICATION_SLOT=y setting. I would help to see the build log if you want to investigate this further.

  • I tried to build the sample application from the link above for the nrf52833dk board. It builds fine for the nrf5340dk, but not for the nrf52833dk. Below is a snippet of the build log, as I can't upload the complete log file.

    <command-line>: warning: "MBEDTLS_CONFIG_FILE" redefined
    <command-line>: note: this is the location of the previous definition
    C:\ncs\v2.4.2\bootloader\mcuboot\ext\tinycrypt\lib\source\ctr_mode.c:33:10: fatal error: tinycrypt/constants.h: No such file or directory
    33 | #include <tinycrypt/constants.h>

  • Please add 'CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y' to the mcuboot.conf overlay in your child_image folder. This should remove the dependency on mbedtls and allow you to use Tinycrypt module for both the signature validation and decryption. 

  • Thank you. Now I can build and test. Which brings me to the original issue. When you add CONFIG_MCUBOOT_SERIAL=y, you get an error:

    C:\ncs\v2.4.2\bootloader\mcuboot\boot\boot_serial\src\boot_serial.c:634: undefined reference to `boot_handle_enc_fw'
    collect2.exe: error: ld returned 1 exit status
    The only way I found to alleviate this is to enable CONFIG_SINGLE_APPLICATION_SLOT=y. This is in the mcuboot child image. I think it's important failsafe to be able to use DFU/SMP Server (USB CDC, UART/Serial, or BLE) from the mcuboot image (can enter DFU in the bootloader using gpio or wait for DFU command for a short time). I don't care about switching images when you're in the bootloader, but there will be some cases where this will be the only way to recover a faulty image (correctly signed and encrypted, but one that needs to be overwritten manually).
Related