예제 #1
0
def test_otfad(data_dir):
    """Test OTFAD generator"""
    otfad = Otfad()
    key = bytes.fromhex("B1A0C56AF31E98CD6936A79D9E6F829D")
    counter = bytes.fromhex("5689fab8b4bfb264")
    key_blob = KeyBlob(start_addr=0x08001000,
                       end_addr=0x0800F3FF,
                       key=key,
                       counter_iv=counter)
    otfad.add_key_blob(key_blob)
    assert otfad[0] == key_blob
    with open(os.path.join(data_dir, "boot_image.bin"), "rb") as f:
        image = f.read()

    # invalid address
    with pytest.raises(SPSDKError):
        key_blob.encrypt_image(0x0, image, True)

    encr_image = otfad.encrypt_image(image, 0x08001000, True)
    otfad.encrypt_image(image, 0x08001000, False)  # TODO finish the test
    with open(os.path.join(data_dir, "otfad_image.bin"), "rb") as f:
        otfad_image = f.read()
    assert encr_image == otfad_image

    otfad.info()
예제 #2
0
def test_otfad_keyblob(data_dir):
    """ Test generation of key blob for OTFAD """
    # generate key blob using random keys
    key_blob = KeyBlob(start_addr=0x08001000, end_addr=0x0800F3FF)
    gen_blob = key_blob.export(kek=bytes.fromhex('50F66BB4F23B855DCD8FEFC0DA59E963'))
    assert gen_blob is not None
    # generate key blob using fixed keys
    key = bytes.fromhex('B1A0C56AF31E98CD6936A79D9E6F829D')
    counter = bytes.fromhex("5689fab8b4bfb264")
    zeros = bytes(4)  # zero_fill and crc are '0' just for this test; in reality should be random
    key_blob = KeyBlob(start_addr=0x08001000, end_addr=0x0800F3FF, key=key, counter_iv=counter,
                       zero_fill=zeros, crc=zeros)
    gen_blob = key_blob.export(kek=bytes.fromhex('50F66BB4F23B855DCD8FEFC0DA59E963'))

    with open(os.path.join(data_dir, 'otfad_keyblob.bin'), "rb") as f:
        keyblob_bin = f.read()
    assert gen_blob == keyblob_bin

    # check that info produces non-empty text
    assert key_blob.info()

    # test image encryption
    with open(os.path.join(data_dir, 'boot_image.bin'), "rb") as f:
        plain_image = f.read()
    encr_image = key_blob.encrypt_image(0x08001000, plain_image, True)
    with open(os.path.join(data_dir, 'otfad_image.bin'), "rb") as f:
        otfad_image = f.read()
    assert encr_image == otfad_image

    # check key blob is created with random bytes for zero_fill and crc
    key_blob = KeyBlob(start_addr=0x08001000, end_addr=0x0800F3FF, key=key, counter_iv=counter)
    gen_blob = key_blob.export(kek=bytes.fromhex('50F66BB4F23B855DCD8FEFC0DA59E963'))
    assert gen_blob != keyblob_bin

    # start address not aligned
    with pytest.raises(ValueError):
        KeyBlob(start_addr=0x08001001, end_addr=0x0800F3FF, key=key, counter_iv=counter)

    # end address not aligned
    with pytest.raises(ValueError):
        KeyBlob(start_addr=0x08001000, end_addr=0x0800F000, key=key, counter_iv=counter)

    # address of the image is not within key blob
    key_blob = KeyBlob(start_addr=0x08001000, end_addr=0x0800F3FF, key=key, counter_iv=counter)
    with pytest.raises(ValueError):
        key_blob.encrypt_image(0x8000000, plain_image, True)
    with pytest.raises(ValueError):
        key_blob.encrypt_image(0x800F000, plain_image, True)
예제 #3
0
def _encrypt(cmd_args: dict) -> CmdLoad:
    """Returns a CmdLoad object initialized based on cmd_args.

    Encrypt holds an ID, which is a reference to keyblob to be used for
    encryption. So the encrypt command requires a list of keyblobs, the keyblob
    ID and load command.

    e.g.
    encrypt (0){
        load myImage > 0x0810000;
    }

    :param cmd_args: dictionary holding list of keyblobs, keyblob ID and load dict
    :raises SPSDKError: If keyblob to be used is not in the list or is invalid
    :return: CmdLoad object
    """
    keyblob_id = cmd_args["keyblob_id"]
    keyblobs = cmd_args.get("keyblobs", [])
    load_dict = cmd_args.get("load", {})

    address = load_dict["address"]

    if load_dict.get("file"):
        data = load_binary(load_dict["file"])
    if load_dict.get("values"):
        values = [int(s, 16) for s in load_dict["values"].split(",")]
        data = struct.pack(f"<{len(values)}L", *values)

    try:
        valid_keyblob = _validate_keyblob(keyblobs, keyblob_id)
    except SPSDKError as exc:
        raise SPSDKError(f"Invalid key blob {str(exc)}") from exc

    if valid_keyblob is None:
        raise SPSDKError(f"Missing keyblob {keyblob_id} for encryption.")

    start_addr = valid_keyblob["keyblob_content"][0]["start"]
    end_addr = valid_keyblob["keyblob_content"][0]["end"]
    key = bytes.fromhex(valid_keyblob["keyblob_content"][0]["key"])
    counter = bytes.fromhex(valid_keyblob["keyblob_content"][0]["counter"])
    byte_swap = valid_keyblob["keyblob_content"][0].get("byte_swap", False)

    keyblob = KeyBlob(start_addr=start_addr,
                      end_addr=end_addr,
                      key=key,
                      counter_iv=counter)

    encoded_data = keyblob.encrypt_image(base_address=address,
                                         data=data,
                                         byte_swap=byte_swap)

    return CmdLoad(address, encoded_data)