def test_ram_encrypted_otp(data_dir: str, image_file_name: str, ram_addr: int) -> None: """Test encrypted load-to-RAM image with key stored in OTP :param data_dir: absolute path with data files :param image_file_name: name of the input image file (including extension) :param ram_addr: address in RAM, where the image should be located """ path = os.path.join(data_dir, INPUT_IMAGES_SUBDIR, image_file_name) org_data = load_binary(path) key_store = KeyStore(KeySourceType.OTP) cert_block, priv_key_pem_data = create_cert_block(data_dir) with open(os.path.join(data_dir, KEYSTORE_SUBDIR, 'userkey.txt'), 'r') as f: hmac_user_key = f.readline() mbi = MasterBootImage(app=org_data, image_type=MasterBootImageType.ENCRYPTED_RAM_IMAGE, load_addr=ram_addr, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data, hmac_key=hmac_user_key, key_store=key_store, ctr_init_vector=ENCR_CTR_IV) out_image_file_name = image_file_name.replace('_unsigned.bin', '_encr_otp.bin') write_image(data_dir, out_image_file_name, mbi.export())
def test_ram_encrypted_keystore(data_dir: str, image_file_name: str, ram_addr: int) -> None: """Test encrypted load-to-RAM image with key stored in key-store :param data_dir: absolute path with data files :param image_file_name: name of the input image file (including extension) :param ram_addr: address in RAM, where the image should be located """ path = os.path.join(data_dir, INPUT_IMAGES_SUBDIR, image_file_name) org_data = load_binary(path) # load keystore with HMAC user key key_store = get_keystore(data_dir) cert_block, priv_key_pem_data = create_cert_block(data_dir) with open(os.path.join(data_dir, KEYSTORE_SUBDIR, "userkey.txt"), "r") as f: hmac_user_key = f.readline() mbi = Mbi_EncryptedRamRtxxx( app=org_data, load_addr=ram_addr, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, hmac_key=hmac_user_key, key_store=key_store, ctr_init_vector=ENCR_CTR_IV, ) out_image_file_name = image_file_name.replace("_unsigned.bin", "_encr_keystore.bin") write_image(data_dir, out_image_file_name, mbi.export())
def test_invalid_export_mbi(data_dir): with open(os.path.join(data_dir, "testfffffff.bin"), "rb") as f: org_data = f.read() user_key = "E39FD7AB61AE6DDDA37158A0FC3008C6D61100A03C7516EA1BE55A39F546BAD5" key_store_bin = None key_store = KeyStore(KeySourceType.KEYSTORE, key_store_bin) cert_block = certificate_block(data_dir, ["selfsign_2048_v3.der.crt"]) priv_key_pem_data = _load_private_key(data_dir, "selfsign_privatekey_rsa2048.pem") mbi = Mbi_EncryptedRamRtxxx( app=org_data, load_addr=0x12345678, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, hmac_key=user_key, key_store=key_store, ctr_init_vector=bytes(16), ) mbi.priv_key_data = None with pytest.raises(SPSDKError): mbi.export() mbi.priv_key_data = priv_key_pem_data mbi.cert_block = None with pytest.raises(SPSDKError): mbi.export()
def test_ram_signed_keystore(data_dir: str, image_file_name: str, ram_addr: int) -> None: """Create signed load-to-RAM image with keys stored in key-store :param data_dir: absolute path with data files :param image_file_name: name of the input image file (including extension) :param ram_addr: address in RAM, where the image should be located """ # read unsigned image (must be built without boot header) path = os.path.join(data_dir, INPUT_IMAGES_SUBDIR, image_file_name) org_data = load_binary(path) cert_block, priv_key_pem_data = create_cert_block(data_dir) key_store = get_keystore(data_dir) with open(os.path.join(data_dir, KEYSTORE_SUBDIR, 'userkey.txt'), 'r') as f: hmac_user_key = f.readline() mbi = MasterBootImage(app=org_data, image_type=MasterBootImageType.SIGNED_RAM_IMAGE, load_addr=ram_addr, trust_zone=TrustZone.disabled(), key_store=key_store, cert_block=cert_block, priv_key_pem_data=priv_key_pem_data, hmac_key=hmac_user_key) out_image_file_name = image_file_name.replace('_unsigned.bin', '_signed_keystore.bin') write_image(data_dir, out_image_file_name, mbi.export())
def test_signed_ram_single_certificate_no_tz(data_dir, user_key, key_store_filename, expected_mbi): """Test non-XIP signed image with single certificate :param data_dir: absolute path, where test data are located """ with open(os.path.join(data_dir, 'testfffffff.bin'), "rb") as f: org_data = f.read() # create certification block cert_block = certificate_block(data_dir, ['selfsign_2048_v3.der.crt']) priv_key_pem_data = _load_private_key(data_dir, 'selfsign_privatekey_rsa2048.pem') key_store = None if key_store_filename: with open(os.path.join(data_dir, key_store_filename), "rb") as f: key_store_bin = f.read() key_store = KeyStore(KeySourceType.KEYSTORE, key_store_bin) mbi = MasterBootImage(app=org_data, image_type=MasterBootImageType.SIGNED_RAM_IMAGE, load_addr=0x12345678, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data, hmac_key=user_key, key_store=key_store) assert _compare_image(mbi, data_dir, expected_mbi)
def test_signed_xip_multiple_certificates_invalid_input(data_dir): """Test invalid input for multiple certificates""" # indexed certificate is not specified der_file_names = ['selfsign_4096_v3.der.crt', 'selfsign_3072_v3.der.crt', 'selfsign_2048_v3.der.crt'] with pytest.raises(IndexError): certificate_block(data_dir, der_file_names, 3) # indexed certificate is not specified der_file_names = ['selfsign_4096_v3.der.crt', None, 'selfsign_3072_v3.der.crt', 'selfsign_2048_v3.der.crt'] with pytest.raises(ValueError): certificate_block(data_dir, der_file_names, 1) # public key in certificate and private key does not match der_file_names = ['selfsign_4096_v3.der.crt'] cert_block = certificate_block(data_dir, der_file_names, 0) priv_key_pem_data = _load_private_key(data_dir, 'selfsign_privatekey_rsa2048.pem') with pytest.raises(ValueError): MasterBootImage(app=bytes(range(128)), load_addr=0, image_type=MasterBootImageType.SIGNED_XIP_IMAGE, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data).export() # chain of certificates does not match der_file_names = ['selfsign_4096_v3.der.crt'] chain_certificates = ['ch3_crt2_v3.der.crt'] with pytest.raises(ValueError): certificate_block(data_dir, der_file_names, 0, chain_certificates)
def test_encrypted_ram_single_certificate_no_tz(data_dir, keysource: KeySourceType, keystore_fn: Optional[str], ctr_iv: str, expected_mbi: str): """Test encrypted image with fixed counter init vector""" with open(os.path.join(data_dir, 'testfffffff.bin'), "rb") as f: org_data = f.read() user_key = 'E39FD7AB61AE6DDDA37158A0FC3008C6D61100A03C7516EA1BE55A39F546BAD5' key_store_bin = None if keystore_fn: with open(os.path.join(data_dir, keystore_fn), "rb") as f: key_store_bin = f.read() key_store = KeyStore(keysource, key_store_bin) ctr_init_vector = bytes.fromhex(ctr_iv) # create certification block cert_block = certificate_block(data_dir, ['selfsign_2048_v3.der.crt']) priv_key_pem_data = _load_private_key(data_dir, 'selfsign_privatekey_rsa2048.pem') mbi = MasterBootImage(app=org_data, image_type=MasterBootImageType.ENCRYPTED_RAM_IMAGE, load_addr=0x12345678, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data, hmac_key=user_key, key_store=key_store, ctr_init_vector=ctr_init_vector) assert _compare_image(mbi, data_dir, expected_mbi)
def test_ram_signed_otp(data_dir: str, image_file_name: str, ram_addr: int) -> None: """Create signed load-to-RAM image with keys stored in OTP :param data_dir: absolute path with data files :param image_file_name: name of the input image file (including extension) :param ram_addr: address in RAM, where the image should be located """ # read unsigned image (must be built without boot header) path = os.path.join(data_dir, INPUT_IMAGES_SUBDIR, image_file_name) unsigned_img = load_binary(path) keystore = KeyStore(KeySourceType.OTP) cert_block, priv_key_pem_data = create_cert_block(data_dir) mbi = Mbi_PlainSignedRamRtxxx( app=unsigned_img, load_addr=ram_addr, key_store=keystore, hmac_key=MASTER_KEY, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, ) out_image_file_name = image_file_name.replace("_unsigned.bin", "_signed_otp.bin") write_image(data_dir, out_image_file_name, mbi.export())
def test_signed_xip_certificates_chain_no_tz(data_dir, der_certificates, chain_certificates, priv_key, expected_mbi): """Test signed image with multiple certificates, different key length :param data_dir: absolute path, where test data are located :param der_certificates: list of filenames of der root certificates :param chain_certificates: list of filenames of der cerificates :param priv_key: private key filename :param expected_mbi: filename of expected bootable image """ with open(os.path.join(data_dir, 'testfffffff.bin'), "rb") as f: org_data = f.read() # create certification block cert_block = certificate_block(data_dir, der_certificates, 0, chain_certificates) priv_key_pem_data = _load_private_key(data_dir, priv_key) mbi = MasterBootImage(app=org_data, load_addr=0, image_type=MasterBootImageType.SIGNED_XIP_IMAGE, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data) assert _compare_image(mbi, data_dir, expected_mbi)
def test_plain_xip_crc_no_tz(data_dir, input_img, expected_mbi: str): """Test plain image with CRC and no TZ-M :param data_dir: absolute path, where test data are located :param input_img: file name of input image (binary) :param expected_mbi: file name of MBI image file with expected data """ with open(os.path.join(data_dir, input_img), "rb") as f: org_data = f.read() mbi = MasterBootImage(app=org_data, load_addr=0, image_type=MasterBootImageType.CRC_XIP_IMAGE, trust_zone=TrustZone.disabled()) assert _compare_image(mbi, data_dir, expected_mbi)
def test_encrypted_random_ctr_single_certificate_no_tz(data_dir): """Test encrypted image with random counter init vector""" with open(os.path.join(data_dir, 'testfffffff.bin'), "rb") as f: org_data = f.read() user_key = 'E39FD7AB61AE6DDDA37158A0FC3008C6D61100A03C7516EA1BE55A39F546BAD5' key_store = KeyStore(KeySourceType.KEYSTORE, None) cert_block = certificate_block(data_dir, ['selfsign_2048_v3.der.crt']) priv_key_pem_data = _load_private_key(data_dir, 'selfsign_privatekey_rsa2048.pem') mbi = MasterBootImage(app=org_data, image_type=MasterBootImageType.ENCRYPTED_RAM_IMAGE, load_addr=0x12345678, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data, hmac_key=user_key, key_store=key_store) assert mbi.export() assert mbi.info()
def _get_trustzone(config: elftosb_helper.MasterBootImageConfig) -> TrustZone: """Create appropriate TrustZone instance.""" if not config.trustzone_preset_file: return TrustZone.disabled() try: tz_config_data = json.loads(load_file(config.trustzone_preset_file)) tz_config = elftosb_helper.TrustZoneConfig(tz_config_data) return TrustZone.custom( family=tz_config.family, revision=tz_config.revision, customizations=tz_config.presets ) except ValueError: tz_raw_data = load_binary(config.trustzone_preset_file) return TrustZone.from_binary( family=config.family, revision=config.revision, raw_data=tz_raw_data )
def test_encrypted_random_ctr_single_certificate_no_tz(data_dir): """Test encrypted image with random counter init vector""" with open(os.path.join(data_dir, "testfffffff.bin"), "rb") as f: org_data = f.read() user_key = "E39FD7AB61AE6DDDA37158A0FC3008C6D61100A03C7516EA1BE55A39F546BAD5" key_store = KeyStore(KeySourceType.KEYSTORE, None) cert_block = certificate_block(data_dir, ["selfsign_2048_v3.der.crt"]) priv_key_pem_data = _load_private_key(data_dir, "selfsign_privatekey_rsa2048.pem") mbi = Mbi_EncryptedRamRtxxx( app=org_data, load_addr=0x12345678, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, hmac_key=user_key, key_store=key_store, ) assert mbi.export()
def test_master_boot_image_invalid_hmac(data_dir): with open(os.path.join(data_dir, "testfffffff.bin"), "rb") as f: org_data = f.read() user_key = "E39FD7AB61AE6DDDA37158A0FC3008C6D61100A03C7516EA1BE55A39F546BAD5" key_store = KeyStore(KeySourceType.KEYSTORE, None) cert_block = certificate_block(data_dir, ["selfsign_2048_v3.der.crt"]) priv_key_pem_data = _load_private_key(data_dir, "selfsign_privatekey_rsa2048.pem") mbi = Mbi_EncryptedRamRtxxx( app=org_data, load_addr=0x12345678, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, hmac_key=user_key, key_store=key_store, ) mbi.hmac_key = None assert mbi.compute_hmac(data=bytes(16)) == bytes()
def test_signed_xip_single_certificate_no_tz(data_dir, priv_key, der_certificate, expected_mbi): """Test signed XIP image with single certificate, different key length :param data_dir: absolute path, where test data are located :param priv_key: filename of private key used for signing :param der_certificate: filename of corresponding certificate in DER format :param expected_mbi: filename of expected bootable image """ with open(os.path.join(data_dir, 'testfffffff.bin'), "rb") as f: org_data = f.read() # create certification block cert_block = certificate_block(data_dir, [der_certificate]) priv_key_pem_data = _load_private_key(data_dir, priv_key) mbi = MasterBootImage(app=org_data, load_addr=0, image_type=MasterBootImageType.SIGNED_XIP_IMAGE, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_pem_data=priv_key_pem_data) assert _compare_image(mbi, data_dir, expected_mbi)
def test_signed_xip_multiple_certificates_invalid_input(data_dir): """Test invalid input for multiple certificates""" # indexed certificate is not specified der_file_names = [ "selfsign_4096_v3.der.crt", "selfsign_3072_v3.der.crt", "selfsign_2048_v3.der.crt", ] with pytest.raises(IndexError): certificate_block(data_dir, der_file_names, 3) # indexed certificate is not specified der_file_names = [ "selfsign_4096_v3.der.crt", None, "selfsign_3072_v3.der.crt", "selfsign_2048_v3.der.crt", ] with pytest.raises(SPSDKError): certificate_block(data_dir, der_file_names, 1) # public key in certificate and private key does not match der_file_names = ["selfsign_4096_v3.der.crt"] cert_block = certificate_block(data_dir, der_file_names, 0) priv_key_pem_data = _load_private_key(data_dir, "selfsign_privatekey_rsa2048.pem") with pytest.raises(SPSDKError): Mbi_SignedXip( app=bytes(range(128)), trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, ).export() # chain of certificates does not match der_file_names = ["selfsign_4096_v3.der.crt"] chain_certificates = ["ch3_crt2_v3.der.crt"] with pytest.raises(SPSDKError): certificate_block(data_dir, der_file_names, 0, chain_certificates)
def test_tz_types(sample_tz_data): # TZ is enabled by default tz = TrustZone() assert tz.type == TrustZoneType.ENABLED tz = TrustZone.enabled() assert tz.type == TrustZoneType.ENABLED tz = TrustZone.disabled() assert tz.type == TrustZoneType.DISABLED tz = TrustZone(family="lpc55xx", customizations=sample_tz_data) assert tz.type == TrustZoneType.CUSTOM tz = TrustZone(family="lpc55xx", customizations=sample_tz_data, tz_type=TrustZoneType.CUSTOM) assert tz.type == TrustZoneType.CUSTOM tz = TrustZone(family="lpc55xx", customizations=sample_tz_data, tz_type=TrustZoneType.ENABLED) assert tz.type == TrustZoneType.CUSTOM tz = TrustZone.custom(family="lpc55xx", customizations=sample_tz_data) assert tz.type == TrustZoneType.CUSTOM assert "TrustZone" in str(tz)
def test_signed_xip_multiple_certificates_no_tz(data_dir, der_certificates, root_index, expected_mbi): """Test signed image with multiple certificates, different key length :param data_dir: absolute path, where test data are located :param der_certificates: list of filenames of der certificates :param root_index: index of root certificate :param expected_mbi: filename of expected bootable image """ with open(os.path.join(data_dir, "testfffffff.bin"), "rb") as f: org_data = f.read() # create certification block cert_block = certificate_block(data_dir, der_certificates, root_index) priv_key_pem_data = _load_private_key(data_dir, "selfsign_privatekey_rsa2048.pem") mbi = Mbi_SignedXip( app=org_data, trust_zone=TrustZone.disabled(), cert_block=cert_block, priv_key_data=priv_key_pem_data, ) assert _compare_image(mbi, data_dir, expected_mbi)
def test_simplified_export(): assert TrustZone().export() == b"" assert TrustZone.enabled().export() == b"" assert TrustZone.disabled().export() == b""