68
68
raise
69
69
70
70
71
- __version__ = "3.0 -dev"
71
+ __version__ = "3.1 -dev"
72
72
73
73
MAX_UINT32 = 0xffffffff
74
74
MAX_UINT24 = 0xffffff
@@ -2051,12 +2051,12 @@ def maybe_patch_segment_data(self, f, segment_data):
2051
2051
raise FatalError ('Cannot place SHA256 digest on segment boundary'
2052
2052
'(elf_sha256_offset=%d, file_pos=%d, segment_size=%d)' %
2053
2053
(self .elf_sha256_offset , file_pos , segment_len ))
2054
+ # offset relative to the data part
2055
+ patch_offset -= self .SEG_HEADER_LEN
2054
2056
if segment_data [patch_offset :patch_offset + self .SHA256_DIGEST_LEN ] != b'\x00 ' * self .SHA256_DIGEST_LEN :
2055
2057
raise FatalError ('Contents of segment at SHA256 digest offset 0x%x are not all zero. Refusing to overwrite.' %
2056
2058
self .elf_sha256_offset )
2057
2059
assert (len (self .elf_sha256 ) == self .SHA256_DIGEST_LEN )
2058
- # offset relative to the data part
2059
- patch_offset -= self .SEG_HEADER_LEN
2060
2060
segment_data = segment_data [0 :patch_offset ] + self .elf_sha256 + \
2061
2061
segment_data [patch_offset + self .SHA256_DIGEST_LEN :]
2062
2062
return segment_data
@@ -2908,8 +2908,8 @@ def write_flash(esp, args):
2908
2908
if args .compress is None and not args .no_compress :
2909
2909
args .compress = not args .no_stub
2910
2910
2911
- # For encrypt option we do few sanity checks before actual flash write
2912
- if args .encrypt :
2911
+ # In case we have encrypted files to write, we first do few sanity checks before actual flash
2912
+ if args .encrypt or args . encrypt_files is not None :
2913
2913
do_write = True
2914
2914
2915
2915
if not esp .secure_download_mode :
@@ -2929,7 +2929,10 @@ def write_flash(esp, args):
2929
2929
print ('Flash encryption key is not programmed' )
2930
2930
do_write = False
2931
2931
2932
- for address , argfile in args .addr_filename :
2932
+ # Determine which files list contain the ones to encrypt
2933
+ files_to_encrypt = args .addr_filename if args .encrypt else args .encrypt_files
2934
+
2935
+ for address , argfile in files_to_encrypt :
2933
2936
if address % esp .FLASH_ENCRYPTED_WRITE_ALIGN :
2934
2937
print ("File %s address 0x%x is not %d byte aligned, can't flash encrypted" %
2935
2938
(argfile .name , address , esp .FLASH_ENCRYPTED_WRITE_ALIGN ))
@@ -2952,29 +2955,54 @@ def write_flash(esp, args):
2952
2955
if args .erase_all :
2953
2956
erase_flash (esp , args )
2954
2957
2955
- if args .encrypt and args .compress :
2956
- print ('\n WARNING: - compress and encrypt options are mutually exclusive ' )
2957
- print ('Will flash uncompressed' )
2958
- args .compress = False
2958
+ """ Create a list describing all the files we have to flash. Each entry holds an "encrypt" flag
2959
+ marking whether the file needs encryption or not. This list needs to be sorted.
2960
+
2961
+ First, append to each entry of our addr_filename list the flag args.encrypt
2962
+ For example, if addr_filename is [(0x1000, "partition.bin"), (0x8000, "bootloader")],
2963
+ all_files will be [(0x1000, "partition.bin", args.encrypt), (0x8000, "bootloader", args.encrypt)],
2964
+ where, of course, args.encrypt is either True or False
2965
+ """
2966
+ all_files = [(offs , filename , args .encrypt ) for (offs , filename ) in args .addr_filename ]
2967
+
2968
+ """Now do the same with encrypt_files list, if defined.
2969
+ In this case, the flag is True
2970
+ """
2971
+ if args .encrypt_files is not None :
2972
+ encrypted_files_flag = [(offs , filename , True ) for (offs , filename ) in args .encrypt_files ]
2973
+
2974
+ # Concatenate both lists and sort them.
2975
+ # As both list are already sorted, we could simply do a merge instead,
2976
+ # but for the sake of simplicity and because the lists are very small,
2977
+ # let's use sorted.
2978
+ all_files = sorted (all_files + encrypted_files_flag , key = lambda x : x [0 ])
2979
+
2980
+ for address , argfile , encrypted in all_files :
2981
+ compress = args .compress
2982
+
2983
+ # Check whether we can compress the current file before flashing
2984
+ if compress and encrypted :
2985
+ print ('\n WARNING: - compress and encrypt options are mutually exclusive ' )
2986
+ print ('Will flash %s uncompressed' % argfile .name )
2987
+ compress = False
2959
2988
2960
- for address , argfile in args .addr_filename :
2961
2989
if args .no_stub :
2962
2990
print ('Erasing flash...' )
2963
- image = pad_to (argfile .read (), esp .FLASH_ENCRYPTED_WRITE_ALIGN if args . encrypt else 4 )
2991
+ image = pad_to (argfile .read (), esp .FLASH_ENCRYPTED_WRITE_ALIGN if encrypted else 4 )
2964
2992
if len (image ) == 0 :
2965
2993
print ('WARNING: File %s is empty' % argfile .name )
2966
2994
continue
2967
2995
image = _update_image_flash_params (esp , address , args , image )
2968
2996
calcmd5 = hashlib .md5 (image ).hexdigest ()
2969
2997
uncsize = len (image )
2970
- if args . compress :
2998
+ if compress :
2971
2999
uncimage = image
2972
3000
image = zlib .compress (uncimage , 9 )
2973
3001
ratio = uncsize / len (image )
2974
3002
blocks = esp .flash_defl_begin (uncsize , len (image ), address )
2975
3003
else :
2976
3004
ratio = 1.0
2977
- blocks = esp .flash_begin (uncsize , address , begin_rom_encrypted = args . encrypt )
3005
+ blocks = esp .flash_begin (uncsize , address , begin_rom_encrypted = encrypted )
2978
3006
argfile .seek (0 ) # in case we need it again
2979
3007
seq = 0
2980
3008
written = 0
@@ -2983,12 +3011,12 @@ def write_flash(esp, args):
2983
3011
print_overwrite ('Writing at 0x%08x... (%d %%)' % (address + seq * esp .FLASH_WRITE_SIZE , 100 * (seq + 1 ) // blocks ))
2984
3012
sys .stdout .flush ()
2985
3013
block = image [0 :esp .FLASH_WRITE_SIZE ]
2986
- if args . compress :
3014
+ if compress :
2987
3015
esp .flash_defl_block (block , seq , timeout = DEFAULT_TIMEOUT * ratio * 2 )
2988
3016
else :
2989
3017
# Pad the last block
2990
3018
block = block + b'\xff ' * (esp .FLASH_WRITE_SIZE - len (block ))
2991
- if args . encrypt :
3019
+ if encrypted :
2992
3020
esp .flash_encrypt_block (block , seq )
2993
3021
else :
2994
3022
esp .flash_block (block , seq )
@@ -2997,7 +3025,7 @@ def write_flash(esp, args):
2997
3025
written += len (block )
2998
3026
t = time .time () - t
2999
3027
speed_msg = ""
3000
- if args . compress :
3028
+ if compress :
3001
3029
if t > 0.0 :
3002
3030
speed_msg = " (effective %.1f kbit/s)" % (uncsize / t * 8 / 1000 )
3003
3031
print_overwrite ('Wrote %d bytes (%d compressed) at 0x%08x in %.1f seconds%s...' % (uncsize , written , address , t , speed_msg ), last_line = True )
@@ -3006,7 +3034,7 @@ def write_flash(esp, args):
3006
3034
speed_msg = " (%.1f kbit/s)" % (written / t * 8 / 1000 )
3007
3035
print_overwrite ('Wrote %d bytes at 0x%08x in %.1f seconds%s...' % (written , address , t , speed_msg ), last_line = True )
3008
3036
3009
- if not args . encrypt and not esp .secure_download_mode :
3037
+ if not encrypted and not esp .secure_download_mode :
3010
3038
try :
3011
3039
res = esp .flash_md5sum (address , uncsize )
3012
3040
if res != calcmd5 :
@@ -3025,15 +3053,27 @@ def write_flash(esp, args):
3025
3053
# skip sending flash_finish to ROM loader here,
3026
3054
# as it causes the loader to exit and run user code
3027
3055
esp .flash_begin (0 , 0 )
3028
- if args .compress :
3056
+
3057
+ # Get the "encrypted" flag for the last file flashed
3058
+ # Note: all_files list contains triplets like:
3059
+ # (address: Integer, filename: String, encrypted: Boolean)
3060
+ last_file_encrypted = all_files [- 1 ][2 ]
3061
+
3062
+ # Check whether the last file flashed was compressed or not
3063
+ if args .compress and not last_file_encrypted :
3029
3064
esp .flash_defl_finish (False )
3030
3065
else :
3031
3066
esp .flash_finish (False )
3032
3067
3033
3068
if args .verify :
3034
3069
print ('Verifying just-written flash...' )
3035
3070
print ('(This option is deprecated, flash contents are now always read back after flashing.)' )
3036
- verify_flash (esp , args )
3071
+ # If some encrypted files have been flashed print a warning saying that we won't check them
3072
+ if args .encrypt or args .encrypt_files is not None :
3073
+ print ('WARNING: - cannot verify encrypted files, they will be ignored' )
3074
+ # Call verify_flash function only if there at least one non-encrypted file flashed
3075
+ if not args .encrypt :
3076
+ verify_flash (esp , args )
3037
3077
3038
3078
3039
3079
def image_info (args ):
@@ -3368,7 +3408,7 @@ def add_spi_flash_subparsers(parent, is_elf2image):
3368
3408
parent .add_argument ('--flash_size' , '-fs' , help = 'SPI Flash size in MegaBytes (1MB, 2MB, 4MB, 8MB, 16M)'
3369
3409
' plus ESP8266-only (256KB, 512KB, 2MB-c1, 4MB-c1)' + extra_fs_message ,
3370
3410
action = FlashSizeAction , auto_detect = auto_detect ,
3371
- default = os .environ .get ('ESPTOOL_FS' , 'detect ' if auto_detect else '1MB ' ))
3411
+ default = os .environ .get ('ESPTOOL_FS' , '1MB ' if is_elf2image else 'keep ' ))
3372
3412
add_spi_connection_arg (parent )
3373
3413
3374
3414
parser_write_flash = subparsers .add_parser (
@@ -3387,6 +3427,10 @@ def add_spi_flash_subparsers(parent, is_elf2image):
3387
3427
'(mostly superfluous, data is read back during flashing)' , action = 'store_true' )
3388
3428
parser_write_flash .add_argument ('--encrypt' , help = 'Apply flash encryption when writing data (required correct efuse settings)' ,
3389
3429
action = 'store_true' )
3430
+ # In order to not break backward compatibility, our list of encrypted files to flash is a new parameter
3431
+ parser_write_flash .add_argument ('--encrypt-files' , metavar = '<address> <filename>' ,
3432
+ help = 'Files to be encrypted on the flash. Address followed by binary filename, separated by space.' ,
3433
+ action = AddrFilenamePairAction )
3390
3434
parser_write_flash .add_argument ('--ignore-flash-encryption-efuse-setting' , help = 'Ignore flash encryption efuse settings ' ,
3391
3435
action = 'store_true' )
3392
3436
@@ -3501,7 +3545,6 @@ def add_spi_flash_subparsers(parent, is_elf2image):
3501
3545
expand_file_arguments ()
3502
3546
3503
3547
args = parser .parse_args (custom_commandline )
3504
-
3505
3548
print ('esptool.py v%s' % __version__ )
3506
3549
3507
3550
# operation function can take 1 arg (args), 2 args (esp, arg)
@@ -3511,6 +3554,13 @@ def add_spi_flash_subparsers(parent, is_elf2image):
3511
3554
parser .print_help ()
3512
3555
sys .exit (1 )
3513
3556
3557
+ # Forbid the usage of both --encrypt, which means encrypt all the given files,
3558
+ # and --encrypt-files, which represents the list of files to encrypt.
3559
+ # The reason is that allowing both at the same time increases the chances of
3560
+ # having contradictory lists (e.g. one file not available in one of list).
3561
+ if args .operation == "write_flash" and args .encrypt and args .encrypt_files is not None :
3562
+ raise FatalError ("Options --encrypt and --encrypt-files must not be specified at the same time." )
3563
+
3514
3564
operation_func = globals ()[args .operation ]
3515
3565
3516
3566
if PYTHON2 :
@@ -3738,7 +3788,7 @@ def __call__(self, parser, namespace, values, option_string=None):
3738
3788
3739
3789
# Sort the addresses and check for overlapping
3740
3790
end = 0
3741
- for address , argfile in sorted (pairs ):
3791
+ for address , argfile in sorted (pairs , key = lambda x : x [ 0 ] ):
3742
3792
argfile .seek (0 , 2 ) # seek to end
3743
3793
size = argfile .tell ()
3744
3794
argfile .seek (0 )
0 commit comments