diff --git a/LICENSE.qosb b/LICENSE.qosb
new file mode 100644
index 0000000..9849381
--- /dev/null
+++ b/LICENSE.qosb
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Patrick Uiterwijk
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/edk2.spec b/edk2.spec
index f0c5022..2e5598f 100644
--- a/edk2.spec
+++ b/edk2.spec
@@ -3,17 +3,14 @@
 %define TOOLCHAIN      GCC5
 %define OPENSSL_VER    1.1.1g
 
-%global qosb_version     20200228-gitc3e16b3
 %global softfloat_version 20180726-gitb64af41
 
-# Enable this to skip secureboot enrollment, if problems pop up
-%global skip_enroll 0
-
 %define qosb_testing 0
-
 %ifarch x86_64
 %define qosb_testing 1
 %endif
+%define qemu_binary /usr/bin/qemu-system-x86_64
+
 %if 0%{?fedora:1}
 %define cross 1
 %endif
@@ -53,21 +50,21 @@ URL:        http://www.tianocore.org
 Source0: edk2-%{GITCOMMIT}.tar.xz
 Source1: ovmf-whitepaper-c770f8c.txt
 Source2: openssl-rhel-bdd048e929dcfcf2f046d74e812e0e3d5fc58504.tar.xz
-#Source3:        https://github.com/puiterwijk/qemu-ovmf-secureboot/archive/v{qosb_version}/qemu-ovmf-secureboot-{qosb_version}.tar.gz
-Source3:        qemu-ovmf-secureboot-%{qosb_version}.tar.xz
-Source4:        softfloat-%{softfloat_version}.tar.xz
-Source5:        RedHatSecureBootPkKek1.pem
-Source11:       build-iso.sh
-
-# Fedora-specific JSON "descriptor files"
-Source14:       40-edk2-ovmf-x64-sb-enrolled.json
-Source15:       50-edk2-ovmf-x64-sb.json
-Source16:       60-edk2-ovmf-x64.json
-Source17:       40-edk2-ovmf-ia32-sb-enrolled.json
-Source18:       50-edk2-ovmf-ia32-sb.json
-Source19:       60-edk2-ovmf-ia32.json
-Source20:       70-edk2-aarch64-verbose.json
-Source21:       70-edk2-arm-verbose.json
+Source3: ovmf-vars-generator
+Source4: LICENSE.qosb
+Source5: RedHatSecureBootPkKek1.pem
+
+# Fedora specific sources
+Source50: softfloat-%{softfloat_version}.tar.xz
+Source51: build-iso.sh
+Source52: 40-edk2-ovmf-x64-sb-enrolled.json
+Source53: 50-edk2-ovmf-x64-sb.json
+Source54: 60-edk2-ovmf-x64.json
+Source55: 40-edk2-ovmf-ia32-sb-enrolled.json
+Source56: 50-edk2-ovmf-ia32-sb.json
+Source57: 60-edk2-ovmf-ia32.json
+Source58: 70-edk2-aarch64-verbose.json
+Source59: 70-edk2-arm-verbose.json
 
 # non-upstream patches
 Patch0008: 0008-BaseTools-do-not-build-BrotliCompress-RH-only.patch
@@ -126,18 +123,16 @@ BuildRequires:  findutils
 # These are for QOSB
 BuildRequires:  python3-requests
 BuildRequires:  qemu-system-x86
-%if %{?qosb_testing}
-# This is used for testing the enrollment: builds are run in a chroot, lacking
-# a kernel. The testing is only performed on x86_64 for now, but we can't make
-# the BuildRequires only on a specific arch, as that'd come through in the SRPM
-# NOTE: The actual enrollment needs to happen in all builds for all architectures,
-# because OVMF is built as noarch, which means that koji enforces that the build
-# results don't actually differ per arch, and then it picks a random arches' build
-# for the actual RPM.
-BuildRequires:  kernel-core
-%endif
 BuildRequires: make
 
+%if %{qosb_testing}
+# For verifying SB enablement in the above variable store template, we need a
+# guest kernel that prints "Secure boot enabled".
+BuildRequires: kernel-core >= 4.18.0-161
+BuildRequires: rpmdevtools
+%endif
+
+
 %description
 EDK II is a development code base for creating UEFI drivers, applications
 and firmware images.
@@ -239,26 +234,25 @@ git config am.keepcr true
 # -D is passed to %%setup to not delete the existing archive dir
 %autosetup -T -D -n edk2-%{GITCOMMIT} -S git_am
 
