def CheckStatus(self): """Update the number of available AT keys for the current product. Need to use GetKeysLeft() function to get the number of keys left. If some error happens, keys_left would be set to -1 to prevent checking again. Raises: FastbootFailure: If error happens with the fastboot oem command. """ if not self.atft_manager.product_info: raise ProductNotSpecifiedException() AtftManager.CheckDevice(self.atft_manager.atfa_dev) # -1 means some error happens. self.atft_manager.atfa_dev.keys_left = -1 out = self.atft_manager.atfa_dev.Oem( 'num-keys ' + self.atft_manager.product_info.product_id, True) # Note: use splitlines instead of split('\n') to prevent '\r\n' problem on # windows. for line in out.splitlines(): if line.startswith('(bootloader) '): try: self.atft_manager.atfa_dev.keys_left = int( line.replace('(bootloader) ', '')) return except ValueError: raise FastbootFailure( 'ATFA device response has invalid format') raise FastbootFailure('ATFA device response has invalid format')
def FusePermAttr(self, target): """Fuse the permanent attributes to the target device. Args: target: The target device. """ if not self.product_info: target.provision_status = ProvisionStatus.FUSEATTR_FAILED raise ProductNotSpecifiedException try: target.provision_status = ProvisionStatus.FUSEATTR_ING temp_file = tempfile.NamedTemporaryFile(delete=False) temp_file.write(self.product_info.product_attributes) temp_file.close() temp_file_name = temp_file.name target.Download(temp_file_name) os.remove(temp_file_name) target.Oem('fuse at-perm-attr') self.CheckProvisionStatus(target) if not target.provision_state.avb_perm_attr_set: raise FastbootFailure('Status not updated') except FastbootFailure as e: target.provision_status = ProvisionStatus.FUSEATTR_FAILED raise e
def FuseVbootKey(self, target): """Fuse the verified boot key to the target device. Args: target: The target device. """ if not self.product_info: target.provision_status = ProvisionStatus.FUSEVBOOT_FAILED raise ProductNotSpecifiedException # Create a temporary file to store the vboot key. target.provision_status = ProvisionStatus.FUSEVBOOT_ING try: temp_file = tempfile.NamedTemporaryFile(delete=False) temp_file.write(self.product_info.vboot_key) temp_file.close() temp_file_name = temp_file.name target.Download(temp_file_name) # Delete the temporary file. os.remove(temp_file_name) target.Oem('fuse at-bootloader-vboot-key') # After a success fuse, the status should be updated. self.CheckProvisionStatus(target) if not target.provision_state.bootloader_locked: raise FastbootFailure('Status not updated.') # # Another possible flow: # target.Flash('sec', temp_file_name) # os.remove(temp_file_name) except FastbootFailure as e: target.provision_status = ProvisionStatus.FUSEVBOOT_FAILED raise e
def UpdateKeysLeft(self): """Update the number of available AT keys for the current product. Need to use GetCachedATFAKeysLeft() function to get the number of keys left. If some error happens, keys_left would be set to -1 to prevent checking again. Raises: FastbootFailure: When fastboot command fails. ProductNotSpecifiedException: When product is not specified. """ if not self.atft_manager.product_info: raise ProductNotSpecifiedException() AtftManager.CheckDevice(self.atft_manager.atfa_dev) try: out = self.atft_manager.atfa_dev.Oem( 'num-keys ' + self.atft_manager.product_info.product_id, True) # Note: use splitlines instead of split('\n') to prevent '\r\n' problem on # windows. for line in out.splitlines(): if line.startswith('(bootloader) '): try: self.atft_manager.atfa_dev.keys_left = int( line.replace('(bootloader) ', '')) return except ValueError: raise FastbootFailure( 'ATFA device response has invalid format') raise FastbootFailure('ATFA device response has invalid format') except FastbootFailure as e: if 'No matching available products' in e.msg: # If there's no matching product key, we set keys left to 0. self.atft_manager.atfa_dev.keys_left = 0 return else: # -1 means some error happens. self.atft_manager.atfa_dev.keys_left = -1 raise e
def LockAvb(self, target): """Lock the android verified boot for the target. Args: target: The target device. """ try: target.provision_status = ProvisionStatus.LOCKAVB_ING target.Oem('at-lock-vboot') self.CheckProvisionStatus(target) if not target.provision_state.avb_locked: raise FastbootFailure('Status not updated') except FastbootFailure as e: target.provision_status = ProvisionStatus.LOCKAVB_FAILED raise e
def Provision(self, target): """Provision the key to the target device. 1. Get supported encryption algorithm 2. Send start-provisioning message to ATFA 3. Transfer content from ATFA to target 4. Send at-get-ca-request to target 5. Transfer content from target to ATFA 6. Send finish-provisioning message to ATFA 7. Transfer content from ATFA to target 8. Send at-set-ca-response message to target Args: target: The target device to be provisioned to. Raises: DeviceNotFoundException: When a device is not available. FastbootFailure: When fastboot command fails. """ try: target.provision_status = ProvisionStatus.PROVISION_ING atfa = self.atfa_dev AtftManager.CheckDevice(atfa) # Set the ATFA's time first. self._atfa_dev_manager.SetTime() algorithm_list = self._GetAlgorithmList(target) algorithm = self._ChooseAlgorithm(algorithm_list) # First half of the DH key exchange atfa.Oem('start-provisioning ' + str(algorithm)) self.TransferContent(atfa, target) # Second half of the DH key exchange target.Oem('at-get-ca-request') self.TransferContent(target, atfa) # Encrypt and transfer key bundle atfa.Oem('finish-provisioning') self.TransferContent(atfa, target) # Provision the key on device target.Oem('at-set-ca-response') # After a success provision, the status should be updated. self.CheckProvisionStatus(target) if not target.provision_state.provisioned: raise FastbootFailure('Status not updated.') except (FastbootFailure, DeviceNotFoundException) as e: target.provision_status = ProvisionStatus.PROVISION_FAILED raise e