@@ -19,14 +19,15 @@ class NrfUtilBinaryRunner(NrfBinaryRunner):
1919 def __init__ (self , cfg , family , softreset , pinreset , dev_id , erase = False ,
2020 erase_mode = None , ext_erase_mode = None , reset = True , tool_opt = None ,
2121 force = False , recover = False , suit_starter = False ,
22- ext_mem_config_file = None ):
22+ ext_mem_config_file = None , ncs_provision = False ):
2323
2424 super ().__init__ (cfg , family , softreset , pinreset , dev_id , erase ,
2525 erase_mode , ext_erase_mode , reset , tool_opt , force ,
2626 recover )
2727
2828 self .suit_starter = suit_starter
2929 self .ext_mem_config_file = ext_mem_config_file
30+ self .ncs_provision = ncs_provision
3031
3132 self ._ops = []
3233 self ._op_id = 1
@@ -57,7 +58,8 @@ def do_create(cls, cfg, args):
5758 reset = args .reset , tool_opt = args .tool_opt ,
5859 force = args .force , recover = args .recover ,
5960 suit_starter = args .suit_manifest_starter ,
60- ext_mem_config_file = args .ext_mem_config_file )
61+ ext_mem_config_file = args .ext_mem_config_file ,
62+ ncs_provision = args .ncs_provision )
6163
6264 @classmethod
6365 def do_add_parser (cls , parser ):
@@ -68,6 +70,9 @@ def do_add_parser(cls, parser):
6870 parser .add_argument ('--ext-mem-config-file' , required = False ,
6971 dest = 'ext_mem_config_file' ,
7072 help = 'path to an JSON file with external memory configuration' )
73+ parser .add_argument ('--ncs-provision' ,
74+ action = 'store_true' ,
75+ help = 'run ncs-provision with default keys' )
7176
7277 def _exec (self , args ):
7378 jout_all = []
@@ -115,6 +120,75 @@ def do_get_boards(self):
115120 def do_require (self ):
116121 self .require ('nrfutil' )
117122
123+ def _generate_ncs_provision_key_file (
124+ self ,
125+ keys : list [str ] | str ,
126+ keyname : str , # UROT_PUBKEY, BL_PUBKEY, APP_PUBKEY
127+ output_file : Path
128+ ):
129+ """Generate a key file for ncs-provision
130+
131+ This function uses the 'west ncs-provision' command to generate a JSON key file.
132+ Note: This functionality requires the sdk-nrf repository to be present, as it's
133+ not part of the Zephyr tree.
134+ """
135+ build_dir = Path (self .cfg .build_dir ).parent
136+ ncs_keyfile = build_dir / 'keyfile.json'
137+ if ncs_keyfile .exists ():
138+ ncs_keyfile .unlink ()
139+ command = [
140+ 'west' , 'ncs-provision' , 'upload' ,
141+ '--keyname' , keyname ,
142+ '--build-dir' , str (build_dir ),
143+ '--dry-run'
144+ ]
145+ for key in keys :
146+ command += ["--key" , key ]
147+ self .check_call (command )
148+
149+ # move the generated ncs keyfile to the output_file
150+ if output_file .exists ():
151+ output_file .unlink ()
152+ ncs_keyfile .rename (output_file )
153+
154+ def _ncs_provision_for_nsib (self ):
155+ if not self .sysbuild_conf .getboolean ('SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519' ):
156+ return
157+ build_dir = Path (self .cfg .build_dir ).parent
158+ key_file = self .sysbuild_conf .get ('SB_CONFIG_SECURE_BOOT_SIGNING_KEY_FILE' ) or str (
159+ build_dir / 'GENERATED_NON_SECURE_SIGN_KEY_PRIVATE.pem' )
160+ if not Path (key_file ).exists ():
161+ raise RuntimeError (f'Key file { key_file } does not exist' )
162+
163+ ncs_keyfile = build_dir / 'keyfile_for_nsib.json'
164+ self ._generate_ncs_provision_key_file (
165+ keys = [key_file ],
166+ keyname = 'BL_PUBKEY' ,
167+ output_file = ncs_keyfile
168+ )
169+ self .exec_op ('x-provision-keys' , keyfile = str (ncs_keyfile ))
170+
171+ def _ncs_provision_for_mcuboot (self ):
172+ if not self .sysbuild_conf .getboolean ('SB_CONFIG_MCUBOOT_SIGNATURE_USING_KMU' ):
173+ return
174+ key_file = self .sysbuild_conf .get ('SB_CONFIG_BOOT_SIGNATURE_KEY_FILE' )
175+ if not Path (key_file ).exists ():
176+ raise RuntimeError (f'Key figrch_rework_testsle { key_file } does not exist' )
177+
178+ ncs_keyfile = Path (self .cfg .build_dir ).parent / 'keyfile_for_mcuboot.json'
179+ self ._generate_ncs_provision_key_file (
180+ keys = [key_file ],
181+ keyname = 'UROT_PUBKEY' ,
182+ output_file = ncs_keyfile
183+ )
184+ self .exec_op ('x-provision-keys' , keyfile = str (ncs_keyfile ))
185+
186+ def do_ncs_provision (self ):
187+ if not self .ncs_provision :
188+ return
189+ self ._ncs_provision_for_nsib ()
190+ self ._ncs_provision_for_mcuboot ()
191+
118192 def _insert_op (self , op ):
119193 op ['operationId' ] = f'{ self ._op_id } '
120194 self ._op_id += 1
@@ -147,6 +221,8 @@ def _append_batch(self, op, json_file):
147221 cmd += ['--reset-kind' , _op ['kind' ]]
148222 elif op_type == 'erase' :
149223 cmd .append (f'--{ _op ["kind" ]} ' )
224+ elif op_type == 'x-provision-keys' :
225+ cmd += ['--key-file' , _op ['keyfile' ]]
150226
151227 cmd += ['--core' , op ['core' ]] if op .get ('core' ) else []
152228 cmd += ['--x-family' , f'{ self .family } ' ]
0 commit comments