nrf5340 qspi has encountered question

Hi All.

Now I use soc:nrf5340, and ncs v2.9.0

I use QSPI to encrypt my external flash memory.
Adding some print functions in xxx_encrypt can ensure that it is encrypted only once and there are no changes in between

#ifdef CONFIG_MCUBOOT_ENC_EXT_FLASH
#define NONCE_CTX "test_string"
#include <hw_unique_key.h>
#include <nrfx_qspi.h>

static bool encrypt_completed = false;
int encrypt_external_flash(void)
{
    nrf_qspi_encryption_t encrypt_param = {0};
    uint8_t label[3] = {0}; // Label used for both key and nonce
    int ret = 0;

    if (encrypt_completed) {
        printk("External flash encryption already done.\n");
        return NRFX_SUCCESS;
    }

    if (!hw_unique_key_are_any_written())
        hw_unique_key_write_random();

    // Derive the key
    uint8_t key_context[16] = {0};
    memcpy(key_context, CONFIG_BOARD, strlen(CONFIG_BOARD));
    ret = hw_unique_key_derive_key(HUK_KEYSLOT_MEXT,
                                    key_context, sizeof(key_context),
                                    label, sizeof(label),
                                    (uint8_t *)encrypt_param.key, sizeof(encrypt_param.key));
    if (ret)
    {
        printk("derive board key error: %d\n", ret);
        return ret;
    }

    // Derive the nonce
    uint8_t nonce_context[32] = {0};
    memcpy(nonce_context, NONCE_CTX, strlen(NONCE_CTX));
    ret = hw_unique_key_derive_key(HUK_KEYSLOT_MEXT,
                                    nonce_context, sizeof(nonce_context),
                                    label, sizeof(label),
                                    (uint8_t *)encrypt_param.nonce, sizeof(encrypt_param.nonce));
    if (ret)
    {
        printk("derive nonce ctx key error: %d\n", ret);
        return ret;
    }

    // Perform encryption with DMA
    ret = nrfx_qspi_dma_encrypt(&encrypt_param);
    if (ret != NRFX_SUCCESS)
    {
        printk("nrfx_qspi_dma_encrypt error: %d\n", ret);
        return ret;
    }

    // Perform encryption with XIP
    ret = nrfx_qspi_xip_encrypt(&encrypt_param);
    if (ret != NRFX_SUCCESS)
    {
        printk("nrfx_qspi_xip_encrypt error: %d\n", ret);
        return ret;
    }

    MCUBOOT_WATCHDOG_FEED();

    encrypt_completed = true;
    printk("External flash encryption completed successfully.\n");
    return NRFX_SUCCESS;
}

SYS_INIT(encrypt_external_flash, POST_KERNEL, 42);
#endif /*CONFIG_MCUBOOT_ENC_EXT_FLASH*/

I found that during the Bluetooth upgrade process, the values written by the "boot_write_magic" function and the values read back were not consistent.

This is using flash_area_write and flash_area_read. This function seems to be using the encryption engine of the underlying QSPI, right?

When I tried to write the hexadecimal numbers from 0x1 to 0x10, the values read out were also inconsistent.

Of course, disabling QSPI encryption will definitely not cause any problems.

However, according to my understanding, the erasure process does not utilize the QSPI encryption engine, as it involves physical-level erasure rather than data stream processing.
This ordinary read/write operation should automatically invoke the encryption and decryption functions of QSPI, right?

Looking forward to reply. Thanks

Parents
  • In the img_mgmt_erase_image_data function located in zephyr\subsys\mgmt\mcumgr\grp\img_mgmt\src\zephyr_img_mgmt.c, the flash_area_write/read operations are normal and the data is consistent.

    but in the boot_write_magic function located in bootloader\mcuboot\boot\bootutil\src\bootutil_public.c, it was not work.the flash_area_write/read operations are normal and the data is inconsistent.

    bootloader\mcuboot\boot\zephyr\main.c, Is everything work normal here?

    SYS_INIT(encrypt_external_flash, POST_KERNEL, 42);

     

  • Hello,

    Since this is currently not supported in the driver I'm not sure how this HW feature is supposed to be used, but it seems to me that the issue is that the wrong nounce is used when encrypting and decrypting the image trailer data. 

    Could it be an option to disable the stream cipher when reading or writing image trailer data?

    Best regards,

    Vidar

  • ut it seems to me that the issue is that the wrong nounce is used when encrypting and decrypting the image trailer data. 

    This nounce is loaded only once during the boot process. It is not called from any other location.

    I added the printing function inside, but it only appeared once. There shouldn't be any other modifications elsewhere.

    Could it be an option to disable the stream cipher when reading or writing header data?

    Do you mean that when operating this, I need to temporarily disable both the encryption registers?

    The same nonce and key must be used for both encryption and decryption of the same memory address.

    Regarding this, I encrypted an entire external flash. So, should stream ciphers related to the external flash automatically perform encryption and decryption?

    Because all other external flash operations are normal encryption and decryption processes, and there are no issues with data writing and reading.

    I don't know why after writing data to the trailer of the image during the upgrade process, the data read back is problematic.

  • Sorry, you’re right. After looking more closely at the figure I posted in my previous comment, it’s clear that the nonce itself is fixed. The only potential issue I can think of is when the program tries to read the magic number or image trailer before anything has been written. In that case, the plaintext data (0xFFs) in the external flash will be encrypted when read as mentioned by the answer in this post:  RE: nrf5340 ncsv2.9.0 ble dfu . It's also important to remember to erase the QSPI flash between test runs to avoid partial writes. 

Reply
  • Sorry, you’re right. After looking more closely at the figure I posted in my previous comment, it’s clear that the nonce itself is fixed. The only potential issue I can think of is when the program tries to read the magic number or image trailer before anything has been written. In that case, the plaintext data (0xFFs) in the external flash will be encrypted when read as mentioned by the answer in this post:  RE: nrf5340 ncsv2.9.0 ble dfu . It's also important to remember to erase the QSPI flash between test runs to avoid partial writes. 

Children
Related