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. 

  • At present, the problem has not been located yet. The specific phenomenon is as follows.

    int img_mgmt_erase_image_data(unsigned int off, unsigned int num_bytes)
    {
    	const struct flash_area *fa;
    	char *rewrite_buf = NULL;
    	int rc;
    
    	if (off != 0) {
    		rc = IMG_MGMT_ERR_INVALID_OFFSET;
    		goto end;
    	}
    
    	rc = flash_area_open(g_img_mgmt_state.area_id, &fa);
    	if (rc != 0) {
    		LOG_ERR("Can't bind to the flash area (err %d)", rc);
    		rc = IMG_MGMT_ERR_FLASH_OPEN_FAILED;
    		goto end;
    	}
    
    	/* align requested erase size to the erase-block-size */
    	const struct device *dev = flash_area_get_device(fa);
    
    	if (dev == NULL) {
    		rc = IMG_MGMT_ERR_FLASH_AREA_DEVICE_NULL;
    		goto end_fa;
    	}
    	struct flash_pages_info page;
    	off_t page_offset = fa->fa_off + num_bytes - 1;
    
    	rc = flash_get_page_info_by_offs(dev, page_offset, &page);
    	if (rc != 0) {
    		LOG_ERR("bad offset (0x%lx)", (long)page_offset);
    		rc = IMG_MGMT_ERR_INVALID_PAGE_OFFSET;
    		goto end_fa;
    	}
    
    	size_t erase_size = page.start_offset + page.size - fa->fa_off;
    
    	rc = flash_area_flatten(fa, 0, erase_size);
    
    	if (rc != 0) {
    		LOG_ERR("image slot erase of 0x%zx bytes failed (err %d)", erase_size,
    				rc);
    		rc = IMG_MGMT_ERR_FLASH_ERASE_FAILED;
    		goto end_fa;
    	}
    
    	LOG_INF("Erased 0x%zx bytes of image slot", erase_size);
    
    #ifdef CONFIG_MCUBOOT_IMG_MANAGER
    	/* Right now MCUmgr supports only mcuboot images.
    	 * Above compilation swich might help to recognize mcuboot related
    	 * code when supports for anothe bootloader will be introduced.
    	 */
    
    	/* erase the image trailer area if it was not erased */
    	off = boot_get_trailer_status_offset(fa->fa_size);
    	if (off >= erase_size) {
    		rc = flash_get_page_info_by_offs(dev, fa->fa_off + off, &page);
    
    		off = page.start_offset - fa->fa_off;
    		erase_size = fa->fa_size - off;
    
    		rc = flash_area_flatten(fa, off, erase_size);
    		if (rc != 0) {
    			LOG_ERR("image slot trailer erase of 0x%zx bytes failed (err %d)",
    					erase_size, rc);
    			rc = IMG_MGMT_ERR_FLASH_ERASE_FAILED;
    			goto end_fa;
    		}
    
    		rewrite_buf = k_malloc(erase_size);
    		if (rewrite_buf == NULL) {
    			LOG_ERR("Failed to allocate memory for trailer rewrite buffer");
    			rc = IMG_MGMT_ERR_NO_FREE_MEMORY;
    			goto end_fa;
    		}
    
    		uint8_t erased_val = flash_area_erased_val(fa);
    		memset(rewrite_buf, erased_val, erase_size);
    
    		rc = flash_area_write(fa, off, rewrite_buf, erase_size);
    		if (rc != 0)
    		{
    			LOG_ERR("image slot trailer write of %u bytes failed (err %d)",
    					erase_size, rc);
    			rc = IMG_MGMT_ERR_FLASH_WRITE_FAILED;
    			goto end_free;
    
    		}
    
    		printf("Erased and Rewrote %u bytes of image ID:%u, addr:0x%x\n", erase_size, fa->fa_id, off);
    
    		rc = flash_area_read(fa, off, rewrite_buf, erase_size);
    		for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
    			if ((i + 1) % 16 == 0) {
    				printk("\n");
    			}
        	}
    	}
    #endif
    	rc = IMG_MGMT_ERR_OK;
    
    end_free:
    	if (rewrite_buf != NULL)
    		k_free(rewrite_buf);
    end_fa:
    	flash_area_close(fa);
    end:
    	return rc;
    }

    First of all, since I enabled QSPI encryption, after erasing the secondary partition before downloading the firmware, I need to write 0xFF to the last block of the flash.

    After writing, the 4k data was read out and printed - all of them were 0xFF (normal)

    Then, the next step is the firmware download process.

    Then it comes to the boot_set_next function. The magic and swap_info values read out through the boot_read_swap_state function are all 0xFF.

    It will set 

    state->magic = BOOT_MAGIC_UNSET;
    
    state->swap_type = BOOT_SWAP_TYPE_NONE;
    state->image_num = 0;

    And the next step is boot_write_magic

    As soon as I entered, I read 4kb of data, then came the "flash_area_write magic" process, and finally I read it back out.The data written at this time is inconsistent with the data read out.

    code
    
    boot_write_magic(const struct flash_area *fap)
    {
        uint32_t off;
        uint32_t pad_off;
        int rc;
        uint8_t magic[BOOT_MAGIC_ALIGN_SIZE];
        uint8_t read_magic[BOOT_MAGIC_ALIGN_SIZE];
        uint8_t erased_val;
    
        printk("boot_write_magic before------------------\n");
        rc = flash_area_read(fap, 0xE1000, rewrite_buf, 4096);
        for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
        	if ((i + 1) % 16 == 0) {
        		printk("\n");
        	}
        }
    
        off = boot_magic_off(fap);
    
        /* image_trailer structure was modified with additional padding such that
         * the pad+magic ends up in a flash minimum write region. The address
         * returned by boot_magic_off() is the start of magic which is not the
         * start of the flash write boundary and thus writes to the magic will fail.
         * To account for this change, write to magic is first padded with 0xFF
         * before writing to the trailer.
         */
        pad_off = ALIGN_DOWN(off, BOOT_MAX_ALIGN);
        
        erased_val = flash_area_erased_val(fap);
        printf("BOOT_MAGIC_ALIGN_SIZE:%u, pad_off:%u, erase val:0x%02X\n", BOOT_MAGIC_ALIGN_SIZE, pad_off, erased_val);
    
        memset(&magic[0], erased_val, sizeof(magic));
        memcpy(&magic[BOOT_MAGIC_ALIGN_SIZE - BOOT_MAGIC_SZ], BOOT_IMG_MAGIC, BOOT_MAGIC_SZ);
    
    
        printf("writing magic; fa_id=%d off=0x%lx (0x%lx)\n",
                     flash_area_get_id(fap), (unsigned long)off,
                     (unsigned long)(flash_area_get_off(fap) + off));
        rc = flash_area_write(fap, pad_off, &magic[0], BOOT_MAGIC_ALIGN_SIZE);
        for(uint8_t i = 0; i < BOOT_MAGIC_ALIGN_SIZE; i++) {
           printf("0x%02x ", magic[i]);
        }
        printf("\n");
    
        k_busy_wait(1000);
        rc = flash_area_read(fap, pad_off, &read_magic[0], BOOT_MAGIC_ALIGN_SIZE);
        if (rc != 0) {
            printf("error flashhhhhhhhhh 333333\n");
            return BOOT_EFLASH;
        }
    
        printf("read magic; fa_id=%d off=0x%lx (0x%lx)\n",
                     flash_area_get_id(fap), (unsigned long)off,
                     (unsigned long)(flash_area_get_off(fap) + off));
        for(uint8_t i = 0; i < BOOT_MAGIC_ALIGN_SIZE; i++) {
           printf("0x%02x ", read_magic[i]);
        }
        printf("\n");
    
        printk("afterrrrrr------------------\n");
        rc = flash_area_read(fap, 0xE1000, rewrite_buf, 4096);
        for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
        	if ((i + 1) % 16 == 0) {
        		printk("\n");
        	}
        }
        return 0;
    }
    
    
    
    logs
    boot_write_magic before------------------
    0xff.....
    .....0xff
    
    BOOT_MAGIC_ALIGN_SIZE:16, pad_off:925680, erase val:0xFF
    writing magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80 
    read magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc3 0xb5 0xf3 0xfa 0xf2 0xef 0x7f 0xf5 0xf6 0xf9 0x8f 0x3c 0xfe 0xff 0xc0 
    
    afterrrrrr------------------
    0xff....
    ........
    0x77 0xc3 0xb5 0xf3 0xfa 0xf2 0xef 0x7f 0xf5 0xf6 0xf9 0x8f 0x3c 0xfe 0xff 0xc0

    Then I attempted to write the data here after erased the flash partition again.
    After erasing, the values read out all appear to be encrypted? Because the erasure operation simply sets it to 0xFF, and then I enabled QSPI encryption, the read-out value is the random value obtained by decrypting the plaintext 0xFF.
    At this point, write "magic" again, and then read it again. The data will be consistent.
    code
    
    int
    boot_write_magic(const struct flash_area *fap)
    {
        ...
        rc = flash_area_erase(fap, 0xE1000, 4096);
        if (rc != 0) {
            printf("error flashhhhhhhhhh 11111111\n");
            return BOOT_EFLASH;
        }
    
        printk("boot_write_magic before------------------\n");
        rc = flash_area_read(fap, 0xE1000, rewrite_buf, 4096);
        for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
        	if ((i + 1) % 16 == 0) {
        		printk("\n");
        	}
        }
        ...
    }
    
    
    
    log
    boot_write_magic before------------------
    0x58 0xf1 0xd6 0xf7 0x67 0x88 0xac 0x32 0x78 0x5c 0x3d 0x0b 0x01 0xc2 0xd0 0xe8 
    0x17 0x10 0xc0 0xc6 0xc8 0xa7 0x2e 0x3e 0x75 0xcb 0xcf 0xf7 0x4f 0x87 0x21 0x7e\
    ...
    0xb8 0x1b 0xbc 0x3c 0x40 0xf5 0x90 0x03 0xee 0x44 0x0d 0x65 0xc0 0x14 0xbc 0xbd 
    
    BOOT_MAGIC_ALIGN_SIZE:16, pad_off:925680, erase val:0xFF
    writing magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80 
    read magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80 
    
    afterrrrrr------------------
    0x58 0xf1 0xd6 0xf7 0x67 0x88 0xac 0x32 0x78 0x5c 0x3d 0x0b 0x01 0xc2 0xd0 0xe8 
    0x17 0x10 0xc0 0xc6 0xc8 0xa7 0x2e 0x3e 0x75 0xcb 0xcf 0xf7 0x4f 0x87 0x21 0x7e
    ....
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80
    Therefore, I am quite puzzled. Is there an issue with the operation of rewriting to 0xFF in the previous step img_mgmt_erase_image_data? However, without this step, there will be problems with the judgment in boot_read_swap_state because the values read are random rather than 0xFF.
    Why, after erasing again, did the reading and writing magic become problem-free once more?
    Perhaps I have some misunderstandings regarding the QSPI encryption and the firmware verification during the Bluetooth upgrade process.
