@@ -497,7 +497,7 @@ int wolfBoot_fallback_is_possible(void)
497497#error option EXT_ENCRYPTED requires EXT_FLASH
498498#endif
499499
500- #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)))
500+ #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 + ENCRYPT_NONCE_SIZE )))
501501
502502
503503#ifdef NVM_FLASH_WRITEONCE
@@ -507,7 +507,7 @@ static uint8_t ENCRYPT_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(32)));
507507#endif
508508
509509
510- static int RAMFUNCTION hal_set_key (const uint8_t * k )
510+ static int RAMFUNCTION hal_set_key (const uint8_t * k , const uint8_t * nonce )
511511{
512512 uint32_t addr = ENCRYPT_TMP_SECRET_OFFSET + WOLFBOOT_PARTITION_BOOT_ADDRESS ;
513513 uint32_t addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1 ));
@@ -519,49 +519,48 @@ static int RAMFUNCTION hal_set_key(const uint8_t *k)
519519 if (ret != 0 )
520520 return ret ;
521521 XMEMCPY (ENCRYPT_CACHE + addr_off , k , ENCRYPT_KEY_SIZE );
522+ XMEMCPY (ENCRYPT_CACHE + addr_off + ENCRYPT_KEY_SIZE , nonce , ENCRYPT_NONCE_SIZE );
522523 ret = hal_flash_write (addr_align , ENCRYPT_CACHE , WOLFBOOT_SECTOR_SIZE );
523524 hal_flash_lock ();
524525 return ret ;
525526}
526527
527- int RAMFUNCTION wolfBoot_set_encrypt_key (const uint8_t * key , int len )
528+ int RAMFUNCTION wolfBoot_set_encrypt_key (const uint8_t * key , const uint8_t * nonce )
528529{
529- if (len != ENCRYPT_KEY_SIZE )
530- return -1 ;
531- hal_set_key (key );
530+ hal_set_key (key , nonce );
532531 return 0 ;
533532}
534533
535534int RAMFUNCTION wolfBoot_erase_encrypt_key (void )
536535{
537- uint8_t ff [ENCRYPT_KEY_SIZE ];
536+ uint8_t ff [ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE ];
538537 int i ;
539- XMEMSET (ff , 0xFF , ENCRYPT_KEY_SIZE );
540- hal_set_key (ff );
538+ XMEMSET (ff , 0xFF , ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE );
539+ hal_set_key (ff , ff + ENCRYPT_KEY_SIZE );
541540 return 0 ;
542541}
543542
544- int RAMFUNCTION wolfBoot_set_encrypt_password (const uint8_t * pwd , int len )
545- {
546- /* TODO */
547- return -1 ;
548- }
549-
550543#ifdef __WOLFBOOT
551544
552545static ChaCha chacha ;
553546static int chacha_initialized = 0 ;
547+ static uint8_t chacha_iv_nonce [ENCRYPT_NONCE_SIZE ];
554548
555549static int chacha_init (void )
556550{
557551 uint8_t * key = (uint8_t * )(WOLFBOOT_PARTITION_BOOT_ADDRESS + ENCRYPT_TMP_SECRET_OFFSET );
558552 uint8_t ff [ENCRYPT_KEY_SIZE ];
553+ uint8_t * stored_nonce = key + ENCRYPT_KEY_SIZE ;
554+
555+ /* Check against 'all 0xff' or 'all zero' cases */
559556 XMEMSET (ff , 0xFF , ENCRYPT_KEY_SIZE );
560557 if (XMEMCMP (key , ff , ENCRYPT_KEY_SIZE ) == 0 )
561558 return -1 ;
562- XMEMSET (ff , 0xFF , ENCRYPT_KEY_SIZE );
559+ XMEMSET (ff , 0x00 , ENCRYPT_KEY_SIZE );
563560 if (XMEMCMP (key , ff , ENCRYPT_KEY_SIZE ) == 0 )
564561 return -1 ;
562+
563+ XMEMCPY (chacha_iv_nonce , stored_nonce , ENCRYPT_NONCE_SIZE );
565564 wc_Chacha_SetKey (& chacha , key , ENCRYPT_KEY_SIZE );
566565 chacha_initialized = 1 ;
567566 return 0 ;
@@ -570,7 +569,6 @@ static int chacha_init(void)
570569
571570static inline uint8_t part_address (uintptr_t a )
572571{
573-
574572 if ( 1 &&
575573#if WOLFBOOT_PARTITION_UPDATE_ADDRESS != 0
576574 (a >= WOLFBOOT_PARTITION_UPDATE_ADDRESS ) &&
@@ -590,10 +588,9 @@ static uint32_t swap_counter = 0;
590588
591589int ext_flash_encrypt_write (uintptr_t address , const uint8_t * data , int len )
592590{
593- uint32_t iv [ ENCRYPT_BLOCK_SIZE / sizeof ( uint32_t )] ;
591+ uint32_t iv_counter ;
594592 uint8_t block [ENCRYPT_BLOCK_SIZE ];
595593 uint8_t part ;
596- uint32_t row_number ;
597594 int sz = len ;
598595 uint32_t row_address = address , row_offset ;
599596 int i ;
@@ -609,20 +606,22 @@ int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
609606 if (!chacha_initialized )
610607 if (chacha_init () < 0 )
611608 return -1 ;
612- XMEMSET (iv , 0 , ENCRYPT_BLOCK_SIZE );
613609 part = part_address (address );
614610 switch (part ) {
615611 case PART_UPDATE :
616- row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
612+ iv_counter = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
617613 /* Do not encrypt last sector */
618- if (row_number == (WOLFBOOT_PARTITION_SIZE - 1 ) / ENCRYPT_BLOCK_SIZE ) {
614+ if (iv_counter == (WOLFBOOT_PARTITION_SIZE - 1 ) / ENCRYPT_BLOCK_SIZE ) {
619615 return ext_flash_write (address , data , len );
620616 }
621617 break ;
622618 case PART_SWAP :
623- row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
624- iv [1 ] = swap_counter ++ ;
625- break ;
619+ {
620+ uint32_t row_number ;
621+ row_number = (address - WOLFBOOT_PARTITION_SWAP_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
622+ iv_counter = ((swap_counter ++ ) << 8 ) + row_number ;
623+ break ;
624+ }
626625 default :
627626 return -1 ;
628627 }
@@ -631,30 +630,28 @@ int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
631630 if (ext_flash_read (row_address , block , ENCRYPT_BLOCK_SIZE ) != ENCRYPT_BLOCK_SIZE )
632631 return -1 ;
633632 XMEMCPY (block + row_offset , data , step );
634- iv [0 ] = row_number ;
635- wc_Chacha_SetIV (& chacha , (byte * )iv , ENCRYPT_BLOCK_SIZE );
633+ wc_Chacha_SetIV (& chacha , chacha_iv_nonce , iv_counter );
636634 wc_Chacha_Process (& chacha , enc_block , block , ENCRYPT_BLOCK_SIZE );
637635 ext_flash_write (row_address , enc_block , ENCRYPT_BLOCK_SIZE );
638636 address += step ;
639637 data += step ;
640638 sz -= step ;
639+ iv_counter ++ ;
641640 }
642641 for (i = 0 ; i < sz / ENCRYPT_BLOCK_SIZE ; i ++ ) {
643- iv [0 ] = row_number ;
644- wc_Chacha_SetIV (& chacha , (byte * )iv , ENCRYPT_BLOCK_SIZE );
642+ wc_Chacha_SetIV (& chacha , chacha_iv_nonce , iv_counter );
645643 XMEMCPY (block , data + (ENCRYPT_BLOCK_SIZE * i ), ENCRYPT_BLOCK_SIZE );
646644 wc_Chacha_Process (& chacha , ENCRYPT_CACHE + (ENCRYPT_BLOCK_SIZE * i ), block , ENCRYPT_BLOCK_SIZE );
647- row_number ++ ;
645+ iv_counter ++ ;
648646 }
649647 return ext_flash_write (address , ENCRYPT_CACHE , len );
650648}
651649
652650int ext_flash_decrypt_read (uintptr_t address , uint8_t * data , int len )
653651{
654- uint32_t iv [ ENCRYPT_BLOCK_SIZE / sizeof ( uint32_t )] ;
652+ uint32_t iv_counter = 0 ;
655653 uint8_t block [ENCRYPT_BLOCK_SIZE ];
656654 uint8_t part ;
657- uint32_t row_number ;
658655 int sz = len ;
659656 uint32_t row_address = address , row_offset ;
660657 int i ;
@@ -671,19 +668,21 @@ int ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len)
671668 if (chacha_init () < 0 )
672669 return -1 ;
673670 part = part_address (row_address );
674- XMEMSET (iv , 0 , ENCRYPT_BLOCK_SIZE );
675671 switch (part ) {
676672 case PART_UPDATE :
677- row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
673+ iv_counter = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
678674 /* Do not decrypt last sector */
679- if (row_number == (WOLFBOOT_PARTITION_SIZE - 1 ) / ENCRYPT_BLOCK_SIZE ) {
675+ if (iv_counter == (WOLFBOOT_PARTITION_SIZE - 1 ) / ENCRYPT_BLOCK_SIZE ) {
680676 return ext_flash_read (address , data , len );
681677 }
682678 break ;
683679 case PART_SWAP :
684- row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
685- iv [1 ] = swap_counter ;
686- break ;
680+ {
681+ uint32_t row_number ;
682+ row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS ) / ENCRYPT_BLOCK_SIZE ;
683+ iv_counter = (swap_counter << 8 ) + row_number ;
684+ break ;
685+ }
687686 default :
688687 return -1 ;
689688 }
@@ -692,22 +691,21 @@ int ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len)
692691 int step = ENCRYPT_BLOCK_SIZE - row_offset ;
693692 if (ext_flash_read (row_address , block , ENCRYPT_BLOCK_SIZE ) != ENCRYPT_BLOCK_SIZE )
694693 return -1 ;
695- iv [0 ] = row_number ;
696- wc_Chacha_SetIV (& chacha , (byte * )iv , ENCRYPT_BLOCK_SIZE );
694+ wc_Chacha_SetIV (& chacha , chacha_iv_nonce , iv_counter );
697695 wc_Chacha_Process (& chacha , dec_block , block , ENCRYPT_BLOCK_SIZE );
698696 XMEMCPY (data , dec_block + row_offset , step );
699697 address += step ;
700698 data += step ;
701699 sz -= step ;
700+ iv_counter ++ ;
702701 }
703702 if (ext_flash_read (address , data , sz ) != sz )
704703 return -1 ;
705704 for (i = 0 ; i < sz / ENCRYPT_BLOCK_SIZE ; i ++ ) {
706- iv [0 ] = row_number ;
707- wc_Chacha_SetIV (& chacha , (byte * )iv , ENCRYPT_BLOCK_SIZE );
705+ wc_Chacha_SetIV (& chacha , chacha_iv_nonce , iv_counter );
708706 XMEMCPY (block , data + (ENCRYPT_BLOCK_SIZE * i ), ENCRYPT_BLOCK_SIZE );
709707 wc_Chacha_Process (& chacha , data + (ENCRYPT_BLOCK_SIZE * i ), block , ENCRYPT_BLOCK_SIZE );
710- row_number ++ ;
708+ iv_counter ++ ;
711709 }
712710 return len ;
713711}
0 commit comments