@@ -54,10 +54,45 @@ def tfm_sign_image(tfm_import_path, signing_key, signing_key_1, non_secure_bin):
54
54
# Find Python 3 command name across platforms
55
55
python3_cmd = "python3" if shutil .which ("python3" ) is not None else "python"
56
56
57
- img_ver_major = 1
58
- img_ver_minor = 3
59
- img_ver_revision = 0
60
- img_ver_build = 0
57
+ # Specify image version
58
+ #
59
+ # MCUboot image version format: Major.Minor.Revision+Build
60
+ #
61
+ # Requirements for image version:
62
+ # 1. Major.Minor.Revision must be non-decremental when used to derive security
63
+ # counter (-s 'auto').
64
+ # 2. Make Major.Minor.Revision+Build incremental to identify the firmware
65
+ # itself uniquely through psa_fwu_query().
66
+ # 3. Get around MCUboot failure with:
67
+ # [INF] Starting bootloader
68
+ # [INF] Swap type: none
69
+ # [ERR] Failed to add Image 0 data to shared memory area
70
+ # [ERR] Unable to find bootable image
71
+ # This is because TF-M underestimates MAX_BOOT_RECORD_SZ for boot record
72
+ # where Major.Minor.Revision will pack into during signing. The more digits
73
+ # of the Major.Minor.Revision, the larger the needed boot record size. And
74
+ # then MCUboot errors in boot_save_boot_status().
75
+ #
76
+ # To meet all the above requirements, we apply the following policy:
77
+ # 1. To not change MAX_BOOT_RECORD_SZ in TF-M, specify Major.Minor.Revision
78
+ # with TF-M version instead of modified Unix timestamp. This needs less digits to
79
+ # fit into MAX_BOOT_RECORD_SZ.
80
+ # 2. To make Major.Minor.Revision+Build incremental, specify the Build part with
81
+ # modified Unix timestamp.
82
+ # 3. To make security counter non-decremental, we can derive it from
83
+ # Major.Minor.Revision (-s 'auto') or explicitly specify it with modified
84
+ # Unix timestamp, depending on security consideration.
85
+ #
86
+ # NOTE: To get around Y2038 problem, we modify Unix timestamp by setting new base
87
+ # point. Using 32-bit unsigned integer to hold the modified Unix timestamp,
88
+ # it will break (wrap around) after Y2156 (2106 + 2020 - 1970).
89
+ # https://en.wikipedia.org/wiki/Year_2038_problem
90
+ #
91
+ modified_timestamp = int (datetime .now ().timestamp ()) - int (datetime (2020 , 1 , 1 ).timestamp ())
92
+ img_ver_major = 1 # Instead of (modified_timestamp >> 24) & 0xFF
93
+ img_ver_minor = 3 # Instead of (modified_timestamp >> 16) & 0xFF
94
+ img_ver_revision = 0 # Instead of modified_timestamp & 0xFFFF
95
+ img_ver_build = modified_timestamp
61
96
62
97
# wrapper.py command template
63
98
cmd_wrapper = [
@@ -82,7 +117,7 @@ def tfm_sign_image(tfm_import_path, signing_key, signing_key_1, non_secure_bin):
82
117
'0x400' ,
83
118
"--overwrite-only" ,
84
119
"-s" ,
85
- 'auto' ,
120
+ 'auto' , # Or modified_timestamp
86
121
"-d" ,
87
122
'(IMAGE_ID,MAJOR.MINOR.REVISION+BUILD)' ,
88
123
"RAW_BIN_PATH" ,
0 commit comments