Reply
  • At present, the problem has not been located yet. The specific phenomenon is as follows.

    int img_mgmt_erase_image_data(unsigned int off, unsigned int num_bytes)
    {
    	const struct flash_area *fa;
    	char *rewrite_buf = NULL;
    	int rc;
    
    	if (off != 0) {
    		rc = IMG_MGMT_ERR_INVALID_OFFSET;
    		goto end;
    	}
    
    	rc = flash_area_open(g_img_mgmt_state.area_id, &fa);
    	if (rc != 0) {
    		LOG_ERR("Can't bind to the flash area (err %d)", rc);
    		rc = IMG_MGMT_ERR_FLASH_OPEN_FAILED;
    		goto end;
    	}
    
    	/* align requested erase size to the erase-block-size */
    	const struct device *dev = flash_area_get_device(fa);
    
    	if (dev == NULL) {
    		rc = IMG_MGMT_ERR_FLASH_AREA_DEVICE_NULL;
    		goto end_fa;
    	}
    	struct flash_pages_info page;
    	off_t page_offset = fa->fa_off + num_bytes - 1;
    
    	rc = flash_get_page_info_by_offs(dev, page_offset, &page);
    	if (rc != 0) {
    		LOG_ERR("bad offset (0x%lx)", (long)page_offset);
    		rc = IMG_MGMT_ERR_INVALID_PAGE_OFFSET;
    		goto end_fa;
    	}
    
    	size_t erase_size = page.start_offset + page.size - fa->fa_off;
    
    	rc = flash_area_flatten(fa, 0, erase_size);
    
    	if (rc != 0) {
    		LOG_ERR("image slot erase of 0x%zx bytes failed (err %d)", erase_size,
    				rc);
    		rc = IMG_MGMT_ERR_FLASH_ERASE_FAILED;
    		goto end_fa;
    	}
    
    	LOG_INF("Erased 0x%zx bytes of image slot", erase_size);
    
    #ifdef CONFIG_MCUBOOT_IMG_MANAGER
    	/* Right now MCUmgr supports only mcuboot images.
    	 * Above compilation swich might help to recognize mcuboot related
    	 * code when supports for anothe bootloader will be introduced.
    	 */
    
    	/* erase the image trailer area if it was not erased */
    	off = boot_get_trailer_status_offset(fa->fa_size);
    	if (off >= erase_size) {
    		rc = flash_get_page_info_by_offs(dev, fa->fa_off + off, &page);
    
    		off = page.start_offset - fa->fa_off;
    		erase_size = fa->fa_size - off;
    
    		rc = flash_area_flatten(fa, off, erase_size);
    		if (rc != 0) {
    			LOG_ERR("image slot trailer erase of 0x%zx bytes failed (err %d)",
    					erase_size, rc);
    			rc = IMG_MGMT_ERR_FLASH_ERASE_FAILED;
    			goto end_fa;
    		}
    
    		rewrite_buf = k_malloc(erase_size);
    		if (rewrite_buf == NULL) {
    			LOG_ERR("Failed to allocate memory for trailer rewrite buffer");
    			rc = IMG_MGMT_ERR_NO_FREE_MEMORY;
    			goto end_fa;
    		}
    
    		uint8_t erased_val = flash_area_erased_val(fa);
    		memset(rewrite_buf, erased_val, erase_size);
    
    		rc = flash_area_write(fa, off, rewrite_buf, erase_size);
    		if (rc != 0)
    		{
    			LOG_ERR("image slot trailer write of %u bytes failed (err %d)",
    					erase_size, rc);
    			rc = IMG_MGMT_ERR_FLASH_WRITE_FAILED;
    			goto end_free;
    
    		}
    
    		printf("Erased and Rewrote %u bytes of image ID:%u, addr:0x%x\n", erase_size, fa->fa_id, off);
    
    		rc = flash_area_read(fa, off, rewrite_buf, erase_size);
    		for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
    			if ((i + 1) % 16 == 0) {
    				printk("\n");
    			}
        	}
    	}
    #endif
    	rc = IMG_MGMT_ERR_OK;
    
    end_free:
    	if (rewrite_buf != NULL)
    		k_free(rewrite_buf);
    end_fa:
    	flash_area_close(fa);
    end:
    	return rc;
    }

    First of all, since I enabled QSPI encryption, after erasing the secondary partition before downloading the firmware, I need to write 0xFF to the last block of the flash.

    After writing, the 4k data was read out and printed - all of them were 0xFF (normal)

    Then, the next step is the firmware download process.

    Then it comes to the boot_set_next function. The magic and swap_info values read out through the boot_read_swap_state function are all 0xFF.

    It will set 

    state->magic = BOOT_MAGIC_UNSET;
    
    state->swap_type = BOOT_SWAP_TYPE_NONE;
    state->image_num = 0;

    And the next step is boot_write_magic

    As soon as I entered, I read 4kb of data, then came the "flash_area_write magic" process, and finally I read it back out.The data written at this time is inconsistent with the data read out.

    code
    
    boot_write_magic(const struct flash_area *fap)
    {
        uint32_t off;
        uint32_t pad_off;
        int rc;
        uint8_t magic[BOOT_MAGIC_ALIGN_SIZE];
        uint8_t read_magic[BOOT_MAGIC_ALIGN_SIZE];
        uint8_t erased_val;
    
        printk("boot_write_magic before------------------\n");
        rc = flash_area_read(fap, 0xE1000, rewrite_buf, 4096);
        for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
        	if ((i + 1) % 16 == 0) {
        		printk("\n");
        	}
        }
    
        off = boot_magic_off(fap);
    
        /* image_trailer structure was modified with additional padding such that
         * the pad+magic ends up in a flash minimum write region. The address
         * returned by boot_magic_off() is the start of magic which is not the
         * start of the flash write boundary and thus writes to the magic will fail.
         * To account for this change, write to magic is first padded with 0xFF
         * before writing to the trailer.
         */
        pad_off = ALIGN_DOWN(off, BOOT_MAX_ALIGN);
        
        erased_val = flash_area_erased_val(fap);
        printf("BOOT_MAGIC_ALIGN_SIZE:%u, pad_off:%u, erase val:0x%02X\n", BOOT_MAGIC_ALIGN_SIZE, pad_off, erased_val);
    
        memset(&magic[0], erased_val, sizeof(magic));
        memcpy(&magic[BOOT_MAGIC_ALIGN_SIZE - BOOT_MAGIC_SZ], BOOT_IMG_MAGIC, BOOT_MAGIC_SZ);
    
    
        printf("writing magic; fa_id=%d off=0x%lx (0x%lx)\n",
                     flash_area_get_id(fap), (unsigned long)off,
                     (unsigned long)(flash_area_get_off(fap) + off));
        rc = flash_area_write(fap, pad_off, &magic[0], BOOT_MAGIC_ALIGN_SIZE);
        for(uint8_t i = 0; i < BOOT_MAGIC_ALIGN_SIZE; i++) {
           printf("0x%02x ", magic[i]);
        }
        printf("\n");
    
        k_busy_wait(1000);
        rc = flash_area_read(fap, pad_off, &read_magic[0], BOOT_MAGIC_ALIGN_SIZE);
        if (rc != 0) {
            printf("error flashhhhhhhhhh 333333\n");
            return BOOT_EFLASH;
        }
    
        printf("read magic; fa_id=%d off=0x%lx (0x%lx)\n",
                     flash_area_get_id(fap), (unsigned long)off,
                     (unsigned long)(flash_area_get_off(fap) + off));
        for(uint8_t i = 0; i < BOOT_MAGIC_ALIGN_SIZE; i++) {
           printf("0x%02x ", read_magic[i]);
        }
        printf("\n");
    
        printk("afterrrrrr------------------\n");
        rc = flash_area_read(fap, 0xE1000, rewrite_buf, 4096);
        for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
        	if ((i + 1) % 16 == 0) {
        		printk("\n");
        	}
        }
        return 0;
    }
    
    
    
    logs
    boot_write_magic before------------------
    0xff.....
    .....0xff
    
    BOOT_MAGIC_ALIGN_SIZE:16, pad_off:925680, erase val:0xFF
    writing magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80 
    read magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc3 0xb5 0xf3 0xfa 0xf2 0xef 0x7f 0xf5 0xf6 0xf9 0x8f 0x3c 0xfe 0xff 0xc0 
    
    afterrrrrr------------------
    0xff....
    ........
    0x77 0xc3 0xb5 0xf3 0xfa 0xf2 0xef 0x7f 0xf5 0xf6 0xf9 0x8f 0x3c 0xfe 0xff 0xc0

    Then I attempted to write the data here after erased the flash partition again.
    After erasing, the values read out all appear to be encrypted? Because the erasure operation simply sets it to 0xFF, and then I enabled QSPI encryption, the read-out value is the random value obtained by decrypting the plaintext 0xFF.
    At this point, write "magic" again, and then read it again. The data will be consistent.
    code
    
    int
    boot_write_magic(const struct flash_area *fap)
    {
        ...
        rc = flash_area_erase(fap, 0xE1000, 4096);
        if (rc != 0) {
            printf("error flashhhhhhhhhh 11111111\n");
            return BOOT_EFLASH;
        }
    
        printk("boot_write_magic before------------------\n");
        rc = flash_area_read(fap, 0xE1000, rewrite_buf, 4096);
        for(uint32_t i=0; i<4096; i++) {
        	printk("0x%02x ", rewrite_buf[i]);
        	if ((i + 1) % 16 == 0) {
        		printk("\n");
        	}
        }
        ...
    }
    
    
    
    log
    boot_write_magic before------------------
    0x58 0xf1 0xd6 0xf7 0x67 0x88 0xac 0x32 0x78 0x5c 0x3d 0x0b 0x01 0xc2 0xd0 0xe8 
    0x17 0x10 0xc0 0xc6 0xc8 0xa7 0x2e 0x3e 0x75 0xcb 0xcf 0xf7 0x4f 0x87 0x21 0x7e\
    ...
    0xb8 0x1b 0xbc 0x3c 0x40 0xf5 0x90 0x03 0xee 0x44 0x0d 0x65 0xc0 0x14 0xbc 0xbd 
    
    BOOT_MAGIC_ALIGN_SIZE:16, pad_off:925680, erase val:0xFF
    writing magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80 
    read magic; fa_id=23 off=0xe1ff0 (0x2e1ff0)
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80 
    
    afterrrrrr------------------
    0x58 0xf1 0xd6 0xf7 0x67 0x88 0xac 0x32 0x78 0x5c 0x3d 0x0b 0x01 0xc2 0xd0 0xe8 
    0x17 0x10 0xc0 0xc6 0xc8 0xa7 0x2e 0x3e 0x75 0xcb 0xcf 0xf7 0x4f 0x87 0x21 0x7e
    ....
    0x77 0xc2 0x95 0xf3 0x60 0xd2 0xef 0x7f 0x35 0x52 0x50 0x0f 0x2c 0xb6 0x79 0x80
    Therefore, I am quite puzzled. Is there an issue with the operation of rewriting to 0xFF in the previous step img_mgmt_erase_image_data? However, without this step, there will be problems with the judgment in boot_read_swap_state because the values read are random rather than 0xFF.
    Why, after erasing again, did the reading and writing magic become problem-free once more?
    Perhaps I have some misunderstandings regarding the QSPI encryption and the firmware verification during the Bluetooth upgrade process.
Children
No Data
Related