6868 raise
6969
7070
71- __version__ = "3.0 -dev"
71+ __version__ = "3.1 -dev"
7272
7373MAX_UINT32 = 0xffffffff
7474MAX_UINT24 = 0xffffff
@@ -2051,12 +2051,12 @@ def maybe_patch_segment_data(self, f, segment_data):
20512051 raise FatalError ('Cannot place SHA256 digest on segment boundary'
20522052 '(elf_sha256_offset=%d, file_pos=%d, segment_size=%d)' %
20532053 (self .elf_sha256_offset , file_pos , segment_len ))
2054+ # offset relative to the data part
2055+ patch_offset -= self .SEG_HEADER_LEN
20542056 if segment_data [patch_offset :patch_offset + self .SHA256_DIGEST_LEN ] != b'\x00 ' * self .SHA256_DIGEST_LEN :
20552057 raise FatalError ('Contents of segment at SHA256 digest offset 0x%x are not all zero. Refusing to overwrite.' %
20562058 self .elf_sha256_offset )
20572059 assert (len (self .elf_sha256 ) == self .SHA256_DIGEST_LEN )
2058- # offset relative to the data part
2059- patch_offset -= self .SEG_HEADER_LEN
20602060 segment_data = segment_data [0 :patch_offset ] + self .elf_sha256 + \
20612061 segment_data [patch_offset + self .SHA256_DIGEST_LEN :]
20622062 return segment_data
@@ -2908,8 +2908,8 @@ def write_flash(esp, args):
29082908 if args .compress is None and not args .no_compress :
29092909 args .compress = not args .no_stub
29102910
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 :
29132913 do_write = True
29142914
29152915 if not esp .secure_download_mode :
@@ -2929,7 +2929,10 @@ def write_flash(esp, args):
29292929 print ('Flash encryption key is not programmed' )
29302930 do_write = False
29312931
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 :
29332936 if address % esp .FLASH_ENCRYPTED_WRITE_ALIGN :
29342937 print ("File %s address 0x%x is not %d byte aligned, can't flash encrypted" %
29352938 (argfile .name , address , esp .FLASH_ENCRYPTED_WRITE_ALIGN ))
@@ -2952,29 +2955,54 @@ def write_flash(esp, args):
29522955 if args .erase_all :
29532956 erase_flash (esp , args )
29542957
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
29592988
2960- for address , argfile in args .addr_filename :
29612989 if args .no_stub :
29622990 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 )
29642992 if len (image ) == 0 :
29652993 print ('WARNING: File %s is empty' % argfile .name )
29662994 continue
29672995 image = _update_image_flash_params (esp , address , args , image )
29682996 calcmd5 = hashlib .md5 (image ).hexdigest ()
29692997 uncsize = len (image )
2970- if args . compress :
2998+ if compress :
29712999 uncimage = image
29723000 image = zlib .compress (uncimage , 9 )
29733001 ratio = uncsize / len (image )
29743002 blocks = esp .flash_defl_begin (uncsize , len (image ), address )
29753003 else :
29763004 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 )
29783006 argfile .seek (0 ) # in case we need it again
29793007 seq = 0
29803008 written = 0
@@ -2983,12 +3011,12 @@ def write_flash(esp, args):
29833011 print_overwrite ('Writing at 0x%08x... (%d %%)' % (address + seq * esp .FLASH_WRITE_SIZE , 100 * (seq + 1 ) // blocks ))
29843012 sys .stdout .flush ()
29853013 block = image [0 :esp .FLASH_WRITE_SIZE ]
2986- if args . compress :
3014+ if compress :
29873015 esp .flash_defl_block (block , seq , timeout = DEFAULT_TIMEOUT * ratio * 2 )
29883016 else :
29893017 # Pad the last block
29903018 block = block + b'\xff ' * (esp .FLASH_WRITE_SIZE - len (block ))
2991- if args . encrypt :
3019+ if encrypted :
29923020 esp .flash_encrypt_block (block , seq )
29933021 else :
29943022 esp .flash_block (block , seq )
@@ -2997,7 +3025,7 @@ def write_flash(esp, args):
29973025 written += len (block )
29983026 t = time .time () - t
29993027 speed_msg = ""
3000- if args . compress :
3028+ if compress :
30013029 if t > 0.0 :
30023030 speed_msg = " (effective %.1f kbit/s)" % (uncsize / t * 8 / 1000 )
30033031 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):
30063034 speed_msg = " (%.1f kbit/s)" % (written / t * 8 / 1000 )
30073035 print_overwrite ('Wrote %d bytes at 0x%08x in %.1f seconds%s...' % (written , address , t , speed_msg ), last_line = True )
30083036
3009- if not args . encrypt and not esp .secure_download_mode :
3037+ if not encrypted and not esp .secure_download_mode :
30103038 try :
30113039 res = esp .flash_md5sum (address , uncsize )
30123040 if res != calcmd5 :
@@ -3025,15 +3053,27 @@ def write_flash(esp, args):
30253053 # skip sending flash_finish to ROM loader here,
30263054 # as it causes the loader to exit and run user code
30273055 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 :
30293064 esp .flash_defl_finish (False )
30303065 else :
30313066 esp .flash_finish (False )
30323067
30333068 if args .verify :
30343069 print ('Verifying just-written flash...' )
30353070 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 )
30373077
30383078
30393079def image_info (args ):
@@ -3368,7 +3408,7 @@ def add_spi_flash_subparsers(parent, is_elf2image):
33683408 parent .add_argument ('--flash_size' , '-fs' , help = 'SPI Flash size in MegaBytes (1MB, 2MB, 4MB, 8MB, 16M)'
33693409 ' plus ESP8266-only (256KB, 512KB, 2MB-c1, 4MB-c1)' + extra_fs_message ,
33703410 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 ' ))
33723412 add_spi_connection_arg (parent )
33733413
33743414 parser_write_flash = subparsers .add_parser (
@@ -3387,6 +3427,10 @@ def add_spi_flash_subparsers(parent, is_elf2image):
33873427 '(mostly superfluous, data is read back during flashing)' , action = 'store_true' )
33883428 parser_write_flash .add_argument ('--encrypt' , help = 'Apply flash encryption when writing data (required correct efuse settings)' ,
33893429 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 )
33903434 parser_write_flash .add_argument ('--ignore-flash-encryption-efuse-setting' , help = 'Ignore flash encryption efuse settings ' ,
33913435 action = 'store_true' )
33923436
@@ -3501,7 +3545,6 @@ def add_spi_flash_subparsers(parent, is_elf2image):
35013545 expand_file_arguments ()
35023546
35033547 args = parser .parse_args (custom_commandline )
3504-
35053548 print ('esptool.py v%s' % __version__ )
35063549
35073550 # operation function can take 1 arg (args), 2 args (esp, arg)
@@ -3511,6 +3554,13 @@ def add_spi_flash_subparsers(parent, is_elf2image):
35113554 parser .print_help ()
35123555 sys .exit (1 )
35133556
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+
35143564 operation_func = globals ()[args .operation ]
35153565
35163566 if PYTHON2 :
@@ -3738,7 +3788,7 @@ def __call__(self, parser, namespace, values, option_string=None):
37383788
37393789 # Sort the addresses and check for overlapping
37403790 end = 0
3741- for address , argfile in sorted (pairs ):
3791+ for address , argfile in sorted (pairs , key = lambda x : x [ 0 ] ):
37423792 argfile .seek (0 , 2 ) # seek to end
37433793 size = argfile .tell ()
37443794 argfile .seek (0 )
0 commit comments