Browse Source

ovmf package update (changed from edk2-ovmf)

Signed-off-by: virtbuilder_pel7x64builder0 <virtbuilder@powerel.org>
master
virtbuilder_pel7x64builder0 5 years ago
parent
commit
cdf157f9f2
  1. BIN
      SOURCES/edk2-ovmf-logo.bmp
  2. 273
      SOURCES/ovmf-vars-generator
  3. 151
      SPECS/ovmf.spec

BIN
SOURCES/edk2-ovmf-logo.bmp

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

273
SOURCES/ovmf-vars-generator

@ -0,0 +1,273 @@ @@ -0,0 +1,273 @@
#!/bin/python
# Copyright (C) 2017 Red Hat
# Authors:
# - Patrick Uiterwijk <puiterwijk@redhat.com>
# - Kashyap Chamarthy <kchamart@redhat.com>
#
# Licensed under MIT License, for full text see LICENSE
#
# Purpose: Launch a QEMU guest and enroll ithe UEFI keys into an OVMF
# variables ("VARS") file. Then boot a Linux kernel with QEMU.
# Finally, perform a check to verify if Secure Boot
# is enabled.

from __future__ import print_function

import argparse
import os
import logging
import tempfile
import shutil
import string
import subprocess


def strip_special(line):
return ''.join([c for c in str(line) if c in string.printable])


def generate_qemu_cmd(args, readonly, *extra_args):
if args.disable_smm:
machinetype = 'pc'
else:
machinetype = 'q35,smm=on'
machinetype += ',accel=%s' % ('kvm' if args.enable_kvm else 'tcg')
return [
args.qemu_binary,
'-machine', machinetype,
'-display', 'none',
'-no-user-config',
'-nodefaults',
'-m', '256',
'-smp', '2,sockets=2,cores=1,threads=1',
'-chardev', 'pty,id=charserial1',
'-device', 'isa-serial,chardev=charserial1,id=serial1',
'-global', 'driver=cfi.pflash01,property=secure,value=%s' % (
'off' if args.disable_smm else 'on'),
'-drive',
'file=%s,if=pflash,format=raw,unit=0,readonly=on' % (
args.ovmf_binary),
'-drive',
'file=%s,if=pflash,format=raw,unit=1,readonly=%s' % (
args.out_temp, 'on' if readonly else 'off'),
'-serial', 'stdio'] + list(extra_args)


