def main(argv): if argv: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_USB_PATH) # Load EC image. with open(common.RB_INITIAL, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() # Make sure rollback is updated to current RW image (rb1) common.connect_usb(updater) inc_rollback(updater, 1) # Update to invalid RW with RB < current RB image_desc = 'Update to invalid RW with RB < current RB' update_invalid_rb(updater, common.RB_LOWER, image_desc) # Restore to valid RB image_desc = 'Restoring to valid RB_1 from RO' restore_valid_rb(updater, common.RB_INITIAL, image_desc) # Update to valid RW with RB > current RB image_desc = 'Update to valid RW with RB > current RB' init_before_updaterw(updater) common.reset_stay_ro(updater) unlock_rw(updater) restore_valid_rb(updater, common.RB_HIGHER, image_desc) # RB should now = RB_HIGHER common.connect_usb(updater) inc_rollback(updater, 9)
def init_before_updaterw(updater): common.connect_usb(updater) print('EC information:') pdu_resp = updater.GetFirstResponsePdu().contents print('PDU Response: %s' % pdu_resp) print('Current section before updating RW: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)'
def flash_invalid_address(updater, rw): # Using TransferTouchpadFirmware method for now as API lacks equivalent. for address in WRONG_ADDR_LIST: common.connect_usb(updater) if rw: updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW) updater.CloseUsb() time.sleep(0.5) updater.TryConnectUsb() assert updater.SendFirstPdu(), 'Error sending first PDU' updater.SendDone() print('Current section: %s' % updater.CurrentSection()) if rw: assert updater.CurrentSection( ) == 1, 'Running section should be 1 (RW)' else: assert updater.CurrentSection( ) == 0, 'Running section should be 0 (RO)' wr = updater.TransferTouchpadFirmware(int(address, 0), 4096) assert wr == 0, 'Should not be able to write to wrong address!' updater.SendSubcommand( hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5)
def init_before_updaterw(updater): common.connect_usb(updater) print('EC information:') pdu_resp = updater.GetFirstResponsePdu().contents print('PDU Response: %s' % pdu_resp) print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO)) print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW)) print('Current running section before RW jump: %s' % updater.CurrentSection())
def transfer_rw(updater, image): with open(image, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) print('Transferring RW') updater.TransferImage(1) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) common.connect_usb(updater)
def inc_rollback(updater, expected_rb): current_rb = updater.GetFirstResponsePdu().contents.min_rollback print('Current RB: %s' % current_rb) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.UnlockRollback) common.sim_disconnect_connect(updater) common.connect_usb(updater) pdu_resp = updater.GetFirstResponsePdu().contents print('PDU Response: %s' % pdu_resp) print('Current running section: %s' % updater.CurrentSection()) new_rb = updater.GetFirstResponsePdu().contents.min_rollback print('New RB version: %s' % new_rb) assert new_rb == expected_rb, 'Error: Failed to increment RB version!'
def main(argv): if argv: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_USB_PATH) # Load EC image. with open(common.IMAGE, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() common.connect_usb(updater) print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('Current running section: %s' % updater.CurrentSection()) protect = get_flash_protection(updater) print('Protection: %04x == %04x?' % (protect, FLASH_PROTECT_INIT)) assert protect == FLASH_PROTECT_INIT, 'Initial WP status error' unlock_rw(updater) reset(updater) updater.CloseUsb() time.sleep(0.5) # Catch it right after reset: RW is still unlocked and can be updated. common.connect_usb(updater) print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('Current running section: %s' % updater.CurrentSection()) protect = get_flash_protection(updater) print('Protection: %04x == %04x?' % (protect, FLASH_PROTECT_NORW)) assert protect == FLASH_PROTECT_NORW, 'WP status after Unlock RW' updater.CloseUsb() time.sleep(2) # By now, hammer will have jumped to RW and locked the flash again common.connect_usb(updater) assert get_flash_protection(updater) == FLASH_PROTECT_INIT, \ 'WP status after jump RW' updater.SendSubcommand(hammerd_api.UpdateExtraCommand.UnlockRollback) reset(updater) updater.CloseUsb() time.sleep(0.5) common.connect_usb(updater) print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('Current running section: %s' % updater.CurrentSection()) assert get_flash_protection(updater) == FLASH_PROTECT_NORB, \ 'WP status after Unlock RB' updater.CloseUsb() time.sleep(2) # By now, hammer will have jumped to RW and locked the flash again common.connect_usb(updater) assert get_flash_protection(updater) == FLASH_PROTECT_INIT, \ 'WP status after jump RW'
def transfer_ro(updater, image): with open(image, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) print('Transferring RO') transfer_result = updater.TransferImage(0) assert transfer_result == 0, 'RW should not be able to update locked RO!' updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) common.connect_usb(updater) print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('Current running section: %s' % updater.CurrentSection())
def flash_invalid_image(updater): # Check that TransferTouchpadFirmware can write to RW in unlocked image for address in WRONG_ADDR_LIST: common.connect_usb(updater) unlock_rw(updater) wr = updater.TransferTouchpadFirmware(int(address, 0), 1) assert wr == 1, 'Cannot write to flash: Is DUT image unlocked?' assert updater.SendFirstPdu() is True, 'Error sending first PDU' updater.SendDone() print('Current section: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)' updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5)
def update_invalid_rw(updater, image, image_desc): init_before_updaterw(updater) common.reset_stay_ro(updater) unlock_rw(updater) print(image_desc) transfer_rw(updater, image) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW) updater.CloseUsb() # If successful (it should not be), jump to RW resets the base. common.connect_usb(updater) updater.SendFirstPdu() updater.SendDone() print('Current section-invalid RW update: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)'
def restore_valid_rw(updater, image): print('Restoring to valid RW') transfer_rw(updater, image) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW) time.sleep(2) updater.CloseUsb() time.sleep(0.5) # Jump to RW resets the base. Need to reconnect common.connect_usb(updater) updater.SendFirstPdu() updater.SendDone() print('Current section after valid RW update: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)' common.sim_disconnect_connect(updater)
def main(argv): if len(argv) > 0: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_BUS, common.BASE_PORT) # Load EC image. with open(common.IMAGE, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() common.connect_usb(updater) print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('Current section before ro update: %s' % updater.CurrentSection()) transfer_ro(updater, common.IMAGE) common.sim_disconnect_connect(updater)
def main(argv): if len(argv) > 0: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_BUS, common.BASE_PORT) with open(common.IMAGE, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() common.connect_usb(updater) print('EC information:') pdu_resp = updater.GetFirstResponsePdu().contents print('PDU Response: %s' % pdu_resp) print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO)) print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW)) print('Is RW locked?: %s' % updater.IsSectionLocked(1)) assert updater.IsSectionLocked(1), "RW should be locked" updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) updater.TryConnectUsb() updater.SendSubcommand(hammerd_api.UpdateExtraCommand.StayInRO) time.sleep(1) assert updater.SendFirstPdu() == True, 'Error sending first PDU' updater.SendDone() print('Current section after StayInRO cmd: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)' init_transfer(updater) # First test that RW can't update anything flash_invalid_address(updater, True) # Uncommenting these line will make the test fail (RO will be able to write to # WRONG_ADDR_RW_OFFSET) #common.connect_usb(updater) #unlock_rw(updater) #updater.CloseUsb() # Then test that RO can't update anything flash_invalid_address(updater, False)
def main(argv): if argv: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_USB_PATH) # Load EC image. with open(common.IMAGE, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() common.connect_usb(updater) print('EC information:') pdu_resp = updater.GetFirstResponsePdu().contents print('PDU Response: %s' % pdu_resp) print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO)) print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW)) print('Current section before StayInRO cmd: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)' # Jump to RO by resetting base updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) updater.TryConnectUsb() updater.SendSubcommand(hammerd_api.UpdateExtraCommand.StayInRO) # Keep DUT in RO for 10 sec to check that it stays in RO time.sleep(10) # Reconnect, in case RO still decided to jump updater.CloseUsb() updater.TryConnectUsb() # Need to SendFirstPdu again after sendig cmd because # CurrentSection reads from results of SendFirstPdu by checking the # writable offset. Non Zero writable offset means RO is running assert updater.SendFirstPdu() is True, 'Error sending first PDU' updater.SendDone() print('Current section after StayInRO cmd: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)' # Reset dut common.sim_disconnect_connect(updater)
def main(argv): if argv: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_USB_PATH) # Use unlocked image on dut to verify that TransferTouchpadFirmware call works with open(common.IMAGE, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() common.connect_usb(updater) print('EC information:') pdu_resp = updater.GetFirstResponsePdu().contents print('PDU Response: %s' % pdu_resp) print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO)) print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW)) print('Is RW locked?: %s' % updater.IsSectionLocked(1)) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) updater.TryConnectUsb() updater.SendSubcommand(hammerd_api.UpdateExtraCommand.StayInRO) time.sleep(1) assert updater.SendFirstPdu() is True, 'Error sending first PDU' updater.SendDone() print('Current section after StayInRO cmd: %s' % updater.CurrentSection()) assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)' init_tp_transfer(updater) # Try to flash to invalid addresses. Since image is unlocked this should flash flash_invalid_image(updater) # Restore valid RW restore_valid_rw(updater, common.IMAGE)
def transfer_rw(updater, image): with open(image, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) print('Transferring RW') updater.TransferImage(1) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) common.connect_usb(updater) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW) time.sleep(2) updater.CloseUsb() time.sleep(0.5) # Jump to RW resets the base. Need to reconnect common.connect_usb(updater) # Check that transferred RW is running print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO)) print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW)) updater.SendFirstPdu() updater.SendDone() print('Current running section after RW jump: %s' % updater.CurrentSection())
def main(argv): if argv: sys.exit('Test takes no args!') updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID, common.BASE_PRODUCT_ID, common.BASE_USB_PATH) public_key_first = (ctypes.c_ubyte * PUBLIC_KEY_SIZE)() # Load EC image. with open(common.IMAGE, 'rb') as f: ec_image = f.read() updater.LoadEcImage(ec_image) common.disable_hammerd() print('Connect to base EC.') common.connect_usb(updater) print('EC information:') print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO)) print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW)) print('Current section : %s' % updater.CurrentSection()) assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)' # Sends 'Need to inject entropy' message if base is new pair_manager = hammerd_api.PairManager() challenge_status = pair_manager.PairChallenge(updater.object, public_key_first) print('Challenge status: %d' % challenge_status) # assert challenge_status == 9, 'Need to inject the entropy' for iteratn in range(INJECTION_RUNS): print('Jumping back to RO to inject entropy. Iteratn: %d' % (iteratn + 1)) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.UnlockRollback) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) updater.TryConnectUsb() updater.SendSubcommand(hammerd_api.UpdateExtraCommand.StayInRO) # Wait for RO to run, else SendFirstPdu() picks up RW time.sleep(1) # Verify that we're in RO assert updater.SendFirstPdu() is True, 'Error sending first PDU' updater.SendDone() assert updater.CurrentSection( ) == 0, 'Not in RO: Cannot inject entropy' print('Inject entropy and sys jump to RW') updater.InjectEntropyWithPayload(b'\x87' * hammerd_api.ENTROPY_SIZE) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset) updater.CloseUsb() time.sleep(0.5) common.connect_usb(updater) updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW) # Wait for RW to run time.sleep(1) updater.CloseUsb() time.sleep(0.5) # Jump to RW resets the base. Need to reconnect common.connect_usb(updater) print('PDU Response: %s' % updater.GetFirstResponsePdu().contents) # Check that RW is running assert updater.SendFirstPdu() is True, 'Error sending first PDU' updater.SendDone() print('Current running section after jumping to RW: %s' % updater.CurrentSection()) assert updater.CurrentSection( ) == 1, 'Running section should be 1 (RW)' # Autheticator should match for each pairing run for i in range(PAIRING_RUNS): public_key = (ctypes.c_ubyte * PUBLIC_KEY_SIZE)() pair_manager = hammerd_api.PairManager() challenge_status = pair_manager.PairChallenge( updater.object, public_key) print('Challenge status: %d' % challenge_status) assert challenge_status == 0, 'Pairing challenge failed!' if i == 0: same = True for j in range(0, PUBLIC_KEY_SIZE - 1): if public_key_first[j] != public_key[j]: same = False assert not same, 'The key did not change after entropy injection!' public_key_first = public_key else: for j in range(0, PUBLIC_KEY_SIZE - 1): assert public_key_first[j] == public_key[j], 'Key changed!' # Reset the base common.sim_disconnect_connect(updater)