(Adding James, David, Daniel) On 01/07/21 09:30, Christophe de Dinechin wrote:
On 6 Jan 2021, at 19:44, Laszlo Ersek <lersek@redhat.com> wrote:
So, if you manage to reach the guest kernel in any way (regardless of SEV recognition) after launching OVMF with "-bios", that's evidence that your OVMF executable (OVMF_CODE.fd) is wrong. (As long as you care about Secure Boot at all, that is.)
Interesting. I'm using /usr/share/OVMF/OVMF_CODE.fd on Fedora 33.
That's great; Fedora 33 provides both kinds of firmware binaries. For example: edk2-20200801stable-3.fc33 https://koji.fedoraproject.org/koji/buildinfo?buildID=1655417 --> edk2-ovmf-20200801stable-3.fc33.noarch.rpm https://koji.fedoraproject.org/koji/rpminfo?rpmID=24208294 See the files: - OVMF_CODE.fd -> firmware binary built without the SMM+SB features - OVMF_CODE.secboot.fd -> firmware binary built with the SMM+SB features - OVMF_VARS.fd -> logically empty variable store template - OVMF_VARS.secboot.fd -> variable store template with MS certificates enrolled, and the SB operational mode enabled The package also contains the firmware descriptor files /usr/share/qemu/firmware/40-edk2-ovmf-x64-sb-enrolled.json /usr/share/qemu/firmware/50-edk2-ovmf-x64-sb.json /usr/share/qemu/firmware/60-edk2-ovmf-x64.json corresponding to the three use cases: - SB+SMM features present in executable, SB operational mode enabled in varstore template - SB+SMM features present in executable, SB operational mode disabled in varstore template - SB+SMM features absent, SB operational mode disabled in varstore template
Is there a doc / BZ / patch that could help me figure out the exact command-line syntax?
I have to take compatibility into account: kata runtime cannot restrict itself to the latest qemu.
Yes, there is comprehensive documentation. Please refer to the file docs/interop/firmware.json in the QEMU source tree. That file defines the *schema* to which the above three metadata (descriptor) files conform. Given a descriptor file, you can construct the corresponding QEMU command line, if you interpret it accordingly to the schema. Specifically, if you check the @FirmwareMappingFlash description, it explains the "-drive" related difference between QEMU 4.0+, and QEMU versions before that. (I didn't want to point you to this schema document at once, because reading through it will certainly require some time on your end. I figured I'd give you the end-result command line.)
Case #3: I don't want to build OVMF myself but rely on the distro's package.
Definitely -- that's the best case, but then: - your distro *must* provide a firmware *use case* descriptor file for each use case that it intends to support, - you need tooling that understand those descriptors, and implements the QEMU command lines accordingly, based on the schema that I linked above. To my knowledge, thus far libvirtd is the only such tool. Dan made sure we'd design the schema such that it is not tied to libvirt in any way -- other management applications are welcome to implement it --, it's just that thus far (to my understanding), only libvirtd has actual code for this.
Also, I don't know if SEV requires SecureBoot. I imagine it probably does, but I'm not sure. I sent another message involving Connor Kuehl, I'd like to build a mental map of the whole attestation process in the case of SEV.
Originally, Secure Boot is a privilege boundary *within* the guest, namely between: (a) the platform firmware (OVMF), and (b) 3rd party UEFI drivers (such as option ROMs for PCI devices), and also the guest OS. Basically the distrust exists between the platform firmware, and everything that is *not* the platform firmware -- all in the guest. Now, with SEV, Secure Boot gains *further* usefulness, but relatedly, it faces a new problem as well. Above, I mention "option ROM verification". Now, where do PCI device option ROMs come from? Usually, for emulated devices, from the host side (from the hypervisor). So, under the SEV threat model, where you distrust *the host* too, you can use Secure Boot in the guest to prevent this kind of code injection from the host -- you won't just run any UEFI driver from the PCI ROM BAR of a device, unless it is signed properly. And there comes the additional challenge -- the contents of the variable store file is also maintained on the host side. If you don't trust the host, then you can't trust the key material that's stored in the varstore file and used for SB verification. This problem should be covered in the remote attestation scenario though, where the guest owner uses a unified firmware image -- the executable and the varstore are fused into a single pflash chip --, and both of those logical halves are attested to in a single measurement. I guess it's possible that this "unified image" is actually the use case that you are after. Now, Fedora does not provide a unified image -- a unified image is certainly totally useless for the traditional use case, where you want each domain to have its own private varstore, but you want a system-wide firmware executable for *all* domains on the system, one that you can centrally upgrade with "yum". Still, if you'd like to test that setup with Kata, simply concatenate OVMF_VARS and OVMF_CODE (in this order), and use a single (read-write mapped) pflash chip with the resultant file. (BTW, this unified image is not expressible per the "docs/interop/firmware.json" schema, as -- again -- it is an extremely bad fit for the traditional virt host setup.) ... Anyway, another note regarding SB: note that direct kernel boot via fw-cfg does not undergo SB verification *at all*, so that should never be permitted in a SEV scenario. James Bottomley's remotely attested OVMF platform indeed removes the fw-cfg kernel boot path altogether from OVMF.
So, for starters, you need to know where your firmware executable (OVMF_CODE.fd) comes from -- that will tell you whether it even contains the SMM+SB *features*. If the answer is positive, you can consider the SB *operational mode*, which can be influenced by picking the right one of the variable store templates, as the origin for the domain's actual variable store file.
Is there an easy way to know which flags the OVMF_CODE.fd was built with?
Yes: just diff the following files on Fedora: /usr/share/qemu/firmware/40-edk2-ovmf-x64-sb-enrolled.json /usr/share/qemu/firmware/50-edk2-ovmf-x64-sb.json /usr/share/qemu/firmware/60-edk2-ovmf-x64.json pair-wise against each other, and then look up the differences in docs/interop/firmware.json in the QEMU tree. Thanks, Laszlo