1
1
# Copyright 2018 Nordic Semiconductor ASA
2
2
# Copyright 2017-2020 Linaro Limited
3
- # Copyright 2019-2020 Arm Limited
3
+ # Copyright 2019-2021 Arm Limited
4
4
#
5
5
# SPDX-License-Identifier: Apache-2.0
6
6
#
51
51
# Image header flags.
52
52
IMAGE_F = {
53
53
'PIC' : 0x0000001 ,
54
+ 'ENCRYPTED_AES128' : 0x0000004 ,
55
+ 'ENCRYPTED_AES256' : 0x0000008 ,
54
56
'NON_BOOTABLE' : 0x0000010 ,
55
57
'RAM_LOAD' : 0x0000020 ,
56
- 'ENCRYPTED ' : 0x0000004 ,
58
+ 'ROM_FIXED ' : 0x0000100 ,
57
59
}
58
60
59
61
TLV_VALUES = {
66
68
'RSA3072' : 0x23 ,
67
69
'ED25519' : 0x24 ,
68
70
'ENCRSA2048' : 0x30 ,
69
- 'ENCKW128 ' : 0x31 ,
71
+ 'ENCKW ' : 0x31 ,
70
72
'ENCEC256' : 0x32 ,
71
73
'ENCX25519' : 0x33 ,
72
74
'DEPENDENCY' : 0x40 ,
@@ -132,7 +134,12 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
132
134
pad_header = False , pad = False , confirm = False , align = 1 ,
133
135
slot_size = 0 , max_sectors = DEFAULT_MAX_SECTORS ,
134
136
overwrite_only = False , endian = "little" , load_addr = 0 ,
135
- erased_val = None , save_enctlv = False , security_counter = None ):
137
+ rom_fixed = None , erased_val = None , save_enctlv = False ,
138
+ security_counter = None ):
139
+
140
+ if load_addr and rom_fixed :
141
+ raise click .UsageError ("Can not set rom_fixed and load_addr at the same time" )
142
+
136
143
self .version = version or versmod .decode_version ("0" )
137
144
self .header_size = header_size
138
145
self .pad_header = pad_header
@@ -145,6 +152,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE,
145
152
self .endian = endian
146
153
self .base_addr = None
147
154
self .load_addr = 0 if load_addr is None else load_addr
155
+ self .rom_fixed = rom_fixed
148
156
self .erased_val = 0xff if erased_val is None else int (erased_val , 0 )
149
157
self .payload = []
150
158
self .enckey = None
@@ -281,7 +289,7 @@ def ecies_hkdf(self, enckey, plainkey):
281
289
return cipherkey , ciphermac , pubk
282
290
283
291
def create (self , key , public_key_format , enckey , dependencies = None ,
284
- sw_type = None , custom_tlvs = None ):
292
+ sw_type = None , custom_tlvs = None , encrypt_keylen = 128 ):
285
293
self .enckey = enckey
286
294
287
295
# Calculate the hash of the public key
@@ -347,10 +355,17 @@ def create(self, key, public_key_format, enckey, dependencies=None,
347
355
if self .enckey is not None :
348
356
pad_len = len (self .payload ) % 16
349
357
if pad_len > 0 :
350
- self .payload += bytes (16 - pad_len )
358
+ pad = bytes (16 - pad_len )
359
+ if isinstance (self .payload , bytes ):
360
+ self .payload += pad
361
+ else :
362
+ self .payload .extend (pad )
351
363
352
364
# This adds the header to the payload as well
353
- self .add_header (enckey , protected_tlv_size )
365
+ if encrypt_keylen == 256 :
366
+ self .add_header (enckey , protected_tlv_size , 256 )
367
+ else :
368
+ self .add_header (enckey , protected_tlv_size )
354
369
355
370
prot_tlv = TLV (self .endian , TLV_PROT_INFO_MAGIC )
356
371
@@ -418,7 +433,10 @@ def create(self, key, public_key_format, enckey, dependencies=None,
418
433
self .payload = self .payload [:protected_tlv_off ]
419
434
420
435
if enckey is not None :
421
- plainkey = os .urandom (16 )
436
+ if encrypt_keylen == 256 :
437
+ plainkey = os .urandom (32 )
438
+ else :
439
+ plainkey = os .urandom (16 )
422
440
423
441
if isinstance (enckey , rsa .RSAPublic ):
424
442
cipherkey = enckey ._get_public ().encrypt (
@@ -451,16 +469,21 @@ def create(self, key, public_key_format, enckey, dependencies=None,
451
469
452
470
self .check_trailer ()
453
471
454
- def add_header (self , enckey , protected_tlv_size ):
472
+ def add_header (self , enckey , protected_tlv_size , aes_length = 128 ):
455
473
"""Install the image header."""
456
474
457
475
flags = 0
458
476
if enckey is not None :
459
- flags |= IMAGE_F ['ENCRYPTED' ]
477
+ if aes_length == 128 :
478
+ flags |= IMAGE_F ['ENCRYPTED_AES128' ]
479
+ else :
480
+ flags |= IMAGE_F ['ENCRYPTED_AES256' ]
460
481
if self .load_addr != 0 :
461
482
# Indicates that this image should be loaded into RAM
462
483
# instead of run directly from flash.
463
484
flags |= IMAGE_F ['RAM_LOAD' ]
485
+ if self .rom_fixed :
486
+ flags |= IMAGE_F ['ROM_FIXED' ]
464
487
465
488
e = STRUCT_ENDIAN_DICT [self .endian ]
466
489
fmt = (e +
@@ -477,7 +500,7 @@ def add_header(self, enckey, protected_tlv_size):
477
500
assert struct .calcsize (fmt ) == IMAGE_HEADER_SIZE
478
501
header = struct .pack (fmt ,
479
502
IMAGE_MAGIC ,
480
- self .load_addr ,
503
+ self .rom_fixed or self . load_addr ,
481
504
self .header_size ,
482
505
protected_tlv_size , # TLV Info header + Protected TLVs
483
506
len (self .payload ) - self .header_size , # ImageSz
@@ -537,16 +560,22 @@ def verify(imgfile, key):
537
560
if magic != IMAGE_MAGIC :
538
561
return VerifyResult .INVALID_MAGIC , None , None
539
562
540
- tlv_info = b [header_size + img_size :header_size + img_size + TLV_INFO_SIZE ]
563
+ tlv_off = header_size + img_size
564
+ tlv_info = b [tlv_off :tlv_off + TLV_INFO_SIZE ]
541
565
magic , tlv_tot = struct .unpack ('HH' , tlv_info )
566
+ if magic == TLV_PROT_INFO_MAGIC :
567
+ tlv_off += tlv_tot
568
+ tlv_info = b [tlv_off :tlv_off + TLV_INFO_SIZE ]
569
+ magic , tlv_tot = struct .unpack ('HH' , tlv_info )
570
+
542
571
if magic != TLV_INFO_MAGIC :
543
572
return VerifyResult .INVALID_TLV_INFO_MAGIC , None , None
544
573
545
574
sha = hashlib .sha256 ()
546
- sha .update (b [:header_size + img_size ])
575
+ prot_tlv_size = tlv_off
576
+ sha .update (b [:prot_tlv_size ])
547
577
digest = sha .digest ()
548
578
549
- tlv_off = header_size + img_size
550
579
tlv_end = tlv_off + tlv_tot
551
580
tlv_off += TLV_INFO_SIZE # skip tlv info
552
581
while tlv_off < tlv_end :
@@ -562,7 +591,7 @@ def verify(imgfile, key):
562
591
elif key is not None and tlv_type == TLV_VALUES [key .sig_tlv ()]:
563
592
off = tlv_off + TLV_SIZE
564
593
tlv_sig = b [off :off + tlv_len ]
565
- payload = b [:header_size + img_size ]
594
+ payload = b [:prot_tlv_size ]
566
595
try :
567
596
if hasattr (key , 'verify' ):
568
597
key .verify (tlv_sig , payload )
0 commit comments