@@ -236,26 +236,38 @@ int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
236236 return 0 ;
237237}
238238
239- static bool aligned_flash_write (size_t dest_addr , const void * src , size_t size )
239+ static bool aligned_flash_write (size_t dest_addr , const void * src , size_t size , bool erase )
240240{
241241#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
242242 bool flash_encryption_enabled = esp_flash_encryption_enabled ();
243243#else
244244 bool flash_encryption_enabled = false;
245245#endif
246- size_t alignment = flash_encryption_enabled ? 32 : 4 ;
246+
247+ /* When flash encryption is enabled, write alignment is 32 bytes, however to avoid
248+ * inconsistences the region may be erased right before writting, thus the alignment
249+ * is set to the erase required alignment (FLASH_SECTOR_SIZE).
250+ * When flash encryption is not enabled, regular write alignment is 4 bytes.
251+ */
252+ size_t alignment = flash_encryption_enabled ? (erase ? FLASH_SECTOR_SIZE : 32 ) : 4 ;
247253
248254 if (IS_ALIGNED (dest_addr , alignment ) && IS_ALIGNED ((uintptr_t )src , 4 ) && IS_ALIGNED (size , alignment )) {
249255 /* A single write operation is enough when all parameters are aligned */
250256
257+ if (flash_encryption_enabled && erase ) {
258+ if (bootloader_flash_erase_range (dest_addr , size ) != ESP_OK ) {
259+ return false;
260+ }
261+ }
251262 return bootloader_flash_write (dest_addr , (void * )src , size , flash_encryption_enabled ) == ESP_OK ;
252263 }
253- 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 );
264+ BOOT_LOG_DBG ("%s: forcing unaligned write dest_addr: 0x%08x src: 0x%08x size: 0x%x erase: %c" ,
265+ __func__ , (uint32_t )dest_addr , (uint32_t )src , size , erase ? 't' : 'f' );
254266
255267 const uint32_t aligned_addr = ALIGN_DOWN (dest_addr , alignment );
256268 const uint32_t addr_offset = ALIGN_OFFSET (dest_addr , alignment );
257269 uint32_t bytes_remaining = size ;
258- uint8_t write_data [FLASH_BUFFER_SIZE ] __attribute__((aligned (32 ))) = {0 };
270+ uint8_t write_data [FLASH_SECTOR_SIZE ] __attribute__((aligned (32 ))) = {0 };
259271
260272 /* Perform a read operation considering an offset not aligned to 4-byte boundary */
261273
@@ -264,6 +276,11 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
264276 return false;
265277 }
266278
279+ if (flash_encryption_enabled && erase ) {
280+ if (bootloader_flash_erase_range (aligned_addr , ALIGN_UP (bytes , FLASH_SECTOR_SIZE )) != ESP_OK ) {
281+ return false;
282+ }
283+ }
267284 uint32_t bytes_written = bytes - addr_offset ;
268285 memcpy (& write_data [addr_offset ], src , bytes_written );
269286
@@ -283,6 +300,12 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
283300 return false;
284301 }
285302
303+ if (flash_encryption_enabled && erase ) {
304+ if (bootloader_flash_erase_range (aligned_addr + offset , ALIGN_UP (bytes , FLASH_SECTOR_SIZE )) != ESP_OK ) {
305+ return false;
306+ }
307+ }
308+
286309 memcpy (write_data , & ((uint8_t * )src )[bytes_written ], bytes );
287310
288311 if (bootloader_flash_write (aligned_addr + offset , write_data , ALIGN_UP (bytes , alignment ), flash_encryption_enabled ) != ESP_OK ) {
@@ -300,7 +323,7 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
300323static bool aligned_flash_erase (size_t addr , size_t size )
301324{
302325 if (IS_ALIGNED (addr , FLASH_SECTOR_SIZE ) && IS_ALIGNED (size , FLASH_SECTOR_SIZE )) {
303- /* A single write operation is enough when all parameters are aligned */
326+ /* A single erase operation is enough when all parameters are aligned */
304327
305328 return bootloader_flash_erase_range (addr , size ) == ESP_OK ;
306329 }
@@ -328,13 +351,13 @@ static bool aligned_flash_erase(size_t addr, size_t size)
328351
329352 /* Write first part of non-erased data */
330353 if (addr_offset > 0 ) {
331- if (!aligned_flash_write (aligned_addr , write_data , addr_offset )) {
354+ if (!aligned_flash_write (aligned_addr , write_data , addr_offset , false )) {
332355 return false;
333356 }
334357 }
335358
336359 if (bytes < sizeof (write_data )) {
337- if (!aligned_flash_write (aligned_addr + bytes , write_data + bytes , sizeof (write_data ) - bytes )) {
360+ if (!aligned_flash_write (aligned_addr + bytes , write_data + bytes , sizeof (write_data ) - bytes , false )) {
338361 return false;
339362 }
340363 }
@@ -356,7 +379,7 @@ static bool aligned_flash_erase(size_t addr, size_t size)
356379 }
357380
358381 if (bytes < sizeof (write_data )) {
359- if (!aligned_flash_write (aligned_addr + offset + bytes , write_data + bytes , sizeof (write_data ) - bytes )) {
382+ if (!aligned_flash_write (aligned_addr + offset + bytes , write_data + bytes , sizeof (write_data ) - bytes , false )) {
360383 return false;
361384 }
362385 }
@@ -383,9 +406,19 @@ int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
383406 }
384407
385408 const uint32_t start_addr = fa -> fa_off + off ;
386- BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
409+ bool erase = false;
410+ BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d (0x%x)" , __func__ , (int )start_addr , (int )len , (int )len );
387411
388- if (!aligned_flash_write (start_addr , src , len )) {
412+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
413+ if (esp_flash_encryption_enabled ()) {
414+ /* Ensuring flash region has been erased before writing in order to
415+ * avoid inconsistences when hardware flash encryption is enabled.
416+ */
417+ erase = true;
418+ }
419+ #endif
420+
421+ if (!aligned_flash_write (start_addr , src , len , erase )) {
389422 BOOT_LOG_ERR ("%s: Flash write failed" , __func__ );
390423 return -1 ;
391424 }
@@ -402,7 +435,7 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
402435 }
403436
404437 const uint32_t start_addr = fa -> fa_off + off ;
405- BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
438+ BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d (0x%x) " , __func__ , (int )start_addr , ( int ) len , (int )len );
406439
407440 if (!aligned_flash_erase (start_addr , len )) {
408441 BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
@@ -411,7 +444,38 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
411444
412445 flush_cache (start_addr , len );
413446
414- #if VALIDATE_PROGRAM_OP
447+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
448+ uint8_t write_data [FLASH_BUFFER_SIZE ];
449+ memset (write_data , flash_area_erased_val (fa ), sizeof (write_data ));
450+ uint32_t bytes_remaining = len ;
451+ uint32_t offset = start_addr ;
452+
453+ uint32_t bytes_written = MIN (sizeof (write_data ), len );
454+ if (esp_flash_encryption_enabled ()) {
455+ /* When hardware flash encryption is enabled, force expected erased
456+ * value (0xFF) into flash when erasing a region.
457+ *
458+ * This is handled on this implementation because MCUboot's state
459+ * machine relies on erased valued data (0xFF) readed from a
460+ * previously erased region that was not written yet, however when
461+ * hardware flash encryption is enabled, the flash read always
462+ * decrypts whats being read from flash, thus a region that was
463+ * erased would not be read as what MCUboot expected (0xFF).
464+ */
465+ while (bytes_remaining != 0 ) {
466+ if (!aligned_flash_write (offset , write_data , bytes_written , false)) {
467+ BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
468+ return -1 ;
469+ }
470+ offset += bytes_written ;
471+ bytes_remaining -= bytes_written ;
472+ }
473+ }
474+
475+ flush_cache (start_addr , len );
476+ #endif
477+
478+ #if VALIDATE_PROGRAM_OP && !defined(CONFIG_SECURE_FLASH_ENC_ENABLED )
415479 for (size_t i = 0 ; i < len ; i ++ ) {
416480 uint8_t * val = (void * )(start_addr + i );
417481 if (* val != 0xff ) {
0 commit comments