41
41
'nvs_partition_generator' ))
42
42
import nvs_partition_gen
43
43
else :
44
- log . error ("Please set the IDF_PATH environment variable." )
44
+ sys . stderr . write ("Please set the IDF_PATH environment variable." )
45
45
exit (0 )
46
46
47
47
INVALID_PASSCODES = [00000000 , 11111111 , 22222222 , 33333333 , 44444444 , 55555555 ,
@@ -236,7 +236,7 @@ def check_str_range(s, min_len, max_len, name):
236
236
237
237
238
238
def check_int_range (value , min_value , max_value , name ):
239
- if value and ((value < min_value ) or (value > max_value )):
239
+ if ( value is not None ) and ((value < min_value ) or (value > max_value )):
240
240
logging .error ('%s is out of range, should be in range [%d, %d]' , name , min_value , max_value )
241
241
sys .exit (1 )
242
242
@@ -277,40 +277,48 @@ def gen_spake2p_params(passcode):
277
277
278
278
279
279
def populate_factory_data (args , spake2p_params ):
280
- FACTORY_DATA ['discriminator' ]['value' ] = args .discriminator
281
- FACTORY_DATA ['iteration-count' ]['value' ] = spake2p_params ['Iteration Count' ]
282
- FACTORY_DATA ['salt' ]['value' ] = spake2p_params ['Salt' ]
283
- FACTORY_DATA ['verifier' ]['value' ] = spake2p_params ['Verifier' ]
284
- FACTORY_DATA ['dac-cert' ]['value' ] = os .path .abspath (args .dac_cert )
285
- FACTORY_DATA ['pai-cert' ]['value' ] = os .path .abspath (args .pai_cert )
286
- FACTORY_DATA ['cert-dclrn' ]['value' ] = os .path .abspath (args .cd )
287
- FACTORY_DATA ['dac-key' ]['value' ] = os .path .abspath ('dac_raw_privkey.bin' )
288
- FACTORY_DATA ['dac-pub-key' ]['value' ] = os .path .abspath ('dac_raw_pubkey.bin' )
289
-
290
- if args .serial_num is not None :
280
+ if args .discriminator is not None :
281
+ FACTORY_DATA ['discriminator' ]['value' ] = args .discriminator
282
+
283
+ if spake2p_params :
284
+ FACTORY_DATA ['iteration-count' ]['value' ] = spake2p_params ['Iteration Count' ]
285
+ FACTORY_DATA ['salt' ]['value' ] = spake2p_params ['Salt' ]
286
+ FACTORY_DATA ['verifier' ]['value' ] = spake2p_params ['Verifier' ]
287
+
288
+ if args .dac_cert :
289
+ FACTORY_DATA ['dac-cert' ]['value' ] = os .path .abspath (args .dac_cert )
290
+ if args .pai_cert :
291
+ FACTORY_DATA ['pai-cert' ]['value' ] = os .path .abspath (args .pai_cert )
292
+ if args .cd :
293
+ FACTORY_DATA ['cert-dclrn' ]['value' ] = os .path .abspath (args .cd )
294
+ if args .dac_key :
295
+ FACTORY_DATA ['dac-key' ]['value' ] = os .path .abspath ('dac_raw_privkey.bin' )
296
+ FACTORY_DATA ['dac-pub-key' ]['value' ] = os .path .abspath ('dac_raw_pubkey.bin' )
297
+
298
+ if args .serial_num :
291
299
FACTORY_DATA ['serial-num' ]['value' ] = args .serial_num
292
- if args .rd_id_uid is not None :
300
+ if args .rd_id_uid :
293
301
FACTORY_DATA ['rd-id-uid' ]['value' ] = args .rd_id_uid
294
- if args .mfg_date is not None :
302
+ if args .mfg_date :
295
303
FACTORY_DATA ['mfg-date' ]['value' ] = args .mfg_date
296
304
if args .vendor_id is not None :
297
305
FACTORY_DATA ['vendor-id' ]['value' ] = args .vendor_id
298
- if args .vendor_name is not None :
306
+ if args .vendor_name :
299
307
FACTORY_DATA ['vendor-name' ]['value' ] = args .vendor_name
300
308
if args .product_id is not None :
301
309
FACTORY_DATA ['product-id' ]['value' ] = args .product_id
302
- if args .product_name is not None :
310
+ if args .product_name :
303
311
FACTORY_DATA ['product-name' ]['value' ] = args .product_name
304
312
if args .hw_ver is not None :
305
313
FACTORY_DATA ['hardware-ver' ]['value' ] = args .hw_ver
306
- if ( args .hw_ver_str is not None ) :
314
+ if args .hw_ver_str :
307
315
FACTORY_DATA ['hw-ver-str' ]['value' ] = args .hw_ver_str
308
316
309
- if ( args .calendar_types is not None ) :
317
+ if args .calendar_types :
310
318
FACTORY_DATA ['cal-types' ]['value' ] = calendar_types_to_uint32 (args .calendar_types )
311
319
312
320
# Supported locale is stored as multiple entries, key format: "locale/<index>, example key: "locale/0"
313
- if ( args .locales is not None ) :
321
+ if args .locales :
314
322
FACTORY_DATA ['locale-sz' ]['value' ] = len (args .locales )
315
323
316
324
for i in range (len (args .locales )):
@@ -325,7 +333,7 @@ def populate_factory_data(args, spake2p_params):
325
333
# - fl-sz/<index> : number of fixed labels for the endpoint
326
334
# - fl-k/<ep>/<index> : fixed label key for the endpoint and index
327
335
# - fl-v/<ep>/<index> : fixed label value for the endpoint and index
328
- if ( args .fixed_labels is not None ) :
336
+ if args .fixed_labels :
329
337
dict = get_fixed_label_dict (args .fixed_labels )
330
338
for key in dict .keys ():
331
339
_sz = {
@@ -378,7 +386,7 @@ def gen_raw_ec_keypair_from_der(key_file, pubkey_raw_file, privkey_raw_file):
378
386
f .write (public_number_y .to_bytes (32 , byteorder = 'big' ))
379
387
380
388
381
- def generate_nvs_bin ( args ):
389
+ def generate_nvs_csv ( out_csv_filename ):
382
390
csv_content = 'key,type,encoding,value\n '
383
391
csv_content += 'chip-factory,namespace,,\n '
384
392
@@ -387,41 +395,46 @@ def generate_nvs_bin(args):
387
395
continue
388
396
csv_content += f"{ k } ,{ v ['type' ]} ,{ v ['encoding' ]} ,{ v ['value' ]} \n "
389
397
390
- with open (FACTORY_PARTITION_CSV , 'w' ) as f :
398
+ with open (out_csv_filename , 'w' ) as f :
391
399
f .write (csv_content )
392
400
393
- if args .encrypt :
401
+ logging .info ('Generated the factory partition csv file : {}' .format (os .path .abspath (out_csv_filename )))
402
+
403
+
404
+ def generate_nvs_bin (encrypt , size , csv_filename , bin_filename ):
405
+ if encrypt :
394
406
nvs_args = SimpleNamespace (version = 2 ,
395
407
keygen = True ,
396
408
keyfile = NVS_KEY_PARTITION_BIN ,
397
409
inputkey = None ,
398
410
outdir = os .getcwd (),
399
- input = FACTORY_PARTITION_CSV ,
400
- output = FACTORY_PARTITION_BIN ,
401
- size = hex (args . size ))
411
+ input = csv_filename ,
412
+ output = bin_filename ,
413
+ size = hex (size ))
402
414
nvs_partition_gen .encrypt (nvs_args )
403
415
else :
404
- nvs_args = SimpleNamespace (input = FACTORY_PARTITION_CSV ,
405
- output = FACTORY_PARTITION_BIN ,
406
- size = hex (args . size ),
416
+ nvs_args = SimpleNamespace (input = csv_filename ,
417
+ output = bin_filename ,
418
+ size = hex (size ),
407
419
outdir = os .getcwd (),
408
420
version = 2 )
409
421
nvs_partition_gen .generate (nvs_args )
410
422
411
423
412
- def print_flashing_help (encrypt ):
413
- logging .info ('Run below command to flash {}' .format (FACTORY_PARTITION_BIN ))
414
- logging .info ('esptool.py -p (PORT) write_flash (FACTORY_PARTITION_ADDR) {}' .format (os .path .join (os .getcwd (), FACTORY_PARTITION_BIN )))
424
+ def print_flashing_help (encrypt , bin_filename ):
425
+ logging .info ('Run below command to flash {}' .format (bin_filename ))
426
+ logging .info ('esptool.py -p (PORT) write_flash (FACTORY_PARTITION_ADDR) {}' .format (os .path .join (os .getcwd (), bin_filename )))
415
427
if (encrypt ):
416
428
logging .info ('Run below command to flash {}' .format (NVS_KEY_PARTITION_BIN ))
417
429
logging .info ('esptool.py -p (PORT) write_flash --encrypt (NVS_KEY_PARTITION_ADDR) {}' .format (
418
430
os .path .join (os .getcwd (), 'keys' , NVS_KEY_PARTITION_BIN )))
419
431
420
432
421
433
def clean_up ():
422
- os .remove (FACTORY_PARTITION_CSV )
423
- os .remove (FACTORY_DATA ['dac-pub-key' ]['value' ])
424
- os .remove (FACTORY_DATA ['dac-key' ]['value' ])
434
+ if FACTORY_DATA ['dac-pub-key' ]['value' ]:
435
+ os .remove (FACTORY_DATA ['dac-pub-key' ]['value' ])
436
+ if FACTORY_DATA ['dac-key' ]['value' ]:
437
+ os .remove (FACTORY_DATA ['dac-key' ]['value' ])
425
438
426
439
427
440
def main ():
@@ -430,53 +443,61 @@ def any_base_int(s): return int(s, 0)
430
443
parser = argparse .ArgumentParser (description = 'Chip Factory NVS binary generator tool' )
431
444
432
445
# These will be used by CommissionalbeDataProvider
433
- parser .add_argument ('-p' , '--passcode' , type = any_base_int , required = True ,
446
+ parser .add_argument ('-p' , '--passcode' , type = any_base_int ,
434
447
help = 'The setup passcode for pairing, range: 0x01-0x5F5E0FE' )
435
- parser .add_argument ('-d' , '--discriminator' , type = any_base_int , required = True ,
448
+ parser .add_argument ('-d' , '--discriminator' , type = any_base_int ,
436
449
help = 'The discriminator for pairing, range: 0x00-0x0FFF' )
437
450
438
451
# These will be used by DeviceAttestationCredentialsProvider
439
- parser .add_argument ('--dac-cert' , type = str , required = True ,
440
- help = 'The path to the DAC certificate in der format' )
441
- parser .add_argument ('--dac-key' , type = str , required = True ,
442
- help = 'The path to the DAC private key in der format' )
443
- parser .add_argument ('--pai-cert' , type = str , required = True ,
444
- help = 'The path to the PAI certificate in der format' )
445
- parser .add_argument ('--cd' , type = str , required = True ,
446
- help = 'The path to the certificate declaration der format' )
452
+ parser .add_argument ('--dac-cert' , help = 'The path to the DAC certificate in der format' )
453
+ parser .add_argument ('--dac-key' , help = 'The path to the DAC private key in der format' )
454
+ parser .add_argument ('--pai-cert' , help = 'The path to the PAI certificate in der format' )
455
+ parser .add_argument ('--cd' , help = 'The path to the certificate declaration der format' )
447
456
448
457
# These will be used by DeviceInstanceInfoProvider
449
- parser .add_argument ('--vendor-id' , type = any_base_int , required = False , help = 'Vendor id' )
450
- parser .add_argument ('--vendor-name' , type = str , required = False , help = 'Vendor name' )
451
- parser .add_argument ('--product-id' , type = any_base_int , required = False , help = 'Product id' )
452
- parser .add_argument ('--product-name' , type = str , required = False , help = 'Product name' )
453
- parser .add_argument ('--hw-ver' , type = any_base_int , required = False , help = 'Hardware version' )
454
- parser .add_argument ('--hw-ver-str' , type = str , required = False , help = 'Hardware version string' )
455
- parser .add_argument ('--mfg-date' , type = str , required = False , help = 'Manufacturing date in format YYYY-MM-DD' )
456
- parser .add_argument ('--serial-num' , type = str , required = False , help = 'Serial number' )
457
- parser .add_argument ('--rd-id-uid' , type = str , required = False ,
458
+ parser .add_argument ('--vendor-id' , type = any_base_int , help = 'Vendor id' )
459
+ parser .add_argument ('--vendor-name' , help = 'Vendor name' )
460
+ parser .add_argument ('--product-id' , type = any_base_int , help = 'Product id' )
461
+ parser .add_argument ('--product-name' , help = 'Product name' )
462
+ parser .add_argument ('--hw-ver' , type = any_base_int , help = 'Hardware version' )
463
+ parser .add_argument ('--hw-ver-str' , help = 'Hardware version string' )
464
+ parser .add_argument ('--mfg-date' , help = 'Manufacturing date in format YYYY-MM-DD' )
465
+ parser .add_argument ('--serial-num' , help = 'Serial number' )
466
+ parser .add_argument ('--rd-id-uid' ,
458
467
help = '128-bit unique identifier for generating rotating device identifier, provide 32-byte hex string, e.g. "1234567890abcdef1234567890abcdef"' )
459
468
460
469
# These will be used by DeviceInfoProvider
461
- parser .add_argument ('--calendar-types' , type = str , nargs = '+' , required = False ,
470
+ parser .add_argument ('--calendar-types' , nargs = '+' ,
462
471
help = 'List of supported calendar types.\n Supported Calendar Types: Buddhist, Chinese, Coptic, Ethiopian, Gregorian, Hebrew, Indian, Islamic, Japanese, Korean, Persian, Taiwanese' )
463
- parser .add_argument ('--locales' , type = str , nargs = '+' , required = False ,
464
- help = 'List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB' )
465
- parser .add_argument ('--fixed-labels' , type = str , nargs = '+' , required = False ,
472
+ parser .add_argument ('--locales' , nargs = '+' , help = 'List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB' )
473
+ parser .add_argument ('--fixed-labels' , nargs = '+' ,
466
474
help = 'List of fixed labels, eg: "0/orientation/up" "1/orientation/down" "2/orientation/down"' )
467
475
468
- parser .add_argument ('-s' , '--size' , type = any_base_int , required = False , default = 0x6000 ,
476
+ parser .add_argument ('-s' , '--size' , type = any_base_int , default = 0x6000 ,
469
477
help = 'The size of the partition.bin, default: 0x6000' )
470
- parser .add_argument ('-e' , '--encrypt' , action = 'store_true' , required = False ,
478
+ parser .add_argument ('-e' , '--encrypt' , action = 'store_true' ,
471
479
help = 'Encrypt the factory parititon NVS binary' )
480
+ parser .add_argument ('--no-bin' , action = 'store_false' , dest = 'generate_bin' ,
481
+ help = 'Do not generate the factory partition binary' )
482
+ parser .set_defaults (generate_bin = True )
472
483
473
484
args = parser .parse_args ()
474
485
validate_args (args )
475
- spake2p_params = gen_spake2p_params (args .passcode )
486
+
487
+ if args .passcode is not None :
488
+ spake2p_params = gen_spake2p_params (args .passcode )
489
+
476
490
populate_factory_data (args , spake2p_params )
477
- gen_raw_ec_keypair_from_der (args .dac_key , FACTORY_DATA ['dac-pub-key' ]['value' ], FACTORY_DATA ['dac-key' ]['value' ])
478
- generate_nvs_bin (args )
479
- print_flashing_help (args .encrypt )
491
+
492
+ if args .dac_key :
493
+ gen_raw_ec_keypair_from_der (args .dac_key , FACTORY_DATA ['dac-pub-key' ]['value' ], FACTORY_DATA ['dac-key' ]['value' ])
494
+
495
+ generate_nvs_csv (FACTORY_PARTITION_CSV )
496
+
497
+ if args .generate_bin :
498
+ generate_nvs_bin (args .encrypt , args .size , FACTORY_PARTITION_CSV , FACTORY_PARTITION_BIN )
499
+ print_flashing_help (args .encrypt , FACTORY_PARTITION_BIN )
500
+
480
501
clean_up ()
481
502
482
503
0 commit comments