def test_reset_cmd(): cmd = CmdReset() assert cmd.info() data = cmd.export() assert len(data) == 16 assert len(data) == cmd.raw_size cmd_parsed = parse_command(data) assert cmd == cmd_parsed
def build_sb(app: str, kek: bytes, address: int = 0) -> bytes: """Build a Secure Boot image. :param app: The application data :param kek: Key Encryption Key value :param address: Entry address for application :return: Serialized SB2.0 image """ with open(app, "rb") as f: boot_data = f.read() boot_section = BootSectionV2( 0, CmdErase(address, len(boot_data)), CmdLoad(address, boot_data), CmdReset(), hmac_count=10, ) boot_image = BootImageV20(signed=False, kek=kek) boot_image.add_boot_section(boot_section) print(boot_image.info()) return boot_image.export()
def gen_boot_section() -> BootSectionV2: """Generate a Boot Section withput encryption.""" with open(f"{DATA_DIR}/boot_image.bin", "rb") as boot_image_file: boot_data = boot_image_file.read() boot_section = BootSectionV2( 0, CmdErase(address=0, length=100000), CmdLoad(address=0, data=boot_data), CmdReset(), hmac_count=10, ) return boot_section
def test_boot_section_v2(): boot_section = BootSectionV2(0, CmdErase(address=0, length=100000), CmdLoad(address=0, data=b"0123456789"), CmdReset()) assert boot_section.uid == 0 assert not boot_section.is_last assert boot_section.hmac_count == 1 assert boot_section.raw_size == 144 dek = crypto_backend().random_bytes(32) mac = crypto_backend().random_bytes(32) nonce = crypto_backend().random_bytes(16) data = boot_section.export(dek, mac, Counter(nonce)) assert data assert BootSectionV2.parse(data, 0, False, dek, mac, Counter(nonce)) with pytest.raises(SPSDKError, match="Invalid type of dek, should be bytes"): BootSectionV2.parse(data=data, offset=0, plain_sect=False, dek=4, mac=mac, counter=Counter(nonce)) with pytest.raises(SPSDKError, match="Invalid type of mac, should be bytes"): BootSectionV2.parse(data=data, offset=0, plain_sect=False, dek=dek, mac=4, counter=Counter(nonce)) with pytest.raises(SPSDKError, match="Invalid type of counter"): BootSectionV2.parse(data=data, offset=0, plain_sect=False, dek=dek, mac=mac, counter=5) with pytest.raises(SPSDKError): assert BootSectionV2.parse(data, 0, False, dek, crypto_backend().random_bytes(32), Counter(nonce))
def test_boot_section_v2_invalid_export(): boot_section = BootSectionV2(0, CmdErase(address=0, length=100000), CmdLoad(address=0, data=b"0123456789"), CmdReset()) dek = 32 mac = 4 nonce = crypto_backend().random_bytes(16) with pytest.raises(SPSDKError, match="Invalid type of dek, should be bytes"): boot_section.export(dek, mac, Counter(nonce)) dek = crypto_backend().random_bytes(32) with pytest.raises(SPSDKError, match="Invalid type of mac, should be bytes"): boot_section.export(dek, mac, Counter(nonce)) counter = 5 mac = crypto_backend().random_bytes(32) with pytest.raises(SPSDKError, match="Invalid type of counter"): boot_section.export(dek, mac, counter)
def gen_boot_section_otfad() -> BootSectionV2: """Generate a Boot Section with content encrypted by OTFAD. :raises SPSDKError: When length of key blobs is not 256 """ with open(f"{DATA_DIR}/boot_image.bin", "rb") as boot_image_file: boot_data = boot_image_file.read() otfad = Otfad() key = bytes.fromhex("B1A0C56AF31E98CD6936A79D9E6F829D") counter = bytes.fromhex("5689fab8b4bfb264") otfad.add_key_blob( KeyBlob( 0x08001000, 0x0800F3FF, key, counter, zero_fill=bytes(4), crc=bytes(4), )) # zero_fill and crc should be used only for testing ! enc_image = otfad.encrypt_image(boot_data, 0x08001000, True) key_blobs = otfad.encrypt_key_blobs( kek=bytes.fromhex("50F66BB4F23B855DCD8FEFC0DA59E963")) if len(key_blobs) != 256: raise SPSDKError("Length of key blobs is not 256") boot_section = BootSectionV2( 0, CmdErase(address=0x08001000, length=0x0800F000 - 0x08001000), CmdLoad(address=0x08001000, data=enc_image), CmdLoad(address=0x08000000, data=key_blobs), CmdReset(), hmac_count=10, ) return boot_section
def get_boot_sections(data_dir: str, otfad: bool, sect_cont: SectionsContent, load_addr: int) -> List[BootSectionV2]: """Create list of boot sections for SB 2.x file :param data_dir: absolute path to load boot image :param otfad: True to encrypt section with OTFAD; False otherwise :param sect_cont: sections content to test :param load_addr: address where to load the image (for simple section) :return: """ result = list() # load input image (binary) with open(os.path.join(data_dir, "sb2_x", "boot_image.bin"), "rb") as f: plain_image = f.read() # OTFAD key_blobs_data = list() if otfad: otfad = Otfad() # key blob 0 key = bytes.fromhex("B1A0C56AF31E98CD6936A79D9E6F829D") counter = bytes.fromhex("5689fab8b4bfb264") key_blob = KeyBlob( 0x08001000, 0x0800F3FF, key, counter, zero_fill=bytes(4), crc=bytes( 4)) # zero_fill and crc should be used only for testing ! otfad.add_key_blob(key_blob) key_blobs_data = list() key_blobs_data.append( key_blob.export( kek=bytes.fromhex("50F66BB4F23B855DCD8FEFC0DA59E963"))) # verify `otfad.encrypt_key_blobs` returns the same assert (key_blobs_data[0] == otfad.encrypt_key_blobs( kek=bytes.fromhex("50F66BB4F23B855DCD8FEFC0DA59E963"))[:64]) # key blob 1 if sect_cont == SectionsContent.ADVANCED: key = bytes.fromhex("12345678901234567890123456789012") counter = bytes.fromhex("0011223344556677") key_blob1 = KeyBlob( 0x08010000, 0x0801F3FF, key, counter, zero_fill=bytes(4), crc=bytes( 4)) # zero_fill and crc should be used only for testing ! otfad.add_key_blob(key_blob1) key_blobs_data.append( key_blob1.export( kek=bytes.fromhex("0123456789ABCDEF0123456789ABCDEF"))) # encrypted image encr_image = otfad.encrypt_image(plain_image, load_addr, True) else: encr_image = plain_image if sect_cont == SectionsContent.ADVANCED: # add boot sections 1 - advanced boot_section2 = BootSectionV2( 1, CmdErase(address=0, length=0x2800), CmdLoad(address=0x10000000, data=plain_image), CmdLoad(address=0x20000000, data=plain_image), CmdCall(0xFFFF0000), CmdJump(0x12345678), CmdReset(), hmac_count=5, ) assert boot_section2.uid == 1 result.append(boot_section2) # create boot section 0 if sect_cont == SectionsContent.NEW_CMDS: boot_section0 = BootSectionV2( 0, CmdVersionCheck(VersionCheckType.SECURE_VERSION, 0x16), CmdVersionCheck(VersionCheckType.NON_SECURE_VERSION, 15263), CmdErase(address=0, length=0x2800), CmdLoad(address=load_addr, data=encr_image), CmdKeyStoreBackup(0x12345678, 3), CmdKeyStoreRestore(0x12345678, 3), hmac_count=1, ) else: boot_section0 = BootSectionV2( 0, CmdErase(address=0, length=0x2800), CmdLoad(address=load_addr, data=encr_image), hmac_count=10, ) for index, key_blob_data in enumerate(key_blobs_data): key_blob_aligned = align_block( key_blob_data, 256) # it seems key-blob from elf-to-sb is aligned to 256 boot_section0.append( CmdLoad(address=0x8000000 + 0x100 * index, data=key_blob_aligned)) boot_section0.append(CmdReset()) result.append(boot_section0) return result
def test_reset_cmd_invalid_parse(): cmd = CmdNop() data = cmd.export() with pytest.raises(SPSDKError, match="Invalid header tag"): CmdReset.parse(data)