def main(): skipConnection = False # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) print "Connected to device" while True: try: mooltipass_device.getInternalDevice().receiveHidMessage() except KeyboardInterrupt: sys.exit(0) except: continue #mooltipass_device.getInternalDevice().benchmarkPingPongSpeed(mooltipass_device.createPingPacket()) # Get Mooltipass Version #version_data = mooltipass_device.getMooltipassVersionAndVariant() #print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status #print "Mooltipass status:", mooltipass_device.getMooltipassStatus() #print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "sendMonitorFrame": # mooltipass_tool.py sendMonitorFrame filename if len(sys.argv) > 2: bitdepth = 4 mooltipass_device.sendAndMonitorFrame(sys.argv[2], bitdepth) else: print "Please specify picture filename" elif sys.argv[1] == "uploadDebugBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 2: filename = sys.argv[2] mooltipass_device.uploadDebugBundle(filename) else: print "Please specify bundle filename" elif sys.argv[1] == "rebootToBootloader": mooltipass_device.rebootToBootloader() elif sys.argv[1] == "accGet": mooltipass_device.getAccData()
def main(): skipConnection = False # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) # Get Mooltipass Version version_data = mooltipass_device.getMooltipassVersionAndVariant() print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status print "Mooltipass status:", mooltipass_device.getMooltipassStatus() print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "uploadBundle": # extract args if len(sys.argv) > 2: filename = sys.argv[2] else: filename = None if len(sys.argv) > 3: password = sys.argv[3] else: password = None # start upload mooltipass_device.uploadBundle(password, filename, True) if sys.argv[1] == "packAndSign": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], True) else: firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], None, sys.argv[5], True) else: print "packAndSign: not enough args!" if sys.argv[1] == "packSignUpload": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], "updatefile.img", True) else: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], None, "updatefile.img", True) # Did we generate the bundle? if bundle_gen == True: if len(sys.argv) > 6: mooltipass_device.uploadBundle(sys.argv[6], "updatefile.img", True) else: mooltipass_device.uploadBundle(sys.argv[5], "updatefile.img", True) else: print "packAndSign: not enough args!" if sys.argv[1] == "minicheck": if len(sys.argv) > 7: mooltipass_security_check.mooltipassMiniSecCheck(mooltipass_device, sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8]) else: print "minicheck: not enough args!" if sys.argv[1] == "initproc": if version_data[2] == "mini": mooltipassMiniInit(mooltipass_device) else: print "Device Not Supported" if sys.argv[1] == "massprodinit": if version_data[2] == "mini": mooltipassMiniMassProdInit(mooltipass_device) else: print "Device Not Supported" # Generate a mass production file if sys.argv[1] == "generate_mass_prod_file": if len(sys.argv) == (2 + 2): # Only firmware hex + bootloader hex are passed as args: 0s for aes keys and uids print "Generating blank mass production file with 0s for AES keys and UID" generateFlashAndEepromHex(sys.argv[2], sys.argv[3], 12345, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0], "newflash.hex", "neweeprom.hex", True) if sys.argv[1] == "get_serial": if version_data[2] == "mini": serial_number = mooltipass_device.getMooltipassMiniSerial() print "Serial number in hex:", "".join(format(x, "02x") for x in serial_number) print "Serial number in decimal:", serial_number[0]*16777216 + serial_number[1]*65536 + serial_number[2]*256 + serial_number[3]*1 else: print "Device Not Supported" if sys.argv[1] == "get_serial_set_tutorial": if version_data[2] == "mini": serial_number = mooltipass_device.getMooltipassMiniSerial() print "Serial number in hex:", "".join(format(x, "02x") for x in serial_number) print "Serial number in decimal:", serial_number[0]*16777216 + serial_number[1]*65536 + serial_number[2]*256 + serial_number[3]*1 else: print "Device Not Supported" mooltipass_device.enableTutorial() if sys.argv[1] == "decrypt_mini_prod": if len(sys.argv) > 2: decryptMiniProdFile(sys.argv[2]) else: print "decrypt_mini_prod: not enough args!" if sys.argv[1] == "get_uid": if len(sys.argv) > 2: uid = mooltipass_device.getUID(sys.argv[2]) if uid != None: print "UID:", "".join(format(x, "02x") for x in uid) else: print "get_uid: not enough args!" if sys.argv[1] == "read_user_db_change_nb": mooltipass_device.getMooltipassUserDbChangeNumber() if sys.argv[1] == "set_user_db_change_nb": if len(sys.argv) > 2: mooltipass_device.setMooltipassUserDbChangeNumber(int(sys.argv[2]), int(sys.argv[3])) else: print "set_user_db_change_nb: not enough args!" if sys.argv[1] == "get_free_user_slots": mooltipass_device.getFreeUserSlots() if sys.argv[1] == "change_login_description": mooltipass_device.changeLoginDescription() if sys.argv[1] == "add_credential": mooltipass_device.addCredential() if sys.argv[1] == "test_please_retry": mooltipass_device.testPleaseRetry() if sys.argv[1] == "get_card_cpz": mooltipass_device.getCardCpz() if sys.argv[1] == "lock": mooltipass_device.lock() if sys.argv[1] == "get_card_creds": mooltipass_device.getCardCreds() if sys.argv[1] == "set_card_login": if len(sys.argv) > 2: mooltipass_device.setCardLogin(sys.argv[2]) else: print "set_card_login: not enough args!" if sys.argv[1] == "set_card_password": if len(sys.argv) > 2: mooltipass_device.setCardPassword(sys.argv[2]) else: print "set_card_password: not enough args!" if sys.argv[1] == "get_upload_password": if len(sys.argv) > 3: AESKey2 = sys.argv[3] UIDReqKey = sys.argv[2] # Check Key sizes if len(AESKey2) != AES_KEY_SIZE*2: print "Wrong AES Key 2 size" return if len(UIDReqKey) != UID_REQUEST_KEY_SIZE*2: print "Wrong UID request key size" return # Convert string into arrays AESKey2_array = array('B', AESKey2.decode("hex")) uid = mooltipass_device.getUID(UIDReqKey) if uid != None: print "Device UID (make sure it's correct):", "".join(format(x, "02x") for x in uid) text_password = generateBundlePasswordUpload(version_data[1], uid, AESKey2_array) print "Your upload password is:",text_password else: print "get_upload_password: not enough args!" print "get_upload_password <UID Request Key> <AES Key 2>"
def main(): skipConnection = False # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) # Get Mooltipass Version version_data = mooltipass_device.getMooltipassVersionAndVariant() print "Mooltipass version: " + version_data[ 1] + ", variant: " + version_data[2] + ", " + str( version_data[0]) + "Mb of Flash" # Print Mooltipass status print "Mooltipass status:", mooltipass_device.getMooltipassStatus() print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "uploadBundle": # extract args if len(sys.argv) > 2: filename = sys.argv[2] else: filename = None if len(sys.argv) > 3: password = sys.argv[3] else: password = None # start upload mooltipass_device.uploadBundle(password, filename, True) if sys.argv[1] == "packAndSign": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], True) else: firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], None, sys.argv[5], True) else: print "packAndSign: not enough args!" if sys.argv[1] == "packSignUpload": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], "updatefile.img", True) else: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], None, "updatefile.img", True) # Did we generate the bundle? if bundle_gen == True: if len(sys.argv) > 6: mooltipass_device.uploadBundle(sys.argv[6], "updatefile.img", True) else: mooltipass_device.uploadBundle(sys.argv[5], "updatefile.img", True) else: print "packAndSign: not enough args!" if sys.argv[1] == "minicheck": if len(sys.argv) > 7: mooltipass_security_check.mooltipassMiniSecCheck( mooltipass_device, sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8]) else: print "minicheck: not enough args!" if sys.argv[1] == "initproc": if version_data[2] == "mini": mooltipassMiniInit(mooltipass_device) else: print "Device Not Supported" if sys.argv[1] == "massprodinit": if version_data[2] == "mini": mooltipassMiniMassProdInit(mooltipass_device) else: print "Device Not Supported" # Generate a mass production file if sys.argv[1] == "generate_mass_prod_file": if len(sys.argv) == (2 + 2): # Only firmware hex + bootloader hex are passed as args: 0s for aes keys and uids print "Generating blank mass production file with 0s for AES keys and UID" generateFlashAndEepromHex(sys.argv[2], sys.argv[3], 12345, [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], "newflash.hex", "neweeprom.hex", True) if sys.argv[1] == "get_serial": if version_data[2] == "mini": serial_number = mooltipass_device.getMooltipassMiniSerial() print "Serial number in hex:", "".join( format(x, "02x") for x in serial_number) print "Serial number in decimal:", serial_number[ 0] * 16777216 + serial_number[1] * 65536 + serial_number[ 2] * 256 + serial_number[3] * 1 else: print "Device Not Supported" if sys.argv[1] == "decrypt_mini_prod": if len(sys.argv) > 2: decryptMiniProdFile(sys.argv[2]) else: print "decrypt_mini_prod: not enough args!" if sys.argv[1] == "get_uid": if len(sys.argv) > 2: uid = mooltipass_device.getUID(sys.argv[2]) if uid != None: print "UID:", "".join(format(x, "02x") for x in uid) else: print "decrypt_mini_prod: not enough args!" if sys.argv[1] == "read_user_db_change_nb": mooltipass_device.getMooltipassUserDbChangeNumber() if sys.argv[1] == "set_user_db_change_nb": if len(sys.argv) > 2: mooltipass_device.setMooltipassUserDbChangeNumber( int(sys.argv[2]), int(sys.argv[3])) else: print "set_user_db_change_nb: not enough args!" if sys.argv[1] == "get_free_user_slots": mooltipass_device.getFreeUserSlots() if sys.argv[1] == "change_login_description": mooltipass_device.changeLoginDescription() if sys.argv[1] == "add_credential": mooltipass_device.addCredential() if sys.argv[1] == "test_please_retry": mooltipass_device.testPleaseRetry() if sys.argv[1] == "get_card_cpz": mooltipass_device.getCardCpz() if sys.argv[1] == "lock": mooltipass_device.lock()
def main(): skipConnection = False # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) # Get Mooltipass Version version_data = mooltipass_device.getMooltipassVersionAndVariant() print "Mooltipass version: " + version_data[ 1] + ", variant: " + version_data[2] + ", " + str( version_data[0]) + "Mb of Flash" # Print Mooltipass status print "Mooltipass status:", mooltipass_device.getMooltipassStatus() print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "uploadBundle": # extract args if len(sys.argv) > 2: filename = sys.argv[2] else: filename = None if len(sys.argv) > 3: password = sys.argv[3] else: password = None # start upload mooltipass_device.uploadBundle(password, filename, True) if sys.argv[1] == "packAndSign": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], True) else: firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], None, sys.argv[5], True) else: print "packAndSign: not enough args!" if sys.argv[1] == "packSignUpload": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], "updatefile.img", True) else: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign( sys.argv[2], sys.argv[3], sys.argv[4], None, "updatefile.img", True) # Did we generate the bundle? if bundle_gen == True: if len(sys.argv) > 6: mooltipass_device.uploadBundle(sys.argv[6], "updatefile.img", True) else: mooltipass_device.uploadBundle(sys.argv[5], "updatefile.img", True) else: print "packAndSign: not enough args!" if sys.argv[1] == "minicheck": if len(sys.argv) > 3: mooltipass_security_check.mooltipassMiniSecCheck( mooltipass_device, sys.argv[2], sys.argv[3], sys.argv[4]) else: print "minicheck: not enough args!" if sys.argv[1] == "init": if len(sys.argv) > 2: if version_data[2] == "mini": mooltipassMiniInit(mooltipass_device) else: print "Device Not Supported" else: print "init: not enough args!" if sys.argv[1] == "decrypt_mini_prod": if len(sys.argv) > 2: decryptMiniProdFile(sys.argv[2]) else: print "decrypt_mini_prod: not enough args!" if sys.argv[1] == "read_user_db_change_nb": mooltipass_device.getMooltipassUserDbChangeNumber() if sys.argv[1] == "set_user_db_change_nb": if len(sys.argv) > 2: mooltipass_device.setMooltipassUserDbChangeNumber( int(sys.argv[2])) else: print "set_user_db_change_nb: not enough args!" if sys.argv[1] == "get_free_user_slots": mooltipass_device.getFreeUserSlots()
def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold") self.configure(background='LightSteelBlue2') self.title("Battery Monitoring Tool") self.resizable(0,0) self.focus_set() self.bind("<Escape>", lambda e: e.widget.quit()) # Vars self.monitoring_bool = False self.log_file_opened = False self.log_counter = 0 # Power Source self.power_source_label = tk.Label(self, text="Power Source :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.power_source_label.grid(sticky="e", row=0, column=0, pady=(5,2), padx=5) self.power_source_value = tk.Label(self, text="Battery", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.power_source_value.grid(row=0, column=1, pady=(5,2), padx=5) # Charging State self.charging_state_label = tk.Label(self, text="Charging State :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.charging_state_label.grid(sticky="e", row=0, column=2, pady=(5,2), padx=5) self.charging_state_value = tk.Label(self, text="Charging", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.charging_state_value.grid(row=0, column=3, pady=(5,2), padx=5) # Main ADC Value self.main_adc_voltage_label = tk.Label(self, text="Main ADC Voltage :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.main_adc_voltage_label.grid(sticky="e", row=1, column=0, pady=(0,2), padx=5) self.main_adc_voltage_value = tk.Label(self, text="1000mV", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.main_adc_voltage_value.grid(row=1, column=1, pady=(0,2), padx=5) # Aux ADC Value self.aux_adc_voltage_label = tk.Label(self, text="Aux ADC Voltage :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.aux_adc_voltage_label.grid(sticky="e", row=1, column=2, pady=(0,2), padx=5) self.aux_adc_voltage_value = tk.Label(self, text="1000mV", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.aux_adc_voltage_value.grid(row=1, column=3, pady=(0,2), padx=5) # Aux Charge Status self.aux_charge_status_label = tk.Label(self, text="Aux Charge Status :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.aux_charge_status_label.grid(sticky="e", row=2, column=0, pady=(0,2), padx=5) self.aux_charge_status_value = tk.Label(self, text="2", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.aux_charge_status_value.grid(row=2, column=1, pady=(0,2), padx=5) # Aux Charge Current self.aux_charge_current_label = tk.Label(self, text="Aux Charge Current :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.aux_charge_current_label.grid(sticky="e", row=2, column=2, pady=(0,2), padx=5) self.aux_charge_current_value = tk.Label(self, text="2", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.aux_charge_current_value.grid(row=2, column=3, pady=(0,2), padx=5) # Aux Stepdown Voltage self.aux_stepdown_voltage_label = tk.Label(self, text="Aux Stepdown Voltage :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.aux_stepdown_voltage_label.grid(sticky="e", row=3, column=0, pady=(0,2), padx=5) self.aux_stepdown_voltage_value = tk.Label(self, text="2", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.aux_stepdown_voltage_value.grid(row=3, column=1, pady=(0,2), padx=5) # Aux DAC data register value self.aux_data_register_label = tk.Label(self, text="Aux DAC DATA :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.aux_data_register_label.grid(sticky="e", row=3, column=2, pady=(0,2), padx=5) self.aux_data_register_value = tk.Label(self, text="2", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12, weight=tkfont.BOLD)) self.aux_data_register_value.grid(row=3, column=3, pady=(0,2), padx=5) # Action Buttons self.platform_connect_button = tk.Button(self, text="Start Charge", font=tkfont.Font(family='Helvetica', size=9), width="18", command=lambda:[self.action_button(True, False, False, False, 0, False)]) self.platform_connect_button.grid(row=4, column=0, pady=(5,2), padx=5) self.platform_connect_button = tk.Button(self, text="Stop Charge", font=tkfont.Font(family='Helvetica', size=9), width="18", command=lambda:[self.action_button(False, True, False, False, 0, False)]) self.platform_connect_button.grid(row=4, column=1, pady=(5,2), padx=5) self.platform_connect_button = tk.Button(self, text="Screen Power: USB", font=tkfont.Font(family='Helvetica', size=9), width="18", command=lambda:[self.action_button(False, False, True, False, 0, False)]) self.platform_connect_button.grid(row=4, column=2, pady=(5,2), padx=5) self.platform_connect_button = tk.Button(self, text="Screen Power: Battery", font=tkfont.Font(family='Helvetica', size=9), width="18", command=lambda:[self.action_button(False, False, False, True, 0, False)]) self.platform_connect_button.grid(row=4, column=3, pady=(5,2), padx=5) # Log output self.log_output_text = tk.Text(self, width=80, height=8, wrap=tk.WORD) self.log_output_text.grid(row=5, column=0, columnspan=4, pady=(15,2), padx = 20) # Monitor Button self.empty_label = tk.Label(self, text="", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.empty_label.grid(sticky="e", row=6, column=0, pady=(5,2), padx=5) self.monitor_button = tk.Button(self, text="Start Battery Monitoring", font=tkfont.Font(family='Helvetica', size=9), width="40", command=lambda:[self.monitor_button_action()]) self.monitor_button.grid(row=6, column=1, columnspan=2, pady=(5,2), padx=5) # Force Charge Voltage Row self.force_charge_voltage_label = tk.Label(self, text="Force Charge Voltage :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") self.force_charge_voltage_label.grid(sticky="e", row=7, column=0, pady=(25,15), padx=5) self.frame_mv = tk.Frame(self, background="LightSteelBlue2") self.force_charge_voltage_text_var = tk.IntVar() self.force_charge_voltage_text = tk.Entry(self.frame_mv, width=10, justify='center', textvariable=self.force_charge_voltage_text_var) self.force_charge_voltage_text.pack(side=tk.LEFT,pady=(0,0),padx=(0,0)) self.force_charge_voltage_label_mv = tk.Label(self.frame_mv, text=" mV", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12)) self.force_charge_voltage_label_mv.pack(side=tk.LEFT,pady=(0,0),padx=(0,0)) self.frame_mv.grid(row=7, column=1, pady=(25,15), padx=5) self.platform_connect_button = tk.Button(self, text="Force Charge Voltage", font=tkfont.Font(family='Helvetica', size=9), width="18", command=lambda:[self.action_button(False, False, False, False, self.force_charge_voltage_text_var.get(), False)]) self.platform_connect_button.grid(row=7, column=2, pady=(25,15), padx=5) self.platform_connect_button = tk.Button(self, text="Stop Force Charge", font=tkfont.Font(family='Helvetica', size=9), width="18", command=lambda:[self.action_button(False, False, False, False, 0, True)]) self.platform_connect_button.grid(row=7, column=3, pady=(25,15), padx=5) # Device connection self.mooltipass_device = mooltipass_hid_device() # Connect to device if self.mooltipass_device.connect(True) == False: sys.exit(0) # Debug self.log_output_text.insert("end", "Connected to device\r\n") self.log_output_text.see(tk.END) # Force UI update self.update_idletasks() self.update() # Initial value fetch self.after(500, self.action_button(False,False,False,False,0,False))
def main(): skipConnection = False waitForDeviceConnection = False # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True # Waiting for device connection if len(sys.argv) > 1 and sys.argv[1] == "initCode": waitForDeviceConnection = True if not skipConnection: # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if waitForDeviceConnection == False: if mooltipass_device.connect(True) == False: sys.exit(0) else: while mooltipass_device.connect(False) == False: time.sleep(1) print("Connected to device") while len(sys.argv) > 1 and sys.argv[1] == "log": mooltipass_device.getInternalDevice().receiveHidMessage( exit_on_timeout=False) #try: # mooltipass_device.getInternalDevice().receiveHidMessage() #except KeyboardInterrupt: # sys.exit(0) #except Exception as e: # continue #mooltipass_device.getInternalDevice().benchmarkPingPongSpeed(mooltipass_device.createPingPacket()) # Get Mooltipass Version #version_data = mooltipass_device.getMooltipassVersionAndVariant() #print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status #print "Mooltipass status:", mooltipass_device.getMooltipassStatus() #print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "sendMonitorFrame": # mooltipass_tool.py sendMonitorFrame filename if len(sys.argv) > 2: bitdepth = 4 mooltipass_device.sendAndMonitorFrame(sys.argv[2], bitdepth) else: print("Please specify picture filename") elif sys.argv[1] == "uploadDebugBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 2: filename = sys.argv[2] mooltipass_device.uploadDebugBundle(filename) else: print("Please specify bundle filename") elif sys.argv[1] == "rebootToBootloader": mooltipass_device.rebootToBootloader() elif sys.argv[1] == "flashAuxMcuFromBundle": mooltipass_device.flashAuxMcuFromBundle() elif sys.argv[1] == "platInfo": mooltipass_device.getPlatInfo() elif sys.argv[1] == "accGet": mooltipass_device.getAccData() elif sys.argv[1] == "flashUniqueData": mooltipass_device.flashUniqueData() elif sys.argv[1] == "timediff": mooltipass_device.timeDiff() elif sys.argv[1] == "initCode": mooltipass_device.initCode() elif sys.argv[1] == "debugListen": while True: try: mooltipass_device.getInternalDevice().receiveHidMessage() except KeyboardInterrupt: sys.exit(0) except: continue
def main(): skipConnection = False waitForDeviceConnection = False # HID device constructor mooltipass_device = mooltipass_hid_device() # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # Connect to device if waitForDeviceConnection == False: if mooltipass_device.connect(True) == False: sys.exit(0) else: while mooltipass_device.connect(False) == False: time.sleep(1) print("Connected to device") while len(sys.argv) > 1 and sys.argv[1] == "log": mooltipass_device.getInternalDevice().receiveHidMessage( exit_on_timeout=False) #try: # mooltipass_device.getInternalDevice().receiveHidMessage() #except KeyboardInterrupt: # sys.exit(0) #except Exception as e: # continue #mooltipass_device.getInternalDevice().benchmarkPingPongSpeed(mooltipass_device.createPingPacket()) # Get Mooltipass Version #version_data = mooltipass_device.getMooltipassVersionAndVariant() #print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status #print "Mooltipass status:", mooltipass_device.getMooltipassStatus() #print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "sendMonitorFrame": # mooltipass_tool.py sendMonitorFrame filename if len(sys.argv) > 2: bitdepth = 4 mooltipass_device.sendAndMonitorFrame(sys.argv[2], bitdepth) else: print("Please specify picture filename") elif sys.argv[1] == "uploadDebugBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 2: filename = sys.argv[2] mooltipass_device.uploadDebugBundle(filename) else: print("Please specify bundle filename") elif sys.argv[1] == "uploadBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 3: filename = sys.argv[2] passwd = sys.argv[3] mooltipass_device.uploadAndUpgradePlatform(filename, passwd) else: print("Please specify bundle filename") elif sys.argv[1] == "rebootToBootloader": mooltipass_device.rebootToBootloader() elif sys.argv[1] == "flashAuxMcuFromBundle": mooltipass_device.flashAuxMcuFromBundle() elif sys.argv[1] == "platInfo": mooltipass_device.getPlatInfo() elif sys.argv[1] == "accGet": mooltipass_device.getAccData() elif sys.argv[1] == "flashUniqueData": mooltipass_device.flashUniqueData() elif sys.argv[1] == "timediff": mooltipass_device.timeDiff() elif sys.argv[1] == "deviceSNLabelPrinting": last_serial_number = -1 while True: while mooltipass_device.connect(False, read_timeout=1000) == False: time.sleep(.1) # Ask for the info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_PLAT_INFO, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) device_serial_number = struct.unpack('I', packet["data"][8:12])[0] # Print if different from before if last_serial_number != device_serial_number: print("device SN:", device_serial_number) print_labels_for_ble_device(device_serial_number) last_serial_number = device_serial_number # Wait for disconnect mooltipass_device.waitForDisconnect() time.sleep(1) elif sys.argv[1] == "printDiagData": mooltipass_device.printDiagData() elif sys.argv[1] == "recondition": mooltipass_device.recondition() elif sys.argv[1] == "debugListen": while True: try: mooltipass_device.getInternalDevice().receiveHidMessage() except KeyboardInterrupt: sys.exit(0) except: continue
def main(): print "Mooltipass Mass Programming Tool" # Check for public key if not os.path.isfile("publickey.bin"): print "Couldn't find public key!" return # Check for firmware file presence if not os.path.isfile("Mooltipass.hex"): print "Couldn't find Mooltipass.hex" sys.exit(0) # Check for bootloader file presence if not os.path.isfile("bootloader_mini.hex"): print "Couldn't find bootloader_mini.hex" sys.exit(0) # Temp vars prog_socket_states = [PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE] programming_threads = [0, 0, 0, 0, 0, 0, 0, 0, 0] next_available_mooltipass_id = 1 mooltipass_ids_pending = [] mooltipass_ids_to_take = [] global displayed_texts temp_counter = 0 # Random bytes buffer random_bytes_buffer = [] # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) # Generate a blank firmware to see if we actually can generate it and then print the hash return_gen = generateFlashAndEepromHex("Mooltipass.hex", "bootloader_mini.hex", 12345, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0], "/tmp/test_flash.hex", "/tmp/test_eeprom.hex", True) os.remove("/tmp/test_flash.hex") os.remove("/tmp/test_eeprom.hex") # Check the success status if return_gen[0] == False: print "Couldn't generate a template flash hex!" sys.exit(0) # Check for random numbers file presence if os.path.isfile("rng.bin"): try: random_bytes_buffer = pickle_read("rng.bin") except EOFError: # This happens when the file is corrupted random_bytes_buffer = [] os.remove("rng.bin") # Set to true to export the random bytes if False: f = open('randombytes.bin', 'wb') random_bytes_buffer.tofile(f) f.flush() f.close() # Check for next mooltipass id file if os.path.isfile("mooltipass_id.bin"): next_available_mooltipass_id = pickle_read("mooltipass_id.bin") # Check for available mooltipass ids file if os.path.isfile("mooltipass_av_ids.bin"): mooltipass_ids_to_take = pickle_read("mooltipass_av_ids.bin") # Check for available mooltipass ids file if os.path.isfile("mooltipass_pending_ids.bin"): mooltipass_ids_pending = pickle_read("mooltipass_pending_ids.bin") if len(mooltipass_ids_pending) > 0: os.remove("mooltipass_pending_ids.bin") mooltipass_ids_to_take.extend(mooltipass_ids_pending) print "Adding previously pending ids:", mooltipass_ids_pending # Remove possible duplicates mooltipass_ids_to_take = list(set(mooltipass_ids_to_take)) print "Mooltipass IDs to take:", mooltipass_ids_to_take pickle_write(mooltipass_ids_to_take, "mooltipass_av_ids.bin") # Read public key public_key = pickle_read("publickey.bin") # Display text on screen add_line_on_screen(mooltipass_device, "Python Script Started") add_line_on_screen(mooltipass_device, return_gen[1][0:20]) add_line_on_screen(mooltipass_device, return_gen[1][20:]) # Main loop while True: time.sleep(.3) temp_counter = temp_counter + 1 # Check if a button is pressed mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_BUTTON_PRESSED, 0, None)) received_data = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout() for i in range(0,9): if received_data[DATA_INDEX+i] != 0: # Programming button was pressed on the bench print "Button", i, "pressed" prog_socket_states[i] = PROG_SOCKET_PENDING # Get number of available random bytes mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_GET_RNG_B_AVAIL, 0, None)) nb_random_bytes_available = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout()[DATA_INDEX] # If more than 32 bytes, fetch them if nb_random_bytes_available >= 32: mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_GET_RANDOM_NUMBER, 0, None)) random_bytes = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout()[DATA_INDEX:DATA_INDEX+32] random_bytes_buffer.extend(random_bytes) # Store random bytes buffer every now and then if temp_counter % 30 == 0: pickle_write(random_bytes_buffer, "rng.bin") print "Random bytes buffer saved:", len(random_bytes_buffer), "bytes available" #print random_bytes_buffer # If we have enough random bytes and a button was pressed, program the MCU for socket_id in range(0, 9): if prog_socket_states[socket_id] == PROG_SOCKET_PENDING and len(random_bytes_buffer) >= AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH: print "Starting programming for socket", socket_id # Generate new mooltipass ID if len(mooltipass_ids_to_take) > 0: mooltipass_id = mooltipass_ids_to_take[0] del(mooltipass_ids_to_take[0]) else: # No ids to take, take the next available one mooltipass_id = next_available_mooltipass_id next_available_mooltipass_id = next_available_mooltipass_id + 1 # Store the new id in file pickle_write(next_available_mooltipass_id, "mooltipass_id.bin") # Generate keys from the random bytes buffer aes_key1 = random_bytes_buffer[0:AES_KEY_LENGTH] aes_key2 = random_bytes_buffer[AES_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH] uid_key = random_bytes_buffer[AES_KEY_LENGTH+AES_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH] uid = random_bytes_buffer[AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH] del(random_bytes_buffer[0:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH]) # Write in file: Mooltipass ID | aes key 1 | aes key 2 | request ID key | UID, flush write aes_key1_text = "".join(format(x, "02x") for x in aes_key1) aes_key2_text = "".join(format(x, "02x") for x in aes_key2) uid_key_text = "".join(format(x, "02x") for x in uid_key) uid_text = "".join(format(x, "02x") for x in uid) string_export = str(mooltipass_id)+"|"+ aes_key1_text +"|"+ aes_key2_text +"|"+ uid_key_text +"|"+ uid_text+"\r\n" #print string_export try: pickle_file_name = time.strftime("export/%Y-%m-%d-%H-%M-%S-Mooltipass-")+str(mooltipass_id)+".txt" pickle_write(seccure.encrypt(string_export, public_key, curve='secp521r1/nistp521'), pickle_file_name) except NameError: pickle_file_name = "test" # Generate programming file generateFlashAndEepromHex("Mooltipass.hex", "bootloader_mini.hex", mooltipass_id, aes_key1, aes_key2, uid_key, uid, "/tmp/flash_"+str(mooltipass_id)+".hex", "/tmp/eeprom_"+str(mooltipass_id)+".hex", False) # Change state to programming prog_socket_states[socket_id] = PROG_SOCKET_PROGRAMMING # Display info on display add_line_on_screen(mooltipass_device, "#"+str(socket_id)+": programming id "+str(mooltipass_id)) # Launch a programming thread mooltipass_ids_pending.append(mooltipass_id) pickle_write(mooltipass_ids_pending, "mooltipass_pending_ids.bin") programming_threads[socket_id] = FuncThread(start_programming, socket_id, mooltipass_id, "/tmp/flash_"+str(mooltipass_id)+".hex", "/tmp/eeprom_"+str(mooltipass_id)+".hex", pickle_file_name) programming_threads[socket_id].start() # Check for thread end for socket_id in range(0, 9): # Check if we're currently programming if prog_socket_states[socket_id] == PROG_SOCKET_PROGRAMMING: # Check if the thread ended if not programming_threads[socket_id].is_alive(): print "Thread for socket", socket_id, "ended" # Fetch the return data return_data = programming_threads[socket_id].join() # Delete the temporary programming files os.remove(return_data[2]) os.remove(return_data[3]) # Check success state if return_data[0] : print "Programming for socket", socket_id, "succeeded (mooltipass id:", str(return_data[1]) + ")" # Save our mooltipass pool in case it was an id to take pickle_write(mooltipass_ids_to_take, "mooltipass_av_ids.bin") # Inform programming platform of success state mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_PROG_DONE, 1, [socket_id])) mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout() add_line_on_screen(mooltipass_device, "#"+str(socket_id)+": "+return_data[4]) else: print "Programming for socket", socket_id, "failed (mooltipass id:", str(return_data[1]) + ")" # Put the mooltipass id back in the pool mooltipass_ids_to_take.append(return_data[1]) pickle_write(mooltipass_ids_to_take, "mooltipass_av_ids.bin") # Delete encrypted keys file os.remove(return_data[5]) # Inform programming platform of success state mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_PROG_FAILURE, 1, [socket_id])) mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout() add_line_on_screen(mooltipass_device, "#"+str(socket_id)+": "+return_data[4]) # Remove id from pending ones mooltipass_ids_pending.remove(return_data[1]) pickle_write(mooltipass_ids_pending, "mooltipass_pending_ids.bin") # Reset prog state prog_socket_states[socket_id] = PROG_SOCKET_IDLE
def main(): skipConnection = False # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) # Get Mooltipass Version version_data = mooltipass_device.getMooltipassVersionAndVariant() print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status print "Mooltipass status:", mooltipass_device.getMooltipassStatus() print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "uploadBundle": # extract args if len(sys.argv) > 2: filename = sys.argv[2] else: filename = None if len(sys.argv) > 3: password = sys.argv[3] else: password = None # start upload mooltipass_device.uploadBundle(password, filename, True) if sys.argv[1] == "packAndSign": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], True) else: firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], None, sys.argv[5], True) else: print "packAndSign: not enough args!" if sys.argv[1] == "packSignUpload": if len(sys.argv) > 5: # Depending on number of args, set a new password or not if len(sys.argv) > 6: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], "updatefile.img", True) else: bundle_gen = firmwareBundlePackAndSign.bundlePackAndSign(sys.argv[2], sys.argv[3], sys.argv[4], None, "updatefile.img", True) # Did we generate the bundle? if bundle_gen == True: if len(sys.argv) > 6: mooltipass_device.uploadBundle(sys.argv[6], "updatefile.img", True) else: mooltipass_device.uploadBundle(sys.argv[5], "updatefile.img", True) else: print "packAndSign: not enough args!" if sys.argv[1] == "minicheck": if len(sys.argv) > 3: mooltipass_security_check.mooltipassMiniSecCheck(mooltipass_device, sys.argv[2], sys.argv[3], sys.argv[4]) else: print "minicheck: not enough args!" if sys.argv[1] == "init": if len(sys.argv) > 2: if version_data[2] == "mini": mooltipassMiniInit(mooltipass_device) else: print "Device Not Supported" else: print "init: not enough args!" if sys.argv[1] == "decrypt_mini_prod": if len(sys.argv) > 2: decryptMiniProdFile(sys.argv[2]) else: print "decrypt_mini_prod: not enough args!" if sys.argv[1] == "read_user_db_change_nb": mooltipass_device.getMooltipassUserDbChangeNumber() if sys.argv[1] == "set_user_db_change_nb": if len(sys.argv) > 2: mooltipass_device.setMooltipassUserDbChangeNumber(int(sys.argv[2])) else: print "set_user_db_change_nb: not enough args!" if sys.argv[1] == "get_free_user_slots": mooltipass_device.getFreeUserSlots() if sys.argv[1] == "change_login_description": mooltipass_device.changeLoginDescription() if sys.argv[1] == "add_credential": mooltipass_device.addCredential() if sys.argv[1] == "test_please_retry": mooltipass_device.testPleaseRetry() if sys.argv[1] == "get_card_cpz": mooltipass_device.getCardCpz() if sys.argv[1] == "lock": mooltipass_device.lock()
def main(): skipConnection = False waitForDeviceConnection = False # HID device constructor mooltipass_device = mooltipass_hid_device() # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # Connect to device if waitForDeviceConnection == False: if mooltipass_device.connect(True) == False: sys.exit(0) else: while mooltipass_device.connect(False) == False: time.sleep(1) print("Connected to device") while len(sys.argv) > 1 and sys.argv[1] == "log": mooltipass_device.getInternalDevice().receiveHidMessage( exit_on_timeout=False) #try: # mooltipass_device.getInternalDevice().receiveHidMessage() #except KeyboardInterrupt: # sys.exit(0) #except Exception as e: # continue #mooltipass_device.getInternalDevice().benchmarkPingPongSpeed(mooltipass_device.createPingPacket()) # Get Mooltipass Version #version_data = mooltipass_device.getMooltipassVersionAndVariant() #print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status #print "Mooltipass status:", mooltipass_device.getMooltipassStatus() #print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "sendMonitorFrame": # mooltipass_tool.py sendMonitorFrame filename if len(sys.argv) > 2: bitdepth = 4 mooltipass_device.sendAndMonitorFrame(sys.argv[2], bitdepth) else: print("Please specify picture filename") elif sys.argv[1] == "uploadDebugBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 2: filename = sys.argv[2] mooltipass_device.uploadDebugBundle(filename) else: print("Please specify bundle filename") elif sys.argv[1] == "uploadBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 3: filename = sys.argv[2] passwd = sys.argv[3] mooltipass_device.uploadAndUpgradePlatform(filename, passwd) else: print("Please specify bundle filename") elif sys.argv[1] == "rebootToBootloader": mooltipass_device.rebootToBootloader() elif sys.argv[1] == "flashAuxMcuFromBundle": mooltipass_device.flashAuxMcuFromBundle() elif sys.argv[1] == "platInfo": mooltipass_device.getPlatInfo() elif sys.argv[1] == "accGet": mooltipass_device.getAccData() elif sys.argv[1] == "flashUniqueData": mooltipass_device.flashUniqueData() elif sys.argv[1] == "timediff": mooltipass_device.timeDiff() elif sys.argv[1] == "getSN": # Ask for the info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(CMD_ID_GET_DEVICE_SN, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) print("Device Serial Number: " + str(struct.unpack('I', packet["data"][0:4])[0])) elif sys.argv[1] == "deviceSNLabelPrinting": last_serial_number = -1 while True: while mooltipass_device.connect(False, read_timeout=1000) == False: time.sleep(.1) # Ask for the info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_PLAT_INFO, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) device_serial_number = struct.unpack('I', packet["data"][8:12])[0] # Print if different from before if last_serial_number != device_serial_number: print("device SN:", device_serial_number) print_labels_for_ble_device(device_serial_number) last_serial_number = device_serial_number # Wait for disconnect mooltipass_device.waitForDisconnect() time.sleep(1) elif sys.argv[1] == "postLabelPrinting": last_serial_number = -1 while True: while mooltipass_device.connect(False, read_timeout=1000) == False: time.sleep(.1) # Ask for the platfor info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_PLAT_INFO, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) device_serial_number = struct.unpack('I', packet["data"][8:12])[0] # Reset default settings device_default_settings = [0] * 64 device_default_settings[0] = 0 # SETTING_RESERVED_ID device_default_settings[1] = 0 # SETTING_RANDOM_PIN_ID device_default_settings[ 2] = 15 # SETTING_USER_INTERACTION_TIMEOUT_ID device_default_settings[3] = 1 # SETTING_FLASH_SCREEN_ID device_default_settings[ 4] = 0 # SETTING_DEVICE_DEFAULT_LANGUAGE device_default_settings[ 5] = 0x09 # SETTINGS_CHAR_AFTER_LOGIN_PRESS device_default_settings[ 6] = 0x0A # SETTINGS_CHAR_AFTER_PASS_PRESS device_default_settings[ 7] = 15 # SETTINGS_DELAY_BETWEEN_PRESSES device_default_settings[8] = 1 # SETTINGS_BOOT_ANIMATION device_default_settings[9] = 0x90 # SETTINGS_MASTER_CURRENT device_default_settings[10] = 1 # SETTINGS_LOCK_ON_DISCONNECT device_default_settings[ 11] = 9 # SETTINGS_KNOCK_DETECT_SENSITIVITY device_default_settings[ 12] = 0 # SETTINGS_LEFT_HANDED_ON_BATTERY device_default_settings[13] = 0 # SETTINGS_LEFT_HANDED_ON_USB device_default_settings[14] = 0 # SETTINGS_PIN_SHOWN_WHEN_BACK device_default_settings[ 15] = 0 # SETTINGS_UNLOCK_FEATURE_PARAM device_default_settings[16] = 1 # SETTINGS_DEVICE_TUTORIAL device_default_settings[17] = 0 # SETTINGS_SHOW_PIN_ON_ENTRY device_default_settings[ 18] = 0 # SETTINGS_DISABLE_BLE_ON_CARD_REMOVE device_default_settings[19] = 0 # SETTINGS_DISABLE_BLE_ON_LOCK device_default_settings[20] = 0 # SETTINGS_NB_MINUTES_FOR_LOCK device_default_settings[ 21] = 0 # SETTINGS_SWITCH_OFF_AFTER_USB_DISC device_default_settings[ 22] = 0 # SETTINGS_HASH_DISPLAY_FEATURE device_default_settings[ 23] = 30 # SETTINGS_INFORMATION_TIME_DELAY device_default_settings[24] = 0 # SETTINGS_BLUETOOTH_SHORTCUTS device_default_settings[25] = 0 # SETTINGS_SCREEN_SAVER_ID device_default_settings[ 26] = 1 # SETTINGS_PREF_ST_SERV_FEATURE mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( 0x0D, device_default_settings), True) # Reset default language mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(0x1F, [0]), True) # Print if different from before if last_serial_number != device_serial_number: print("device SN:", device_serial_number) print_labels_for_ble_device(device_serial_number) last_serial_number = device_serial_number # Wait for disconnect mooltipass_device.waitForDisconnect() time.sleep(1) elif sys.argv[1] == "printDiagData": mooltipass_device.printDiagData() elif sys.argv[1] == "switchOffAfterDisconnect": mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(0x0039, None), True) elif sys.argv[1] == "recondition": mooltipass_device.recondition() elif sys.argv[1] == "debugListen": while True: try: mooltipass_device.getInternalDevice().receiveHidMessage() except KeyboardInterrupt: sys.exit(0) except: continue
def main(): print "Mooltipass Programming Tool" rng_buf_save_armed = True global main_program_running global serial_to_program global serial_entered global ic_programmed # Delete temp .hex file that might have been left there commands.getstatusoutput("rm /tmp/*.hex") # Check for public key if not os.path.isfile("publickey.bin"): print "Couldn't find public key!" return # Check for firmware file presence if not os.path.isfile("Mooltipass.hex"): print "Couldn't find Mooltipass.hex" sys.exit(0) # Check for bootloader file presence if not os.path.isfile("bootloader_mini.hex"): print "Couldn't find bootloader_mini.hex" sys.exit(0) # Random bytes buffer random_bytes_buffer = [] # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: print "No Mooltipass Connected!" sys.exit(0) # Generate a blank firmware to see if we actually can generate it and then print the hash return_gen = generateFlashAndEepromHex("Mooltipass.hex", "bootloader_mini.hex", 12345, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0], "/tmp/test_flash.hex", "/tmp/test_eeprom.hex", True) os.remove("/tmp/test_flash.hex") os.remove("/tmp/test_eeprom.hex") # Check the success status if return_gen[0] == False: print "Couldn't generate a template flash hex!" sys.exit(0) # Check for random numbers file presence if os.path.isfile("rng.bin"): try: random_bytes_buffer = pickle_read("rng.bin") except EOFError: # This happens when the file is corrupted random_bytes_buffer = [] os.remove("rng.bin") # Set to true to export the random bytes if False: f = open('randombytes.bin', 'wb') random_bytes_buffer.tofile(f) f.flush() f.close() # Read public key public_key = pickle_read("publickey.bin") # Start user input thread user_input_thread = threading.Thread(target=user_input_loop, args=()) user_input_thread.start() # Main loop last_second = int(time.time()) while main_program_running: time.sleep(.1) # Our generator generates 8 bytes per second ts = int(time.time()) if (ts - last_second) > 4: # Fetch random bytes mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_GET_RANDOM_NUMBER, 0, None)) random_bytes = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout()[DATA_INDEX:DATA_INDEX+32] random_bytes_buffer.extend(random_bytes) last_second = ts # Store buffer every minute if datetime.now().second == 0: if rng_buf_save_armed: #print "Random bytes buffer saved:", len(random_bytes_buffer), "bytes available" pickle_write(random_bytes_buffer, "rng.bin") rng_buf_save_armed = False else: rng_buf_save_armed = True # If a serial number was entered if serial_entered == True and len(random_bytes_buffer) >= AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH: # Store serial number to program mooltipass_id = serial_to_program # Generate keys from the random bytes buffer aes_key1 = random_bytes_buffer[0:AES_KEY_LENGTH] aes_key2 = random_bytes_buffer[AES_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH] uid_key = random_bytes_buffer[AES_KEY_LENGTH+AES_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH] uid = random_bytes_buffer[AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH] del(random_bytes_buffer[0:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH]) # Write in file: Mooltipass ID | aes key 1 | aes key 2 | request ID key | UID, flush write aes_key1_text = "".join(format(x, "02x") for x in aes_key1) aes_key2_text = "".join(format(x, "02x") for x in aes_key2) uid_key_text = "".join(format(x, "02x") for x in uid_key) uid_text = "".join(format(x, "02x") for x in uid) string_export = str(mooltipass_id)+"|"+ aes_key1_text +"|"+ aes_key2_text +"|"+ uid_key_text +"|"+ uid_text+"\r\n" #print string_export pickle_file_name = time.strftime("export/%Y-%m-%d-%H-%M-%S-Mooltipass-")+str(mooltipass_id)+".txt" pickle_write(seccure.encrypt(string_export, public_key, curve='secp521r1/nistp521'), pickle_file_name) # Generate programming file generateFlashAndEepromHex("Mooltipass.hex", "bootloader_mini.hex", mooltipass_id, aes_key1, aes_key2, uid_key, uid, "/tmp/flash_"+str(mooltipass_id)+".hex", "/tmp/eeprom_"+str(mooltipass_id)+".hex", False) # Start programming return_data = start_programming(mooltipass_id, "/tmp/flash_"+str(mooltipass_id)+".hex", "/tmp/eeprom_"+str(mooltipass_id)+".hex", pickle_file_name) # Check success state if return_data[0] : print "Programming succeeded (mooltipass id:", str(return_data[1]) + ")" else: print "Programming failed (mooltipass id:", str(return_data[1]) + ")" # Delete encrypted keys file os.remove(return_data[5]) # Free waiting thread serial_entered = False ic_programmed = True
def main(): skipConnection = False waitForDeviceConnection = False # HID device constructor mooltipass_device = mooltipass_hid_device() # If an arg is supplied and if the command doesn't require to connect to a device if len(sys.argv) > 1 and sys.argv[1] in nonConnectionCommands: skipConnection = True if not skipConnection: # Connect to device if waitForDeviceConnection == False: if mooltipass_device.connect(True) == False: sys.exit(0) else: while mooltipass_device.connect(False) == False: time.sleep(1) print("Connected to device") while len(sys.argv) > 1 and sys.argv[1] == "log": mooltipass_device.getInternalDevice().receiveHidMessage( exit_on_timeout=False) #try: # mooltipass_device.getInternalDevice().receiveHidMessage() #except KeyboardInterrupt: # sys.exit(0) #except Exception as e: # continue #mooltipass_device.getInternalDevice().benchmarkPingPongSpeed(mooltipass_device.createPingPacket()) # Get Mooltipass Version #version_data = mooltipass_device.getMooltipassVersionAndVariant() #print "Mooltipass version: " + version_data[1] + ", variant: " + version_data[2] + ", " + str(version_data[0]) + "Mb of Flash" # Print Mooltipass status #print "Mooltipass status:", mooltipass_device.getMooltipassStatus() #print "" # See if args were passed if len(sys.argv) > 1: if sys.argv[1] == "sendMonitorFrame": # mooltipass_tool.py sendMonitorFrame filename if len(sys.argv) > 2: bitdepth = 4 mooltipass_device.sendAndMonitorFrame(sys.argv[2], bitdepth) else: print("Please specify picture filename") elif sys.argv[1] == "uploadDebugBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 2: filename = sys.argv[2] mooltipass_device.uploadDebugBundle(filename) else: print("Please specify bundle filename") elif sys.argv[1] == "spamWithTraffic": while True: packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_GET_DEVICE_LANG, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) elif sys.argv[1] == "uploadBundle": # mooltipass_tool.py uploadDebugBundle filename if len(sys.argv) > 3: filename = sys.argv[2] passwd = sys.argv[3] mooltipass_device.uploadAndUpgradePlatform(filename, passwd) else: print("Please specify bundle filename") elif sys.argv[1] == "rebootToBootloader": mooltipass_device.rebootToBootloader() elif sys.argv[1] == "flashAuxMcuFromBundle": mooltipass_device.flashAuxMcuFromBundle() elif sys.argv[1] == "platInfo": mooltipass_device.getPlatInfo() elif sys.argv[1] == "accGet": mooltipass_device.getAccData() elif sys.argv[1] == "flashUniqueData": mooltipass_device.flashUniqueData() elif sys.argv[1] == "timediff": mooltipass_device.timeDiff() elif sys.argv[1] == "getSN": # Ask for the info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(CMD_ID_GET_DEVICE_SN, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) print("Device Serial Number: " + str(struct.unpack('I', packet["data"][0:4])[0])) elif sys.argv[1] == "setDefaultSettings": # Ask for the info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_SET_DEVICE_SETTINGS, [ 0x00, 0x00, 0x0f, 0x01, 0x00, 0x09, 0x0a, 0x0f, 0x01, 0x90, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) elif sys.argv[1] == "deviceSNLabelPrinting": last_serial_number = -1 while True: while mooltipass_device.connect(False, read_timeout=1000) == False: time.sleep(.1) # Ask for the info packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_PLAT_INFO, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) device_serial_number = struct.unpack('I', packet["data"][8:12])[0] # Print if different from before if last_serial_number != device_serial_number: print("device SN:", device_serial_number) print_labels_for_ble_device(device_serial_number) last_serial_number = device_serial_number # Wait for disconnect mooltipass_device.waitForDisconnect() time.sleep(1) elif sys.argv[1] == "printDiagData": mooltipass_device.printDiagData() elif sys.argv[1] == "switchOffAfterDisconnect": mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(0x0039, None), True) elif sys.argv[1] == "recondition": mooltipass_device.recondition() elif sys.argv[1] == "printMiniBleLabels": export_file_names = [ f for f in listdir("export") if isfile(join("export", f)) ] while True: # Check if we can actually flash the SN... packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_PREPARE_SN_FLASH, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) # Check for answer unit_already_programmed = True if packet["data"][0] == CMD_HID_ACK: print("Flash prepare: unit is not already programmed!") unit_already_programmed = False # Switch off after disconnect mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(0x0039, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage( True) if unit_already_programmed: # Ask for the internal serial number packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_GET_DEVICE_INT_SN, None)) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage( True) internal_device_sn = struct.unpack('I', packet["data"][0:4])[0] # Find the matched SN matched_sn = -1 for file_name in export_file_names: if "Mooltipass-" in file_name: string = file_name.split("Mooltipass-")[1] splits = string.split(" ") prev_num = int(splits[0]) new_num = int(splits[2].replace(".txt", "")) if prev_num == internal_device_sn: matched_sn = new_num # Did we find the matched SN? if matched_sn != -1: # Print labels print_labels_for_ble_device(matched_sn) else: print("Couldn't find matched SN!") # Switch off after disconnect mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(0x0039, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage( True) # Debug print("Done, please disconnect") print("") # Wait for disconnect mooltipass_device.waitForDisconnect() time.sleep(1) # Wait for next connection while mooltipass_device.connect(False, read_timeout=1000) == False: time.sleep(.1) elif sys.argv[1] == "massProdProg": # Setup bluetooth scanning setup_bluetooth_scanning() # Create export directory if not os.path.isdir("export"): os.mkdir("export") last_serial_number = -1 while True: # Ask for platform internal SN packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_GET_DEVICE_INT_SN, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage(True) device_internal_serial_number = struct.unpack( 'I', packet["data"][0:4])[0] print("Device internal serial number: " + str(device_internal_serial_number)) # Do operations if device different than before if last_serial_number != device_internal_serial_number: # Inform device to prepare for SN flash packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_PREPARE_SN_FLASH, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage( True) # Check for answer if packet["data"][0] != CMD_HID_ACK: print("Flash prepare: unit already programmed!") mooltipass_device.waitForDisconnect() time.sleep(1) continue # Wait for device to come up over bluetooth... print("Waiting for Bluetooth to be picked up...") if not find_bluetooth_address( "68:79:12:30:" + "{0:02x}".format( (device_internal_serial_number >> 8) & 0x0FF) + ":" + "{0:02x}".format(device_internal_serial_number & 0x0FF), 30, 10): print("ATBTLC1000 error") mooltipass_device.waitForDisconnect() time.sleep(1) continue # Ask for SN input and program it device_programmed_sn = int( input("Input new device serial number: ")) packet = mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand( CMD_ID_SET_DEVICE_INT_SN, struct.pack('I', device_programmed_sn)), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage( True) # Check for answer if packet["data"][0] != CMD_HID_ACK: print("Couldn't program serial number!") mooltipass_device.waitForDisconnect() time.sleep(1) continue # Write LUT file with open( os.path.join( "export", time.strftime("%Y-%m-%d-%H-%M-%S-Mooltipass-")) + str(device_internal_serial_number) + " to " + str(device_programmed_sn) + ".txt", 'w') as f: # Write it down f.write( str(device_internal_serial_number) + ":" + str(device_programmed_sn) + "\r\n") # Finally, print labels print_labels_for_ble_device(device_programmed_sn) last_serial_number = device_internal_serial_number # Switch off after disconnect mooltipass_device.device.sendHidMessageWaitForAck( mooltipass_device.getPacketForCommand(0x0039, None), True) if packet["cmd"] == CMD_GET_DEVICE_STATUS: packet = mooltipass_device.device.receiveHidMessage( True) # Debug print("Done, please disconnect") print("") # Wait for disconnect mooltipass_device.waitForDisconnect() time.sleep(1) # Wait for next connection while mooltipass_device.connect(False, read_timeout=1000) == False: time.sleep(.1) elif sys.argv[1] == "debugListen": while True: try: mooltipass_device.getInternalDevice().receiveHidMessage() except KeyboardInterrupt: sys.exit(0) except: continue
def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold") self.configure(background='LightSteelBlue2') self.title("OLED Settings Test GUI") self.resizable(0, 0) self.focus_set() self.bind("<Escape>", lambda e: e.widget.quit()) # Contrast current contrast_current_label = tk.Label(self, text="Contrast current :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") contrast_current_label.grid(sticky="e", row=0, column=0, pady=(18, 2), padx=5) self.contrast_current_var = tk.DoubleVar() contrast_current_scale = tk.Scale( self, variable=self.contrast_current_var, command=lambda x: [self.value_changed_callback()], from_=0, to=255, length=300, orient=tk.HORIZONTAL, relief="flat", bd=2, bg="LightSteelBlue2", highlightbackground="LightSteelBlue2") contrast_current_scale.grid(row=0, column=1, pady=2, padx=5) self.contrast_current_var.set(0x90) # VCOMH vcomh_label = tk.Label(self, text="VCOMH level :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") vcomh_label.grid(sticky="e", row=1, column=0, pady=(18, 2), padx=5) self.vcomh_var = tk.DoubleVar() vcomh_scale = tk.Scale( self, variable=self.vcomh_var, command=lambda x: [self.value_changed_callback()], from_=0, to=255, length=300, orient=tk.HORIZONTAL, relief="flat", bd=2, bg="LightSteelBlue2", highlightbackground="LightSteelBlue2") vcomh_scale.grid(row=1, column=1, pady=2, padx=5) self.vcomh_var.set(0x30) self.last_vcomh = 0x30 # VSEGM vsegm_label = tk.Label(self, text="VSEGM level :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") vsegm_label.grid(sticky="e", row=2, column=0, pady=(18, 2), padx=5) self.vsegm_var = tk.DoubleVar() vsegm_scale = tk.Scale( self, variable=self.vsegm_var, command=lambda x: [self.value_changed_callback()], from_=0, to=255, length=300, orient=tk.HORIZONTAL, relief="flat", bd=2, bg="LightSteelBlue2", highlightbackground="LightSteelBlue2") vsegm_scale.grid(row=2, column=1, pady=2, padx=5) self.vsegm_var.set(0x1e) # Precharge period precharge_period_label = tk.Label(self, text="Precharge period :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") precharge_period_label.grid(sticky="e", row=3, column=0, pady=(18, 2), padx=5) self.precharge_period_var = tk.DoubleVar() precharge_period_scale = tk.Scale( self, variable=self.precharge_period_var, command=lambda x: [self.value_changed_callback()], from_=0, to=8, sliderlength=100, length=300, orient=tk.HORIZONTAL, relief="flat", bd=2, bg="LightSteelBlue2", highlightbackground="LightSteelBlue2") precharge_period_scale.grid(row=3, column=1, pady=2, padx=5) self.precharge_period_var.set(8) # Discharge period dishcharge_period_label = tk.Label(self, text="Discharge period :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") dishcharge_period_label.grid(sticky="e", row=4, column=0, pady=(18, 2), padx=5) self.discharge_period_var = tk.DoubleVar() discharge_period_scale = tk.Scale( self, variable=self.discharge_period_var, command=lambda x: [self.value_changed_callback()], from_=0, to=8, sliderlength=100, length=300, orient=tk.HORIZONTAL, relief="flat", bd=2, bg="LightSteelBlue2", highlightbackground="LightSteelBlue2") discharge_period_scale.grid(row=4, column=1, pady=2, padx=5) self.discharge_period_var.set(2) # Discharge level discharge_level_label = tk.Label(self, text="Discharge level :", background="LightSteelBlue2", font=tkfont.Font(family='Helvetica', size=12), anchor="e") discharge_level_label.grid(sticky="e", row=5, column=0, pady=(18, 2), padx=5) self.discharge_level_var = tk.DoubleVar() discharge_level_scale = tk.Scale( self, variable=self.discharge_level_var, command=lambda x: [self.value_changed_callback()], from_=0, to=3, sliderlength=100, length=300, orient=tk.HORIZONTAL, relief="flat", bd=2, bg="LightSteelBlue2", highlightbackground="LightSteelBlue2") discharge_level_scale.grid(row=5, column=1, pady=2, padx=5) self.discharge_level_var.set(0) # Log output self.log_output_text = tk.Text(self, width=70, height=8, wrap=tk.WORD) self.log_output_text.grid(row=6, column=0, columnspan=2, pady=20, padx=20) # Device connection self.mooltipass_device = mooltipass_hid_device() # Connect to device if self.mooltipass_device.connect(True) == False: sys.exit(0) #pass # Debug self.log_output_text.insert("end", "Connected to device\r\n") self.log_output_text.see(tk.END)
def main(): print "Mooltipass Mass Programming Tool" # Check for public key if not os.path.isfile("publickey.bin"): print "Couldn't find public key!" return # Check for firmware file presence if not os.path.isfile("Mooltipass.hex"): print "Couldn't find Mooltipass.hex" sys.exit(0) # Check for bootloader file presence if not os.path.isfile("bootloader_mini.hex"): print "Couldn't find bootloader_mini.hex" sys.exit(0) # Temp vars prog_socket_states = [PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE, PROG_SOCKET_IDLE] programming_threads = [0, 0, 0, 0, 0, 0, 0, 0, 0] next_available_mooltipass_id = 1 mooltipass_ids_pending = [] mooltipass_ids_to_take = [] global displayed_texts temp_counter = 0 # Random bytes buffer random_bytes_buffer = [] # HID device constructor mooltipass_device = mooltipass_hid_device() # Connect to device if mooltipass_device.connect(True) == False: sys.exit(0) # Generate a blank firmware to see if we actually can generate it and then print the hash return_gen = generateFlashAndEepromHex("Mooltipass.hex", "bootloader_mini.hex", 12345, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0], "/tmp/test_flash.hex", "/tmp/test_eeprom.hex", True) os.remove("/tmp/test_flash.hex") os.remove("/tmp/test_eeprom.hex") # Check the success status if return_gen[0] == False: print "Couldn't generate a template flash hex!" sys.exit(0) # Check for random numbers file presence if os.path.isfile("rng.bin"): try: random_bytes_buffer = pickle_read("rng.bin") except EOFError: # This happens when the file is corrupted random_bytes_buffer = [] os.remove("rng.bin") # Set to true to export the random bytes if False: f = open('randombytes.bin', 'wb') random_bytes_buffer.tofile(f) f.flush() f.close() # Check for next mooltipass id file if os.path.isfile("mooltipass_id.bin"): next_available_mooltipass_id = pickle_read("mooltipass_id.bin") # Check for available mooltipass ids file if os.path.isfile("mooltipass_av_ids.bin"): mooltipass_ids_to_take = pickle_read("mooltipass_av_ids.bin") # Check for available mooltipass ids file if os.path.isfile("mooltipass_pending_ids.bin"): mooltipass_ids_pending = pickle_read("mooltipass_pending_ids.bin") if len(mooltipass_ids_pending) > 0: os.remove("mooltipass_pending_ids.bin") mooltipass_ids_to_take.extend(mooltipass_ids_pending) print "Adding previously pending ids:", mooltipass_ids_pending # Remove possible duplicates mooltipass_ids_to_take = list(set(mooltipass_ids_to_take)) print "Mooltipass IDs to take:", mooltipass_ids_to_take pickle_write(mooltipass_ids_to_take, "mooltipass_av_ids.bin") # Read public key public_key = pickle_read("publickey.bin") # Display text on screen add_line_on_screen(mooltipass_device, "Python Script Started") add_line_on_screen(mooltipass_device, return_gen[1][0:20]) add_line_on_screen(mooltipass_device, return_gen[1][20:]) # Main loop while True: time.sleep(.3) temp_counter = temp_counter + 1 # Check if a button is pressed mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_BUTTON_PRESSED, 0, None)) received_data = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout() for i in range(0,9): if received_data[DATA_INDEX+i] != 0: # Programming button was pressed on the bench print "Button", i, "pressed" prog_socket_states[i] = PROG_SOCKET_PENDING # Get number of available random bytes mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_GET_RNG_B_AVAIL, 0, None)) nb_random_bytes_available = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout()[DATA_INDEX] # If more than 32 bytes, fetch them if nb_random_bytes_available >= 32: mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_GET_RANDOM_NUMBER, 0, None)) random_bytes = mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout()[DATA_INDEX:DATA_INDEX+32] random_bytes_buffer.extend(random_bytes) # Store random bytes buffer every now and then if temp_counter % 30 == 0: pickle_write(random_bytes_buffer, "rng.bin") print "Random bytes buffer saved:", len(random_bytes_buffer), "bytes available" #print random_bytes_buffer # If we have enough random bytes and a button was pressed, program the MCU for socket_id in range(0, 9): if prog_socket_states[socket_id] == PROG_SOCKET_PENDING and len(random_bytes_buffer) >= AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH: print "Starting programming for socket", socket_id # Generate new mooltipass ID if len(mooltipass_ids_to_take) > 0: mooltipass_id = mooltipass_ids_to_take[0] del(mooltipass_ids_to_take[0]) else: # No ids to take, take the next available one mooltipass_id = next_available_mooltipass_id next_available_mooltipass_id = next_available_mooltipass_id + 1 # Store the new id in file pickle_write(next_available_mooltipass_id, "mooltipass_id.bin") # Generate keys from the random bytes buffer aes_key1 = random_bytes_buffer[0:AES_KEY_LENGTH] aes_key2 = random_bytes_buffer[AES_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH] uid_key = random_bytes_buffer[AES_KEY_LENGTH+AES_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH] uid = random_bytes_buffer[AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH] del(random_bytes_buffer[0:AES_KEY_LENGTH+AES_KEY_LENGTH+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH]) # Write in file: Mooltipass ID | aes key 1 | aes key 2 | request ID key | UID, flush write aes_key1_text = "".join(format(x, "02x") for x in aes_key1) aes_key2_text = "".join(format(x, "02x") for x in aes_key2) uid_key_text = "".join(format(x, "02x") for x in uid_key) uid_text = "".join(format(x, "02x") for x in uid) string_export = str(mooltipass_id)+"|"+ aes_key1_text +"|"+ aes_key2_text +"|"+ uid_key_text +"|"+ uid_text+"\r\n" #print string_export try: pickle_file_name = time.strftime("export/%Y-%m-%d-%H-%M-%S-Mooltipass-")+str(mooltipass_id)+".txt" pickle_write(seccure.encrypt(string_export, public_key, curve='secp521r1/nistp521'), pickle_file_name) except NameError: pickle_file_name = "test" # Generate programming file generateFlashAndEepromHex("Mooltipass.hex", "bootloader_mini.hex", mooltipass_id, aes_key1, aes_key2, uid_key, uid, "/tmp/flash_"+str(mooltipass_id)+".hex", "/tmp/eeprom_"+str(mooltipass_id)+".hex", False) # Change state to programming prog_socket_states[socket_id] = PROG_SOCKET_PROGRAMMING # Display info on display add_line_on_screen(mooltipass_device, "#"+str(socket_id)+": programming id "+str(mooltipass_id)) # Launch a programming thread mooltipass_ids_pending.append(mooltipass_id) pickle_write(mooltipass_ids_pending, "mooltipass_pending_ids.bin") programming_threads[socket_id] = FuncThread(start_programming, socket_id, mooltipass_id, "/tmp/flash_"+str(mooltipass_id)+".hex", "/tmp/eeprom_"+str(mooltipass_id)+".hex", pickle_file_name) programming_threads[socket_id].start() # Check for thread end for socket_id in range(0, 9): # Check if we're currently programming if prog_socket_states[socket_id] == PROG_SOCKET_PROGRAMMING: # Check if the thread ended if not programming_threads[socket_id].is_alive(): print "Thread for socket", socket_id, "ended" # Fetch the return data return_data = programming_threads[socket_id].join() # Delete the temporary programming files os.remove(return_data[2]) os.remove(return_data[3]) # Check success state if return_data[0] : print "Programming for socket", socket_id, "succeeded (mooltipass id:", str(return_data[1]) + ")" # Save our mooltipass pool in case it was an id to take pickle_write(mooltipass_ids_to_take, "mooltipass_av_ids.bin") # Inform programming platform of success state mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_PROG_DONE, 1, [socket_id])) mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout() add_line_on_screen(mooltipass_device, "#"+str(socket_id)+": "+return_data[4]) else: print "Programming for socket", socket_id, "failed (mooltipass id:", str(return_data[1]) + ")" # Put the mooltipass id back in the pool mooltipass_ids_to_take.append(return_data[1]) pickle_write(mooltipass_ids_to_take, "mooltipass_av_ids.bin") # Delete encrypted keys file os.remove(return_data[5]) # Inform programming platform of success state mooltipass_device.getInternalDevice().sendHidPacket(mooltipass_device.getPacketForCommand(CMD_PROG_FAILURE, 1, [socket_id])) mooltipass_device.getInternalDevice().receiveHidPacketWithTimeout() add_line_on_screen(mooltipass_device, "#"+str(socket_id)+": "+return_data[4]) # Remove id from pending ones mooltipass_ids_pending.remove(return_data[1]) pickle_write(mooltipass_ids_pending, "mooltipass_pending_ids.bin") # Reset prog state prog_socket_states[socket_id] = PROG_SOCKET_IDLE