@@ -237,26 +237,38 @@ int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
237237 return 0 ;
238238}
239239
240- static bool aligned_flash_write (size_t dest_addr , const void * src , size_t size )
240+ static bool aligned_flash_write (size_t dest_addr , const void * src , size_t size , bool erase )
241241{
242242#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
243243 bool flash_encryption_enabled = esp_flash_encryption_enabled ();
244244#else
245245 bool flash_encryption_enabled = false;
246246#endif
247- size_t alignment = flash_encryption_enabled ? 32 : 4 ;
247+
248+ /* When flash encryption is enabled, write alignment is 32 bytes, however to avoid
249+ * inconsistences the region may be erased right before writting, thus the alignment
250+ * is set to the erase required alignment (FLASH_SECTOR_SIZE).
251+ * When flash encryption is not enabled, regular write alignment is 4 bytes.
252+ */
253+ size_t alignment = flash_encryption_enabled ? (erase ? FLASH_SECTOR_SIZE : 32 ) : 4 ;
248254
249255 if (IS_ALIGNED (dest_addr , alignment ) && IS_ALIGNED ((uintptr_t )src , 4 ) && IS_ALIGNED (size , alignment )) {
250256 /* A single write operation is enough when all parameters are aligned */
251257
258+ if (flash_encryption_enabled && erase ) {
259+ if (bootloader_flash_erase_range (dest_addr , size ) != ESP_OK ) {
260+ return false;
261+ }
262+ }
252263 return bootloader_flash_write (dest_addr , (void * )src , size , flash_encryption_enabled ) == ESP_OK ;
253264 }
254- BOOT_LOG_DBG ("%s: forcing unaligned write dest_addr: 0x%08x src: 0x%08x size: 0x%x" , __func__ , (uint32_t )dest_addr , (uint32_t )src , size );
265+ BOOT_LOG_DBG ("%s: forcing unaligned write dest_addr: 0x%08x src: 0x%08x size: 0x%x erase: %c" ,
266+ __func__ , (uint32_t )dest_addr , (uint32_t )src , size , erase ? 't' : 'f' );
255267
256268 const uint32_t aligned_addr = ALIGN_DOWN (dest_addr , alignment );
257269 const uint32_t addr_offset = ALIGN_OFFSET (dest_addr , alignment );
258270 uint32_t bytes_remaining = size ;
259- uint8_t write_data [FLASH_BUFFER_SIZE ] __attribute__((aligned (32 ))) = {0 };
271+ uint8_t write_data [FLASH_SECTOR_SIZE ] __attribute__((aligned (32 ))) = {0 };
260272
261273 /* Perform a read operation considering an offset not aligned to 4-byte boundary */
262274
@@ -265,6 +277,11 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
265277 return false;
266278 }
267279
280+ if (flash_encryption_enabled && erase ) {
281+ if (bootloader_flash_erase_range (aligned_addr , ALIGN_UP (bytes , FLASH_SECTOR_SIZE )) != ESP_OK ) {
282+ return false;
283+ }
284+ }
268285 uint32_t bytes_written = bytes - addr_offset ;
269286 memcpy (& write_data [addr_offset ], src , bytes_written );
270287
@@ -284,6 +301,12 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
284301 return false;
285302 }
286303
304+ if (flash_encryption_enabled && erase ) {
305+ if (bootloader_flash_erase_range (aligned_addr + offset , ALIGN_UP (bytes , FLASH_SECTOR_SIZE )) != ESP_OK ) {
306+ return false;
307+ }
308+ }
309+
287310 memcpy (write_data , & ((uint8_t * )src )[bytes_written ], bytes );
288311
289312 if (bootloader_flash_write (aligned_addr + offset , write_data , ALIGN_UP (bytes , alignment ), flash_encryption_enabled ) != ESP_OK ) {
@@ -301,7 +324,7 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
301324static bool aligned_flash_erase (size_t addr , size_t size )
302325{
303326 if (IS_ALIGNED (addr , FLASH_SECTOR_SIZE ) && IS_ALIGNED (size , FLASH_SECTOR_SIZE )) {
304- /* A single write operation is enough when all parameters are aligned */
327+ /* A single erase operation is enough when all parameters are aligned */
305328
306329 return bootloader_flash_erase_range (addr , size ) == ESP_OK ;
307330 }
@@ -329,13 +352,13 @@ static bool aligned_flash_erase(size_t addr, size_t size)
329352
330353 /* Write first part of non-erased data */
331354 if (addr_offset > 0 ) {
332- if (!aligned_flash_write (aligned_addr , write_data , addr_offset )) {
355+ if (!aligned_flash_write (aligned_addr , write_data , addr_offset , false )) {
333356 return false;
334357 }
335358 }
336359
337360 if (bytes < sizeof (write_data )) {
338- if (!aligned_flash_write (aligned_addr + bytes , write_data + bytes , sizeof (write_data ) - bytes )) {
361+ if (!aligned_flash_write (aligned_addr + bytes , write_data + bytes , sizeof (write_data ) - bytes , false )) {
339362 return false;
340363 }
341364 }
@@ -357,7 +380,7 @@ static bool aligned_flash_erase(size_t addr, size_t size)
357380 }
358381
359382 if (bytes < sizeof (write_data )) {
360- if (!aligned_flash_write (aligned_addr + offset + bytes , write_data + bytes , sizeof (write_data ) - bytes )) {
383+ if (!aligned_flash_write (aligned_addr + offset + bytes , write_data + bytes , sizeof (write_data ) - bytes , false )) {
361384 return false;
362385 }
363386 }
@@ -384,9 +407,19 @@ int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
384407 }
385408
386409 const uint32_t start_addr = fa -> fa_off + off ;
387- BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
410+ bool erase = false;
411+ BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d (0x%x)" , __func__ , (int )start_addr , (int )len , (int )len );
388412
389- if (!aligned_flash_write (start_addr , src , len )) {
413+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
414+ if (esp_flash_encryption_enabled ()) {
415+ /* Ensuring flash region has been erased before writing in order to
416+ * avoid inconsistences when hardware flash encryption is enabled.
417+ */
418+ erase = true;
419+ }
420+ #endif
421+
422+ if (!aligned_flash_write (start_addr , src , len , erase )) {
390423 BOOT_LOG_ERR ("%s: Flash write failed" , __func__ );
391424 return -1 ;
392425 }
@@ -403,7 +436,7 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
403436 }
404437
405438 const uint32_t start_addr = fa -> fa_off + off ;
406- BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
439+ BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d (0x%x) " , __func__ , (int )start_addr , ( int ) len , (int )len );
407440
408441 if (!aligned_flash_erase (start_addr , len )) {
409442 BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
@@ -412,7 +445,38 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
412445
413446 flush_cache (start_addr , len );
414447
415- #if VALIDATE_PROGRAM_OP
448+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
449+ uint8_t write_data [FLASH_BUFFER_SIZE ];
450+ memset (write_data , flash_area_erased_val (fa ), sizeof (write_data ));
451+ uint32_t bytes_remaining = len ;
452+ uint32_t offset = start_addr ;
453+
454+ uint32_t bytes_written = MIN (sizeof (write_data ), len );
455+ if (esp_flash_encryption_enabled ()) {
456+ /* When hardware flash encryption is enabled, force expected erased
457+ * value (0xFF) into flash when erasing a region.
458+ *
459+ * This is handled on this implementation because MCUboot's state
460+ * machine relies on erased valued data (0xFF) read from a
461+ * previously erased region that was not written yet, however when
462+ * hardware flash encryption is enabled, the flash read always
463+ * decrypts what's being read from flash, thus a region that was
464+ * erased would not be read as what MCUboot expected (0xFF).
465+ */
466+ while (bytes_remaining != 0 ) {
467+ if (!aligned_flash_write (offset , write_data , bytes_written , false)) {
468+ BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
469+ return -1 ;
470+ }
471+ offset += bytes_written ;
472+ bytes_remaining -= bytes_written ;
473+ }
474+ }
475+
476+ flush_cache (start_addr , len );
477+ #endif
478+
479+ #if VALIDATE_PROGRAM_OP && !defined(CONFIG_SECURE_FLASH_ENC_ENABLED )
416480 for (size_t i = 0 ; i < len ; i ++ ) {
417481 uint8_t * val = (void * )(start_addr + i );
418482 if (* val != 0xff ) {
0 commit comments