4444
4545#define NVM_CACHE_SIZE WOLFBOOT_SECTOR_SIZE
4646
47- uint32_t ext_cache ;
47+ static uint32_t ext_cache ;
4848static const uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL ;
4949
50+
5051#ifndef TRAILER_SKIP
5152# define TRAILER_SKIP 0
5253#endif
@@ -56,11 +57,8 @@ static const uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL;
5657#ifdef NVM_FLASH_WRITEONCE
5758#include <stddef.h>
5859#include <string.h>
59- #define XMEMSET memset
60- #define XMEMCPY memcpy
61- #define XMEMCMP memcmp
60+ static uint8_t NVM_CACHE [NVM_CACHE_SIZE ] __attribute__((aligned (16 )));
6261
63- static uint8_t NVM_CACHE [NVM_CACHE_SIZE ];
6462int RAMFUNCTION hal_trailer_write (uint32_t addr , uint8_t val ) {
6563 uint32_t addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1 ));
6664 uint32_t addr_off = addr & (WOLFBOOT_SECTOR_SIZE - 1 );
@@ -497,28 +495,30 @@ int wolfBoot_fallback_is_possible(void)
497495#error option EXT_ENCRYPTED requires EXT_FLASH
498496#endif
499497
500- #define ENCRYPT_TMP_SECRET_OFFSET (((WOLFBOOT_SECTOR_SIZE - (sizeof(uint32_t) + (2 + WOLFBOOT_SECTOR_SIZE ) / (WOLFBOOT_PARTITION_SIZE * 8)) + ENCRYPT_KEY_SIZE)) / ENCRYPT_KEY_SIZE * ENCRYPT_KEY_SIZE )
498+ #define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - (TRAILER_SKIP + ( sizeof(uint32_t) + 1 + ((1 + WOLFBOOT_PARTITION_SIZE ) / (WOLFBOOT_SECTOR_SIZE * 8)) + ENCRYPT_KEY_SIZE)))
501499
502500
503501#ifdef NVM_FLASH_WRITEONCE
504- #define KEY_CACHE NVM_CACHE
502+ #define ENCRYPT_CACHE NVM_CACHE
505503#else
506- static uint8_t KEY_CACHE [NVM_CACHE_SIZE ];
504+ static uint8_t ENCRYPT_CACHE [NVM_CACHE_SIZE ] __attribute__(( aligned ( 32 ))) ;
507505#endif
508506
509507
510508static int RAMFUNCTION hal_set_key (const uint8_t * k )
511509{
512- uint32_t addr = ENCRYPT_TMP_SECRET_OFFSET ;
510+ uint32_t addr = ENCRYPT_TMP_SECRET_OFFSET + WOLFBOOT_PARTITION_BOOT_ADDRESS ;
513511 uint32_t addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1 ));
514512 uint32_t addr_off = addr & (WOLFBOOT_SECTOR_SIZE - 1 );
515513 int ret = 0 ;
516- XMEMCPY (KEY_CACHE , (void * )addr_align , WOLFBOOT_SECTOR_SIZE );
514+ hal_flash_unlock ();
515+ XMEMCPY (ENCRYPT_CACHE , (void * )addr_align , WOLFBOOT_SECTOR_SIZE );
517516 ret = hal_flash_erase (addr_align , WOLFBOOT_SECTOR_SIZE );
518517 if (ret != 0 )
519518 return ret ;
520- XMEMCPY (KEY_CACHE + addr_off , k , ENCRYPT_KEY_SIZE );
521- ret = hal_flash_write (addr_align , KEY_CACHE , WOLFBOOT_SECTOR_SIZE );
519+ XMEMCPY (ENCRYPT_CACHE + addr_off , k , ENCRYPT_KEY_SIZE );
520+ ret = hal_flash_write (addr_align , ENCRYPT_CACHE , WOLFBOOT_SECTOR_SIZE );
521+ hal_flash_lock ();
522522 return ret ;
523523}
524524
@@ -566,12 +566,23 @@ static int chacha_init(void)
566566}
567567
568568
569- #define PART_ADDRESS (a ) ((a >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) && \
570- (a <= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE))?\
571- (PART_UPDATE):\
572- ((a >= WOLFBOOT_PARTITION_SWAP_ADDRESS && \
573- (a <= WOLFBOOT_PARTITION_SWAP_ADDRESS + WOLFBOOT_SECTOR_SIZE))?(PART_SWAP):\
574- PART_NONE)
569+ static inline uint8_t part_address (uintptr_t a )
570+ {
571+
572+ if ( 1 &&
573+ #if WOLFBOOT_PARTITION_UPDATE_ADDRESS != 0
574+ (a >= WOLFBOOT_PARTITION_UPDATE_ADDRESS ) &&
575+ #endif
576+ (a <= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE ))
577+ return PART_UPDATE ;
578+ if ( 1 &&
579+ #if WOLFBOOT_PARTITION_SWAP_ADDRESS != 0
580+ (a >= WOLFBOOT_PARTITION_SWAP_ADDRESS ) &&
581+ #endif
582+ (a <= WOLFBOOT_PARTITION_SWAP_ADDRESS + WOLFBOOT_SECTOR_SIZE ))
583+ return PART_SWAP ;
584+ return PART_NONE ;
585+ }
575586
576587static uint32_t swap_counter = 0 ;
577588
@@ -580,65 +591,109 @@ int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
580591 uint32_t iv [ENCRYPT_BLOCK_SIZE / sizeof (uint32_t )];
581592 uint8_t block [ENCRYPT_BLOCK_SIZE ];
582593 uint8_t part ;
583- uint32_t offset ;
594+ uint32_t row_number ;
595+ int sz = len ;
596+ uint32_t row_address = address , row_offset ;
584597 int i ;
598+ uint8_t enc_block [ENCRYPT_BLOCK_SIZE ];
599+ row_offset = address & (ENCRYPT_BLOCK_SIZE - 1 );
600+ if (row_offset != 0 ) {
601+ row_address = address & ~(ENCRYPT_BLOCK_SIZE - 1 );
602+ sz += ENCRYPT_BLOCK_SIZE - row_offset ;
603+ }
604+ if (sz < ENCRYPT_BLOCK_SIZE ) {
605+ sz = ENCRYPT_BLOCK_SIZE ;
606+ }
585607 if (!chacha_initialized )
586608 if (chacha_init () < 0 )
587609 return -1 ;
588- part = PART_ADDRESS (address );
610+ XMEMSET (iv , 0 , ENCRYPT_BLOCK_SIZE );
611+ part = part_address (address );
589612 switch (part ) {
590613 case PART_UPDATE :
591- offset = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
614+ row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
592615 break ;
593616 case PART_SWAP :
594- offset = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
617+ row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
618+ iv [1 ] = swap_counter ++ ;
595619 break ;
596620 default :
597621 return -1 ;
598622 }
599- XMEMSET (iv , 0 , ENCRYPT_BLOCK_SIZE );
600- if (part == PART_SWAP )
601- iv [1 ] = swap_counter ++ ;
602- for (i = 0 ; i < len / ENCRYPT_BLOCK_SIZE ; i ++ ) {
603- iv [0 ] = offset ++ ;
623+ if (sz > len ) {
624+ int step = ENCRYPT_BLOCK_SIZE - row_offset ;
625+ if (ext_flash_read (row_address , block , ENCRYPT_BLOCK_SIZE ) != ENCRYPT_BLOCK_SIZE )
626+ return -1 ;
627+ XMEMCPY (block + row_offset , data , step );
628+ wc_Chacha_Process (& chacha , enc_block , block , ENCRYPT_BLOCK_SIZE );
629+ ext_flash_write (row_address , enc_block , ENCRYPT_BLOCK_SIZE );
630+ address += step ;
631+ data += step ;
632+ sz -= step ;
633+ }
634+ for (i = 0 ; i < sz / ENCRYPT_BLOCK_SIZE ; i ++ ) {
635+ iv [0 ] = row_number ;
604636 wc_Chacha_SetIV (& chacha , (byte * )iv , ENCRYPT_BLOCK_SIZE );
605637 XMEMCPY (block , data + (ENCRYPT_BLOCK_SIZE * i ), ENCRYPT_BLOCK_SIZE );
606- wc_Chacha_Process (& chacha , block , data + (ENCRYPT_BLOCK_SIZE * i ), ENCRYPT_BLOCK_SIZE );
638+ wc_Chacha_Process (& chacha , ENCRYPT_CACHE + (ENCRYPT_BLOCK_SIZE * i ), block , ENCRYPT_BLOCK_SIZE );
639+ row_number ++ ;
607640 }
608- return ext_flash_write (address , data , len );
641+ return ext_flash_write (address , ENCRYPT_CACHE , len );
609642}
610643
611644int ext_flash_decrypt_read (uintptr_t address , uint8_t * data , int len )
612645{
613646 uint32_t iv [ENCRYPT_BLOCK_SIZE / sizeof (uint32_t )];
614647 uint8_t block [ENCRYPT_BLOCK_SIZE ];
615648 uint8_t part ;
616- uint32_t offset ;
649+ uint32_t row_number ;
650+ int sz = len ;
651+ uint32_t row_address = address , row_offset ;
617652 int i ;
653+
654+ row_offset = address & (ENCRYPT_BLOCK_SIZE - 1 );
655+ if (row_offset != 0 ) {
656+ row_address = address & ~(ENCRYPT_BLOCK_SIZE - 1 );
657+ sz += ENCRYPT_BLOCK_SIZE - row_offset ;
658+ }
659+ if (sz < ENCRYPT_BLOCK_SIZE ) {
660+ sz = ENCRYPT_BLOCK_SIZE ;
661+ }
618662 if (!chacha_initialized )
619663 if (chacha_init () < 0 )
620664 return -1 ;
621- part = PART_ADDRESS (address );
665+ XMEMSET (iv , 0 , ENCRYPT_BLOCK_SIZE );
666+ part = part_address (row_address );
622667 switch (part ) {
623668 case PART_UPDATE :
624- offset = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
669+ row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
625670 break ;
626671 case PART_SWAP :
627- offset = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
672+ row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
628673 iv [1 ] = swap_counter ;
629674 break ;
630675 default :
631676 return -1 ;
632677 }
633- if (ext_flash_read (address , data , len ) != len )
678+ if (sz > len ) {
679+ uint8_t dec_block [ENCRYPT_BLOCK_SIZE ];
680+ int step = ENCRYPT_BLOCK_SIZE - row_offset ;
681+ if (ext_flash_read (row_address , block , ENCRYPT_BLOCK_SIZE ) != ENCRYPT_BLOCK_SIZE )
682+ return -1 ;
683+ wc_Chacha_Process (& chacha , dec_block , block , ENCRYPT_BLOCK_SIZE );
684+ XMEMCPY (data , dec_block + row_offset , step );
685+ address += step ;
686+ data += step ;
687+ sz -= step ;
688+ }
689+ if (ext_flash_read (address , data , sz ) != sz )
634690 return -1 ;
635- XMEMSET (iv , 0 , ENCRYPT_BLOCK_SIZE );
636- for (i = 0 ; i < len / ENCRYPT_BLOCK_SIZE ; i ++ ) {
637- iv [0 ] = offset ++ ;
691+ for (i = 0 ; i < sz / ENCRYPT_BLOCK_SIZE ; i ++ ) {
692+ iv [0 ] = row_number ;
638693 wc_Chacha_SetIV (& chacha , (byte * )iv , ENCRYPT_BLOCK_SIZE );
639694 XMEMCPY (block , data + (ENCRYPT_BLOCK_SIZE * i ), ENCRYPT_BLOCK_SIZE );
640- wc_Chacha_Process (& chacha , block , data + (ENCRYPT_BLOCK_SIZE * i ), ENCRYPT_BLOCK_SIZE );
641- offset ++ ;
695+ wc_Chacha_Process (& chacha , data + (ENCRYPT_BLOCK_SIZE * i ), block , ENCRYPT_BLOCK_SIZE );
696+ row_number ++ ;
642697 }
643698 return len ;
644699}
0 commit comments