Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if offset >= num_bytes:
raise RuntimeError("Invalid offset: Key block only holds %d bytes." % num_bytes)
if len(data) > num_bytes - offset:
raise RuntimeError("Data will not fit: Key block size %d bytes, data file is %d bytes" % (num_bytes, len(data)))
if efuses.coding_scheme == CODING_SCHEME_34:
if offset % 6 != 0:
raise RuntimeError("Device has 3/4 Coding Scheme. Can only write at offsets which are a multiple of 6.")
if len(data) % 6 != 0:
raise RuntimeError("Device has 3/4 Coding Scheme. Can only write data lengths which are a multiple of 6 (data is %d bytes)" % len(data))
efuse = [e for e in efuses if e.register_name == args.block.upper()][0]
if not args.force_write_always and \
efuse.get_raw() != b'\x00' * num_bytes:
raise esptool.FatalError("Efuse block already has values written.")
if efuses.coding_scheme == CODING_SCHEME_NONE:
pad = offset % 4
if pad != 0: # left-pad to a word boundary
data = (b'\x00' * pad) + data
offset -= pad
pad = len(data) % 4
if pad != 0: # right-pad to a word boundary
data += (b'\x00' * (4 - pad))
words = struct.unpack("<" + "I" * (len(data) // 4), data)
word_offset = offset // 4
else: # CODING_SCHEME_34
words = efuse.apply_34_encoding(data)
word_offset = (offset // 6) * 2
confirm("Burning efuse %s (%s) with %d bytes of data at offset %d in the block" % (efuse.register_name, efuse.description, len(data), offset), args)
def check_command(self, op_description, op=None, data=b'', chk=0, timeout=DEFAULT_TIMEOUT):
"""
Execute a command with 'command', check the result code and throw an appropriate
FatalError if it fails.
Returns the "result" of a successful command.
"""
val, data = self.command(op, data, chk, timeout=timeout)
# things are a bit weird here, bear with us
# the status bytes are the last 2/4 bytes in the data (depending on chip)
if len(data) < self.STATUS_BYTES_LENGTH:
raise FatalError("Failed to %s. Only got %d byte status response." % (op_description, len(data)))
status_bytes = data[-self.STATUS_BYTES_LENGTH:]
# we only care if the first one is non-zero. If it is, the second byte is a reason.
if byte(status_bytes, 0) != 0:
raise FatalError.WithResult('Failed to %s' % op_description, status_bytes)
# if we had more data than just the status bytes, return it as the result
# (this is used by the md5sum command, maybe other commands?)
if len(data) > self.STATUS_BYTES_LENGTH:
return data[:-self.STATUS_BYTES_LENGTH]
else: # otherwise, just return the 'val' field which comes from the reply header (this is used by read_reg)
return val
def erase_region(self, offset, size):
if offset % self.FLASH_SECTOR_SIZE != 0:
raise FatalError("Offset to erase from must be a multiple of 4096")
if size % self.FLASH_SECTOR_SIZE != 0:
raise FatalError("Size of data to erase must be a multiple of 4096")
timeout = timeout_per_mb(ERASE_REGION_TIMEOUT_PER_MB, size)
self.check_command("erase region", self.ESP_ERASE_REGION, struct.pack('
def wait_idle():
deadline = time.time() + EFUSE_BURN_TIMEOUT
while time.time() < deadline:
if self._esp.read_reg(EFUSE_REG_CMD) == 0:
return
raise esptool.FatalError("Timed out waiting for Efuse controller command to complete")
wait_idle()
def disable_read(self):
if self.read_disable_bit is None:
raise esptool.FatalError("This efuse cannot be read-disabled")
rddis_reg_addr = efuse_write_reg_addr(0, 0)
self.parent.write_reg(rddis_reg_addr, 1 << (16 + self.read_disable_bit))
self.parent.write_efuses()
return self.get()
def wait_idle():
deadline = time.time() + EFUSE_BURN_TIMEOUT
while time.time() < deadline:
if self._esp.read_reg(EFUSE_REG_CMD) == 0:
return
raise esptool.FatalError("Timed out waiting for Efuse controller command to complete")
wait_idle()
def burn(self, new_value):
# Writing the BLK0 default MAC is not sensible, as it's written in the factory.
#
# TODO: support writing a new base MAC @ efuse BLK3
raise esptool.FatalError("Writing MAC address is not supported")
def _load_hardware_key(keyfile):
""" Load a 256-bit key, similar to stored in efuse, from a file
192-bit keys will be extended to 256-bit using the same algorithm used
by hardware if 3/4 Coding Scheme is set.
"""
key = keyfile.read()
if len(key) not in [24, 32]:
raise esptool.FatalError("Key file contains wrong length (%d bytes), 24 or 32 expected." % len(key))
if len(key) == 24:
key = key + key[8:16]
print("Using 192-bit key (extended)")
else:
print("Using 256-bit key")
assert len(key) == 32
return key
def burn_efuse(esp, efuses, args):
efuse = efuses[args.efuse_name]
old_value = efuse.get()
if efuse.efuse_type == "flag":
if args.new_value not in [None, 1]:
raise esptool.FatalError("Efuse %s is type 'flag'. New value is not accepted for this efuse (will always burn 0->1)" % efuse.register_name)
args.new_value = 1
if old_value:
print("Efuse %s is already burned." % efuse.register_name)
return
elif efuse.efuse_type == "int":
if args.new_value is None:
raise esptool.FatalError("New value required for efuse %s" % efuse.register_name)
elif efuse.efuse_type == "spipin":
if args.new_value is None or args.new_value == 0:
raise esptool.FatalError("New value required for efuse %s" % efuse.register_name)
elif efuse.efuse_type == "bitcount":
if args.new_value is None: # find the first unset bit and set it
args.new_value = old_value
bit = 1
while args.new_value == old_value:
args.new_value = bit | old_value