3838#include "user_settings.h"
3939#include "wolfboot/wolfboot.h"
4040#include "libwolfboot.c"
41+ #ifdef DELTA_UPDATES
42+ #define wb_patch_init unit_test_wb_patch_init
43+ #define wb_patch unit_test_wb_patch
44+ #endif
4145#include "update_flash.c"
46+ #ifdef DELTA_UPDATES
47+ #undef wb_patch_init
48+ #undef wb_patch
49+ #endif
4250#include <fcntl.h>
4351#include <unistd.h>
4452#include <sys/mman.h>
@@ -55,6 +63,30 @@ static void cleanup_flash(void);
5563static int add_payload_type (uint8_t part , uint32_t version , uint32_t size ,
5664 uint16_t img_type );
5765
66+ #ifdef DELTA_UPDATES
67+ static int mock_wb_patch_init_calls = 0 ;
68+
69+ int unit_test_wb_patch_init (WB_PATCH_CTX * bm , uint8_t * src , uint32_t ssz ,
70+ uint8_t * patch , uint32_t psz )
71+ {
72+ (void )bm ;
73+ (void )src ;
74+ (void )ssz ;
75+ (void )patch ;
76+ (void )psz ;
77+ mock_wb_patch_init_calls ++ ;
78+ return 0 ;
79+ }
80+
81+ int unit_test_wb_patch (WB_PATCH_CTX * ctx , uint8_t * dst , uint32_t len )
82+ {
83+ (void )ctx ;
84+ (void )dst ;
85+ (void )len ;
86+ return 0 ;
87+ }
88+ #endif
89+
5890#ifdef CUSTOM_ENCRYPT_KEY
5991static int mock_get_encrypt_key_ret = 0 ;
6092static int mock_set_encrypt_key_ret = 0 ;
@@ -158,6 +190,9 @@ static void reset_mock_stats(void)
158190#ifdef RAM_CODE
159191 arch_reboot_called = 0 ;
160192#endif
193+ #ifdef DELTA_UPDATES
194+ mock_wb_patch_init_calls = 0 ;
195+ #endif
161196}
162197
163198static void clear_erase_stats (void )
@@ -997,6 +1032,88 @@ START_TEST (test_delta_zero_size_erased_header_uses_recovery_heuristic)
9971032 cleanup_flash ();
9981033}
9991034END_TEST
1035+
1036+ START_TEST (test_delta_base_version_mismatch_rejected )
1037+ {
1038+ struct wolfBoot_image boot , update , swap ;
1039+ uint32_t word ;
1040+ uint32_t delta_sz = 0 ;
1041+ uint32_t delta_base = 3 ;
1042+ int ret ;
1043+
1044+ reset_mock_stats ();
1045+ prepare_flash ();
1046+
1047+ add_payload (PART_BOOT , 1 , TEST_SIZE_SMALL );
1048+ add_payload (PART_UPDATE , 2 , TEST_SIZE_SMALL );
1049+
1050+ ext_flash_unlock ();
1051+ word = (4u << 16 ) | HDR_IMG_DELTA_SIZE ;
1052+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 64 ,
1053+ (const uint8_t * )& word , sizeof (word ));
1054+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 68 ,
1055+ (const uint8_t * )& delta_sz , sizeof (delta_sz ));
1056+ word = (4u << 16 ) | HDR_IMG_DELTA_BASE ;
1057+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 72 ,
1058+ (const uint8_t * )& word , sizeof (word ));
1059+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 76 ,
1060+ (const uint8_t * )& delta_base , sizeof (delta_base ));
1061+ ext_flash_lock ();
1062+
1063+ ck_assert_int_eq (wolfBoot_open_image (& boot , PART_BOOT ), 0 );
1064+ ck_assert_int_eq (wolfBoot_open_image (& update , PART_UPDATE ), 0 );
1065+ memset (& swap , 0 , sizeof (swap ));
1066+ swap .part = PART_SWAP ;
1067+ swap .hdr = (void * )(uintptr_t )WOLFBOOT_PARTITION_SWAP_ADDRESS ;
1068+
1069+ ret = wolfBoot_delta_update (& boot , & update , & swap , 0 , 0 );
1070+ ck_assert_int_eq (ret , -1 );
1071+ ck_assert_int_eq (mock_wb_patch_init_calls , 0 );
1072+
1073+ cleanup_flash ();
1074+ }
1075+ END_TEST
1076+
1077+ START_TEST (test_delta_base_version_match_accepts )
1078+ {
1079+ struct wolfBoot_image boot , update , swap ;
1080+ uint32_t word ;
1081+ uint32_t delta_sz = 0 ;
1082+ uint32_t delta_base = 1 ;
1083+ int ret ;
1084+
1085+ reset_mock_stats ();
1086+ prepare_flash ();
1087+
1088+ add_payload (PART_BOOT , 1 , TEST_SIZE_SMALL );
1089+ add_payload (PART_UPDATE , 2 , TEST_SIZE_SMALL );
1090+
1091+ ext_flash_unlock ();
1092+ word = (4u << 16 ) | HDR_IMG_DELTA_SIZE ;
1093+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 64 ,
1094+ (const uint8_t * )& word , sizeof (word ));
1095+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 68 ,
1096+ (const uint8_t * )& delta_sz , sizeof (delta_sz ));
1097+ word = (4u << 16 ) | HDR_IMG_DELTA_BASE ;
1098+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 72 ,
1099+ (const uint8_t * )& word , sizeof (word ));
1100+ ext_flash_write (WOLFBOOT_PARTITION_UPDATE_ADDRESS + 76 ,
1101+ (const uint8_t * )& delta_base , sizeof (delta_base ));
1102+ ext_flash_lock ();
1103+
1104+ ck_assert_int_eq (wolfBoot_open_image (& boot , PART_BOOT ), 0 );
1105+ ck_assert_int_eq (wolfBoot_open_image (& update , PART_UPDATE ), 0 );
1106+ memset (& swap , 0 , sizeof (swap ));
1107+ swap .part = PART_SWAP ;
1108+ swap .hdr = (void * )(uintptr_t )WOLFBOOT_PARTITION_SWAP_ADDRESS ;
1109+
1110+ ret = wolfBoot_delta_update (& boot , & update , & swap , 0 , 0 );
1111+ ck_assert_int_eq (ret , 0 );
1112+ ck_assert_int_eq (mock_wb_patch_init_calls , 1 );
1113+
1114+ cleanup_flash ();
1115+ }
1116+ END_TEST
10001117#endif
10011118#endif
10021119
@@ -1058,6 +1175,7 @@ Suite *wolfboot_suite(void)
10581175 TCase * boot_success = tcase_create ("Boot success state" );
10591176#ifdef DELTA_UPDATES
10601177 TCase * delta_zero_size = tcase_create ("Delta zero size" );
1178+ TCase * delta_base_version = tcase_create ("Delta base version check" );
10611179#endif
10621180#ifdef RAM_CODE
10631181 TCase * self_update_sameversion = tcase_create ("Self update same version erased" );
@@ -1105,6 +1223,8 @@ Suite *wolfboot_suite(void)
11051223#ifdef DELTA_UPDATES
11061224 tcase_add_test (delta_zero_size , test_delta_zero_size_valid_header_rejected_without_recovery_heuristic );
11071225 tcase_add_test (delta_zero_size , test_delta_zero_size_erased_header_uses_recovery_heuristic );
1226+ tcase_add_test (delta_base_version , test_delta_base_version_mismatch_rejected );
1227+ tcase_add_test (delta_base_version , test_delta_base_version_match_accepts );
11081228#endif
11091229#ifdef RAM_CODE
11101230 tcase_add_test (self_update_sameversion , test_self_update_sameversion_erased );
@@ -1140,6 +1260,7 @@ Suite *wolfboot_suite(void)
11401260 suite_add_tcase (s , boot_success );
11411261#ifdef DELTA_UPDATES
11421262 suite_add_tcase (s , delta_zero_size );
1263+ suite_add_tcase (s , delta_base_version );
11431264#endif
11441265#ifdef RAM_CODE
11451266 suite_add_tcase (s , self_update_sameversion );
0 commit comments