-# copy whitepaper into place
-cp -a -- %{SOURCE1} .
+cp -a -- %{SOURCE1} %{SOURCE3} .
 # extract openssl into place
 tar -C CryptoPkg/Library/OpensslLib -a -f %{SOURCE2} -x
 # extract softfloat into place
-tar -xf %{SOURCE4} --strip-components=1 --directory ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3/
-
-# Extract QOSB
-tar -xf %{SOURCE3}
-mv qemu-ovmf-secureboot-%{qosb_version}/README.md README.qosb
-mv qemu-ovmf-secureboot-%{qosb_version}/LICENSE LICENSE.qosb
-
-# Extract OEM string from the RH cert, as described here
-# https://bugzilla.tianocore.org/show_bug.cgi?id=1747#c2
+tar -xf %{SOURCE50} --strip-components=1 --directory ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3/
+
+# Format the Red Hat-issued certificate that is to be enrolled as both Platform
+# Key and first Key Exchange Key, as an SMBIOS OEM String. This means stripping
+# the PEM header and footer, and prepending the textual representation of the
+# GUID that identifies this particular OEM String to "EnrollDefaultKeys.efi",
+# plus the separator ":". For details, see
+# <https://bugzilla.tianocore.org/show_bug.cgi?id=1747> comments 2, 7, 14.
 sed \
   -e 's/^-----BEGIN CERTIFICATE-----$/4e32566d-8e9e-4f52-81d3-5bb9715f9727:/' \
   -e '/^-----END CERTIFICATE-----$/d' \
-  %{_sourcedir}/RedHatSecureBootPkKek1.pem \
-| tr -d '\n' \
-> PkKek1.oemstr
+  %{SOURCE5} \
+  > PkKek1.oemstr
+
+cp -a -- %{SOURCE4} .
 
 
 %build
@@ -325,20 +319,15 @@ cp Build/Ovmf3264/*/X64/Shell.efi ovmf/
 cp Build/Ovmf3264/*/X64/EnrollDefaultKeys.efi ovmf
 sh %{_sourcedir}/build-iso.sh ovmf/
 
-%if !%{skip_enroll}
-python3 qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator \
-    --qemu-binary /usr/bin/qemu-system-x86_64 \
-    --ovmf-binary ovmf/OVMF_CODE.secboot.fd \
+# Enroll the default certificates in a separate variable store template.
+%{__python3} ovmf-vars-generator --verbose --verbose \
+    --qemu-binary        %{qemu_binary} \
+    --ovmf-binary        ovmf/OVMF_CODE.secboot.fd \
     --ovmf-template-vars ovmf/OVMF_VARS.fd \
-    --uefi-shell-iso ovmf/UefiShell.iso \
-    --oem-string "$(< PkKek1.oemstr)" \
+    --uefi-shell-iso     ovmf/UefiShell.iso \
+    --oem-string         "$(< PkKek1.oemstr)" \
     --skip-testing \
     ovmf/OVMF_VARS.secboot.fd
-%else
-# This isn't going to actually give secureboot, but makes json files happy
-# if we need to test disabling ovmf-vars-generator
-cp ovmf/OVMF_VARS.fd ovmf/OVMF_VARS.secboot.fd
-%endif
 %endif
 
 
@@ -386,25 +375,25 @@ dd of="arm/vars-template-pflash.raw" if="/dev/zero" bs=1M count=64
 
 
 %check
-%if 0%{?build_ovmf_x64:1}
-%if 0%{?qosb_testing}
-%if !%{skip_enroll}
-KERNELPATH="$(find /lib/modules -name vmlinuz | head -1)"
-python3 qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator \
-    --qemu-binary /usr/bin/qemu-system-x86_64 \
-    --ovmf-binary ovmf/OVMF_CODE.secboot.fd \
-    --ovmf-template-vars ovmf/OVMF_VARS.fd \
-    --uefi-shell-iso ovmf/UefiShell.iso \
-    --skip-enrollment \
-    --print-output \
-    --no-download \
-    -vv \
-    --kernel-path "$KERNELPATH" \
-    ovmf/OVMF_VARS.secboot.fd
-%endif
-%endif
-%endif
 
