def create_device_cert_and_manifest(): """AWS IoT EduKit MCU hardware device registration script Checkes environment is set correctly, generates ECDSA certificates, ensures all required python libraries are included, retrieves on-board device certificate using the esp-cryptoauth library and utility, creates an AWS IoT thing using the AWS CLI and Microchip Trust Platform Design Suite. """ app_binary = 'sample_bins/secure_cert_mfg.bin' args = manifest_args(env.get("UPLOAD_PORT")) args.signer_cert = os.path.join(dest_folder, "signer_cert.crt") args.signer_privkey = os.path.join(dest_folder, "signer_key.pem") args.print_atecc608_type = False check_environment() generate_signer_certificate() esp = esptool.ESP32ROM(args.port, baud=115200) esp_hs.serial.load_app_stub(app_binary, esp) init_mfg = esp_hs.serial.cmd_interpreter() retval = init_mfg.wait_for_init(esp._port) if retval is not True: print("CMD prompt timed out.") exit(0) retval = init_mfg.exec_cmd( esp._port, "init {0} {1}".format(atecc608_i2c_sda_pin, atecc608_i2c_scl_pin)) esp_hs.serial.esp_cmd_check_ok( retval, "init {0} {1}".format(atecc608_i2c_sda_pin, atecc608_i2c_scl_pin)) os.makedirs(temp_folder, exist_ok=True) esp_hs.generate_manifest_file(esp, args, init_mfg)
def connect(self): initial_baud = 115200 * 2 if(self.chip_type == 'ESP32'): try: self.esp = esptool.ESP32ROM(self.port, initial_baud) except: if(DEBUG): print "ERROR!! The com port is occupied!!" return err_conn, "ERROR!! The com port is occupied!!" elif(self.chip_type == 'ESP8266'): try: self.esp = esptool.ESP8266ROM(self.port, initial_baud) except: if(DEBUG): print "ERROR!! The com port is occupied!!" return err_conn, "ERROR!! The com port is occupied!!" times = 3 while True: try: if times-1>0: self.esp.connect() else: return err_conn, "ERROR!! sync to chip fail" break except: times -= 1 pass return no_err, 'sync succ'
def t_loadBin(esprftool, params): initial_baud = 115200 esprftool._SignalTX.emit('sync...') esprftool._SignalLoadStatus.emit(4) esprftool._Signalprb.emit(0) if (params.chip_type == 'ESP32'): try: esp = esptool.ESP32ROM(params.port, initial_baud) except: print "ERROR!! The com port is occupied!!\n" esprftool._SignalTX.emit('ERROR!! The com port is occupied!!') return elif (params.chip_type == 'ESP8266'): try: esp = esptool.ESP8266ROM(params.port, initial_baud) except: print "ERROR!! The com port is occupied!!\n" esprftool._SignalTX.emit('ERROR!! The com port is occupied!!') return esprftool._SignalLoadStatus.emit(1) esp_mac = (00, 00, 00, 00, 00, 00) cus_mac = "00:00:00:00:00:00" print('%s: %s' % ("ESP_MAC", ':'.join(map(lambda x: '%02x' % x, esp_mac)))) esprftool._SignalLoadStatus.emit(1) while True: try: esp.connect() break except: pass try: esprftool._SignalTX.emit('sync success') esp_mac = esp.read_mac() print 'esp_mac:%02x-%02x-%02x-%02x-%02x-%02x' % (esp_mac) esprftool._SignalTX.emit('esp_mac:%02x-%02x-%02x-%02x-%02x-%02x' % (esp_mac)) esprftool._SignalLoadStatus.emit(2) if (params.esp_download_mode == 1): #print "load ram ..." load_ram(esp, params, esprftool) elif (params.esp_download_mode == 2): if not params.no_stub: esp = esp.run_stub() esp.change_baud(921600) #print "load flash ..." write_flash(esp, params, esprftool) except: esprftool._SignalLoadStatus.emit(4) esprftool._SignalTX.emit('load bin fail') return esprftool._SignalLoadStatus.emit(3)
def mesh_read_mac(self, str_port): esp = esptool.ESP32ROM(port=str_port, baud=115200) esp.connect() mac = esp.read_mac() def mac_to_str(mac): return ('%s' % (':'.join(map(lambda x: '%02x' % x, mac)))) str_mac = mac_to_str(mac) return str_mac
def _create_esp_connection(self): '''Connect to ESP32. Child method. Need to indicate self.connecting=False when self.esp.connect() encounter an exception. No need to update self.connecting=True when connected as it is done Parent method.''' port = self.port.get() try: baud = self.baud.get() except tk.TclError as err: baud = esptool.ESPLoader.ESP_ROM_BAUD self.baud.set(baud) self.bauds.update_idletasks() try: if self.esp: self.esp._port.close() self.esp = esptool.ESP32ROM( port, baud, #trace_enabled=True, ) #Created attributes: # self.esp._port - Is an instance of serial.Serial() or a compatible object # see https://pythonhosted.org/pyserial/pyserial_api.html?highlight=setdtr#serial.Serial # - It will close the defined serial port when self.esp._port is freed, i.e. # when tk.Tk() instance is destroyed. # - set self.esp._port.baud # self.esp._slip_reader - Is a generator to read SLIP packets from the # defined serial port in self.esp._port. # self.esp._trace_enabled - Denotes wheather tracing is activated. # For debugging. Default value is "False" # self.esp._last_trace - stores time.time() self.esp.connect() except (esptool.FatalError, OSError) as err: self.esp._port.close() self._sop_for_not_connected() if "Failed to connect to ESP32: Timed out waiting for packet header" in err.__str__( ): self.status.set(ESP32Device.MSG2a ) #Fail to Connect. Try another Baud value. else: self.status.set( ESP32Device.MSG2 ) #Fail to Connect. Hold down BOOT & click WRITE.' print(err) except SerialException as err: self.esp._port.close() self._sop_for_not_connected() print("{} ESP32 device is busy".format(port)) self.status.set(ESP32Device.MSG1) print(err) else: pprint(self.esp.__dict__) print('esp is created & connected.\n')
def handler(self, *args, **kwargs): self.stop_receive() settings = self.port_inst.get_settings() rom = esptool.ESP32ROM(self.port_inst) rom.connect('hard_reset') esp = rom.run_stub() ret = func(self, esp, *args, **kwargs) self.port_inst.apply_settings(settings) self.start_receive() return ret
def get_mac(cls, app, port): """ get MAC address via esptool :param app: application instance (to get tool) :param port: serial port as string :return: MAC address or None """ try: esp = esptool.ESP32ROM(port) esp.connect() return esp.read_mac() except RuntimeError: return None finally: esp._port.close()
def main(): """AWS IoT EduKit MCU hardware device registration script Checkes environment is set correctly, generates ECDSA certificates, ensures all required python libraries are included, retrieves on-board device certificate using the esp-cryptoauth library and utility, creates an AWS IoT thing using the AWS CLI and Microchip Trust Platform Design Suite. """ app_binary = 'sample_bins/secure_cert_mfg.bin' parser = argparse.ArgumentParser( description='''Provision the Core2 for AWS IoT EduKit with device_certificate and signer_certificate required for TLS authentication''' ) parser.add_argument( "--port", '-p', dest='port', metavar='[port]', required=True, help='Serial comm port of the Core2 for AWS IoT EduKit device') args = parser.parse_args() args.signer_cert = "output_files/signer_cert.crt" args.signer_privkey = "output_files/signer_key.pem" args.print_atecc608_type = False check_environment() generate_signer_certificate() esp = esptool.ESP32ROM(args.port, baud=115200) esp_hs.serial.load_app_stub(app_binary, esp) init_mfg = esp_hs.serial.cmd_interpreter() retval = init_mfg.wait_for_init(esp._port) if retval is not True: print("CMD prompt timed out.") exit(0) retval = init_mfg.exec_cmd( esp._port, "init {0} {1}".format(atecc608_i2c_sda_pin, atecc608_i2c_scl_pin)) esp_hs.serial.esp_cmd_check_ok( retval, "init {0} {1}".format(atecc608_i2c_sda_pin, atecc608_i2c_scl_pin)) esp_hs.generate_manifest_file(esp, args, init_mfg) upload_manifest()
def get_mac(cls, port): """ get MAC address via esptool :param port: serial port as string :return: MAC address or None """ esp = None try: esp = esptool.ESP32ROM(port) esp.connect() return esp.read_mac() except RuntimeError: return None finally: if esp: # do hard reset after use esptool esp.hard_reset() esp._port.close()
def handler(self, *args, **kwargs): self.stop_receive() settings = self.port_inst.get_settings() try: rom = esptool.ESP32ROM(self.port_inst) rom.connect('hard_reset') esp = rom.run_stub() ret = func(self, esp, *args, **kwargs) # do hard reset after use esptool esp.hard_reset() finally: # always need to restore port settings self.port_inst.apply_settings(settings) self.start_receive() return ret
def setUp(self): # reset and zero efuses serialport.dtr = False serialport.rts = True time.sleep(0.05) serialport.rts = False time.sleep(0.05) serialport.dtr = True # connect & verify efuses are really zero self.esp = esptool.ESP32ROM(serialport) self.esp.connect('no_reset') # takes ~7 seconds self.efuses = espefuse.EspEfuses(self.esp) # Check every efuse is zero (~1 second) for efuse in self.efuses: val = efuse.get_raw() BAD_EFUSE_MSG = "Efuse %s not all zeroes - either this is a real ESP32 chip (VERY BAD, read top of file), or the reset is not erasing all efuses correctly." % efuse.register_name try: self.assertEqual(b'\x00' * len(val), val, BAD_EFUSE_MSG) except TypeError: self.assertEqual(0, val, BAD_EFUSE_MSG)
def get_secret_key(port, esptool): """ Generate Secret Key :param port: Serial Port :type port: str :param esptool: esptool module :type esptool: module :return: Secret Key on Success :rtype: str """ esp = esptool.ESP32ROM(port) esp.connect('default_reset') for (name, idx, read_addr, _, _) in BLOCKS: addrs = range(read_addr, read_addr + 32, 4) secret = "".join(["%08x" % esp.read_reg(addr) for addr in addrs[0:4]]) secret = secret[6:8]+secret[4:6]+secret[2:4]+secret[0:2] +\ secret[14:16]+secret[12:14]+secret[10:12]+secret[8:10] +\ secret[22:24]+secret[20:22]+secret[18:20]+secret[16:18] +\ secret[30:32]+secret[28:30]+secret[26:28]+secret[24:26] return secret
def valid_key_present(self): esp = esptool.ESP32ROM(serialport) esp.connect() efuses, _ = espefuse.get_efuses(esp=esp) blk1_rd_en = efuses["BLOCK1"].is_readable() return not blk1_rd_en
def main(): parser = argparse.ArgumentParser( description='''Provision the ESPWROOM32SE device with device_certificate and signer_certificate required for TLS authentication''' ) parser.add_argument( "--flash", dest='bin_path', default='/sample_bins/secure_cert_mfg.bin', metavar='relative/path/to/bins', help= 'relative path(from secure_cert_mfg.py) to binary to be flashed on the ESP device' ) parser.add_argument( '--signer-cert', dest='signer_cert', default='sample_certs/sample_signer_cert.pem', metavar='relative/path/to/signer_cert.pem', help='relative path(from secure_cert_mfg.py) to signer certificate.') parser.add_argument( '--signer-cert-private-key', dest='signer_privkey', default='sample_certs/sample_signer_key.pem', metavar='relative/path/to/signer-priv-key', help= 'relative path(from secure_cert_mfg.py) to signer certificate private key' ) parser.add_argument("--pwd", '--password', dest='password', metavar='[password]', help='the password associated with the private key') parser.add_argument("--port", '-p', dest='port', metavar='[port]', required=True, help='uart com port to which ESP device is connected') parser.add_argument( "--type", "--print-atecc608a-type", dest='print_atecc608a_type', action='store_true', help='print type of atecc608a chip connected to your ESP device') parser.add_argument( "--valid-for-years", dest='nva_years', default=40, type=int, help= 'number of years for which device cert is valid (from current year), default = 40' ) args = parser.parse_args() esp = esptool.ESP32ROM(args.port, baud=115200) hs.serial.load_app_stub(args.bin_path, esp) init_mfg = hs.serial.cmd_interpreter() retval = init_mfg.wait_for_init(esp._port) if retval is not True: print("CMD prompt timed out.") exit(0) retval = init_mfg.exec_cmd(esp._port, "init") hs.serial.esp_cmd_check_ok(retval, "init") if "TrustCustom" in retval[1]['Return']: print("ATECC608A chip is of type TrustCustom") provision_trustcustom_device(esp, args, init_mfg) elif "Trust&Go" in retval[1]['Return']: print("ATECC608A chip is of type Trust&Go") hs.manifest.generate_manifest_file(esp, args, init_mfg) elif "TrustFlex" in retval[1]['Return']: print("ATECC608A chip is of type TrustFlex") hs.manifest.generate_manifest_file(esp, args, init_mfg) else: print("Invalid type") exit(0)
def main(): parser = argparse.ArgumentParser( description='espefuse.py v%s - ESP32 efuse get/set tool' % esptool.__version__, prog='espefuse') parser.add_argument('--port', '-p', help='Serial port device', default=os.environ.get('ESPTOOL_PORT', esptool.ESPLoader.DEFAULT_PORT)) parser.add_argument('--before', help='What to do before connecting to the chip', choices=['default_reset', 'no_reset', 'esp32r1'], default='default_reset') parser.add_argument( '--do-not-confirm', help= 'Do not pause for confirmation before permanently writing efuses. Use with caution.', action='store_true') subparsers = parser.add_subparsers( dest='operation', help='Run espefuse.py {command} -h for additional help') subparsers.add_parser('dump', help='Dump raw hex values of all efuses') subparsers.add_parser('summary', help='Print human-readable summary of efuse values') p = subparsers.add_parser('burn_efuse', help='Burn the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[efuse[0] for efuse in EFUSES]) p.add_argument('new_value', help='New value to burn (not needed for flag-type efuses', nargs='?', type=esptool.arg_auto_int) p = subparsers.add_parser( 'read_protect_efuse', help='Disable readback for the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[ efuse[0] for efuse in EFUSES if efuse[6] is not None ]) # only allow if read_disable_bit is not None p = subparsers.add_parser( 'write_protect_efuse', help='Disable writing to the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[efuse[0] for efuse in EFUSES]) p = subparsers.add_parser( 'burn_key', help= 'Burn a 256-bit AES key to EFUSE BLK1,BLK2 or BLK3 (flash_encryption, secure_boot).' ) p.add_argument( '--no-protect-key', help='Disable default read- and write-protecting of the key. ' + 'If this option is not set, once the key is flashed it cannot be read back or changed.', action='store_true') p.add_argument( '--force-write-always', help= "Write the key even if it looks like it's already been written, or is write protected. " + "Note that this option can't disable write protection, or clear any bit which has already been set.", action='store_true') p.add_argument( 'block', help='Key block to burn. "flash_encryption" is an alias for BLK1, ' + '"secure_boot" is an alias for BLK2.', choices=["secure_boot", "flash_encryption", "BLK1", "BLK2", "BLK3"]) p.add_argument('keyfile', help='File containing 256 bits of binary key data', type=argparse.FileType('rb')) p = subparsers.add_parser( 'set_flash_voltage', help= 'Permanently set the internal flash voltage regulator to either 1.8V, 3.3V or OFF. ' + 'This means GPIO12 can be high or low at reset without changing the flash voltage.' ) p.add_argument('voltage', help='Voltage selection', choices=['1.8V', '3.3V', 'OFF']) args = parser.parse_args() print('espefuse.py v%s' % esptool.__version__) if args.operation is None: parser.print_help() parser.exit(1) # each 'operation' is a module-level function of the same name operation_func = globals()[args.operation] esp = esptool.ESP32ROM(args.port) esp.connect(args.before) # dict mapping register name to its efuse object efuses = [EfuseField.from_tuple(esp, efuse) for efuse in EFUSES] operation_func(esp, efuses, args)
def main(): parser = argparse.ArgumentParser( description='espefuse.py v%s - ESP32 efuse get/set tool' % esptool.__version__, prog='espefuse') parser.add_argument( '--baud', '-b', help='Serial port baud rate used when flashing/reading', type=arg_auto_int, default=os.environ.get('ESPTOOL_BAUD', esptool.ESPLoader.ESP_ROM_BAUD)) parser.add_argument('--port', '-p', help='Serial port device', default=os.environ.get('ESPTOOL_PORT', esptool.ESPLoader.DEFAULT_PORT)) parser.add_argument( '--before', help='What to do before connecting to the chip', choices=['default_reset', 'no_reset', 'esp32r1', 'no_reset_no_sync'], default='default_reset') parser.add_argument( '--do-not-confirm', help= 'Do not pause for confirmation before permanently writing efuses. Use with caution.', action='store_true') def add_force_write_always(p): p.add_argument( '--force-write-always', help= "Write the efuse even if it looks like it's already been written, or is write protected. " + "Note that this option can't disable write protection, or clear any bit which has already been set.", action='store_true') subparsers = parser.add_subparsers( dest='operation', help='Run espefuse.py {command} -h for additional help') subparsers.add_parser('dump', help='Dump raw hex values of all efuses') p = subparsers.add_parser( 'summary', help='Print human-readable summary of efuse values') p.add_argument('--format', help='Select the summary format', choices=['summary', 'json'], default='summary') p.add_argument('--file', help='File to save the efuse summary', type=argparse.FileType('w'), default=sys.stdout) p = subparsers.add_parser('burn_efuse', help='Burn the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[efuse[0] for efuse in EFUSES]) p.add_argument('new_value', help='New value to burn (not needed for flag-type efuses', nargs='?', type=esptool.arg_auto_int) p = subparsers.add_parser( 'read_protect_efuse', help='Disable readback for the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[ efuse[0] for efuse in EFUSES if efuse[6] is not None ]) # only allow if read_disable_bit is not None p = subparsers.add_parser( 'write_protect_efuse', help='Disable writing to the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[efuse[0] for efuse in EFUSES]) p = subparsers.add_parser( 'burn_key', help= 'Burn a 256-bit AES key to EFUSE BLK1,BLK2 or BLK3 (flash_encryption, secure_boot).' ) p.add_argument( '--no-protect-key', help='Disable default read- and write-protecting of the key. ' + 'If this option is not set, once the key is flashed it cannot be read back or changed.', action='store_true') add_force_write_always(p) p.add_argument( 'block', help='Key block to burn. "flash_encryption" is an alias for BLK1, ' + '"secure_boot" is an alias for BLK2.', choices=["secure_boot", "flash_encryption", "BLK1", "BLK2", "BLK3"]) p.add_argument('keyfile', help='File containing 256 bits of binary key data', type=argparse.FileType('rb')) p = subparsers.add_parser( 'burn_block_data', help="Burn non-key data to EFUSE BLK1, BLK2 or BLK3. " + " Don't use this command to burn key data for Flash Encryption or Secure Boot, " + "as the byte order of keys is swapped (use burn_key).") p.add_argument('--offset', '-o', help='Byte offset in the efuse block', type=int, default=0) add_force_write_always(p) p.add_argument('block', help='Efuse block to burn.', choices=["BLK1", "BLK2", "BLK3"]) p.add_argument('datafile', help='File containing data to burn into the efuse block', type=argparse.FileType('rb')) p = subparsers.add_parser( 'set_flash_voltage', help= 'Permanently set the internal flash voltage regulator to either 1.8V, 3.3V or OFF. ' + 'This means GPIO12 can be high or low at reset without changing the flash voltage.' ) p.add_argument('voltage', help='Voltage selection', choices=['1.8V', '3.3V', 'OFF']) p = subparsers.add_parser( 'adc_info', help='Display information about ADC calibration data stored in efuse.') p = subparsers.add_parser( 'burn_custom_mac', help='Burn a 48-bit Custom MAC Address to EFUSE BLK3.') p.add_argument( 'mac', help= 'Custom MAC Address to burn given in hexadecimal format with bytes separated by colons' + ' (e.g. AB:CD:EF:01:02:03).', type=mac_int) p = subparsers.add_parser('get_custom_mac', help='Prints the Custom MAC Address.') args = parser.parse_args() print('espefuse.py v%s' % esptool.__version__) if args.operation is None: parser.print_help() parser.exit(1) # each 'operation' is a module-level function of the same name operation_func = globals()[args.operation] esp = esptool.ESP32ROM(args.port, baud=args.baud) esp.connect(args.before) # dict mapping register name to its efuse object efuses = EspEfuses(esp) operation_func(esp, efuses, args)
def main(): parser = argparse.ArgumentParser( description='efuse722.py v%s - Chip 7.2.2 efuse get/set tool' % esptool.__version__, prog='espefuse') parser.add_argument('--port', '-p', help='Serial port device', default=os.environ.get('ESPTOOL_PORT', esptool.ESPLoader.DEFAULT_PORT)) parser.add_argument('--before', help='What to do before connecting to the chip', choices=['default_reset', 'no_reset', 'esp32r1'], default='default_reset') subparsers = parser.add_subparsers( dest='operation', help='Run espefuse.py {command} -h for additional help') subparsers.add_parser('dump', help='Dump raw hex values of all efuses') subparsers.add_parser('summary', help='Summary of all known efuse values') p = subparsers.add_parser('burn_efuse', help='Burn the efuse with the specified name') p.add_argument('efuse_name', help='Name of efuse register to burn', choices=[efuse[0] for efuse in BLK0_EFUSES]) p.add_argument('value', help='New value to burn', type=esptool.arg_auto_int) p = subparsers.add_parser( 'burn_key', help='Burn the key block with the specified name') p.add_argument('file', help='File to write (must be 32 bytes long)', type=argparse.FileType('rb')) p.add_argument('key_block', help='Number of key block to burn', type=int, choices=range(0, 7)) p.add_argument('purpose', help='Purpose to set)', choices=KEY_PURPOSES) p = subparsers.add_parser( 'burn_key_digest', help='Parse a RSA public key and burn the digest to key efuse block') p.add_argument('file', help='Key file to digest (PEM format)', type=argparse.FileType('r')) p.add_argument('key_block', help='Number of key block to burn', type=int, choices=range(0, 7)) p.add_argument('purpose', help='Purpose to set)', choices=KEY_PURPOSES) args = parser.parse_args() # each 'operation' is a module-level function of the same name operation_func = globals()[args.operation] esp = esptool.ESP32ROM(args.port) esp.connect(args.before) operation_func(esp, args)