def download(url, target, suffix, no_download):
istemp = False
if target and os.path.exists(target):
return target, istemp
if not target:
temped = tempfile.mkstemp(prefix='qosb.', suffix='.%s' % suffix)
os.close(temped[0])
target = temped[1]
istemp = True
if no_download:
raise Exception('%s did not exist, but downloading was disabled' %
target)
import requests
logging.debug('Downloading %s to %s', url, target)
r = requests.get(url, stream=True)
with open(target, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
return target, istemp


def enroll_keys(args):
shutil.copy(args.ovmf_template_vars, args.out_temp)

logging.info('Starting enrollment')

cmd = generate_qemu_cmd(
args,
False,
'-drive',
'file=%s,format=raw,if=none,media=cdrom,id=drive-cd1,'
'readonly=on' % args.uefi_shell_iso,
'-device',
'ide-cd,drive=drive-cd1,id=cd1,'
'bootindex=1')
p = subprocess.Popen(cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
logging.info('Performing enrollment')
# Wait until the UEFI shell starts (first line is printed)
read = p.stdout.readline()
#if b'char device redirected' in read:
# read = p.stdout.readline()
#if args.print_output:
# print(strip_special(read), end='')
# print()
# Send the escape char to enter the UEFI shell early
p.stdin.write(b'\x1b')
p.stdin.flush()
# And then run the following three commands from the UEFI shell:
# change into the first file system device; install the default
# keys and certificates, and reboot
p.stdin.write(b'fs0:\r\n')
p.stdin.write(b'EnrollDefaultKeys.efi\r\n')
p.stdin.write(b'reset -s\r\n')
p.stdin.flush()
#while True:
# read = p.stdout.readline()
# if args.print_output:
# print('OUT: %s' % strip_special(read), end='')
# print()
# if b'info: success' in read:
# break
#p.wait()
if args.print_output:
print(strip_special(p.stdout.read()), end='')
logging.info('Finished enrollment')


def test_keys(args):
logging.info('Grabbing test kernel')
kernel, kerneltemp = download(args.kernel_url, args.kernel_path,
'kernel', args.no_download)

logging.info('Starting verification')
try:
cmd = generate_qemu_cmd(
args,
True,
'-append', 'console=tty0 console=ttyS0,115200n8',
'-kernel', kernel)
p = subprocess.Popen(cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
logging.info('Performing verification')
while True:
read = p.stdout.readline()
if args.print_output:
print('OUT: %s' % strip_special(read), end='')
print()
if b'Secure boot disabled' in read:
raise Exception('Secure Boot was disabled')
elif b'Secure boot enabled' in read:
logging.info('Confirmed: Secure Boot is enabled')
break
elif b'Kernel is locked down from EFI secure boot' in read:
logging.info('Confirmed: Secure Boot is enabled')
break
p.kill()
if args.print_output:
print(strip_special(p.stdout.read()), end='')
logging.info('Finished verification')
finally:
if kerneltemp:
os.remove(kernel)


def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('output', help='Filename for output vars file')
parser.add_argument('--out-temp', help=argparse.SUPPRESS)
parser.add_argument('--force', help='Overwrite existing output file',
action='store_true')
parser.add_argument('--print-output', help='Print the QEMU guest output',
action='store_true')
parser.add_argument('--verbose', '-v', help='Increase verbosity',
action='count')
parser.add_argument('--quiet', '-q', help='Decrease verbosity',
action='count')
parser.add_argument('--qemu-binary', help='QEMU binary path',
default='/usr/bin/qemu-system-x86_64')
parser.add_argument('--enable-kvm', help='Enable KVM acceleration',
action='store_true')
parser.add_argument('--ovmf-binary', help='OVMF secureboot code file',
default='/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd')
parser.add_argument('--ovmf-template-vars', help='OVMF empty vars file',
default='/usr/share/edk2/ovmf/OVMF_VARS.fd')
parser.add_argument('--uefi-shell-iso', help='Path to uefi shell iso',
default='/usr/share/edk2/ovmf/UefiShell.iso')
parser.add_argument('--skip-enrollment',
help='Skip enrollment, only test', action='store_true')
parser.add_argument('--skip-testing',
help='Skip testing generated "VARS" file',
action='store_true')
parser.add_argument('--kernel-path',
help='Specify a consistent path for kernel')
parser.add_argument('--no-download', action='store_true',
help='Never download a kernel')
parser.add_argument('--fedora-version',
help='Fedora version to get kernel for checking',
default='27')
parser.add_argument('--kernel-url', help='Kernel URL',
default='https://download.fedoraproject.org/pub/fedora'
'/linux/releases/%(version)s/Everything/x86_64'
'/os/images/pxeboot/vmlinuz')
parser.add_argument('--disable-smm',
help=('Don\'t restrict varstore pflash writes to '
'guest code that executes in SMM. Use this '
'option only if your OVMF binary doesn\'t have '
'the edk2 SMM driver stack built into it '
'(possibly because your QEMU binary lacks SMM '
'emulation). Note that without restricting '
'varstore pflash writes to guest code that '
'executes in SMM, a malicious guest kernel, '
'used for testing, could undermine Secure '
'Boot.'),
action='store_true')
args = parser.parse_args()
args.kernel_url = args.kernel_url % {'version': args.fedora_version}

validate_args(args)
return args


def validate_args(args):
if (os.path.exists(args.output)
and not args.force
and not args.skip_enrollment):
raise Exception('%s already exists' % args.output)

if args.skip_enrollment and not os.path.exists(args.output):
raise Exception('%s does not yet exist' % args.output)

verbosity = (args.verbose or 1) - (args.quiet or 0)
if verbosity >= 2:
logging.basicConfig(level=logging.DEBUG)
elif verbosity == 1:
logging.basicConfig(level=logging.INFO)
elif verbosity < 0:
logging.basicConfig(level=logging.ERROR)
else:
logging.basicConfig(level=logging.WARN)

if args.skip_enrollment:
args.out_temp = args.output
else:
temped = tempfile.mkstemp(prefix='qosb.', suffix='.vars')
os.close(temped[0])
args.out_temp = temped[1]
logging.debug('Temp output: %s', args.out_temp)


def move_to_dest(args):
shutil.copy(args.out_temp, args.output)
os.remove(args.out_temp)


def main():
args = parse_args()
if not args.skip_enrollment:
enroll_keys(args)
if not args.skip_testing:
test_keys(args)
if not args.skip_enrollment:
move_to_dest(args)
if args.skip_testing:
logging.info('Created %s' % args.output)
else:
logging.info('Created and verified %s' % args.output)
else:
logging.info('Verified %s', args.output)


if __name__ == '__main__':
main()

151
SPECS/ovmf.spec

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
%global debug_package %{nil}
%global __python %{__python}
%define GITDATE 201905
%define OPENSSLVER 1_1_1b

Name: ovmf
Version: %{GITDATE}
Release: 1%{?dist}
Summary: UEFI firmware for 64-bit virtual machines
Group: Applications/Emulators
License: BSD and OpenSSL and MIT
URL: http://www.tianocore.org
Source0: https://github.com/tianocore/edk2/archive/edk2-stable%{GITDATE}.tar.gz
Source1: https://github.com/openssl/openssl/archive/OpenSSL_%{OPENSSLVER}.tar.gz
Source2: ovmf-vars-generator
Source3: edk2-ovmf-logo.bmp
ExclusiveArch: x86_64
BuildRequires: python2-devel
BuildRequires: libuuid-devel
BuildRequires: /usr/bin/iasl
BuildRequires: binutils gcc git
BuildRequires: nasm
BuildRequires: dosfstools
BuildRequires: mtools
BuildRequires: genisoimage
BuildRequires: qemu-kvm >= 1.5.3-44
BuildRequires: kernel >= 3.10.0-52
BuildRequires: rpmdevtools


%description
EDK II is a modern, feature-rich, cross-platform firmware development
environment for the UEFI and PI specifications. This package contains sample
64-bit UEFI firmware builds for QEMU and KVM.


%prep
%setup -q -n edk2-edk2-stable%{GITDATE}
tar xvf %{SOURCE1} -C CryptoPkg/Library/OpensslLib/
mv CryptoPkg/Library/OpensslLib/openssl-OpenSSL_%{OPENSSLVER}/* CryptoPkg/Library/OpensslLib/openssl/
cp %{SOURCE2} .
cp %{SOURCE3} MdeModulePkg/Logo/Logo.bmp


%build
make -j32 -C BaseTools/
source ./edksetup.sh
make -C "$EDK_TOOLS_PATH"

SMP_MFLAGS="%{?_smp_mflags}"
if [[ x"$SMP_MFLAGS" = x-j* ]]; then
CC_FLAGS="$CC_FLAGS -n ${SMP_MFLAGS#-j}"
elif [ -n "%{?jobs}" ]; then
CC_FLAGS="$CC_FLAGS -n %{?jobs}"
fi

CC_FLAGS="$CC_FLAGS --cmd-len=65536 -t GCC48 -b DEBUG --hash"

# Build with SB but without SMM; include UEFI shell.
build ${CC_FLAGS} -D FD_SIZE_4MB -a X64 -p OvmfPkg/OvmfPkgX64.dsc -D SECURE_BOOT_ENABLE
# Build with SB and SMM; exclude UEFI shell.
build -D SECURE_BOOT_ENABLE -D EXCLUDE_SHELL_FROM_FD ${CC_FLAGS} -a IA32 -a X64 -p OvmfPkg/OvmfPkgIa32X64.dsc -D SMM_REQUIRE -D FD_SIZE_4MB
# Sanity check: the varstore templates must be identical.
cmp Build/OvmfX64/DEBUG_GCC4?/FV/OVMF_VARS.fd Build/Ovmf3264/DEBUG_GCC4?/FV/OVMF_VARS.fd

# Prepare an ISO image that boots the UEFI shell.
(
UEFI_SHELL_BINARY=Build/Ovmf3264/DEBUG_GCC48/X64/Shell.efi
ENROLLER_BINARY=Build/Ovmf3264/DEBUG_GCC48/X64/EnrollDefaultKeys.efi
UEFI_SHELL_IMAGE=uefi_shell.img
ISO_IMAGE=UefiShell.iso

UEFI_SHELL_BINARY_BNAME=$(basename -- "$UEFI_SHELL_BINARY")
UEFI_SHELL_SIZE=$(stat --format=%s -- "$UEFI_SHELL_BINARY")
ENROLLER_SIZE=$(stat --format=%s -- "$ENROLLER_BINARY")

# add 1MB then 10% for metadata
UEFI_SHELL_IMAGE_KB=$((
(UEFI_SHELL_SIZE + ENROLLER_SIZE + 1 * 1024 * 1024) * 11 / 10 / 1024
))

# create non-partitioned FAT image
rm -f -- "$UEFI_SHELL_IMAGE"
mkdosfs -C "$UEFI_SHELL_IMAGE" -n UEFI_SHELL -- "$UEFI_SHELL_IMAGE_KB"

# copy the shell binary into the FAT image
export MTOOLS_SKIP_CHECK=1
mmd -i "$UEFI_SHELL_IMAGE" ::efi
mmd -i "$UEFI_SHELL_IMAGE" ::efi/boot
mcopy -i "$UEFI_SHELL_IMAGE" "$UEFI_SHELL_BINARY" ::efi/boot/bootx64.efi
mcopy -i "$UEFI_SHELL_IMAGE" "$ENROLLER_BINARY" ::
mdir -i "$UEFI_SHELL_IMAGE" -/ ::

# build ISO with FAT image file as El Torito EFI boot image
genisoimage -input-charset ASCII -J -rational-rock \
-efi-boot "$UEFI_SHELL_IMAGE" -no-emul-boot \
-o "$ISO_IMAGE" -- "$UEFI_SHELL_IMAGE"
)

# Enroll the default certificates in a separate variable store template. Base
# RHEL7 qemu-kvm does not emulate SMM, but we don't need SMM for the enrollment
# here.
chmod +x ./ovmf-vars-generator
./ovmf-vars-generator --verbose --verbose \
--qemu-binary /usr/bin/qemu-system-x86_64 \
--ovmf-binary Build/OvmfX64/DEBUG_GCC4?/FV/OVMF_CODE.fd \
--ovmf-template-vars Build/OvmfX64/DEBUG_GCC4?/FV/OVMF_VARS.fd \
--uefi-shell-iso UefiShell.iso \
--skip-testing \
--disable-smm \
OVMF_VARS.secboot.fd


%install

copy_license() {
install -m 0644 $1 $RPM_BUILD_ROOT%{_docdir}/%{name}/Licenses/$2-License.txt
}

mkdir -p $RPM_BUILD_ROOT%{_docdir}/%{name}/Licenses
copy_license License.txt edk2
copy_license OvmfPkg/License.txt OvmfPkg

mkdir -p $RPM_BUILD_ROOT%{_datadir}/OVMF

install -m 0644 Build/OvmfX64/DEBUG_GCC4?/FV/OVMF_CODE.fd $RPM_BUILD_ROOT%{_datadir}/OVMF/OVMF_CODE.fd
install -m 0644 Build/Ovmf3264/DEBUG_GCC4?/FV/OVMF_CODE.fd $RPM_BUILD_ROOT%{_datadir}/OVMF/OVMF_CODE.secboot.fd
install -m 0644 Build/OvmfX64/DEBUG_GCC4?/FV/OVMF_VARS.fd $RPM_BUILD_ROOT%{_datadir}/OVMF/OVMF_VARS.fd
install -m 0644 OVMF_VARS.secboot.fd $RPM_BUILD_ROOT%{_datadir}/OVMF/OVMF_VARS.secboot.fd
install -m 0644 UefiShell.iso $RPM_BUILD_ROOT%{_datadir}/OVMF/UefiShell.iso
install -m 0644 OvmfPkg/README $RPM_BUILD_ROOT%{_docdir}/%{name}/README

copy_license CryptoPkg/Library/OpensslLib/openssl/LICENSE OpensslLib


%files
%defattr(-,root,root,-)
%dir %{_docdir}/%{name}/Licenses
%doc %{_docdir}/%{name}/Licenses/edk2-License.txt
%doc %{_docdir}/%{name}/Licenses/OvmfPkg-License.txt
%doc %{_docdir}/%{name}/Licenses/OpensslLib-License.txt
%doc %{_docdir}/%{name}/README
%dir %{_datadir}/OVMF/
%{_datadir}/OVMF/OVMF_CODE.fd
%{_datadir}/OVMF/OVMF_CODE.secboot.fd
%{_datadir}/OVMF/OVMF_VARS.fd
%{_datadir}/OVMF/OVMF_VARS.secboot.fd
%{_datadir}/OVMF/UefiShell.iso


%changelog
Loading…
Cancel
Save