Message ID | 20220228114254.1099945-1-dovmurik@linux.ibm.com (mailing list archive) |
---|---|
Headers | show |
Series | Allow guest access to EFI confidential computing secret area | expand |
On Mon, Feb 28, 2022 at 11:42:50AM +0000, Dov Murik wrote: > Confidential computing (coco) hardware such as AMD SEV (Secure Encrypted > Virtualization) allows guest owners to inject secrets into the VMs > memory without the host/hypervisor being able to read them. In SEV, > secret injection is performed early in the VM launch process, before the > guest starts running. > > OVMF already reserves designated area for secret injection (in its > AmdSev package; see edk2 commit 01726b6d23d4 "OvmfPkg/AmdSev: Expose the > Sev Secret area using a configuration table" [1]), but the secrets were > not available in the guest kernel. > > The patch series keeps the address of the EFI-provided memory for > injected secrets, and exposes the secrets to userspace via securityfs > using a new efi_secret kernel module. The module is autoloaded (by the > EFI driver) if the secret area is populated. Right, so this thing. Tom and I were talking about SEV* guest debugging today and I believe there might be another use case for this: SEV-ES guests cannot find out from an attestation report - like SNP guests can - whether they're being debugged or not so it would be very helpful if the fact that a -ES guest is being debugged, could be supplied through such a secrets blob. Because then, when I'm singlestepping the guest with gdb over the gdbstub, the guest could determine based on those guest-owner previously injected secrets whether it should allow debugging or not. And this is where your set comes in. However, I'm wondering if - instead of defining your own secrets structs etc - you could use the SNP confidential computing blob machinery the SNP set is adding. In particular: https://lore.kernel.org/all/20220307213356.2797205-30-brijesh.singh@amd.com/ And you're adding another GUID but maybe you could simply use the SNP thing called EFI_CC_BLOB_GUID and mimick that layout. That should unify things more. And then guest kernel code could query the blob also for debugging policy and so on. Thoughts, opinions?
Hello Boris, On 24/03/2022 18:33, Borislav Petkov wrote: > On Mon, Feb 28, 2022 at 11:42:50AM +0000, Dov Murik wrote: >> Confidential computing (coco) hardware such as AMD SEV (Secure Encrypted >> Virtualization) allows guest owners to inject secrets into the VMs >> memory without the host/hypervisor being able to read them. In SEV, >> secret injection is performed early in the VM launch process, before the >> guest starts running. >> >> OVMF already reserves designated area for secret injection (in its >> AmdSev package; see edk2 commit 01726b6d23d4 "OvmfPkg/AmdSev: Expose the >> Sev Secret area using a configuration table" [1]), but the secrets were >> not available in the guest kernel. >> >> The patch series keeps the address of the EFI-provided memory for >> injected secrets, and exposes the secrets to userspace via securityfs >> using a new efi_secret kernel module. The module is autoloaded (by the >> EFI driver) if the secret area is populated. > > Right, so this thing. > > Tom and I were talking about SEV* guest debugging today and I believe > there might be another use case for this: SEV-ES guests cannot find out > from an attestation report - like SNP guests can - whether they're being > debugged or not so it would be very helpful if the fact that a -ES guest > is being debugged, could be supplied through such a secrets blob. > > Because then, when I'm singlestepping the guest with gdb over the > gdbstub, the guest could determine based on those guest-owner previously > injected secrets whether it should allow debugging or not. > Let's see if I understand this correctly: You want the guest to know if the its own SEV VM policy allows debugging. And that flag has to be trusted -- so passed from the Guest Owner in a secure channel (otherwise the host could set it to ALLOW_DEBUGGING even though the Guest Owner didn't approve that). > And this is where your set comes in. > > However, I'm wondering if - instead of defining your own secrets structs > etc - you could use the SNP confidential computing blob machinery the > SNP set is adding. In particular: > > https://lore.kernel.org/all/20220307213356.2797205-30-brijesh.singh@amd.com/ > > And you're adding another GUID but maybe you could simply use the SNP > thing called EFI_CC_BLOB_GUID and mimick that layout. > > That should unify things more. And then guest kernel code could query > the blob also for debugging policy and so on. > Maybe you could do that, but that will unify things that are not the same, so I think it is the wrong approach here. The SNP secrets are secrets generated by the AMD-SP and allow the guest to communicate with the PSP. There are exactly 4 of them (if I remember correctly) and they are only AES-256-GCM keys (if I remember correctly). On the other hand, the SEV launch secrets (which this series is about) are secrets populated by the Guest Owner and are intended for the proper operation of the applications in the guest (example use cases: luks passphrase, secret API keys, file decryption keys, encrypted container images keys, ...). The SEV launch secrets area can also be read by grub [1], for example, to fetch a luks passphrase from there (instead of from keyboard). That's why its structure is generic. [1] https://lists.gnu.org/archive/html/grub-devel/2022-02/msg00066.html > Thoughts, opinions? > I think Guest Owner can add a 1-byte predefined secret to the SEV secret table, let's say an entry with GUID 2b91a212-b0e1-4816-b021-1e9991ddb6af and value "\x01" to indicate debugging is allowed. With the efi_secrets module, a 1-byte file called /sys/kernel/security/secrets/coco/2b91a212-b0e1-4816-b021-1e9991ddb6af will appear with "\x01" in its content. This can indicate to the guest that debugging was permitted by the Guest Owner. If you want this unified in the kernel, maybe we can look for this entry and set the relevant kernel variable. -Dov
Hi Dov, On Tue, Mar 29, 2022 at 03:55:38PM +0300, Dov Murik wrote: > Let's see if I understand this correctly: > > You want the guest to know if the its own SEV VM policy allows > debugging. And that flag has to be trusted -- so passed from the Guest > Owner in a secure channel (otherwise the host could set it to > ALLOW_DEBUGGING even though the Guest Owner didn't approve that). Yeah, and then dump all the guest memory and thus bypass the whole memory encryption fun. So yeah, it should be encrypted and accessible only to the guest and supplied by the guest owner. > The SEV launch secrets area can also be read by grub [1], for example, > to fetch a luks passphrase from there (instead of from keyboard). > That's why its structure is generic. Ok, fair enough. > I think Guest Owner can add a 1-byte predefined secret to the SEV secret > table, let's say an entry with GUID 2b91a212-b0e1-4816-b021-1e9991ddb6af > and value "\x01" to indicate debugging is allowed. > > With the efi_secrets module, a 1-byte file called > /sys/kernel/security/secrets/coco/2b91a212-b0e1-4816-b021-1e9991ddb6af I'd love it if that were more user-friendly: /sys/kernel/security/secrets/coco/attributes and there's: debugging:1 ... and others. > will appear with "\x01" in its content. > > This can indicate to the guest that debugging was permitted by the Guest > Owner. But yeah, that should be the gist of the functionality. > If you want this unified in the kernel, maybe we can look for this entry > and set the relevant kernel variable. So now that I think of it, it would be even nicer if the fact whether guest debugging is allowed, were available to the guest *very early* during boot. Because I think the most important cases where you'd want to singlestep a SEV* guest with the qemu gdbstub is early guest kernel boot code. So it would be cool if we'd have access to the debugging setting that early. Lemme have a look at your patches in detail to get an idea what's happening there. Thx.
On 29/03/2022 21:30, Borislav Petkov wrote: > > So now that I think of it, it would be even nicer if the fact whether > guest debugging is allowed, were available to the guest *very early* > during boot. Because I think the most important cases where you'd want > to singlestep a SEV* guest with the qemu gdbstub is early guest kernel > boot code. So it would be cool if we'd have access to the debugging > setting that early. > > Lemme have a look at your patches in detail to get an idea what's > happening there. Is efi_config_parse_tables() early enough? That's where we learn for the first time that the firmware has a launch-secrets area that we can look at. We can add there (say, next to the call to efi_tpm_eventlog_init()) a code to: 1. map the secret area (ioremap_encrypted()) 2. parse the table, look for the "sev debug enabled" GUID. 3. set the value of the kernel variable that we can later use anywhere. Of course Ard might know about a better mechanism or place to do that. -Dov
On 29/03/2022 23:28, Dov Murik wrote: > > > On 29/03/2022 21:30, Borislav Petkov wrote: > >> >> So now that I think of it, it would be even nicer if the fact whether >> guest debugging is allowed, were available to the guest *very early* >> during boot. Because I think the most important cases where you'd want >> to singlestep a SEV* guest with the qemu gdbstub is early guest kernel >> boot code. So it would be cool if we'd have access to the debugging >> setting that early. >> >> Lemme have a look at your patches in detail to get an idea what's >> happening there. > After a night's sleep I figured out that an SEV guest cannot tell if a value it's reading was (a) encrypted by the host using KVM_SEV_LAUNCH_UPDATE_DATA, or (b) added using secret injection using KVM_SEV_LAUNCH_SECRET. The only difference is that if the host is using KVM_SEV_LAUNCH_UPDATE_DATA, then it changes the measurement. But maybe for debugging scenarios we (= Guest Owner) don't care about the measurement being correct. If that's the case, we don't need a secure channel and secret injection. You can use a simple "sev=debug" (or whatever) in the kernel command-line to indicate your needs. Did I miss something? -Dov
On Wed, Mar 30, 2022 at 09:11:54AM +0300, Dov Murik wrote: > If that's the case, we don't need a secure channel and secret injection. > You can use a simple "sev=debug" (or whatever) in the kernel > command-line to indicate your needs. Yeah, that would work for a normal SEV guest. However, if it is an -ES guest, you need to somehow tell it as the guest owner: "hey you're being debugged and that's fine." Because if you want to singlestep the thing, you're going to land in the #VC handler and destroy registers so you want to save them first if you're being debugged and then shovel them out to the host somehow. And that's another question but first things first. And "if you're being debugged" needs to be somehow told the guest through a secure channel so that the HV doesn't go and simply enable debugging by booting with "sev=debug" and bypass it all. And SNP has access to the policy in the attestation report, says Tom, so that's possible there. So we need a way to add the debugging aspect to the measurement and be able to recreate that measurement quickly so that a simple debugging session of a kernel in a guest can work pretty much the same with a SEV* guest. I'm still digging the details tho...
On 31/03/2022 12:19, Borislav Petkov wrote: > On Wed, Mar 30, 2022 at 09:11:54AM +0300, Dov Murik wrote: >> If that's the case, we don't need a secure channel and secret injection. >> You can use a simple "sev=debug" (or whatever) in the kernel >> command-line to indicate your needs. > > Yeah, that would work for a normal SEV guest. > > However, if it is an -ES guest, you need to somehow tell it as the guest > owner: "hey you're being debugged and that's fine." > > Because if you want to singlestep the thing, you're going to land in > the #VC handler and destroy registers so you want to save them first if > you're being debugged and then shovel them out to the host somehow. And > that's another question but first things first. > > And "if you're being debugged" needs to be somehow told the guest > through a secure channel so that the HV doesn't go and simply enable > debugging by booting with "sev=debug" and bypass it all. > Note that the HV can also start the VM with SEV completely turned off. Similarly, it can enable debugging and "fool" the guest. Of course all this tricks will affect the measurement, and then the Guest Owner will know that something is wrong and won't inject the secrets. If you don't rely on secret injection anyway, then I think a kernel command-line param is good enough. (I might be missing a scenario though) Maybe you can use KVM_SEV_GET_ATTESTATION_REPORT (ask the host to do it for you). But I think it returns only the launch digest, and you can't figure out the SEV Policy field from it. > And SNP has access to the policy in the attestation report, says Tom, so > that's possible there. True. But not in really early boot? This is all in the sev-guest platform driver. > > So we need a way to add the debugging aspect to the measurement and be > able to recreate that measurement quickly so that a simple debugging > session of a kernel in a guest can work pretty much the same with a SEV* > guest. > > I'm still digging the details tho... >