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))
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)