diff options
author | Ricardo Neri <ricardo.neri-calderon@linux.intel.com> | 2019-08-05 18:18:23 -0400 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-08-12 16:23:57 +0100 |
commit | 9b90717e9102a31dd8b99b16d62cd644091fd57e (patch) | |
tree | d2ec7b9abd1542350e672e02efbc860563157614 | |
parent | c7fb87ee6fb9cc4c6ed8bf93978445a0794e40aa (diff) | |
download | poky-9b90717e9102a31dd8b99b16d62cd644091fd57e.tar.gz |
runqemu: Add support to handle EnrollDefaultKeys PK/KEK1 certificate
The EnrollDefaultKeys.efi application (distributed in ovmf-shell-image)
expects the hypervisor to provide a Platform Key and first Key Exchange
Key certificate.
For QEMU, this is done by adding an OEM string in the Type 11 SMBIOS
table. The string contains the EnrollDefaultKeys application GUID followed
by the certificate string. For now, the string is passed in the command
line until QEMU understands OEM strings from regular files (please see
https://bugs.launchpad.net/qemu/+bug/1826200).
If runqemu detects it is given an OVMF binary with support for Secure Boot
(i.e., ovmf.secboot* binaries), extract the certificate string from the
OvmfPkKek1.pem certificate and modify the command-line parameters to
provide the key. Such certificate is created when building OVMF with
support for Secure Boot.
Cc: Ross Burton <ross.burton@intel.com>
Cc: Patrick Ohly <patrick.ohly@intel.com>
(From OE-Core rev: 5e47316ae62f7632fb62bc3b8093ac42f9e3541c)
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-x | scripts/runqemu | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/scripts/runqemu b/scripts/runqemu index 9d6a2e86d4..df3c8aad08 100755 --- a/scripts/runqemu +++ b/scripts/runqemu | |||
@@ -148,6 +148,10 @@ class BaseConfig(object): | |||
148 | # Setting one also adds "-vga std" because that is all that | 148 | # Setting one also adds "-vga std" because that is all that |
149 | # OVMF supports. | 149 | # OVMF supports. |
150 | self.ovmf_bios = [] | 150 | self.ovmf_bios = [] |
151 | # When enrolling default Secure Boot keys, the hypervisor | ||
152 | # must provide the Platform Key and the first Key Exchange Key | ||
153 | # certificate in the Type 11 SMBIOS table. | ||
154 | self.ovmf_secboot_pkkek1 = '' | ||
151 | self.qemuboot = '' | 155 | self.qemuboot = '' |
152 | self.qbconfload = False | 156 | self.qbconfload = False |
153 | self.kernel = '' | 157 | self.kernel = '' |
@@ -638,6 +642,23 @@ class BaseConfig(object): | |||
638 | if not os.path.exists(self.rootfs): | 642 | if not os.path.exists(self.rootfs): |
639 | raise RunQemuError("Can't find rootfs: %s" % self.rootfs) | 643 | raise RunQemuError("Can't find rootfs: %s" % self.rootfs) |
640 | 644 | ||
645 | def setup_pkkek1(self): | ||
646 | """ | ||
647 | Extract from PEM certificate the Platform Key and first Key | ||
648 | Exchange Key certificate string. The hypervisor needs to provide | ||
649 | it in the Type 11 SMBIOS table | ||
650 | """ | ||
651 | pemcert = '%s/%s' % (self.get('DEPLOY_DIR_IMAGE'), 'OvmfPkKek1.pem') | ||
652 | try: | ||
653 | with open(pemcert, 'r') as pemfile: | ||
654 | key = pemfile.read().replace('\n', ''). \ | ||
655 | replace('-----BEGIN CERTIFICATE-----', ''). \ | ||
656 | replace('-----END CERTIFICATE-----', '') | ||
657 | self.ovmf_secboot_pkkek1 = key | ||
658 | |||
659 | except FileNotFoundError: | ||
660 | raise RunQemuError("Can't open PEM certificate %s " % pemcert) | ||
661 | |||
641 | def check_ovmf(self): | 662 | def check_ovmf(self): |
642 | """Check and set full path for OVMF firmware and variable file(s).""" | 663 | """Check and set full path for OVMF firmware and variable file(s).""" |
643 | 664 | ||
@@ -648,6 +669,8 @@ class BaseConfig(object): | |||
648 | path = '%s/%s.%s' % (self.get('DEPLOY_DIR_IMAGE'), ovmf, suffix) | 669 | path = '%s/%s.%s' % (self.get('DEPLOY_DIR_IMAGE'), ovmf, suffix) |
649 | if os.path.exists(path): | 670 | if os.path.exists(path): |
650 | self.ovmf_bios[index] = path | 671 | self.ovmf_bios[index] = path |
672 | if ovmf.endswith('secboot'): | ||
673 | self.setup_pkkek1() | ||
651 | break | 674 | break |
652 | else: | 675 | else: |
653 | raise RunQemuError("Can't find OVMF firmware: %s" % ovmf) | 676 | raise RunQemuError("Can't find OVMF firmware: %s" % ovmf) |
@@ -914,6 +937,8 @@ class BaseConfig(object): | |||
914 | print('ROOTFS: [%s]' % self.rootfs) | 937 | print('ROOTFS: [%s]' % self.rootfs) |
915 | if self.ovmf_bios: | 938 | if self.ovmf_bios: |
916 | print('OVMF: %s' % self.ovmf_bios) | 939 | print('OVMF: %s' % self.ovmf_bios) |
940 | if (self.ovmf_secboot_pkkek1): | ||
941 | print('SECBOOT PKKEK1: [%s...]' % self.ovmf_secboot_pkkek1[0:100]) | ||
917 | print('CONFFILE: [%s]' % self.qemuboot) | 942 | print('CONFFILE: [%s]' % self.qemuboot) |
918 | print('') | 943 | print('') |
919 | 944 | ||
@@ -1262,6 +1287,13 @@ class BaseConfig(object): | |||
1262 | 1287 | ||
1263 | self.qemu_opt += ' ' + self.qemu_opt_script | 1288 | self.qemu_opt += ' ' + self.qemu_opt_script |
1264 | 1289 | ||
1290 | if self.ovmf_secboot_pkkek1: | ||
1291 | # Provide the Platform Key and first Key Exchange Key certificate as an | ||
1292 | # OEM string in the SMBIOS Type 11 table. Prepend the certificate string | ||
1293 | # with "application prefix" of the EnrollDefaultKeys.efi application | ||
1294 | self.qemu_opt += ' -smbios type=11,value=4e32566d-8e9e-4f52-81d3-5bb9715f9727:' \ | ||
1295 | + self.ovmf_secboot_pkkek1 | ||
1296 | |||
1265 | # Append qemuparams to override previous settings | 1297 | # Append qemuparams to override previous settings |
1266 | if self.qemuparams: | 1298 | if self.qemuparams: |
1267 | self.qemu_opt += ' ' + self.qemuparams | 1299 | self.qemu_opt += ' ' + self.qemuparams |