11#! /usr/bin/env python3
22#
33# Copyright 2017 Linaro Limited
4- # Copyright (c) 2018, Arm Limited.
4+ # Copyright (c) 2018-2019 , Arm Limited.
55#
66# Licensed under the Apache License, Version 2.0 (the "License");
77# you may not use this file except in compliance with the License.
2424from .imgtool_lib import version
2525import sys
2626
27+ sign_bin_size_re = re .compile (r"^\s*RE_SIGN_BIN_SIZE\s*=\s*(.*)" )
28+ image_load_address_re = re .compile (r"^\s*RE_IMAGE_LOAD_ADDRESS\s*=\s*(.*)" )
29+
2730def find_load_address (args ):
2831 load_address_re = re .compile (r"^#define\sIMAGE_LOAD_ADDRESS\s+(0x[0-9a-fA-F]+)" )
2932
@@ -60,30 +63,37 @@ def get_last_version(path):
6063
6164def next_version_number (args , defaultVersion , path ):
6265 newVersion = None
66+ versionProvided = False
6367 if (version .compare (args .version , defaultVersion ) == 0 ): # Default version
6468 lastVersion = get_last_version (path )
6569 if (lastVersion is not None ):
6670 newVersion = version .increment_build_num (lastVersion )
6771 else :
6872 newVersion = version .increment_build_num (defaultVersion )
6973 else : # Version number has been explicitly provided (not using the default)
74+ versionProvided = True
7075 newVersion = args .version
7176 versionString = "{a}.{b}.{c}+{d}" .format (
7277 a = str (newVersion .major ),
7378 b = str (newVersion .minor ),
7479 c = str (newVersion .revision ),
7580 d = str (newVersion .build )
7681 )
77- with open (path , "w" ) as newFile :
78- newFile .write (versionString )
82+ if not versionProvided :
83+ with open (path , "w" ) as newFile :
84+ newFile .write (versionString )
7985 print ("**[INFO]** Image version number set to " + versionString )
8086 return newVersion
8187
8288def gen_rsa2048 (args ):
83- keys .RSA2048 .generate ().export_private (args .key )
89+ keys .RSAutil .generate ().export_private (args .key )
90+
91+ def gen_rsa3072 (args ):
92+ keys .RSAutil .generate (key_size = 3072 ).export_private (args .key )
8493
8594keygens = {
86- 'rsa-2048' : gen_rsa2048 , }
95+ 'rsa-2048' : gen_rsa2048 ,
96+ 'rsa-3072' : gen_rsa3072 , }
8797
8898def do_keygen (args ):
8999 if args .type not in keygens :
@@ -102,18 +112,38 @@ def do_getpub(args):
102112def do_sign (args ):
103113 if args .rsa_pkcs1_15 :
104114 keys .sign_rsa_pss = False
115+
116+ version_num = next_version_number (args ,
117+ version .decode_version ("0" ),
118+ "lastVerNum.txt" )
119+
120+ if args .security_counter is None :
121+ # Security counter has not been explicitly provided,
122+ # generate it from the version number
123+ args .security_counter = ((version_num .major << 24 )
124+ + (version_num .minor << 16 )
125+ + version_num .revision )
126+
127+ if "_s.c" in args .layout :
128+ sw_type = "SPE"
129+ elif "_ns.c" in args .layout :
130+ sw_type = "NSPE"
131+ else :
132+ sw_type = "NSPE_SPE"
133+
134+ pad_size = args .pad
105135 img = image .Image .load (args .infile ,
106- version = next_version_number ( args ,
107- version . decode_version ( "0" ) ,
108- "lastVerNum.txt" ) ,
109- header_size = args .header_size ,
110- included_header = args . included_header ,
111- pad = args .pad )
112- key = keys . load (args . key ) if args . key else None
113- img .sign (key , find_load_address ( args ) )
114-
115- if args . pad :
116- img .pad_to (args . pad , args .align )
136+ version = version_num ,
137+ header_size = args . header_size ,
138+ security_cnt = args . security_counter ,
139+ included_header = args .included_header ,
140+ pad = pad_size )
141+ key = keys . load ( args . key , args . public_key_format ) if args .key else None
142+ ram_load_address = find_load_address (args )
143+ img .sign (sw_type , key , ram_load_address , args . dependencies )
144+
145+ if pad_size :
146+ img .pad_to (pad_size , args .align )
117147
118148 img .save (args .outfile )
119149
@@ -122,6 +152,30 @@ def do_sign(args):
122152 'getpub' : do_getpub ,
123153 'sign' : do_sign , }
124154
155+
156+ def get_dependencies (text ):
157+ if text is not None :
158+ versions = []
159+ images = re .findall (r"\((\d+)" , text )
160+ if len (images ) == 0 :
161+ msg = "Image dependency format is invalid: {}" .format (text )
162+ raise argparse .ArgumentTypeError (msg )
163+ raw_versions = re .findall (r",\s*([0-9.+]+)\)" , text )
164+ if len (images ) != len (raw_versions ):
165+ msg = '''There's a mismatch between the number of dependency images
166+ and versions in: {}''' .format (text )
167+ raise argparse .ArgumentTypeError (msg )
168+ for raw_version in raw_versions :
169+ try :
170+ versions .append (version .decode_version (raw_version ))
171+ except ValueError as e :
172+ print (e )
173+ dependencies = dict ()
174+ dependencies [image .DEP_IMAGES_KEY ] = images
175+ dependencies [image .DEP_VERSIONS_KEY ] = versions
176+ return dependencies
177+
178+
125179def alignment_value (text ):
126180 value = int (text )
127181 if value not in [1 , 2 , 4 , 8 ]:
@@ -149,17 +203,23 @@ def args():
149203 getpub .add_argument ('-l' , '--lang' , metavar = 'lang' , default = 'c' )
150204
151205 sign = subs .add_parser ('sign' , help = 'Sign an image with a private key' )
152- sign .add_argument ('--layout' , required = True ,
153- help = 'Location of the memory layout file ' )
206+ sign .add_argument ('-l' , '- -layout' , required = True ,
207+ help = 'Location of the file that contains preprocessed macros ' )
154208 sign .add_argument ('-k' , '--key' , metavar = 'filename' )
209+ sign .add_argument ("-K" , "--public-key-format" ,
210+ help = 'In what format to add the public key to the image manifest: full or hash' ,
211+ metavar = 'pub_key_format' , choices = ['full' , 'hash' ], default = 'hash' )
155212 sign .add_argument ("--align" , type = alignment_value , required = True )
156213 sign .add_argument ("-v" , "--version" , type = version .decode_version ,
157214 default = "0.0.0+0" )
215+ sign .add_argument ("-d" , "--dependencies" , type = get_dependencies ,
216+ required = False , help = '''Add dependence on another image,
217+ format: "(<image_ID>,<image_version>), ... "''' )
218+ sign .add_argument ("-s" , "--security-counter" , type = intparse ,
219+ help = 'Specify explicitly the security counter value' )
158220 sign .add_argument ("-H" , "--header-size" , type = intparse , required = True )
159221 sign .add_argument ("--included-header" , default = False , action = 'store_true' ,
160222 help = 'Image has gap for header' )
161- sign .add_argument ("--pad" , type = intparse ,
162- help = 'Pad image to this many bytes, adding trailer magic' )
163223 sign .add_argument ("--rsa-pkcs1-15" ,
164224 help = 'Use old PKCS#1 v1.5 signature algorithm' ,
165225 default = False , action = 'store_true' )
@@ -174,4 +234,4 @@ def args():
174234 subcmds [args .subcmd ](args )
175235
176236if __name__ == '__main__' :
177- args ()
237+ args ()
0 commit comments