Exemplo n.º 1
0
def main():
    """Entry to script."""

    parser = create_arg_parser()
    args = parser.parse_args()

    # Use absolute path for openSSL
    sbrgn_file = Path(args.subregion_file).resolve()
    signer_file = Path(args.signerfile).resolve()
    outfile = Path(args.signed_file).resolve()

    filenames = [str(sbrgn_file), str(signer_file)]

    # Verify file input file exist
    status = utils.file_exist(filenames, LOGGER)
    if status != 0:
        sys.exit(status)

    if os.path.getsize(sbrgn_file) == 0:
        LOGGER.critical(
            "size of {} subregion file must be greater than 0!".format(
                sbrgn_file))
        sys.exit(status)

    status = utils.check_key(signer_file, args.signer_type, LOGGER)
    if status != 0:
        sys.exit(status)

    outfile = utils.file_not_exist(outfile, LOGGER)

    cert_info = get_certifcation_info(args, signer_file)

    uefi_subreg_authen = UefiSubregAuthenClass(cert_info)

    # read input file to store into structure
    payload = read_file(sbrgn_file)
    uefi_subreg_authen.payload = payload

    # add Vendor Guid to Payload
    payload = uefi_subreg_authen.vendor_guid.bytes + payload

    # calculate the signature store in structure
    cert_data = generate_signature(cert_info["openssl_cmd"], payload)

    if cert_info["openssl_cmd2"]:
        # Read in the private key
        payload = read_file(signer_file)

        # Extract the public key modulus from private key
        cert_pub = generate_signature(cert_info["openssl_cmd2"], payload)

        # convert public key from bytes to string
        cert_pub_string = cert_pub.decode("utf-8")

        # remove word Moudlus= from the file
        cert_pubkey = cert_pub_string.replace("Modulus=", "")

        # remove end of line from public key
        cert_pubkey = cert_pubkey.rstrip()

        # Conert to hex bytes and add to signature
        cert_pubkey = bytes.fromhex(cert_pubkey)

        # public key and signature are packed back to back
        cert_data = cert_pubkey + cert_data

    uefi_subreg_authen.cert_data = cert_data

    # pack structure with signature and get update size of header
    uefi_signed_data = uefi_subreg_authen.encode()

    if args.show:
        uefi_subreg_authen.dump_info()

    # Create output EFI subregion authentication header and signature and original file
    build_subreg_signed_file(uefi_signed_data, str(outfile))

    print("Signed {} sub-region({}) was successfully generated.".format(
        args.name, outfile))
Exemplo n.º 2
0
def main():
    """Entry to script."""

    # files created that needs to be remove
    to_remove = [
        "tmp.fmmt.txt", "tmp.raw", "tmp.ui", "tmp.all", "tmp.cmps", "tmp.guid",
        "tmp.pe32", "tmp.ffs"
    ]
    try:
        parser = parse_cmdline()
        args = parser.parse_args()

        outfile = Path(args.OUTPUT_FILE).resolve()
        outfile = utils.file_not_exist(outfile, logger)

        for f in (FMMT, GENFV, GENFFS, GENSEC, LZCOMPRESS, RSA_HELPER,
                  FMMT_CFG):
            if not os.path.exists(f):
                raise FileNotFoundError(
                    "Thirdparty tool not found ({})".format(f))

        # Use absolute path because GenSec does not like relative ones
        IFWI_file = Path(args.IFWI_IN.name).resolve()

        # If input IP file is a JSON file, convert it to binary as the real input file
        if args.IPNAME_IN.name.lower().endswith('.json'):
            logger.info(
                "Found JSON as input file. Converting it to binary ...\n")

            desc = SubRegionDescriptor()
            desc.parse_json_data(args.IPNAME_IN.name)

            # Currently only creates the first file
            generate_sub_region_image(desc.ffs_files[0],
                                      output_file="tmp.payload.bin")
            IPNAME_file = Path("tmp.payload.bin").resolve()

            # add to remove files
            to_remove.append("tmp.payload.bin")
        else:
            IPNAME_file = Path(args.IPNAME_IN.name).resolve()

        filenames = [str(IFWI_file), str(IPNAME_file)]
        if args.ipname in ["gop", "gfxpeim", "vbt"]:
            if not args.private_key or not os.path.exists(args.private_key):
                logger.critical(
                    "\nMissing RSA key to stitch GOP/PEIM GFX/VBT from command line\n"
                )
                parser.print_help()
                sys.exit(2)
            else:
                key_file = Path(args.private_key).resolve()
                status = utils.check_key(key_file, "rsa", logger)
                if status != 0:
                    sys.exit(status)
                filenames.append(key_file)

        # Verify file is not empty or the IP files are smaller than the input file
        status = utils.check_file_size(logger, filenames)
        if status != 0:
            sys.exit(status)

        # Copy key file to the required name needed for the rsa_helper.py
        if args.private_key:
            shutil.copyfile(key_file, os.path.join(TOOLS_DIR, "privkey.pem"))
            to_remove.append(os.path.join(TOOLS_DIR, 'privkey.pem'))
            filenames.remove(key_file)

        logger.info("*** Replacing {} ...".format(args.ipname))
        stitch_and_update(args.IFWI_IN.name, args.ipname, filenames, outfile)

        # Update OBB digest after stitching any data inside OBB region
        if args.ipname in ["gop", "vbt", "gfxpeim"]:

            if args.ipname == "gop":
                ipname = "obbdxe_digest"
                fv_list = [GUID_FVOSBOOT, GUID_FVUEFIBOOT, GUID_FVADVANCED]
            else:
                ipname = "obbpei_digest"
                fv_list = [GUID_FVPOSTMEMORY, GUID_FVFSPS]

            digest_file = "tmp.obb.hash.bin"

            to_remove.append(digest_file)

            calculate_new_obb_digest(outfile, fv_list, digest_file)

            filenames = [
                str(Path(f).resolve()) for f in [outfile, digest_file]
            ]

            logger.info("*** Replacing {} ...".format(ipname))
            stitch_and_update(outfile, ipname, filenames, outfile)
    finally:
        utils.cleanup(to_remove)