17
17
"""
18
18
Parse and print header, TLV area and trailer information of a signed image.
19
19
"""
20
- from imgtool import image
21
- import click
22
- import struct
23
- import yaml
24
20
import os .path
21
+ import struct
25
22
import sys
26
23
24
+ import click
25
+ import yaml
26
+
27
+ from imgtool import image
28
+
27
29
HEADER_ITEMS = ("magic" , "load_addr" , "hdr_size" , "protected_tlv_size" ,
28
30
"img_size" , "flags" , "version" )
29
31
TLV_TYPES = dict ((value , key ) for key , value in image .TLV_VALUES .items ())
39
41
0x1f , 0x8a , ])
40
42
BOOT_MAGIC_SIZE = len (BOOT_MAGIC )
41
43
_LINE_LENGTH = 60
44
+ STATUS = {
45
+ '0x1' : 'SET' ,
46
+ '0x2' : 'BAD' ,
47
+ '0x3' : 'UNSET' ,
48
+ '0x4' : 'ANY' ,
49
+ }
50
+
51
+
52
+ def parse_enc (key_field_len ):
53
+ if key_field_len is not None :
54
+ return "(len: {}, if BOOT_SWAP_SAVE_ENCTLV is unset)" .format (hex (key_field_len ))
55
+ else :
56
+ return "Image not encrypted"
57
+
58
+
59
+ def parse_size (size_hex ):
60
+ if size_hex == '0xffffffff' :
61
+ return "unknown"
62
+ return size_hex + " octal: " + str (int (size_hex , 0 ))
63
+
64
+
65
+ def parse_status (status_hex ):
66
+ return f"{ STATUS [status_hex ]} ({ status_hex } )" if status_hex in STATUS else f"INVALID ({ status_hex } )"
67
+
68
+
69
+ def parse_boot_magic (trailer_magic ):
70
+ magic = ""
71
+ for i in range (BOOT_MAGIC_SIZE ):
72
+ magic += "{0:#04x} " .format (trailer_magic [i ])
73
+ if i == (BOOT_MAGIC_SIZE / 2 - 1 ):
74
+ magic += ("\n " + " " )
75
+ return magic
76
+
77
+
78
+ def print_in_frame (header_text , content ):
79
+ sepc = " "
80
+ header = "#### " + header_text + sepc
81
+ post_header = "#" * (_LINE_LENGTH - len (header ))
82
+ print (header + post_header )
83
+
84
+ print ("|" , sepc * (_LINE_LENGTH - 2 ), "|" , sep = "" )
85
+ offset = (_LINE_LENGTH - len (content )) // 2
86
+ pre = "|" + (sepc * (offset - 1 ))
87
+ post = sepc * (_LINE_LENGTH - len (pre ) - len (content ) - 1 ) + "|"
88
+ print (pre , content , post , sep = "" )
89
+ print ("|" , sepc * (_LINE_LENGTH - 2 ), "|" , sep = "" )
90
+ print ("#" * _LINE_LENGTH )
91
+
92
+
93
+ def print_in_row (row_text ):
94
+ row_text = "#### " + row_text + " "
95
+ fill = "#" * (_LINE_LENGTH - len (row_text ))
96
+ print (row_text + fill )
42
97
43
98
44
99
def print_tlv_records (tlv_list ):
@@ -66,10 +121,11 @@ def print_tlv_records(tlv_list):
66
121
def dump_imginfo (imgfile , outfile = None , silent = False ):
67
122
"""Parse a signed image binary and print/save the available information."""
68
123
trailer_magic = None
69
- swap_size = 0
70
- swap_info = 0
71
- copy_done = 0
72
- image_ok = 0
124
+ # set to INVALID by default
125
+ swap_size = 0x99
126
+ swap_info = 0x99
127
+ copy_done = 0x99
128
+ image_ok = 0x99
73
129
trailer = {}
74
130
key_field_len = None
75
131
@@ -92,16 +148,16 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
92
148
93
149
# Parsing the TLV area
94
150
tlv_area = {"tlv_hdr_prot" : {},
95
- "tlvs_prot" : [],
96
- "tlv_hdr" : {},
97
- "tlvs" : []}
151
+ "tlvs_prot" : [],
152
+ "tlv_hdr" : {},
153
+ "tlvs" : []}
98
154
tlv_off = header ["hdr_size" ] + header ["img_size" ]
99
155
protected_tlv_size = header ["protected_tlv_size" ]
100
156
101
157
if protected_tlv_size != 0 :
102
158
_tlv_prot_head = struct .unpack (
103
- 'HH' ,
104
- b [tlv_off :(tlv_off + image .TLV_INFO_SIZE )])
159
+ 'HH' ,
160
+ b [tlv_off :(tlv_off + image .TLV_INFO_SIZE )])
105
161
tlv_area ["tlv_hdr_prot" ]["magic" ] = _tlv_prot_head [0 ]
106
162
tlv_area ["tlv_hdr_prot" ]["tlv_tot" ] = _tlv_prot_head [1 ]
107
163
tlv_end = tlv_off + tlv_area ["tlv_hdr_prot" ]["tlv_tot" ]
@@ -110,8 +166,8 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
110
166
# Iterating through the protected TLV area
111
167
while tlv_off < tlv_end :
112
168
tlv_type , tlv_len = struct .unpack (
113
- 'HH' ,
114
- b [tlv_off :(tlv_off + image .TLV_INFO_SIZE )])
169
+ 'HH' ,
170
+ b [tlv_off :(tlv_off + image .TLV_INFO_SIZE )])
115
171
tlv_off += image .TLV_INFO_SIZE
116
172
tlv_data = b [tlv_off :(tlv_off + tlv_len )]
117
173
tlv_area ["tlvs_prot" ].append (
@@ -128,8 +184,8 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
128
184
# Iterating through the TLV area
129
185
while tlv_off < tlv_end :
130
186
tlv_type , tlv_len = struct .unpack (
131
- 'HH' ,
132
- b [tlv_off :(tlv_off + image .TLV_INFO_SIZE )])
187
+ 'HH' ,
188
+ b [tlv_off :(tlv_off + image .TLV_INFO_SIZE )])
133
189
tlv_off += image .TLV_INFO_SIZE
134
190
tlv_data = b [tlv_off :(tlv_off + tlv_len )]
135
191
tlv_area ["tlvs" ].append (
@@ -177,7 +233,7 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
177
233
178
234
# Encryption key 0/1
179
235
if ((header ["flags" ] & image .IMAGE_F ["ENCRYPTED_AES128" ]) or
180
- (header ["flags" ] & image .IMAGE_F ["ENCRYPTED_AES256" ])):
236
+ (header ["flags" ] & image .IMAGE_F ["ENCRYPTED_AES256" ])):
181
237
# The image is encrypted
182
238
# Estimated value of key_field_len is correct if
183
239
# BOOT_SWAP_SAVE_ENCTLV is unset
@@ -192,17 +248,16 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
192
248
# sort_keys - from pyyaml 5.1
193
249
yaml .dump (imgdata , outf , sort_keys = False )
194
250
195
- ###############################################################################
251
+ ###############################################################################
196
252
197
253
if silent :
198
254
sys .exit (0 )
199
255
200
256
print ("Printing content of signed image:" , os .path .basename (imgfile ), "\n " )
201
257
202
258
# Image header
203
- str1 = "#### Image header (offset: 0x0) "
204
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
205
- print (str1 + str2 )
259
+ section_name = "Image header (offset: 0x0)"
260
+ print_in_row (section_name )
206
261
for key , value in header .items ():
207
262
if key == "flags" :
208
263
if not value :
@@ -214,45 +269,34 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
214
269
if flag_string :
215
270
flag_string += ("\n " + (" " * 20 ))
216
271
flag_string += "{} ({})" .format (
217
- flag , hex (image .IMAGE_F [flag ]))
272
+ flag , hex (image .IMAGE_F [flag ]))
218
273
value = flag_string
219
274
220
- if type (value ) != str :
275
+ if not isinstance (value , str ) :
221
276
value = hex (value )
222
277
print (key , ":" , " " * (19 - len (key )), value , sep = "" )
223
278
print ("#" * _LINE_LENGTH )
224
279
225
280
# Image payload
226
281
_sectionoff = header ["hdr_size" ]
227
- sepc = " "
228
- str1 = "#### Payload (offset: {}) " .format (hex (_sectionoff ))
229
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
230
- print (str1 + str2 )
231
- print ("|" , sepc * (_LINE_LENGTH - 2 ), "|" , sep = "" )
232
- str1 = "FW image (size: {} Bytes)" .format (hex (header ["img_size" ]))
233
- numc = (_LINE_LENGTH - len (str1 )) // 2
234
- str2 = "|" + (sepc * (numc - 1 ))
235
- str3 = sepc * (_LINE_LENGTH - len (str2 ) - len (str1 ) - 1 ) + "|"
236
- print (str2 , str1 , str3 , sep = "" )
237
- print ("|" , sepc * (_LINE_LENGTH - 2 ), "|" , sep = "" )
238
- print ("#" * _LINE_LENGTH )
282
+ frame_header_text = "Payload (offset: {})" .format (hex (_sectionoff ))
283
+ frame_content = "FW image (size: {} Bytes)" .format (hex (header ["img_size" ]))
284
+ print_in_frame (frame_header_text , frame_content )
239
285
240
286
# TLV area
241
287
_sectionoff += header ["img_size" ]
242
288
if protected_tlv_size != 0 :
243
289
# Protected TLV area
244
- str1 = "#### Protected TLV area (offset: {}) " .format (hex (_sectionoff ))
245
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
246
- print (str1 + str2 )
290
+ section_name = "Protected TLV area (offset: {})" .format (hex (_sectionoff ))
291
+ print_in_row (section_name )
247
292
print ("magic: " , hex (tlv_area ["tlv_hdr_prot" ]["magic" ]))
248
293
print ("area size:" , hex (tlv_area ["tlv_hdr_prot" ]["tlv_tot" ]))
249
294
print_tlv_records (tlv_area ["tlvs_prot" ])
250
295
print ("#" * _LINE_LENGTH )
251
296
252
297
_sectionoff += protected_tlv_size
253
- str1 = "#### TLV area (offset: {}) " .format (hex (_sectionoff ))
254
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
255
- print (str1 + str2 )
298
+ section_name = "TLV area (offset: {})" .format (hex (_sectionoff ))
299
+ print_in_row (section_name )
256
300
print ("magic: " , hex (tlv_area ["tlv_hdr" ]["magic" ]))
257
301
print ("area size:" , hex (tlv_area ["tlv_hdr" ]["tlv_tot" ]))
258
302
print_tlv_records (tlv_area ["tlvs" ])
@@ -261,40 +305,24 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
261
305
if _img_pad_size :
262
306
_sectionoff += tlv_area ["tlv_hdr" ]["tlv_tot" ]
263
307
_erased_val = b [_sectionoff ]
264
- str1 = "#### Image padding (offset: {}) " .format (hex (_sectionoff ))
265
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
266
- print (str1 + str2 )
267
- print ("|" , sepc * (_LINE_LENGTH - 2 ), "|" , sep = "" )
268
- str1 = "padding ({})" .format (hex (_erased_val ))
269
- numc = (_LINE_LENGTH - len (str1 )) // 2
270
- str2 = "|" + (sepc * (numc - 1 ))
271
- str3 = sepc * (_LINE_LENGTH - len (str2 ) - len (str1 ) - 1 ) + "|"
272
- print (str2 , str1 , str3 , sep = "" )
273
- print ("|" , sepc * (_LINE_LENGTH - 2 ), "|" , sep = "" )
274
- print ("#" * _LINE_LENGTH )
308
+ frame_header_text = "Image padding (offset: {})" .format (hex (_sectionoff ))
309
+ frame_content = "padding ({})" .format (hex (_erased_val ))
310
+ print_in_frame (frame_header_text , frame_content )
275
311
276
312
# Image trailer
277
- str1 = "#### Image trailer (offset: unknown) "
278
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
279
- print (str1 + str2 )
280
- print ("(Note: some field may not be used, \n "
281
- " depending on the update strategy)\n " )
282
-
313
+ section_name = "Image trailer (offset: unknown)"
314
+ print_in_row (section_name )
315
+ notice = "(Note: some fields may not be used, depending on the update strategy)\n "
316
+ notice = '\n ' .join (notice [i :i + _LINE_LENGTH ] for i in range (0 , len (notice ), _LINE_LENGTH ))
317
+ print (notice )
283
318
print ("swap status: (len: unknown)" )
284
- if key_field_len is not None :
285
- print ("enc. keys: (len: {}, if BOOT_SWAP_SAVE_ENCTLV is unset)"
286
- .format (hex (key_field_len )))
287
- print ("swap size: " , hex (swap_size ))
288
- print ("swap_info: " , hex (swap_info ))
289
- print ("copy_done: " , hex (copy_done ))
290
- print ("image_ok: " , hex (image_ok ))
291
- print ("boot magic: " , end = "" )
292
- for i in range (BOOT_MAGIC_SIZE ):
293
- print ("{0:#04x}" .format (trailer_magic [i ]), end = " " )
294
- if i == (BOOT_MAGIC_SIZE / 2 - 1 ):
295
- print ("\n " , end = " " )
319
+ print ("enc. keys: " , parse_enc (key_field_len ))
320
+ print ("swap size: " , parse_size (hex (swap_size )))
321
+ print ("swap_info: " , parse_status (hex (swap_info )))
322
+ print ("copy_done: " , parse_status (hex (copy_done )))
323
+ print ("image_ok: " , parse_status (hex (image_ok )))
324
+ print ("boot magic: " , parse_boot_magic (trailer_magic ))
296
325
print ()
297
326
298
- str1 = "#### End of Image "
299
- str2 = "#" * (_LINE_LENGTH - len (str1 ))
300
- print (str1 + str2 )
327
+ footer = "End of Image "
328
+ print_in_row (footer )
0 commit comments