+%if %{qosb_testing}
+# Of the installed host kernels, boot the one with the highest Version-Release
+# under OVMF, and check if it prints "Secure boot enabled".
+KERNEL_PKG=$(rpm -q kernel-core | rpmdev-sort | tail -n 1)
+KERNEL_IMG=$(rpm -q -l $KERNEL_PKG | egrep '^/lib/modules/[^/]+/vmlinuz$')
+
+%{__python3} ovmf-vars-generator --verbose --verbose \
+  --qemu-binary        %{qemu_binary} \
+  --ovmf-binary        ovmf/OVMF_CODE.secboot.fd \
+  --ovmf-template-vars ovmf/OVMF_VARS.fd \
+  --uefi-shell-iso     ovmf/UefiShell.iso \
+  --kernel-path        $KERNEL_IMG \
+  --skip-enrollment \
+  --no-download \
+  ovmf/OVMF_VARS.secboot.fd
+
+# endif qosb_testing
+%endif
 
 
 %install
@@ -490,8 +479,7 @@ done
 %py_byte_compile %{python3} %{buildroot}%{_datadir}/edk2/Python
 %endif
 
-
-install qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator %{buildroot}%{_bindir}
+install -p ovmf-vars-generator %{buildroot}%{_bindir}
 
 
 %files tools
@@ -533,7 +521,6 @@ install qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator %{buildroot}%{_
 
 %files qosb
 %license LICENSE.qosb
-%doc README.qosb
 %{_bindir}/ovmf-vars-generator
 
 %if 0%{?build_ovmf_x64:1}
diff --git a/ovmf-vars-generator b/ovmf-vars-generator
new file mode 100755
index 0000000..111e438
--- /dev/null
+++ b/ovmf-vars-generator
@@ -0,0 +1,295 @@
+#!/bin/python3
+# 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')
+
+    if args.oem_string is None:
+        oemstrings = []
+    else:
+        oemstring_values = [
+            ",value=" + s.replace(",", ",,") for s in args.oem_string ]
+        oemstrings = [
+            '-smbios',
+            "type=11" + ''.join(oemstring_values) ]
+
+    return [
+        args.qemu_binary,
+        '-machine', machinetype,
+        '-display', 'none',
+        '-no-user-config',
+        '-nodefaults',
+        '-m', '768',
+        '-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'] + oemstrings + 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()
+    # Skip passed QEMU warnings, like the following one we see in Ubuntu:
+    # qemu-system-x86_64: warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
+    while b'qemu-system-x86_64: warning:' 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')
+    parser.add_argument('--oem-string',
+                        help=('Pass the argument to the guest as a string in '
+                              'the SMBIOS Type 11 (OEM Strings) table. '
+                              'Multiple occurrences of this option are '
+                              'collected into a single SMBIOS Type 11 table. '
+                              'A pure ASCII string argument is strongly '
+                              'suggested.'),
+                        action='append')
+    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()
diff --git a/sources b/sources
index 38b6e11..ee5edd1 100644
--- a/sources
+++ b/sources
@@ -1,5 +1,4 @@
 SHA512 (softfloat-20180726-gitb64af41.tar.xz) = f079debd1bfcc0fe64329a8947b0689ef49246793edcdd28a2879f6550c652b0cf0f53ac4f6f5ab61ac4f7933972e0019d0ab63eb9931b6884c2909f3a5ead30
-SHA512 (qemu-ovmf-secureboot-20200228-gitc3e16b3.tar.xz) = 123889b9277adda472035f72e4836b6fe8e0cd8e2e87d28400bbc846ea1308378fc7aae413d463e0c1bfda096d85e51be100eb8d7dfb0738707c3412f2855711
 SHA512 (openssl-rhel-a75722161d20fd632f8875585d3aa066ec5fea93.tar.xz) = f88284054e33921fbebfad973abe83b83528e88b4b07b21b0c4999c07e7cb95270817144122209f4bf992deb96684d9fd2e871c63aa563cf39d14b087decf907
 SHA512 (edk2-e1999b264f1f.tar.xz) = 323e28ae205e0aa670674e1bd39845f942331348da34a3c48a9ec7da1d3e617b0abf1c52347c818ea84e7218b74760cbeb4ba761656919748f799b984ab04e6a
 SHA512 (openssl-rhel-bdd048e929dcfcf2f046d74e812e0e3d5fc58504.tar.xz) = d6c0be28cefaa7993f479aecf45f5523e10aab388a92c3e4add55d6ff8483cc01fba367be62f6e9a23bfad7b46986befd3eca0d0e89b984049719645e37d52df