Message ID | 20211129114251.3741721-1-dovmurik@linux.ibm.com |
---|---|
Headers | show |
Series | Allow guest access to EFI confidential computing secret area | expand |
Gentle ping for this series. (also at https://lore.kernel.org/linux-coco/20211129114251.3741721-1-dovmurik@linux.ibm.com/ ) [+cc Gerd, Lenny] Thanks, -Dov On 29/11/2021 13:42, 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. > > The first patch in EFI keeps the address of the secret area as passed in > the EFI configuration table. The second patch is a quirk fix for older > firmwares didn't mark the secrets page as EFI_RESERVED_TYPE. The third > patch introduces the new efi_secret module that exposes the content of > the secret entries as securityfs files, and allows clearing out secrets > with a file unlink interface. The fourth patch auto-loads the > efi_secret module during startup if the injected secrets area is > populated. The last patch documents the data flow of confidential > computing secret injection. > > As a usage example, consider a guest performing computations on > encrypted files. The Guest Owner provides the decryption key (= secret) > using the secret injection mechanism. The guest application reads the > secret from the efi_secret filesystem and proceeds to decrypt the files > into memory and then performs the needed computations on the content. > > In this example, the host can't read the files from the disk image > because they are encrypted. Host can't read the decryption key because > it is passed using the secret injection mechanism (= secure channel). > Host can't read the decrypted content from memory because it's a > confidential (memory-encrypted) guest. > > This has been tested with AMD SEV and SEV-ES guests, but the kernel side > of handling the secret area has no SEV-specific dependencies, and > therefore might be usable (perhaps with minor changes) for any > confidential computing hardware that can publish the secret area via the > standard EFI config table entry. > > To enable this functionality, set CONFIG_EFI_SECRET=m when building the > guest kernel. > > Here is a simple example for usage of the efi_secret module in a guest > to which an EFI secret area with 4 secrets was injected during launch: > > # ls -la /sys/kernel/security/coco/efi_secret > total 0 > drwxr-xr-x 2 root root 0 Jun 28 11:54 . > drwxr-xr-x 3 root root 0 Jun 28 11:54 .. > -r--r----- 1 root root 0 Jun 28 11:54 736870e5-84f0-4973-92ec-06879ce3da0b > -r--r----- 1 root root 0 Jun 28 11:54 83c83f7f-1356-4975-8b7e-d3a0b54312c6 > -r--r----- 1 root root 0 Jun 28 11:54 9553f55d-3da2-43ee-ab5d-ff17f78864d2 > -r--r----- 1 root root 0 Jun 28 11:54 e6f5a162-d67f-4750-a67c-5d065f2a9910 > > # xxd /sys/kernel/security/coco/efi_secret/e6f5a162-d67f-4750-a67c-5d065f2a9910 > 00000000: 7468 6573 652d 6172 652d 7468 652d 6b61 these-are-the-ka > 00000010: 7461 2d73 6563 7265 7473 0001 0203 0405 ta-secrets...... > 00000020: 0607 .. > > # rm /sys/kernel/security/coco/efi_secret/e6f5a162-d67f-4750-a67c-5d065f2a9910 > > # ls -la /sys/kernel/security/coco/efi_secret > total 0 > drwxr-xr-x 2 root root 0 Jun 28 11:55 . > drwxr-xr-x 3 root root 0 Jun 28 11:54 .. > -r--r----- 1 root root 0 Jun 28 11:54 736870e5-84f0-4973-92ec-06879ce3da0b > -r--r----- 1 root root 0 Jun 28 11:54 83c83f7f-1356-4975-8b7e-d3a0b54312c6 > -r--r----- 1 root root 0 Jun 28 11:54 9553f55d-3da2-43ee-ab5d-ff17f78864d2 > > > [1] https://github.com/tianocore/edk2/commit/01726b6d23d4 > > > --- > > v6 changes: > - Autoload the efi_secret module if the secret area is populated > (thanks Greg KH). > - efi_secret: Depend on X86_64 because we use ioremap_encrypted() which > is only defined for this arch. > - efi_secret.c: Remove unneeded tableheader_guid local variable. > - Documentation fixes. > > v5: https://lore.kernel.org/linux-coco/20211118113359.642571-1-dovmurik@linux.ibm.com/ > v5 changes: > - Simplify EFI code: instead of copying the secret area, the firmware > marks the secret area as EFI_RESERVED_TYPE, and then the uefi_init() > code just keeps the pointer as it appears in the EFI configuration > table. The use of reserved pages is similar to the AMD SEV-SNP > patches for handling SNP-Secrets and SNP-CPUID pages. > - In order to handle OVMF releases out there which mark the > confidential computing secrets page as EFI_BOOT_SERVICES_DATA, add > efi/libstub code that detects this and fixes the E820 map to reserve > this page. > - In the efi_secret module code, map the secrets page using > ioremap_encrypted (again, similar to the AMD SEV-SNP guest patches > for accessing SNP-Secrets and SNP-CPUID pages). > - Add documentation in Documentation/security/coco/efi_secret. > > v4: https://lore.kernel.org/linux-coco/20211020061408.3447533-1-dovmurik@linux.ibm.com/ > v4 changes: > - Guard all the new EFI and efi-stub code (patches 1+2) with #ifdef > CONFIG_EFI_COCO_SECRET (thanks Greg KH). Selecting > CONFIG_EFI_SECRET=m (patch 3) will enable the EFI parts as well. > - Guard call to clflush_cache_range() with #ifdef CONFIG_X86 > (Reported-by: kernel test robot <lkp@intel.com>) > > v3: https://lore.kernel.org/linux-coco/20211014130848.592611-1-dovmurik@linux.ibm.com/ > v3 changes: > - Rename the module to efi_secret > - Remove the exporting of clean_cache_range > - Use clflush_cache_range in wipe_memory > - Document function wipe_memory > - Initialize efi.coco_secret to EFI_INVALID_TABLE_ADDR to correctly detect > when there's no secret area published in the EFI configuration tables > > v2: https://lore.kernel.org/linux-coco/20211007061838.1381129-1-dovmurik@linux.ibm.com > v2 changes: > - Export clean_cache_range() > - When deleteing a secret, call clean_cache_range() after explicit_memzero > - Add Documentation/ABI/testing/securityfs-coco-sev_secret > > v1: https://lore.kernel.org/linux-coco/20210809190157.279332-1-dovmurik@linux.ibm.com/ > > RFC: https://lore.kernel.org/linux-coco/20210628183431.953934-1-dovmurik@linux.ibm.com/ > > > Dov Murik (5): > efi: Save location of EFI confidential computing area > efi/libstub: Reserve confidential computing secret area > virt: Add efi_secret module to expose confidential computing secrets > efi: Load efi_secret module if EFI secret area is populated > docs: security: Add coco/efi_secret documentation > > .../ABI/testing/securityfs-coco-efi_secret | 51 +++ > Documentation/security/coco/efi_secret.rst | 102 ++++++ > Documentation/security/coco/index.rst | 9 + > Documentation/security/index.rst | 1 + > arch/x86/platform/efi/efi.c | 3 + > drivers/firmware/efi/Kconfig | 16 + > drivers/firmware/efi/Makefile | 1 + > drivers/firmware/efi/coco.c | 58 +++ > drivers/firmware/efi/efi.c | 6 + > drivers/firmware/efi/libstub/x86-stub.c | 28 ++ > drivers/virt/Kconfig | 3 + > drivers/virt/Makefile | 1 + > drivers/virt/coco/efi_secret/Kconfig | 14 + > drivers/virt/coco/efi_secret/Makefile | 2 + > drivers/virt/coco/efi_secret/efi_secret.c | 337 ++++++++++++++++++ > include/linux/efi.h | 10 + > 16 files changed, 642 insertions(+) > create mode 100644 Documentation/ABI/testing/securityfs-coco-efi_secret > create mode 100644 Documentation/security/coco/efi_secret.rst > create mode 100644 Documentation/security/coco/index.rst > create mode 100644 drivers/firmware/efi/coco.c > create mode 100644 drivers/virt/coco/efi_secret/Kconfig > create mode 100644 drivers/virt/coco/efi_secret/Makefile > create mode 100644 drivers/virt/coco/efi_secret/efi_secret.c > > > base-commit: 42eb8fdac2fc5d62392dcfcf0253753e821a97b0
On Mon, Nov 29, 2021 at 11:42:46AM +0000, Dov Murik wrote: > As a usage example, consider a guest performing computations on > encrypted files. The Guest Owner provides the decryption key (= secret) > using the secret injection mechanism. The guest application reads the > secret from the efi_secret filesystem and proceeds to decrypt the files > into memory and then performs the needed computations on the content. > > In this example, the host can't read the files from the disk image > because they are encrypted. Host can't read the decryption key because > it is passed using the secret injection mechanism (= secure channel). > Host can't read the decrypted content from memory because it's a > confidential (memory-encrypted) guest. So maybe I don't understand the example properly or something's missing but why can't the guest owner simply scp the secrets into the guest? Why is this special thing needed? The secret below says "...kata-secrets" so this sounds like something-automated-containers-thing where they'd profit from getting secrets automatically supplied to the guest. But I guess there you can scp too... So what am I missing? Thx.
On Tue, Jan 04, 2022 at 09:02:03AM +0200, Dov Murik wrote: > If the Guest Owner chooses to inject secrets via scp, it needs > to be sure it is scp-ing to the correct VM - the one that has SEV > enabled and was measured at launch. Hmm, I'd expect that to be part of the attestation dance. I admit, though, I have only listened about the whole attestation bla from the sidelines so I'm unclear whether that's part of that protocol. I guess Tom and Brijesh should have a better idea here. > One way to achieve that would be to inject the guest's SSH private key Well, is that "one way" or *the way*? > using the proposed efi_secret mechanism. This way the Guest Owner is > sure it is talking to the correct guest and not to some other VM that > was started by the untrusted cloud provider (say, with SEV disabled so > the cloud provider can steal its memory content). Because we would need *some* way of verifying the owner is talking to the correct guest. And if so, this should be made part of the big picture of SEV guest attestation. Or is this part of that attestation dance? I guess I'm wondering where in the big picture this fits into? > Indeed this proposed efi_secret module is in use for enabling SEV > confidential containers using Kata containers [1], but there's nothing > specific in the current patch series about containers. The patch series > just exposes the launch-injected SEV secrets to userspace as virtual files > (under securityfs). > > [1] https://github.com/confidential-containers/attestation-agent/tree/main/src/kbc_modules/offline_sev_kbc So one of the aspects for this is to use it in automated deployments. > It boils down to: the confidential guest needs to have access to a > secret which the untrusted host can't read, and which is essential for > the normal operation of the guest. This secret can be a decryption key, > an SSH private key, an API key to a Key Management system, etc. If a > malicious cloud provider tries to start that VM without a secret (or > with the wrong one), the actual workload that the guest is supposed to > run will not execute meaningfully. > > The proposed patch series exposes the SEV injected secrets as virtual > files, which can later be used as decryption keys (as done in the kata > confidential containers use-case), or SSH private keys, or any other > possible implementation. Right, and is this going to be the proper way to authenticate SEV guests to their owners or is this just another technique for safely supplying secrets into the guest? I hope I'm making some sense here...
On Wed, Jan 05, 2022 at 08:07:04PM +0000, Dr. David Alan Gilbert wrote: > I thought I saw something in their patch series where they also had a > secret that got passed down from EFI? Probably. I've seen so many TDX patchsets so that I'm completely confused what is what. > As I remember they had it with an ioctl and something; but it felt to > me if it would be great if it was shared. I guess we could try to share https://lore.kernel.org/r/20211210154332.11526-28-brijesh.singh@amd.com for SNP and TDX. > I'd love to hear from those other cloud vendors; I've not been able to > find any detail on how their SEV(-ES) systems actually work. Same here. > However, this aims to be just a comms mechanism to pass that secret; > so it's pretty low down in the stack and is there for them to use - > hopefully it's general enough. Exactly! > (An interesting question is what exactly gets passed in this key and > what it means). > > All the contentious stuff I've seen seems to be further up the stack - like > who does the attestation and where they get the secrets and how they > know what a valid measurement looks like. It would be much much better if all the parties involved would sit down and decide on a common scheme so that implementation can be shared but getting everybody to agree is likely hard...
On Fri, Jan 7, 2022 at 4:59 AM Borislav Petkov <bp@suse.de> wrote: > > On Wed, Jan 05, 2022 at 08:07:04PM +0000, Dr. David Alan Gilbert wrote: > > I thought I saw something in their patch series where they also had a > > secret that got passed down from EFI? > > Probably. I've seen so many TDX patchsets so that I'm completely > confused what is what. > > > As I remember they had it with an ioctl and something; but it felt to > > me if it would be great if it was shared. > > I guess we could try to share > > https://lore.kernel.org/r/20211210154332.11526-28-brijesh.singh@amd.com > > for SNP and TDX. > > > I'd love to hear from those other cloud vendors; I've not been able to > > find any detail on how their SEV(-ES) systems actually work. > > Same here. > > > However, this aims to be just a comms mechanism to pass that secret; > > so it's pretty low down in the stack and is there for them to use - > > hopefully it's general enough. > > Exactly! > > > (An interesting question is what exactly gets passed in this key and > > what it means). > > > > All the contentious stuff I've seen seems to be further up the stack - like > > who does the attestation and where they get the secrets and how they > > know what a valid measurement looks like. > > It would be much much better if all the parties involved would sit down > and decide on a common scheme so that implementation can be shared but > getting everybody to agree is likely hard... I saw a request for other cloud provider input here. A little background for our SEV VMs in GCE we rely on our vTPM for attestation, we do this because of SEV security properties quoting from AMD being to protect guests from a benign but vulnerable hypervisor. So a benign/compliant hypervisor's vTPM wouldn't lie to the guest. So we added a few bits in the PCRs to allow users to see their SEV status in vTPM quotes. It would be very interesting to offer an attestation solution that doesn't rely on our virtual TPM. But after reading through this cover letter and the linked OVMF patches I am confused what's the high level flow you are working towards? Are you loading in some OVMF using LAUNCH_UPDATE_DATA, getting the measurement with LAUNCH_MEASURE, then sending that to the customer who can then craft a "secret" (maybe say SSH key) for injection with LAUNCH_SECRET? Thats sounds good but there are a lot details left unattested there, how do you know you will boot from the image loaded with the PSP into a known state? Do you have some documentation I could read through to try and understand a little more and apologies if I missed it. > > -- > Regards/Gruss, > Boris. > > SUSE Software Solutions Germany GmbH, GF: Ivo Totev, HRB 36809, AG Nürnberg >
On 07/01/2022 21:16, Peter Gonda wrote: > On Fri, Jan 7, 2022 at 4:59 AM Borislav Petkov <bp@suse.de> wrote: >> >> On Wed, Jan 05, 2022 at 08:07:04PM +0000, Dr. David Alan Gilbert wrote: >>> I thought I saw something in their patch series where they also had a >>> secret that got passed down from EFI? >> >> Probably. I've seen so many TDX patchsets so that I'm completely >> confused what is what. >> >>> As I remember they had it with an ioctl and something; but it felt to >>> me if it would be great if it was shared. >> >> I guess we could try to share >> >> https://lore.kernel.org/r/20211210154332.11526-28-brijesh.singh@amd.com >> >> for SNP and TDX. >> >>> I'd love to hear from those other cloud vendors; I've not been able to >>> find any detail on how their SEV(-ES) systems actually work. >> >> Same here. >> >>> However, this aims to be just a comms mechanism to pass that secret; >>> so it's pretty low down in the stack and is there for them to use - >>> hopefully it's general enough. >> >> Exactly! >> >>> (An interesting question is what exactly gets passed in this key and >>> what it means). >>> >>> All the contentious stuff I've seen seems to be further up the stack - like >>> who does the attestation and where they get the secrets and how they >>> know what a valid measurement looks like. >> >> It would be much much better if all the parties involved would sit down >> and decide on a common scheme so that implementation can be shared but >> getting everybody to agree is likely hard... > > I saw a request for other cloud provider input here. A little > background for our SEV VMs in GCE we rely on our vTPM for attestation, > we do this because of SEV security properties quoting from AMD being > to protect guests from a benign but vulnerable hypervisor. So a > benign/compliant hypervisor's vTPM wouldn't lie to the guest. So we > added a few bits in the PCRs to allow users to see their SEV status in > vTPM quotes. Thanks Peter for explaining the GCE approach. If I understand correctly, if the hypervisor is malicious, it could lie to the vTPM and set those "few bits" so it'll look like the VM is running with SEV enabled (whereas in fact it is running without memory encryption). But that's outside the scope, right? > > It would be very interesting to offer an attestation solution that > doesn't rely on our virtual TPM. But after reading through this cover > letter and the linked OVMF patches I am confused what's the high level > flow you are working towards? Are you loading in some OVMF using > LAUNCH_UPDATE_DATA, getting the measurement with LAUNCH_MEASURE, then > sending that to the customer who can then craft a "secret" (maybe say > SSH key) for injection with LAUNCH_SECRET? Thats sounds good but there > are a lot details left unattested there, how do you know you will boot > from the image loaded with the PSP into a known state? Do you have > some documentation I could read through to try and understand a little > more and apologies if I missed it. > We rely on the OvmfPkg/AmdSev build of OVMF, which is a stripped down firmware that can boot only in one of two ways: a. direct boot to kernel/initrd/cmdline whose hashes are included in the LAUNCH_MEASURE data (see [1], [2], [3]). b. boot to embedded grub (in OVMF) which decrypts an encrypted boot drive using a secret from LAUNCH_SECRET (see [4] and [5]). For the current series (efi_secret kernel module), method (a) is the relevant one. The Cloud Provider boots a guest VM with OVMF, and -kernel/-initrd/-append. The content of OVMF and the hashes of kernel/initrd/cmdline are measured in LAUNCH_MEASURE and sent to the Guest Owner (=Customer). If they match, the Guest Owner should perform a LAUNCH_SECRET and inject the secret to a designated SEV launch secrets page. Then the guest starts running; when the kernel starts the EFI driver saves the address of this page (patch 1), and later exposes the secrets in this page as files in securityfs (patch 3). The secrets can be used by the guest workload in whatever way it needs (examples discussed above: ssh private key; API key to obtain secrets; decryption key for some encrypted files; ...). Any attempt of a malicious cloud provider to modify OVMF, kernel, initrd, or cmdline will cause the SEV measurement to be wrong. Note again that the proposed kernel patch series has nothing to do with the measurement sequence -- it assumes the secrets page is already populated, and exposes it to userspace as files. Hope this explains our approach. [1] https://www.youtube.com/watch?v=jzP8RlTRErk [2] https://lore.kernel.org/qemu-devel/20210930054915.13252-1-dovmurik@linux.ibm.com/ [3] https://lore.kernel.org/qemu-devel/20211111100048.3299424-1-dovmurik@linux.ibm.com/ [4] https://www.youtube.com/watch?v=rCsIxzM6C_I [5] https://blog.hansenpartnership.com/deploying-encrypted-images-for-confidential-computing/ -Dov