def _decode_binary_header_blob(self, binary_blob, l1_key_blob): string_offset = 0 string_end = EncryptionParamsSectionBody.B0block.get_spec_size() self.L2B0block = EncryptionParamsSectionBody.B0block( binary_blob[string_offset:string_end]) self.L2_IV = self.L2B0block.nonce_fld logger.debug("L2 IV: \n" + hexdump(self.L2_IV)) string_offset = string_end string_end += EncryptionParamsSectionBody.L2AssociatedData.get_spec_size( ) self.L2_associated_data = EncryptionParamsSectionBody.L2AssociatedData( binary_blob[string_offset:string_end]) string_offset = string_end string_end += EncryptionParamsSectionBody.ENCRYPTED_KEY_PAYLOAD_LEN_BYTES self.L1_key_payload = binary_blob[string_offset:string_end] string_offset = string_end string_end += EncryptionParamsSectionBody.MAC_LEN_BYTES self.L2_MAC = binary_blob[string_offset:string_end] self.l2_key = crypto_functions.ccm_decrypt_binary( self.L1_key_payload + self.L2_MAC, binascii.hexlify(l1_key_blob), binascii.hexlify(self.L2_IV), binascii.hexlify(self.L2_associated_data.get_binary_blob())) logger.debug("decrypted L2 key: \n" + hexdump(self.l2_key)) string_offset = string_end string_end += EncryptionParamsSectionBody.B0block.get_spec_size() self.L3B0block = EncryptionParamsSectionBody.B0block( binary_blob[string_offset:string_end]) self.L3_IV = self.L3B0block.nonce_fld logger.debug("L3 IV: \n" + hexdump(self.L3_IV)) string_offset = string_end string_end += EncryptionParamsSectionBody.L3AssociatedData.get_spec_size( ) self.L3_associated_data = EncryptionParamsSectionBody.L3AssociatedData( binary_blob[string_offset:string_end]) string_offset = string_end string_end += EncryptionParamsSectionBody.ENCRYPTED_KEY_PAYLOAD_LEN_BYTES self.L2_key_payload = binary_blob[string_offset:string_end] string_offset = string_end string_end += EncryptionParamsSectionBody.MAC_LEN_BYTES self.L3_MAC = binary_blob[string_offset:string_end] self.l3_key = crypto_functions.ccm_decrypt_binary( self.L2_key_payload + self.L3_MAC, binascii.hexlify(self.l2_key), binascii.hexlify(self.L3_IV), binascii.hexlify(self.L3_associated_data.get_binary_blob())) logger.debug("decrypted L3 key: \n" + hexdump(self.l3_key)) string_offset = string_end string_end += EncryptionParamsSectionBody.BASE_IV_LEN_BYTES self.base_iv = binary_blob[string_offset:string_end]
def _get_l1_encrypted_l2_key(self): key = binascii.hexlify(self.l1_key) aad = binascii.hexlify(self.L2_associated_data) message = binascii.hexlify(self.l2_key) logger.debug("L1 encrypted L2 key:") logger.debug("KEY = \n" + hexdump(key)) logger.debug("AAD = \n" + hexdump(aad)) logger.debug("MSG = \n" + hexdump(message)) return binascii.unhexlify(crypto.eciesad.encrypt(key, aad, message))
def _get_l2_encrypted_l3_key(self): pt = self.l3_key key = binascii.hexlify(self.l2_key) iv = binascii.hexlify(self.L3_IV) aad = binascii.hexlify(self.L3_associated_data) logger.debug("L2 encrypted L3 key:") logger.debug("PT = \n" + hexdump(pt)) logger.debug("KEY = \n" + hexdump(key)) logger.debug("IV = \n" + hexdump(iv)) logger.debug("AAD = \n" + hexdump(aad)) enc_l3_key = crypto.aes_ccm.encrypt(pt, key, iv, aad) return enc_l3_key[0:16], enc_l3_key[16:32]
def __repr__(self, *args, **kwargs): string = "" string += "L1 KEY: \n" + hexdump(self.l1_key) + "\n" string += "L2 KEY: \n" + hexdump(self.l2_key) + "\n" string += "Encrypted L2 KEY: \n" + hexdump(self.enc_l2_key) + "\n" string += "L3 KEY: \n" + hexdump(self.l3_key) + "\n" string += "Encrypted L3 KEY: \n" + hexdump(self.enc_l3_key) + "\n" string += "L1 NONCE: \n" + hexdump(self.l1_nonce) + "\n" string += "L2 NONCE: \n" + hexdump(self.l2_nonce) + "\n" string += "L1 AAD: \n" + hexdump(self.l1_aad) + "\n" string += "L2 AAD: \n" + hexdump(self.l2_aad) + "\n" string += "Encryption Parameters Blob: \n" + hexdump(self.encryption_params_blob) + "\n" return string
def __repr__(self, *args, **kwargs): string = "" string += "L1 KEY: \n" + hexdump(self.l1_key) + "\n" string += "L2 KEY: \n" + hexdump(self.l2_key) + "\n" string += "Encrypted L2 KEY: \n" + hexdump(self.enc_l2_key) + "\n" string += "L3 KEY: \n" + hexdump(self.l3_key) + "\n" string += "Encrypted L3 KEY: \n" + hexdump(self.enc_l3_key) + "\n" string += "L1 NONCE: \n" + hexdump(self.l1_nonce) + "\n" string += "L2 NONCE: \n" + hexdump(self.l2_nonce) + "\n" string += "L1 AAD: \n" + hexdump(self.l1_aad) + "\n" string += "L2 AAD: \n" + hexdump(self.l2_aad) + "\n" string += "Encryption Parameters Blob: \n" + hexdump(self.encryption_params_blob) + "\n" return string
def _get_l2_encrypted_l3_key(self): pt = self.l3_key key = binascii.hexlify(self.l2_key) iv = binascii.hexlify(self.L3_IV) aad = binascii.hexlify(self.L3_associated_data) logger.debug("L2 encrypted L3 key:") logger.debug("PT = \n" + hexdump(pt)) logger.debug("KEY = \n" + hexdump(key)) logger.debug("IV = \n" + hexdump(iv)) logger.debug("AAD = \n" + hexdump(aad)) (enc_l3_key, encryption_key, image_iv, hex_preexisting_aad) = crypto_functions.ccm_encrypt_binary( pt, key, iv, aad) return enc_l3_key[0:16], enc_l3_key[16:32]
def _get_l1_encrypted_l2_key(self, l1_key_blob): pt = self.key_service.get_l2_key() key = binascii.hexlify(l1_key_blob) iv = binascii.hexlify(self.L2_IV) aad = binascii.hexlify(self.L2_associated_data.get_binary_blob()) logger.debug("L1 encrypted L2 key:") logger.debug("PT = \n" + hexdump(pt)) logger.debug("KEY = \n" + hexdump(key)) logger.debug("IV = \n" + hexdump(iv)) logger.debug("AAD = \n" + hexdump(aad)) (enc_l2_key, encryption_key, image_iv, hex_preexisting_aad) = crypto_functions.ccm_encrypt_binary( pt, key, iv, aad) return enc_l2_key[0:16], enc_l2_key[16:32]
def privkey_pem_to_der(pem_privkey): """ Convert PEM format PRIVATE key into DER format input: pem_privkey: String containing base64 PEM Private key output der_privkey: String containing binary Private key """ der_privkey = '' pem_tempfile_name = utility_functions.store_data_to_temp_file(pem_privkey) try: der_privkey = utility_functions.system_command_logged( [ openssl_binary_path, 'rsa', '-in', pem_tempfile_name, '-inform', 'PEM', '-outform', 'DER' ], stderr_to_temp=True) logger.debug2("PEM Format private key: " + hexdump(der_privkey)) except: logger.critical( "privkey_pem_to_der: OPENSSL Could not convert PEM key to DER key") finally: os.unlink(pem_tempfile_name) logger.debug("Deleting temporary file: " + pem_tempfile_name) return der_privkey
def cert_pem_to_der(pem_certificate): """ Convert PEM format certificate into DER format input: pem_certificate: String containing base64 PEM certificate output der_certificate: String containing binary certificate """ pem_tempfile_name = utility_functions.store_data_to_temp_file( pem_certificate) try: der_certificate = utility_functions.system_command_logged( [ openssl_binary_path, 'x509', '-in', pem_tempfile_name, '-inform', 'PEM', '-outform', 'DER' ], stderr_to_temp=True) except: logger.critical( "cert_pem_to_der: OPENSSL could not convert PEM cert to DER") logger.debug2("PEM Format certificate: " + hexdump(der_certificate)) logger.debug("Deleting temporary file: " + pem_tempfile_name) os.unlink(pem_tempfile_name) return der_certificate
def _generate_new_blob(self, config, debug_dir, encrypted_segments_indices=None): if self.key_service.get_l1_public_key() is not None: logger.debug("L1 public key was provided locally") self.l1_key = self.key_service.get_l1_public_key() logger.debug("Generating random values for L2 and L3 keys...") self.l2_key = KeyService.get_new_random_clear_key() self.l3_key = KeyService.get_new_random_clear_key() logger.debug("L1 Public Key: \n" + hexdump(self.l1_key)) logger.debug("L2 Key: \n" + hexdump(self.l2_key)) logger.debug("L3 Key: \n" + hexdump(self.l3_key)) else: raise EncryptionParameters_1_0_L2_1_0.InvalidKeyComboException( "\nMissing L1 public key.\n" "L1 public key must be provided when encrypting an image using UIE 2.0.\n" "If L1 public key is provided, ensure that the corresponding config file \n" "contains the correct l1_public_file_name METACONFIG tag and value." ) encryption_params_hdr = EncryptionParamsInfoHdr_2_0() encryption_params_hdr.add_encryption_param_section() eps_hdr = EncryptionParamsSectionHdr_2_0( root_key_type=config.signing_attributes.UIE_root_key_type) eps_body = self._get_encryption_params_section_body_class()( self.image_id, l1_key=self.l1_key, l2_key=self.l2_key, l3_key=self.l3_key, debug_dir=debug_dir, encrypted_segments_indices=encrypted_segments_indices, feature_id=self.feature_id) self.l3_image_iv = eps_body.get_image_iv() self.encryption_params_blob = encryption_params_hdr.get_header_blob() + \ eps_hdr.get_header_blob() + \ eps_body.get_binary_blob() logger.debug("Encryption Params: \n" + hexdump(self.encryption_params_blob)) return self.encryption_params_blob, self.l1_key
def _generate_new_encryption_params_blob(self): self.l1_key = self._get_l1_key() self.l2_key = self._get_l2_key() self.l3_key = self._get_l3_key() encryption_params_hdr = EncryptionParamsHeader() encryption_params_hdr.add_encryption_param_section() eps_hdr1 = EncryptionParamsSectionHdr(None, None, 1, 0) eps_body1 = EncryptionParamsSectionBody(l1_key_blob=self.l1_key, image_id_bitmap=self.image_id) self.encryption_params_blob = encryption_params_hdr.get_header_blob() + \ eps_hdr1.get_header_blob() + \ eps_body1.get_binary_blob() self.l3_image_iv = eps_body1.get_image_iv() self.l3_key = eps_body1.get_l3_key() logger.debug("Encryption Params: \n" + hexdump(self.encryption_params_blob)) logger.debug("L1 Key: \n" + hexdump(self.l1_key)) return self.encryption_params_blob, self.l1_key
def __init__(self, encryption_params_blob=None, private_key=None, config=None, debug_dir=None, l3_key_blob=None, validating=False, encrypted_segments_indices=None): self.image_id = int( config.signing_attributes.sw_id[EncryptionParameters. SOFTWARE_TYPE_FLD_OFFSET:], 16) if encryption_params_blob is None and private_key is None and l3_key_blob is None: self.key_service = key_service_module.KeyService(config) encryption_params_blob, private_key = self._generate_new_blob( config, debug_dir, encrypted_segments_indices=encrypted_segments_indices) # Set the base params BaseEncryptionParameters.__init__( self, encryption_params_blob=encryption_params_blob, key=private_key, debug_dir=debug_dir, validating=validating) elif encryption_params_blob is not None and l3_key_blob is not None: self._set_l3_and_iv(encryption_params_blob, l3_key_blob) # Set the base params BaseEncryptionParameters.__init__( self, encryption_params_blob=encryption_params_blob, key=None, debug_dir=debug_dir, validating=validating) elif encryption_params_blob is not None and private_key is not None: # Set the base params BaseEncryptionParameters.__init__( self, encryption_params_blob=encryption_params_blob, key=private_key, debug_dir=debug_dir, validating=validating) # Get the image encryption key & iv self._decode_blob(encryption_params_blob, private_key, debug_dir) else: raise RuntimeError( "ERROR: Invalid configuration of params used to create encryption params." ) store_debug_data_to_file(defines.DEST_DEBUG_FILE_ENCRYPTION_PARAMETERS, hexdump(self.encryption_params_blob), debug_dir)
def sign_req_data(self, signing_attrs, attest_cert_dict, image_hash, data_to_hash): """This API replaces sign_req and enables inspection of the data being signed. Args: signing_attrs (object): An object containing the following signing attributes: - key_size: Size of the key for attestation key - exponent: Exponent for attestation key attest_cert_dict (dict): Dictionary containing the parameters to be put in the attestation certificate. image_hash (str): The image hash binary blob to be signed. data_to_hash (StructDynamic): An object which encapsulates the format of the authentication-relevant fields which were hashed to create image_hash. The authentication-relevant fields available for interrogation can be retrieved via the "fields" member. Returns: A tuple containing the root certificate, ca certificate, attestation certificate and the signature corresponding to the image hash. root_cert (str): - Binary blob of the root certificate. - None if root certificate is provided under: resources/data_prov_assets/Signing/Local ca_cert (str): - Binary blob of the ca certificate. - None if ca certificate is provided under: resources/data_prov_assets/Signing/Local attest_cert (str): Binary blob of the attestation certificate. signature (str): Binary blob of the signature. """ # Demonstrate how to inspect the data being signed logger.info("Data being signed:\n" + hexdump(data_to_hash.binary_data)) logger.info("Format of authentication-relevant data being signed: " + data_to_hash.format) logger.info( "Authentication-relevant fields within data being signed: " + comma_separated_string(data_to_hash.fields, "and")) logger.info("SW ID of image being signed: " + str(data_to_hash.sw_id)) # Initialize the return variables root_cert, ca_cert, attest_cert, signature = None, None, None, None # OEM to fill in this part raise NotImplementedError('OEM to implement hsm signer') # Return the required secure assets return root_cert, ca_cert, attest_cert, signature
def privkey_pem_to_der(pem_privkey): """ Convert PEM format PRIVATE key into DER format input: pem_privkey: String containing base64 PEM Private key output der_privkey: String containing binary Private key """ pem_tempfile_name = utility_functions.store_data_to_temp_file(pem_privkey) try: der_privkey = utility_functions.system_command_logged([openssl_binary_path, 'rsa', '-in', pem_tempfile_name, '-inform', 'PEM', '-outform', 'DER'], stderr_to_temp=True) except: logger.critical("privkey_pem_to_der: OPENSSL Could not convert PEM key to DER key") logger.debug2("PEM Format private key: " + hexdump(der_privkey)) logger.debug("Deleting temporary file: " + pem_tempfile_name) os.unlink(pem_tempfile_name) return der_privkey
def cert_pem_to_der(pem_certificate): """ Convert PEM format certificate into DER format input: pem_certificate: String containing base64 PEM certificate output der_certificate: String containing binary certificate """ pem_tempfile_name = utility_functions.store_data_to_temp_file(pem_certificate) try: der_certificate = utility_functions.system_command_logged([openssl_binary_path, 'x509', '-in', pem_tempfile_name, '-inform', 'PEM', '-outform', 'DER'], stderr_to_temp=True) except: logger.critical("cert_pem_to_der: OPENSSL could not convert PEM cert to DER") logger.debug2("PEM Format certificate: " + hexdump(der_certificate)) logger.debug("Deleting temporary file: " + pem_tempfile_name) os.unlink(pem_tempfile_name) return der_certificate
def _generate_new_blob(self, config, debug_dir, encrypted_segments_indices=None): self.enc_key_prov_is_qti = False if self.key_service.using_encrypted_key_provider(): # UIE_key value was set to an encrypted key provider value. ex: "encrypted_qti" or "encrypted_oem" logger.info( "Attempting to retrieve encrypted L2, encrypted L3, and clear L3 keys from encrypted key provider..." ) self.l1_key = None self.l2_key = None # get the encrypted key provider from sectools.features.isc.encryption_service.unified import get_encrypted_key_provider encrypted_key_provider_class = get_encrypted_key_provider( self.key_service.get_encrypted_key_provider_id()) self.enc_key_prov_is_qti = encrypted_key_provider_class.is_qti() if self.enc_key_prov_is_qti: sa = config.signing_attributes encrypted_key_provider = encrypted_key_provider_class( sa.UIE_capability, sa.UIE_server_url, sa.UIE_server_cert_path) else: encrypted_key_provider = encrypted_key_provider_class() # get the encrypted keys and clear l3 key from the encrypted key provider self.encrypted_l2 = encrypted_key_provider.get_encrypted_l2_key() self.encrypted_l3 = encrypted_key_provider.get_encrypted_l3_key() self.l3_key = encrypted_key_provider.get_clear_l3_key() logger.info( "Encrypted L2, encrypted L3, and clear L3 keys were successfully retrieved from encrypted key provider." ) logger.debug("Encrypted L2 Key: \n" + hexdump(self.encrypted_l2)) logger.debug("Encrypted L3 Key: \n" + hexdump(self.encrypted_l3)) elif self.key_service.get_l1_key( ) is not None and self.key_service.get_l2_key( ) is None and self.key_service.get_l3_key( ) is None and self.key_service.no_enc_keys_provided(): # only l1 key is provided locally. l2 and l3 keys will be set to randomly generated values logger.info( "Clear L1 key was provided locally but clear L2 and clear L3 keys were not. Generating random values for clear L2 and clear L3 keys..." ) self.l1_key = self.key_service.get_l1_key() self.l2_key = key_service_module.KeyService.get_new_random_clear_key( ) self.l3_key = key_service_module.KeyService.get_new_random_clear_key( ) logger.debug("L1 Key: \n" + hexdump(self.l1_key)) logger.debug("L2 Key: \n" + hexdump(self.l2_key)) logger.debug("L3 Key: \n" + hexdump(self.l3_key)) self.encrypted_l2 = None self.encrypted_l3 = None elif self.key_service.all_clear_keys_provided( ) and self.key_service.no_enc_keys_provided(): # all 3 clear keys are provided locally logger.info( "Clear L1 key, clear L2 key, and clear L3 keys were provided locally." ) self.l1_key = self.key_service.get_l1_key() self.l2_key = self.key_service.get_l2_key() self.l3_key = self.key_service.get_l3_key() logger.debug("L1 Key: \n" + hexdump(self.l1_key)) logger.debug("L2 Key: \n" + hexdump(self.l2_key)) logger.debug("L3 Key: \n" + hexdump(self.l3_key)) self.encrypted_l2 = None self.encrypted_l3 = None elif self.key_service.all_enc_keys_provided( ) and self.key_service.get_l3_key( ) is not None and self.key_service.get_l1_key( ) is None and self.key_service.get_l2_key() is None: # encrypted l2, encrypted l3, and clear l3 are provided locally logger.info( "Encrypted L2 key, encrypted L3 key, and clear L3 keys were provided locally." ) self.l1_key = None self.l2_key = None self.l3_key = self.key_service.get_l3_key() self.encrypted_l2 = self.key_service.get_encrypted_l2_key() self.encrypted_l3 = self.key_service.get_encrypted_l3_key() logger.debug("Encrypted L2 Key: \n" + hexdump(self.encrypted_l2)) logger.debug("Encrypted L3 Key: \n" + hexdump(self.encrypted_l3)) logger.debug("L3 Key: \n" + hexdump(self.l3_key)) else: raise EncryptionParameters.InvalidKeyComboException( "The found key configuration is not allowed.\n \ Supported configurations: \n \ #1 clear L1 key \n \ #2 clear L1, L2, and L3 key \n \ #3 encrypted L2, encrypted L3, and clear L3 key \n \ #4 specify an encrypted key provider.\n \ If required files are provided, ensure that the corresponding config file \n \ contains the correct METACONFIG tags and values.") encryption_params_hdr = EncryptionParamsHeader() encryption_params_hdr.add_encryption_param_section() eps_hdr = EncryptionParamsSectionHdr( None, None, 1 if config.signing_attributes.UIE_root_key_type is None else config.signing_attributes.UIE_root_key_type, 0) eps_body = EncryptionParamsSectionBody( self.major_version, self.minor_version, self.image_id, l1_key=self.l1_key, l2_key=self.l2_key, l3_key=self.l3_key, enc_l2_key=self.encrypted_l2, enc_l3_key=self.encrypted_l3, enc_key_prov_is_qti=self.enc_key_prov_is_qti, debug_dir=debug_dir, encrypted_segments_indices=encrypted_segments_indices) self.l3_image_iv = eps_body.get_image_iv() self.encryption_params_blob = encryption_params_hdr.get_header_blob() + \ eps_hdr.get_header_blob() + \ eps_body.get_binary_blob() logger.debug("Encryption Params: \n" + hexdump(self.encryption_params_blob)) return self.encryption_params_blob, self.l1_key
def _decode_binary_blob(self, binary_blob, validating, l1_key, debug_dir): string_offset = 0 string_end = EncryptionParamsSectionBody.B0block.get_spec_size() self.L2B0block = EncryptionParamsSectionBody.B0block(binary_blob[string_offset:string_end]) self.L2_IV = self.L2B0block.nonce_fld logger.debug("L2 IV: \n" + hexdump(self.L2_IV)) string_offset = string_end string_end += EncryptionParamsSectionBody.L2AssociatedData.get_spec_size() self.L2_associated_data = binary_blob[string_offset:string_end] EncryptionParamsSectionBody.L2AssociatedData(self.L2_associated_data_major_version, self.L2_associated_data_minor_version, self.image_id, binary_blob=self.L2_associated_data, validating=validating) string_offset = string_end string_end += EncryptionParamsSectionBody.ENCRYPTED_KEY_PAYLOAD_LEN_BYTES self.L1_key_payload = binary_blob[string_offset:string_end] string_offset = string_end string_end += EncryptionParamsSectionBody.MAC_LEN_BYTES self.L2_MAC = binary_blob[string_offset:string_end] store_debug_data_to_file(defines.DEST_DEBUG_FILE_ENCRYPTED_L2_KEY, self.L1_key_payload + self.L2_MAC, debug_dir) store_debug_data_to_file(defines.DEST_DEBUG_FILE_L2_IMAGE_IV, self.L2_IV, debug_dir) store_debug_data_to_file(defines.DEST_DEBUG_FILE_L2_ADD, self.L2_associated_data, debug_dir) try: self.l2_key = crypto.aes_ccm.decrypt(self.L1_key_payload + self.L2_MAC, binascii.hexlify(l1_key), binascii.hexlify(self.L2_IV), binascii.hexlify(self.L2_associated_data)) logger.debug("L2 Key extracted from image: \n" + hexdump(self.l2_key)) logger.debug("Any previously generated L2 keys will be ignored.") except subprocess.CalledProcessError: raise RuntimeError("Extraction of L2 key from image failed. This can be caused by the use of an invalid L1 key.") string_offset = string_end string_end += EncryptionParamsSectionBody.B0block.get_spec_size() self.L3B0block = EncryptionParamsSectionBody.B0block(binary_blob[string_offset:string_end]) self.L3_IV = self.L3B0block.nonce_fld logger.debug("L3 IV: \n" + hexdump(self.L3_IV)) string_offset = string_end string_end += EncryptionParamsSectionBody.L3AssociatedData.get_spec_size() self.L3_associated_data = binary_blob[string_offset:string_end] string_offset = string_end string_end += EncryptionParamsSectionBody.ENCRYPTED_KEY_PAYLOAD_LEN_BYTES self.L2_key_payload = binary_blob[string_offset:string_end] string_offset = string_end string_end += EncryptionParamsSectionBody.MAC_LEN_BYTES self.L3_MAC = binary_blob[string_offset:string_end] store_debug_data_to_file(defines.DEST_DEBUG_FILE_ENCRYPTED_L3_KEY, self.L2_key_payload + self.L3_MAC, debug_dir) store_debug_data_to_file(defines.DEST_DEBUG_FILE_L3_IMAGE_IV, self.L3_IV, debug_dir) store_debug_data_to_file(defines.DEST_DEBUG_FILE_L3_ADD, self.L3_associated_data, debug_dir) try: self.l3_key = crypto.aes_ccm.decrypt(self.L2_key_payload + self.L3_MAC, binascii.hexlify(self.l2_key), binascii.hexlify(self.L3_IV), binascii.hexlify(self.L3_associated_data)) logger.debug("L3 Key extracted from image: \n" + hexdump(self.l3_key)) logger.debug("Any previously generated L3 keys will be ignored.") except subprocess.CalledProcessError: raise RuntimeError("Extraction of L3 key from image failed. This can be caused by the use of an invalid L1 or L2 key.") string_offset = string_end string_end += EncryptionParamsSectionBody.BASE_IV_LEN_BYTES self.base_iv = binary_blob[string_offset:string_end]