Example #1
0
def calculate_new_obb_digest(ifwi_file, fv_list, digest_file):
    """Calculate new OBB hash for one or more firmware volumes.
       The assumption is all FVs are continuous in one region."""

    bios = bytearray()

    ifwi = IFWI_IMAGE(ifwi_file)
    if not ifwi.is_ifwi_image():
        logger.warn("Invalid IFWI descriptor signature. Assuming BIOS image")
        with open(ifwi_file, "rb") as fd:
            bios = FirmwareDevice(0, bytearray(fd.read()))
    else:
        ifwi.parse()
        bios_start = ifwi.region_list[1][1]
        bios_limit = ifwi.region_list[1][2]
        bios = FirmwareDevice(0, ifwi.data[bios_start:bios_limit + 1])

    logger.info("Found BIOS ({}MB)...".format(
        len(bios.FdData) // (1024 * 1024)))
    bios.ParseFd()

    # Locate FVs (note: only the first FV index is used)
    fv_id_list = []
    for fv in fv_list:
        obb_fv_idx = bios.get_fv_index_by_guid(fv.bytes_le)
        if not (0 < obb_fv_idx < len(bios.FvList)):
            raise ValueError("FV {} for OBB region is not found".format(fv))
        logger.info("Found FV @ index {}".format(obb_fv_idx))
        fv_id_list.append(obb_fv_idx)

    starting_fv_idx = fv_id_list[0]
    logger.info("*** OBB region starts from FV{} (len:{})".format(
        starting_fv_idx, len(fv_id_list)))
    obb_offset = bios.FvList[starting_fv_idx].Offset
    obb_length = 0
    if bios.is_fsp_wrapper():
        logger.info("FSP Wrapper BIOS")
        obb_fv_end = starting_fv_idx + len(fv_list)
    else:
        logger.critical("EDK2 BIOS image format is not supported any more")
        exit(2)

    # Get total length of OBB
    logger.info("start FV: {} end FV: {}".format(starting_fv_idx, obb_fv_end))
    for fv in bios.FvList[starting_fv_idx:obb_fv_end]:
        logger.info("Adding FV size 0x{:x} ...".format(len(fv.FvData)))
        obb_length += len(fv.FvData)

    logger.debug("OBB offset: {:x} len {:x}".format(obb_offset, obb_length))

    # Hash it
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(bios.FdData[obb_offset:obb_offset + obb_length])
    result = digest.finalize()
    with open(digest_file, "wb") as hash_fd:
        hash_fd.write(result)

    return
Example #2
0
def update_obb_digest(ifwi_file, digest_file):
    """Calculate OBB hash according to a predefined range"""

    ifwi = IFWI_IMAGE(ifwi_file)
    if not ifwi.is_ifwi_image():
        logger.critical("Bad IFWI image")
        exit(1)

    ifwi.parse()
    bios_start = ifwi.region_list[1][1]
    bios_limit = ifwi.region_list[1][2]

    logger.info("Parsing BIOS ...")
    bios = FirmwareDevice(0, ifwi.data[bios_start:bios_limit + 1])
    bios.ParseFd()

    # Extract FVs belongs to OBB
    obb_fv_idx = bios.get_fv_index_by_guid(GUID_FVOSBOOT.bytes_le)
    if not (0 < obb_fv_idx < len(bios.FvList)):
        raise ValueError("Starting OBB FV is not found")

    logger.debug("OBB region starts from FV{}".format(obb_fv_idx))
    obb_offset = bios.FvList[obb_fv_idx].Offset
    obb_length = 0
    if bios.is_fsp_wrapper():
        # FVOSBOOT + FVUEFIBOOT_PRIME + FVADVANCED + FVPOSTMEMORY + FSPS
        logger.info("FSP Wrapper BIOS")
        obb_fv_end = obb_fv_idx + 5
    else:
        # FVOSBOOT + FVUEFIBOOT_PRIME + FVADVANCED + FVPOSTMEMORY
        logger.info("EDK2 BIOS")
        obb_fv_end = obb_fv_idx + 4

    for fv in bios.FvList[obb_fv_idx:obb_fv_end]:
        obb_length += len(fv.FvData)

    logger.debug("OBB offset: {:x} len {:x}".format(obb_offset, obb_length))

    # Hash it
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(bios.FdData[obb_offset:obb_offset + obb_length])
    result = digest.finalize()
    with open(digest_file, "wb") as hash_fd:
        hash_fd.write(result)

    return