[edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf

James Bottomley posted 4 patches 3 years, 5 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/edk2 tags/patchew/20201112001316.11341-1-jejb@linux.ibm.com
There is a newer version of this series
OvmfPkg/OvmfPkg.dec                           |    6 +
OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
.../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
.../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
.../PlatformBootManagerLibGrub.inf            |   84 +
OvmfPkg/ResetVector/ResetVector.inf           |    4 +
.../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
.../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
.../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
.../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
.../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
18 files changed, 3846 insertions(+)
create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
[edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by James Bottomley 3 years, 5 months ago
From: James Bottomley <James.Bottomley@HansenPartnership.com>

This patch series is modelled on the structure of the Bhyve patches
for Ovmf, since it does somewhat similar things.  This patch series
creates a separate build for an AmdSev OVMF.fd that does nothing
except combine with grub and boot straight through the internal grub
to try to mount an encrypted volume.

Concept: SEV Secure Encrypted Images
====================================

The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
an encrypted state, but don't really show how this could be done with
an encrypted image.  Since the key used to decrypt the image must be
maintained within the SEV encryption envelope, encrypted QCOW is not
an option because the key would then have to be known to QEMU which is
outside the encryption envelope.  The proposal here is that an
encrypted image should be a QCOW image consisting of two partitions,
the normal unencrypted EFI partition (Identifying it as an OVMF
bootable image) and a luks encrypted root partition.  The kernel would
be inside the encrypted root in the /boot directory.  The secret
injected securely through QEMU is extracted by OVMF and passed to grub
which uses it to mount the encrypted root and boot the kernel
normally.  The creator of the secret bundle must be satisfied with the
SEV attestation before the secret is constructed.  Unfortunately, the
SEV attestation can only be on the first QEMU firmware volume and
nothing else, so this patch series builds grub itself into a firmware
volume and places it inside OVMF so that the entire boot system can be
attested.  In a normal OVMF KVM system, the variable store is on the
second flash volume (which is read/write).  Unfortunately, this
mutable configuration provided by the variables is outside the
attestation envelope and can significantly alter the boot path,
possibly leading to secret leak, so encrypted image boot should only
be done with the OVMF.fd that combines both the code and variables.
the OVMF.fd is constructed so that it becomes impossible to interrupt
the boot sequence after attestation and the system will either boot
the image or fail. The boot sequence runs the grub.efi embedded in the
OVMF firmware volume so the encrypted image owner knows their own
version of grub is the only one that will boot before injecting the
secret.  Note this boot path actually ignores the unencrypted EFI
partition.  However, as part of this design, the encrypted image may be
booted by a standard OVMF KVM boot and in that case, the user will
have to type the encryption password.  This standard boot will be
insecure but it might be used by the constructor of the encrypted
images on their own private laptop, for instance.  The standard boot
path will use the unencrypted EFI partition.

Patches Required Outside of OVMF
================================

There is a patch set to grub which allows it to extract the SEV secret
area from the configuration table and use the secret as a password to
do a luks crypto mount of root (this is the sevsecret grub module).

There is also a patch to qemu which allows it to search through the
OVMF.fd and find the SEV secret area which is now described inside the
Reset Vector using the existing SEV_ES reset block.  This area is the
place QEMU will inject the encrypted SEV secret bundle.

Security of the System
======================

Since Grub is now part of the attested OVMF.fd bundle, the VM owner
knows absolutely that it will proceed straight to partition decryption
inside the attested code and boot the kernel off the encrypted
partition.  Even if a different QCOW image is substituted, the boot
will fail without revealing the secret because the system is designed
to fail hard in that case and because the secret is always contained
within the encrypted envelope it should be impossible for the cloud
operator to obtain it even if they can pause the boot and examine the
machine memory.

Putting it All Together
=======================

This is somewhat hard.  You must first understand how to boot a QEMU
system so as to have the VM pause after firmware loading (-S option)
and use the qmp port to request an attestation.  Only if the
attestation corresponds to the expected sha256sum of OVMF.fd should
the secret bundle be constructed and injected using qmp.  The tools
for constructing the secret bundle are in

https://github.com/AMDESE/sev-tool/

James

---

James Bottomley (4):
  OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
  OvmfPkg/AmdSev: add Grub Firmware Volume Package
  OvmfPkg: create a SEV secret area in the AmdSev memfd
  OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table

 OvmfPkg/OvmfPkg.dec                           |    6 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
 OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
 OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
 .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
 .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
 .../PlatformBootManagerLibGrub.inf            |   84 +
 OvmfPkg/ResetVector/ResetVector.inf           |    4 +
 .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
 .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
 .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
 .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
 .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
 OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
 OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
 OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
 OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
 18 files changed, 3846 insertions(+)
 create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
 create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
 create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
 create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
 create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
 create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
 create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
 create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
 create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
 create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
 create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh

-- 
2.26.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67339): https://edk2.groups.io/g/devel/message/67339
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by James Bottomley 3 years, 5 months ago
On Wed, 2020-11-11 at 16:13 -0800, James Bottomley wrote:
> This patch series is modelled on the structure of the Bhyve patches
> for Ovmf, since it does somewhat similar things.  This patch series
> creates a separate build for an AmdSev OVMF.fd that does nothing
> except combine with grub and boot straight through the internal grub
> to try to mount an encrypted volume.

The necessary patches to grub to allow it to retrieve the SEV secret
are now posted on the grub development list:

https://lists.gnu.org/archive/html/grub-devel/2020-11/msg00078.html

This includes the sevsecret module which is required to build the
embedded grub.

Regards,

James




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67515): https://edk2.groups.io/g/devel/message/67515
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Ashish Kalra 3 years, 5 months ago
On Wed, Nov 11, 2020 at 04:13:12PM -0800, James Bottomley wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> This patch series is modelled on the structure of the Bhyve patches
> for Ovmf, since it does somewhat similar things.  This patch series
> creates a separate build for an AmdSev OVMF.fd that does nothing
> except combine with grub and boot straight through the internal grub
> to try to mount an encrypted volume.
> 
> Concept: SEV Secure Encrypted Images
> ====================================
> 
> The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
> an encrypted state, but don't really show how this could be done with
> an encrypted image.  

A basic question here ... the SEV usage model in which the firmware is
encrypted and loaded into VM using LAUNCH_UPDATA_DATA and then
measurement is provided and attestation is done with the VM owner and
after VM owner verifies measurement, the VM owner encrypts the disk
encryption key and sends it to the guest and it is injected into the 
guest using the LAUNCH_SECRET API, which is then used to decrypt the
OS encrypted image, won't this work to start the SEV VM
with an encrypted image ?

Thanks,
Ashish

>Since the key used to decrypt the image must be
> maintained within the SEV encryption envelope, encrypted QCOW is not
> an option because the key would then have to be known to QEMU which is
> outside the encryption envelope.  The proposal here is that an
> encrypted image should be a QCOW image consisting of two partitions,
> the normal unencrypted EFI partition (Identifying it as an OVMF
> bootable image) and a luks encrypted root partition.  The kernel would
> be inside the encrypted root in the /boot directory.  The secret
> injected securely through QEMU is extracted by OVMF and passed to grub
> which uses it to mount the encrypted root and boot the kernel
> normally.  The creator of the secret bundle must be satisfied with the
> SEV attestation before the secret is constructed.  Unfortunately, the
> SEV attestation can only be on the first QEMU firmware volume and
> nothing else, so this patch series builds grub itself into a firmware
> volume and places it inside OVMF so that the entire boot system can be
> attested.  In a normal OVMF KVM system, the variable store is on the
> second flash volume (which is read/write).  Unfortunately, this
> mutable configuration provided by the variables is outside the
> attestation envelope and can significantly alter the boot path,
> possibly leading to secret leak, so encrypted image boot should only
> be done with the OVMF.fd that combines both the code and variables.
> the OVMF.fd is constructed so that it becomes impossible to interrupt
> the boot sequence after attestation and the system will either boot
> the image or fail. The boot sequence runs the grub.efi embedded in the
> OVMF firmware volume so the encrypted image owner knows their own
> version of grub is the only one that will boot before injecting the
> secret.  Note this boot path actually ignores the unencrypted EFI
> partition.  However, as part of this design, the encrypted image may be
> booted by a standard OVMF KVM boot and in that case, the user will
> have to type the encryption password.  This standard boot will be
> insecure but it might be used by the constructor of the encrypted
> images on their own private laptop, for instance.  The standard boot
> path will use the unencrypted EFI partition.
> 
> Patches Required Outside of OVMF
> ================================
> 
> There is a patch set to grub which allows it to extract the SEV secret
> area from the configuration table and use the secret as a password to
> do a luks crypto mount of root (this is the sevsecret grub module).
> 
> There is also a patch to qemu which allows it to search through the
> OVMF.fd and find the SEV secret area which is now described inside the
> Reset Vector using the existing SEV_ES reset block.  This area is the
> place QEMU will inject the encrypted SEV secret bundle.
> 
> Security of the System
> ======================
> 
> Since Grub is now part of the attested OVMF.fd bundle, the VM owner
> knows absolutely that it will proceed straight to partition decryption
> inside the attested code and boot the kernel off the encrypted
> partition.  Even if a different QCOW image is substituted, the boot
> will fail without revealing the secret because the system is designed
> to fail hard in that case and because the secret is always contained
> within the encrypted envelope it should be impossible for the cloud
> operator to obtain it even if they can pause the boot and examine the
> machine memory.
> 
> Putting it All Together
> =======================
> 
> This is somewhat hard.  You must first understand how to boot a QEMU
> system so as to have the VM pause after firmware loading (-S option)
> and use the qmp port to request an attestation.  Only if the
> attestation corresponds to the expected sha256sum of OVMF.fd should
> the secret bundle be constructed and injected using qmp.  The tools
> for constructing the secret bundle are in
> 
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fsev-tool%2F&amp;data=04%7C01%7Cashish.kalra%40amd.com%7Ceb007b21e05c4e9c05cf08d8869fc874%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637407368115912177%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=TwcpYSl10ePPfomMIQQjjxcOufjlxkzDkR8H7BxKZtw%3D&amp;reserved=0
> 
> James
> 
> ---
> 
> James Bottomley (4):
>   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
>   OvmfPkg/AmdSev: add Grub Firmware Volume Package
>   OvmfPkg: create a SEV secret area in the AmdSev memfd
>   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
> 
>  OvmfPkg/OvmfPkg.dec                           |    6 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
>  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
>  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
>  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
>  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
>  .../PlatformBootManagerLibGrub.inf            |   84 +
>  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
>  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
>  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
>  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
>  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
>  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
>  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
>  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
>  18 files changed, 3846 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
>  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
>  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
> 
> -- 
> 2.26.2
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67401): https://edk2.groups.io/g/devel/message/67401
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Dr. David Alan Gilbert 3 years, 5 months ago
* Ashish Kalra (ashish.kalra@amd.com) wrote:
> On Wed, Nov 11, 2020 at 04:13:12PM -0800, James Bottomley wrote:
> > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > 
> > This patch series is modelled on the structure of the Bhyve patches
> > for Ovmf, since it does somewhat similar things.  This patch series
> > creates a separate build for an AmdSev OVMF.fd that does nothing
> > except combine with grub and boot straight through the internal grub
> > to try to mount an encrypted volume.
> > 
> > Concept: SEV Secure Encrypted Images
> > ====================================
> > 
> > The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
> > an encrypted state, but don't really show how this could be done with
> > an encrypted image.  
> 
> A basic question here ... the SEV usage model in which the firmware is
> encrypted and loaded into VM using LAUNCH_UPDATA_DATA and then
> measurement is provided and attestation is done with the VM owner and
> after VM owner verifies measurement, the VM owner encrypts the disk
> encryption key and sends it to the guest and it is injected into the 
> guest using the LAUNCH_SECRET API, which is then used to decrypt the
> OS encrypted image, won't this work to start the SEV VM
> with an encrypted image ?

That's still what James system does, but the problem is maintaining a
chain of trust from the set of measured binaries to the point at
which you can use the injected secret.

On the current OVMF world we end up measuring the OVMF binary, but not
the stored variable flash; but then what? Who would read the injected
secret?
Because SEV/SEV-ES has no way of performing a later attestation, or
updating the measurements, we have no way of following the path from
OVMF (possibly via variables) to a boot loader, to a filesystem.

Dave

> Thanks,
> Ashish
> 
> >Since the key used to decrypt the image must be
> > maintained within the SEV encryption envelope, encrypted QCOW is not
> > an option because the key would then have to be known to QEMU which is
> > outside the encryption envelope.  The proposal here is that an
> > encrypted image should be a QCOW image consisting of two partitions,
> > the normal unencrypted EFI partition (Identifying it as an OVMF
> > bootable image) and a luks encrypted root partition.  The kernel would
> > be inside the encrypted root in the /boot directory.  The secret
> > injected securely through QEMU is extracted by OVMF and passed to grub
> > which uses it to mount the encrypted root and boot the kernel
> > normally.  The creator of the secret bundle must be satisfied with the
> > SEV attestation before the secret is constructed.  Unfortunately, the
> > SEV attestation can only be on the first QEMU firmware volume and
> > nothing else, so this patch series builds grub itself into a firmware
> > volume and places it inside OVMF so that the entire boot system can be
> > attested.  In a normal OVMF KVM system, the variable store is on the
> > second flash volume (which is read/write).  Unfortunately, this
> > mutable configuration provided by the variables is outside the
> > attestation envelope and can significantly alter the boot path,
> > possibly leading to secret leak, so encrypted image boot should only
> > be done with the OVMF.fd that combines both the code and variables.
> > the OVMF.fd is constructed so that it becomes impossible to interrupt
> > the boot sequence after attestation and the system will either boot
> > the image or fail. The boot sequence runs the grub.efi embedded in the
> > OVMF firmware volume so the encrypted image owner knows their own
> > version of grub is the only one that will boot before injecting the
> > secret.  Note this boot path actually ignores the unencrypted EFI
> > partition.  However, as part of this design, the encrypted image may be
> > booted by a standard OVMF KVM boot and in that case, the user will
> > have to type the encryption password.  This standard boot will be
> > insecure but it might be used by the constructor of the encrypted
> > images on their own private laptop, for instance.  The standard boot
> > path will use the unencrypted EFI partition.
> > 
> > Patches Required Outside of OVMF
> > ================================
> > 
> > There is a patch set to grub which allows it to extract the SEV secret
> > area from the configuration table and use the secret as a password to
> > do a luks crypto mount of root (this is the sevsecret grub module).
> > 
> > There is also a patch to qemu which allows it to search through the
> > OVMF.fd and find the SEV secret area which is now described inside the
> > Reset Vector using the existing SEV_ES reset block.  This area is the
> > place QEMU will inject the encrypted SEV secret bundle.
> > 
> > Security of the System
> > ======================
> > 
> > Since Grub is now part of the attested OVMF.fd bundle, the VM owner
> > knows absolutely that it will proceed straight to partition decryption
> > inside the attested code and boot the kernel off the encrypted
> > partition.  Even if a different QCOW image is substituted, the boot
> > will fail without revealing the secret because the system is designed
> > to fail hard in that case and because the secret is always contained
> > within the encrypted envelope it should be impossible for the cloud
> > operator to obtain it even if they can pause the boot and examine the
> > machine memory.
> > 
> > Putting it All Together
> > =======================
> > 
> > This is somewhat hard.  You must first understand how to boot a QEMU
> > system so as to have the VM pause after firmware loading (-S option)
> > and use the qmp port to request an attestation.  Only if the
> > attestation corresponds to the expected sha256sum of OVMF.fd should
> > the secret bundle be constructed and injected using qmp.  The tools
> > for constructing the secret bundle are in
> > 
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fsev-tool%2F&amp;data=04%7C01%7Cashish.kalra%40amd.com%7Ceb007b21e05c4e9c05cf08d8869fc874%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637407368115912177%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=TwcpYSl10ePPfomMIQQjjxcOufjlxkzDkR8H7BxKZtw%3D&amp;reserved=0
> > 
> > James
> > 
> > ---
> > 
> > James Bottomley (4):
> >   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
> >   OvmfPkg/AmdSev: add Grub Firmware Volume Package
> >   OvmfPkg: create a SEV secret area in the AmdSev memfd
> >   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
> > 
> >  OvmfPkg/OvmfPkg.dec                           |    6 +
> >  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
> >  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
> >  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
> >  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
> >  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
> >  .../PlatformBootManagerLibGrub.inf            |   84 +
> >  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
> >  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
> >  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
> >  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
> >  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
> >  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
> >  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
> >  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
> >  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
> >  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
> >  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
> >  18 files changed, 3846 insertions(+)
> >  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
> >  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
> >  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> >  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
> >  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
> >  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
> > 
> > -- 
> > 2.26.2
> > 
> 
-- 
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67395): https://edk2.groups.io/g/devel/message/67395
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by James Bottomley 3 years, 5 months ago
On Thu, 2020-11-12 at 16:34 +0000, Dr. David Alan Gilbert wrote:
> * Ashish Kalra (ashish.kalra@amd.com) wrote:
> > On Wed, Nov 11, 2020 at 04:13:12PM -0800, James Bottomley wrote:
> > > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > > 
> > > This patch series is modelled on the structure of the Bhyve
> > > patches for Ovmf, since it does somewhat similar things.  This
> > > patch series creates a separate build for an AmdSev OVMF.fd that
> > > does nothing except combine with grub and boot straight through
> > > the internal grub to try to mount an encrypted volume.
> > > 
> > > Concept: SEV Secure Encrypted Images
> > > ====================================
> > > 
> > > The SEV patches in Linux and OVMF allow for the booting of SEV
> > > VMs in an encrypted state, but don't really show how this could
> > > be done with an encrypted image.  
> > 
> > A basic question here ... the SEV usage model in which the firmware
> > is encrypted and loaded into VM using LAUNCH_UPDATA_DATA and then
> > measurement is provided and attestation is done with the VM owner
> > and after VM owner verifies measurement, the VM owner encrypts the
> > disk encryption key and sends it to the guest and it is injected
> > into the guest using the LAUNCH_SECRET API, which is then used to
> > decrypt the OS encrypted image, won't this work to start the SEV VM
> > with an encrypted image ?
> 
> That's still what James system does, but the problem is maintaining a
> chain of trust from the set of measured binaries to the point at
> which you can use the injected secret.
> 
> On the current OVMF world we end up measuring the OVMF binary, but
> not the stored variable flash; but then what? Who would read the
> injected secret?  Because SEV/SEV-ES has no way of performing a later
> attestation, or updating the measurements, we have no way of
> following the path from OVMF (possibly via variables) to a boot
> loader, to a filesystem.

Right, the specific problem is our current linux boot sequence goes 

OVMF->grub->linux

But OVMF can only execute things on an unencrypted vFAT filesytem, so
if grub is on vFAT there's no way to prevent a cloud admin substituting
the grub binary after attestation is done and the key released if we
only attest OVMF, so the bogus grub binary could simply capture the key
and transmit it to a hacker.

Pulling grub inside OVMF allows us to attest both OVMF and grub as one
entity and also prevents the boot going via the unencrypted vFAT
filesystem, eliminating the potential interception point.

James




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67402): https://edk2.groups.io/g/devel/message/67402
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Ashish Kalra 3 years, 5 months ago
On Thu, Nov 12, 2020 at 09:07:11AM -0800, James Bottomley wrote:
> On Thu, 2020-11-12 at 16:34 +0000, Dr. David Alan Gilbert wrote:
> > * Ashish Kalra (ashish.kalra@amd.com) wrote:
> > > On Wed, Nov 11, 2020 at 04:13:12PM -0800, James Bottomley wrote:
> > > > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > > > 
> > > > This patch series is modelled on the structure of the Bhyve
> > > > patches for Ovmf, since it does somewhat similar things.  This
> > > > patch series creates a separate build for an AmdSev OVMF.fd that
> > > > does nothing except combine with grub and boot straight through
> > > > the internal grub to try to mount an encrypted volume.
> > > > 
> > > > Concept: SEV Secure Encrypted Images
> > > > ====================================
> > > > 
> > > > The SEV patches in Linux and OVMF allow for the booting of SEV
> > > > VMs in an encrypted state, but don't really show how this could
> > > > be done with an encrypted image.  
> > > 
> > > A basic question here ... the SEV usage model in which the firmware
> > > is encrypted and loaded into VM using LAUNCH_UPDATA_DATA and then
> > > measurement is provided and attestation is done with the VM owner
> > > and after VM owner verifies measurement, the VM owner encrypts the
> > > disk encryption key and sends it to the guest and it is injected
> > > into the guest using the LAUNCH_SECRET API, which is then used to
> > > decrypt the OS encrypted image, won't this work to start the SEV VM
> > > with an encrypted image ?
> > 
> > That's still what James system does, but the problem is maintaining a
> > chain of trust from the set of measured binaries to the point at
> > which you can use the injected secret.
> > 
> > On the current OVMF world we end up measuring the OVMF binary, but
> > not the stored variable flash; but then what? Who would read the
> > injected secret?  Because SEV/SEV-ES has no way of performing a later
> > attestation, or updating the measurements, we have no way of
> > following the path from OVMF (possibly via variables) to a boot
> > loader, to a filesystem.
> 
> Right, the specific problem is our current linux boot sequence goes 
> 
> OVMF->grub->linux
> 
> But OVMF can only execute things on an unencrypted vFAT filesytem, so
> if grub is on vFAT there's no way to prevent a cloud admin substituting
> the grub binary after attestation is done and the key released if we
> only attest OVMF, so the bogus grub binary could simply capture the key
> and transmit it to a hacker.
> 
> Pulling grub inside OVMF allows us to attest both OVMF and grub as one
> entity and also prevents the boot going via the unencrypted vFAT
> filesystem, eliminating the potential interception point.
> 
> James
> 
> 

Thanks James and Dave for the detailed explanations, i get the picture.

Also after discussion with Brijesh, i understand that this is fixing a
known gap in the SEV s/w stack.

Ashish


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67403): https://edk2.groups.io/g/devel/message/67403
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Brijesh Singh 3 years, 5 months ago
Hi James,

Thanks for series, I glanced at it, the changes looks okay to me. I have
one questions.

How does the grub locate the disk decryption key ? Am I correct in
assuming that the gurb is iterating through a configuration table
entries and comparing the Secret GUID to locate the secret key. As per
the SEV spec, its possible that a guest owner can call the secret
injection more than once. I don't see the patch consider that case,
should we support this or limit to one inject?  Maybe Qemu can enforce
this property.

Do you see any need for the Linux kernel needing to access the secret?
Since the secret blob is available through configuration table, I
believe we can have a platform driver that can read the configuration
table and retrieve the secret blob.

thanks

On 11/11/20 6:13 PM, James Bottomley wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> This patch series is modelled on the structure of the Bhyve patches
> for Ovmf, since it does somewhat similar things.  This patch series
> creates a separate build for an AmdSev OVMF.fd that does nothing
> except combine with grub and boot straight through the internal grub
> to try to mount an encrypted volume.
>
> Concept: SEV Secure Encrypted Images
> ====================================
>
> The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
> an encrypted state, but don't really show how this could be done with
> an encrypted image.  Since the key used to decrypt the image must be
> maintained within the SEV encryption envelope, encrypted QCOW is not
> an option because the key would then have to be known to QEMU which is
> outside the encryption envelope.  The proposal here is that an
> encrypted image should be a QCOW image consisting of two partitions,
> the normal unencrypted EFI partition (Identifying it as an OVMF
> bootable image) and a luks encrypted root partition.  The kernel would
> be inside the encrypted root in the /boot directory.  The secret
> injected securely through QEMU is extracted by OVMF and passed to grub
> which uses it to mount the encrypted root and boot the kernel
> normally.  The creator of the secret bundle must be satisfied with the
> SEV attestation before the secret is constructed.  Unfortunately, the
> SEV attestation can only be on the first QEMU firmware volume and
> nothing else, so this patch series builds grub itself into a firmware
> volume and places it inside OVMF so that the entire boot system can be
> attested.  In a normal OVMF KVM system, the variable store is on the
> second flash volume (which is read/write).  Unfortunately, this
> mutable configuration provided by the variables is outside the
> attestation envelope and can significantly alter the boot path,
> possibly leading to secret leak, so encrypted image boot should only
> be done with the OVMF.fd that combines both the code and variables.
> the OVMF.fd is constructed so that it becomes impossible to interrupt
> the boot sequence after attestation and the system will either boot
> the image or fail. The boot sequence runs the grub.efi embedded in the
> OVMF firmware volume so the encrypted image owner knows their own
> version of grub is the only one that will boot before injecting the
> secret.  Note this boot path actually ignores the unencrypted EFI
> partition.  However, as part of this design, the encrypted image may be
> booted by a standard OVMF KVM boot and in that case, the user will
> have to type the encryption password.  This standard boot will be
> insecure but it might be used by the constructor of the encrypted
> images on their own private laptop, for instance.  The standard boot
> path will use the unencrypted EFI partition.
>
> Patches Required Outside of OVMF
> ================================
>
> There is a patch set to grub which allows it to extract the SEV secret
> area from the configuration table and use the secret as a password to
> do a luks crypto mount of root (this is the sevsecret grub module).
>
> There is also a patch to qemu which allows it to search through the
> OVMF.fd and find the SEV secret area which is now described inside the
> Reset Vector using the existing SEV_ES reset block.  This area is the
> place QEMU will inject the encrypted SEV secret bundle.
>
> Security of the System
> ======================
>
> Since Grub is now part of the attested OVMF.fd bundle, the VM owner
> knows absolutely that it will proceed straight to partition decryption
> inside the attested code and boot the kernel off the encrypted
> partition.  Even if a different QCOW image is substituted, the boot
> will fail without revealing the secret because the system is designed
> to fail hard in that case and because the secret is always contained
> within the encrypted envelope it should be impossible for the cloud
> operator to obtain it even if they can pause the boot and examine the
> machine memory.
>
> Putting it All Together
> =======================
>
> This is somewhat hard.  You must first understand how to boot a QEMU
> system so as to have the VM pause after firmware loading (-S option)
> and use the qmp port to request an attestation.  Only if the
> attestation corresponds to the expected sha256sum of OVMF.fd should
> the secret bundle be constructed and injected using qmp.  The tools
> for constructing the secret bundle are in
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fsev-tool%2F&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ceb007b21e05c4e9c05cf08d8869fc874%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637407368116062086%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=BbCtv37bH0%2B6JDLM3afAubVN6K0Y%2FdO4TRz4ZkP1AKg%3D&amp;reserved=0


Where you able to use the sev-tool as-is to generate a secret blob that
can be injected through the Qemu QMP interface? The reason why I am
asking this is because the last time when I looked at the sev-tool I
found that it did not generated the blob which was in the correct format.


>
> James
>
> ---
>
> James Bottomley (4):
>   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
>   OvmfPkg/AmdSev: add Grub Firmware Volume Package
>   OvmfPkg: create a SEV secret area in the AmdSev memfd
>   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
>
>  OvmfPkg/OvmfPkg.dec                           |    6 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
>  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
>  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
>  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
>  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
>  .../PlatformBootManagerLibGrub.inf            |   84 +
>  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
>  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
>  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
>  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
>  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
>  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
>  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
>  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
>  18 files changed, 3846 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
>  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
>  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
>


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67404): https://edk2.groups.io/g/devel/message/67404
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by James Bottomley 3 years, 5 months ago
On Thu, 2020-11-12 at 11:32 -0600, Brijesh Singh wrote:
> Hi James,
> 
> Thanks for series, I glanced at it, the changes looks okay to me. I
> have
> one questions.
> 
> How does the grub locate the disk decryption key ? Am I correct in
> assuming that the gurb is iterating through a configuration table
> entries and comparing the Secret GUID to locate the secret key. As
> per the SEV spec, its possible that a guest owner can call the secret
> injection more than once. I don't see the patch consider that case,
> should we support this or limit to one inject?  Maybe Qemu can
> enforce this property.

Well in the original patch, grub recognized the secret in the area by
the prefix "PASSWORD:".  I think that's a bit fragile, so I was
planning to rework the grub patch to do everything by guid, so the
secrets table itself would have its own guid which would be followed by
the entire table length.  Then the entries in the table would have the
format

|guid|len|data|

So every consumer first of all validates the table by the initial guid
and gets the total length then iterates over the entries to see if its
interested in any of them.  The format of |data| would be up to the
consumer.

> Do you see any need for the Linux kernel needing to access the
> secret? Since the secret blob is available through configuration
> table, I believe we can have a platform driver that can read the
> configuration table and retrieve the secret blob.

I've only been really concentrating on the grub use case.  However, as
you saw in my reply about migration, we likely also need an entry so
that the migration helper can pick up its ECDH identity.  The scheme
would definitely cover passing a secret to the kernel as well.  The one
caveat there is that the HOB that covers the secret is boot time, so
the secret would have to be extracted in the kernel EFI stub before
ExitBootServices() is called.  I suppose nothing really prevent the HOB
from becoming runtime except the security maxim that you want all
secret lifetimes to be as short as possible.

James




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67405): https://edk2.groups.io/g/devel/message/67405
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Dr. David Alan Gilbert 3 years, 5 months ago
* Brijesh Singh (brijesh.singh@amd.com) wrote:
> Hi James,
> 
> Thanks for series, I glanced at it, the changes looks okay to me. I have
> one questions.
> 
> How does the grub locate the disk decryption key ? Am I correct in
> assuming that the gurb is iterating through a configuration table
> entries and comparing the Secret GUID to locate the secret key. As per
> the SEV spec, its possible that a guest owner can call the secret
> injection more than once. I don't see the patch consider that case,
> should we support this or limit to one inject?  Maybe Qemu can enforce
> this property.

That's interesting, I hadn't realised that was possible - however,
I can't see a way to use it - for it to be useful, you would have to
have a way for the guest to communicate to the owner that it had
finished with the first injection and would like the next; but if you
already have a way to communicate from the guest to the owner to request
stuff, then you could pass a new secret by that comms route?

> Do you see any need for the Linux kernel needing to access the secret?
> Since the secret blob is available through configuration table, I
> believe we can have a platform driver that can read the configuration
> table and retrieve the secret blob.

I guess it depends if you get the Grub to pass the fs secret down to the
kernel or let it pick it up itself from the same place.

Dave

> 
> thanks
> 
> On 11/11/20 6:13 PM, James Bottomley wrote:
> > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> >
> > This patch series is modelled on the structure of the Bhyve patches
> > for Ovmf, since it does somewhat similar things.  This patch series
> > creates a separate build for an AmdSev OVMF.fd that does nothing
> > except combine with grub and boot straight through the internal grub
> > to try to mount an encrypted volume.
> >
> > Concept: SEV Secure Encrypted Images
> > ====================================
> >
> > The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
> > an encrypted state, but don't really show how this could be done with
> > an encrypted image.  Since the key used to decrypt the image must be
> > maintained within the SEV encryption envelope, encrypted QCOW is not
> > an option because the key would then have to be known to QEMU which is
> > outside the encryption envelope.  The proposal here is that an
> > encrypted image should be a QCOW image consisting of two partitions,
> > the normal unencrypted EFI partition (Identifying it as an OVMF
> > bootable image) and a luks encrypted root partition.  The kernel would
> > be inside the encrypted root in the /boot directory.  The secret
> > injected securely through QEMU is extracted by OVMF and passed to grub
> > which uses it to mount the encrypted root and boot the kernel
> > normally.  The creator of the secret bundle must be satisfied with the
> > SEV attestation before the secret is constructed.  Unfortunately, the
> > SEV attestation can only be on the first QEMU firmware volume and
> > nothing else, so this patch series builds grub itself into a firmware
> > volume and places it inside OVMF so that the entire boot system can be
> > attested.  In a normal OVMF KVM system, the variable store is on the
> > second flash volume (which is read/write).  Unfortunately, this
> > mutable configuration provided by the variables is outside the
> > attestation envelope and can significantly alter the boot path,
> > possibly leading to secret leak, so encrypted image boot should only
> > be done with the OVMF.fd that combines both the code and variables.
> > the OVMF.fd is constructed so that it becomes impossible to interrupt
> > the boot sequence after attestation and the system will either boot
> > the image or fail. The boot sequence runs the grub.efi embedded in the
> > OVMF firmware volume so the encrypted image owner knows their own
> > version of grub is the only one that will boot before injecting the
> > secret.  Note this boot path actually ignores the unencrypted EFI
> > partition.  However, as part of this design, the encrypted image may be
> > booted by a standard OVMF KVM boot and in that case, the user will
> > have to type the encryption password.  This standard boot will be
> > insecure but it might be used by the constructor of the encrypted
> > images on their own private laptop, for instance.  The standard boot
> > path will use the unencrypted EFI partition.
> >
> > Patches Required Outside of OVMF
> > ================================
> >
> > There is a patch set to grub which allows it to extract the SEV secret
> > area from the configuration table and use the secret as a password to
> > do a luks crypto mount of root (this is the sevsecret grub module).
> >
> > There is also a patch to qemu which allows it to search through the
> > OVMF.fd and find the SEV secret area which is now described inside the
> > Reset Vector using the existing SEV_ES reset block.  This area is the
> > place QEMU will inject the encrypted SEV secret bundle.
> >
> > Security of the System
> > ======================
> >
> > Since Grub is now part of the attested OVMF.fd bundle, the VM owner
> > knows absolutely that it will proceed straight to partition decryption
> > inside the attested code and boot the kernel off the encrypted
> > partition.  Even if a different QCOW image is substituted, the boot
> > will fail without revealing the secret because the system is designed
> > to fail hard in that case and because the secret is always contained
> > within the encrypted envelope it should be impossible for the cloud
> > operator to obtain it even if they can pause the boot and examine the
> > machine memory.
> >
> > Putting it All Together
> > =======================
> >
> > This is somewhat hard.  You must first understand how to boot a QEMU
> > system so as to have the VM pause after firmware loading (-S option)
> > and use the qmp port to request an attestation.  Only if the
> > attestation corresponds to the expected sha256sum of OVMF.fd should
> > the secret bundle be constructed and injected using qmp.  The tools
> > for constructing the secret bundle are in
> >
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fsev-tool%2F&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Ceb007b21e05c4e9c05cf08d8869fc874%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637407368116062086%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=BbCtv37bH0%2B6JDLM3afAubVN6K0Y%2FdO4TRz4ZkP1AKg%3D&amp;reserved=0
> 
> 
> Where you able to use the sev-tool as-is to generate a secret blob that
> can be injected through the Qemu QMP interface? The reason why I am
> asking this is because the last time when I looked at the sev-tool I
> found that it did not generated the blob which was in the correct format.
> 
> 
> >
> > James
> >
> > ---
> >
> > James Bottomley (4):
> >   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
> >   OvmfPkg/AmdSev: add Grub Firmware Volume Package
> >   OvmfPkg: create a SEV secret area in the AmdSev memfd
> >   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
> >
> >  OvmfPkg/OvmfPkg.dec                           |    6 +
> >  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
> >  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
> >  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
> >  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
> >  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
> >  .../PlatformBootManagerLibGrub.inf            |   84 +
> >  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
> >  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
> >  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
> >  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
> >  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
> >  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
> >  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
> >  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
> >  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
> >  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
> >  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
> >  18 files changed, 3846 insertions(+)
> >  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
> >  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
> >  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
> >  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
> >  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
> >  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
> >  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
> >  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
> >
> 
-- 
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67399): https://edk2.groups.io/g/devel/message/67399
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Brijesh Singh 3 years, 5 months ago
On 11/12/20 1:38 PM, Dr. David Alan Gilbert wrote:
> * Brijesh Singh (brijesh.singh@amd.com) wrote:
>> Hi James,
>>
>> Thanks for series, I glanced at it, the changes looks okay to me. I have
>> one questions.
>>
>> How does the grub locate the disk decryption key ? Am I correct in
>> assuming that the gurb is iterating through a configuration table
>> entries and comparing the Secret GUID to locate the secret key. As per
>> the SEV spec, its possible that a guest owner can call the secret
>> injection more than once. I don't see the patch consider that case,
>> should we support this or limit to one inject?  Maybe Qemu can enforce
>> this property.
> That's interesting, I hadn't realised that was possible - however,
> I can't see a way to use it - for it to be useful, you would have to
> have a way for the guest to communicate to the owner that it had
> finished with the first injection and would like the next; but if you
> already have a way to communicate from the guest to the owner to request
> stuff, then you could pass a new secret by that comms route?


The main reason for its existence was to allow guest owner to inject
multiple blocks of the data if they need to do so, e.g IIRC, Enarx folks
use this to inject the keep which is much bigger than 128K. I am not
sure if we really need it for the VM boot flow but we probably need to
define the secret page layout such that it contains multiple entries in
it. In our case the Secret can't be more than a page, so, we can define
a secret page layout such that it can contain more than one disk key. I
was thinking about something like this

typedef enum {

   DISK_KEY_AES_128,

   SSH_PRIVATE_KEY,

   ...

} data_type;

struct secret_data {

   u8 entries;

   struct {

      data_type type;

      u16 len;

      u8 name[16];

      u8 data[];

   } entry[];

}

This should allow us to package multiple secrets in one inject.

>
>> Do you see any need for the Linux kernel needing to access the secret?
>> Since the secret blob is available through configuration table, I
>> believe we can have a platform driver that can read the configuration
>> table and retrieve the secret blob.
> I guess it depends if you get the Grub to pass the fs secret down to the
> kernel or let it pick it up itself from the same place.


I guess the main reason why I was asking this is, what if guest owner
provides more than one disk keys in the secret injection blob. Grub can
use the boot disk key to access the Linux images and other disk keys may
later be used by Linux.

> Dave
>
>> thanks
>>
>> On 11/11/20 6:13 PM, James Bottomley wrote:
>>> From: James Bottomley <James.Bottomley@HansenPartnership.com>
>>>
>>> This patch series is modelled on the structure of the Bhyve patches
>>> for Ovmf, since it does somewhat similar things.  This patch series
>>> creates a separate build for an AmdSev OVMF.fd that does nothing
>>> except combine with grub and boot straight through the internal grub
>>> to try to mount an encrypted volume.
>>>
>>> Concept: SEV Secure Encrypted Images
>>> ====================================
>>>
>>> The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
>>> an encrypted state, but don't really show how this could be done with
>>> an encrypted image.  Since the key used to decrypt the image must be
>>> maintained within the SEV encryption envelope, encrypted QCOW is not
>>> an option because the key would then have to be known to QEMU which is
>>> outside the encryption envelope.  The proposal here is that an
>>> encrypted image should be a QCOW image consisting of two partitions,
>>> the normal unencrypted EFI partition (Identifying it as an OVMF
>>> bootable image) and a luks encrypted root partition.  The kernel would
>>> be inside the encrypted root in the /boot directory.  The secret
>>> injected securely through QEMU is extracted by OVMF and passed to grub
>>> which uses it to mount the encrypted root and boot the kernel
>>> normally.  The creator of the secret bundle must be satisfied with the
>>> SEV attestation before the secret is constructed.  Unfortunately, the
>>> SEV attestation can only be on the first QEMU firmware volume and
>>> nothing else, so this patch series builds grub itself into a firmware
>>> volume and places it inside OVMF so that the entire boot system can be
>>> attested.  In a normal OVMF KVM system, the variable store is on the
>>> second flash volume (which is read/write).  Unfortunately, this
>>> mutable configuration provided by the variables is outside the
>>> attestation envelope and can significantly alter the boot path,
>>> possibly leading to secret leak, so encrypted image boot should only
>>> be done with the OVMF.fd that combines both the code and variables.
>>> the OVMF.fd is constructed so that it becomes impossible to interrupt
>>> the boot sequence after attestation and the system will either boot
>>> the image or fail. The boot sequence runs the grub.efi embedded in the
>>> OVMF firmware volume so the encrypted image owner knows their own
>>> version of grub is the only one that will boot before injecting the
>>> secret.  Note this boot path actually ignores the unencrypted EFI
>>> partition.  However, as part of this design, the encrypted image may be
>>> booted by a standard OVMF KVM boot and in that case, the user will
>>> have to type the encryption password.  This standard boot will be
>>> insecure but it might be used by the constructor of the encrypted
>>> images on their own private laptop, for instance.  The standard boot
>>> path will use the unencrypted EFI partition.
>>>
>>> Patches Required Outside of OVMF
>>> ================================
>>>
>>> There is a patch set to grub which allows it to extract the SEV secret
>>> area from the configuration table and use the secret as a password to
>>> do a luks crypto mount of root (this is the sevsecret grub module).
>>>
>>> There is also a patch to qemu which allows it to search through the
>>> OVMF.fd and find the SEV secret area which is now described inside the
>>> Reset Vector using the existing SEV_ES reset block.  This area is the
>>> place QEMU will inject the encrypted SEV secret bundle.
>>>
>>> Security of the System
>>> ======================
>>>
>>> Since Grub is now part of the attested OVMF.fd bundle, the VM owner
>>> knows absolutely that it will proceed straight to partition decryption
>>> inside the attested code and boot the kernel off the encrypted
>>> partition.  Even if a different QCOW image is substituted, the boot
>>> will fail without revealing the secret because the system is designed
>>> to fail hard in that case and because the secret is always contained
>>> within the encrypted envelope it should be impossible for the cloud
>>> operator to obtain it even if they can pause the boot and examine the
>>> machine memory.
>>>
>>> Putting it All Together
>>> =======================
>>>
>>> This is somewhat hard.  You must first understand how to boot a QEMU
>>> system so as to have the VM pause after firmware loading (-S option)
>>> and use the qmp port to request an attestation.  Only if the
>>> attestation corresponds to the expected sha256sum of OVMF.fd should
>>> the secret bundle be constructed and injected using qmp.  The tools
>>> for constructing the secret bundle are in
>>>
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fsev-tool%2F&amp;data=04%7C01%7Cbrijesh.singh%40amd.com%7Cc5b99bba03c74eb5bc2308d887428054%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637408066981024287%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=SSmQZgDWx4P5a2hOJZRnhrM0n5ExpqzjLGolv0f0CC8%3D&amp;reserved=0
>>
>> Where you able to use the sev-tool as-is to generate a secret blob that
>> can be injected through the Qemu QMP interface? The reason why I am
>> asking this is because the last time when I looked at the sev-tool I
>> found that it did not generated the blob which was in the correct format.
>>
>>
>>> James
>>>
>>> ---
>>>
>>> James Bottomley (4):
>>>   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
>>>   OvmfPkg/AmdSev: add Grub Firmware Volume Package
>>>   OvmfPkg: create a SEV secret area in the AmdSev memfd
>>>   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
>>>
>>>  OvmfPkg/OvmfPkg.dec                           |    6 +
>>>  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
>>>  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
>>>  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
>>>  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
>>>  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
>>>  .../PlatformBootManagerLibGrub.inf            |   84 +
>>>  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
>>>  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
>>>  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
>>>  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
>>>  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
>>>  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
>>>  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
>>>  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
>>>  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
>>>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
>>>  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
>>>  18 files changed, 3846 insertions(+)
>>>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
>>>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
>>>  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
>>>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
>>>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
>>>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
>>>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
>>>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
>>>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
>>>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
>>>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
>>>  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
>>>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
>>>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
>>>


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67406): https://edk2.groups.io/g/devel/message/67406
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by James Bottomley 3 years, 5 months ago
On Thu, 2020-11-12 at 15:56 -0600, Brijesh Singh wrote:
> On 11/12/20 1:38 PM, Dr. David Alan Gilbert wrote:
> > * Brijesh Singh (brijesh.singh@amd.com) wrote:
> > > Hi James,
> > > 
> > > Thanks for series, I glanced at it, the changes looks okay to me.
> > > I have one questions.
> > > 
> > > How does the grub locate the disk decryption key ? Am I correct
> > > in assuming that the gurb is iterating through a configuration
> > > table entries and comparing the Secret GUID to locate the secret
> > > key. As per the SEV spec, its possible that a guest owner can
> > > call the secret injection more than once. I don't see the patch
> > > consider that case, should we support this or limit to one
> > > inject?  Maybe Qemu can enforce this property.
> > That's interesting, I hadn't realised that was possible - however,
> > I can't see a way to use it - for it to be useful, you would have
> > to have a way for the guest to communicate to the owner that it had
> > finished with the first injection and would like the next; but if
> > you already have a way to communicate from the guest to the owner
> > to request stuff, then you could pass a new secret by that comms
> > route?
> 
> The main reason for its existence was to allow guest owner to inject
> multiple blocks of the data if they need to do so, e.g IIRC, Enarx
> folks use this to inject the keep which is much bigger than 128K.

In some ways this sounds like the wrong approach.  I mean we could use
injection to inject the entire VM image as well, but we don't, we
inject the key and decrypt the image ... it does rather sound like
that's what should be happening for other bulk data, like the keep.  If
you do it this way you can use the main CPU and bulk memory encryption
to pull the data into the secure memory rather than using the PSP,
which is a lot slower.

Also one of the problems with having OVMF define the secret location is
that we have to find space in the MEMFD.  For a single page like the
current implementation uses, that's easy, but for tens to hundreds of
pages it would be impossible.  Even if we guid describe everything,
standard aes keys are 16-32 bytes, so even in the worst case we can fit
85 guid described decryption keys in a page, which should be more than
enough for anyone, provided we inject the key to the bulk data, not the
bulk data itself.

>  I am not sure if we really need it for the VM boot flow but we
> probably need to define the secret page layout such that it contains
> multiple entries in it. In our case the Secret can't be more than a
> page, so, we can define a secret page layout such that it can contain
> more than one disk key. I was thinking about something like this
> 
> typedef enum {
> 
>    DISK_KEY_AES_128,
> 
>    SSH_PRIVATE_KEY,
> 
>    ...
> 
> } data_type;
> 
> struct secret_data {
> 
>    u8 entries;
> 
>    struct {
> 
>       data_type type;
> 
>       u16 len;
> 
>       u8 name[16];
> 
>       u8 data[];
> 
>    } entry[];
> 
> }
> 
> This should allow us to package multiple secrets in one inject.

I proposed something slightly different in a prior email.  If we use
the guid approach, we don't have to define the data structure a-priori
... just the producer and consumer have to agree on what it is.

> > > Do you see any need for the Linux kernel needing to access the
> > > secret? Since the secret blob is available through configuration
> > > table, I believe we can have a platform driver that can read the
> > > configuration table and retrieve the secret blob.
> > I guess it depends if you get the Grub to pass the fs secret down
> > to the kernel or let it pick it up itself from the same place.
> 
> I guess the main reason why I was asking this is, what if guest owner
> provides more than one disk keys in the secret injection blob. Grub
> can use the boot disk key to access the Linux images and other disk
> keys may later be used by Linux.

Right, see other email for limitations.

James




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67407): https://edk2.groups.io/g/devel/message/67407
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Brijesh Singh 3 years, 5 months ago
On 11/12/20 4:50 PM, James Bottomley wrote:
> On Thu, 2020-11-12 at 15:56 -0600, Brijesh Singh wrote:
>> On 11/12/20 1:38 PM, Dr. David Alan Gilbert wrote:
>>> * Brijesh Singh (brijesh.singh@amd.com) wrote:
>>>> Hi James,
>>>>
>>>> Thanks for series, I glanced at it, the changes looks okay to me.
>>>> I have one questions.
>>>>
>>>> How does the grub locate the disk decryption key ? Am I correct
>>>> in assuming that the gurb is iterating through a configuration
>>>> table entries and comparing the Secret GUID to locate the secret
>>>> key. As per the SEV spec, its possible that a guest owner can
>>>> call the secret injection more than once. I don't see the patch
>>>> consider that case, should we support this or limit to one
>>>> inject?  Maybe Qemu can enforce this property.
>>> That's interesting, I hadn't realised that was possible - however,
>>> I can't see a way to use it - for it to be useful, you would have
>>> to have a way for the guest to communicate to the owner that it had
>>> finished with the first injection and would like the next; but if
>>> you already have a way to communicate from the guest to the owner
>>> to request stuff, then you could pass a new secret by that comms
>>> route?
>> The main reason for its existence was to allow guest owner to inject
>> multiple blocks of the data if they need to do so, e.g IIRC, Enarx
>> folks use this to inject the keep which is much bigger than 128K.
> In some ways this sounds like the wrong approach.  I mean we could use
> injection to inject the entire VM image as well, but we don't, we
> inject the key and decrypt the image ... it does rather sound like
> that's what should be happening for other bulk data, like the keep.  If
> you do it this way you can use the main CPU and bulk memory encryption
> to pull the data into the secure memory rather than using the PSP,
> which is a lot slower.

I wanted to highlight spec. I agree that in our VM launch I don't see a
need to provide a multiple LAUNCH_SECRET as long as we define producer
and consumer format to package the multiple secrets in one inject.


>
> Also one of the problems with having OVMF define the secret location is
> that we have to find space in the MEMFD.  For a single page like the
> current implementation uses, that's easy, but for tens to hundreds of
> pages it would be impossible.  Even if we guid describe everything,
> standard aes keys are 16-32 bytes, so even in the worst case we can fit
> 85 guid described decryption keys in a page, which should be more than
> enough for anyone, provided we inject the key to the bulk data, not the
> bulk data itself.
>>  I am not sure if we really need it for the VM boot flow but we
>> probably need to define the secret page layout such that it contains
>> multiple entries in it. In our case the Secret can't be more than a
>> page, so, we can define a secret page layout such that it can contain
>> more than one disk key. I was thinking about something like this
>>
>> typedef enum {
>>
>>    DISK_KEY_AES_128,
>>
>>    SSH_PRIVATE_KEY,
>>
>>    ...
>>
>> } data_type;
>>
>> struct secret_data {
>>
>>    u8 entries;
>>
>>    struct {
>>
>>       data_type type;
>>
>>       u16 len;
>>
>>       u8 name[16];
>>
>>       u8 data[];
>>
>>    } entry[];
>>
>> }
>>
>> This should allow us to package multiple secrets in one inject.
> I proposed something slightly different in a prior email.  If we use
> the guid approach, we don't have to define the data structure a-priori
> ... just the producer and consumer have to agree on what it is.


Yes, your guid approach is much preferred. thanks

>
>>>> Do you see any need for the Linux kernel needing to access the
>>>> secret? Since the secret blob is available through configuration
>>>> table, I believe we can have a platform driver that can read the
>>>> configuration table and retrieve the secret blob.
>>> I guess it depends if you get the Grub to pass the fs secret down
>>> to the kernel or let it pick it up itself from the same place.
>> I guess the main reason why I was asking this is, what if guest owner
>> provides more than one disk keys in the secret injection blob. Grub
>> can use the boot disk key to access the Linux images and other disk
>> keys may later be used by Linux.
> Right, see other email for limitations.
>
> James
>
>


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67585): https://edk2.groups.io/g/devel/message/67585
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Laszlo Ersek 3 years, 5 months ago
On 11/12/20 01:13, James Bottomley wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> This patch series is modelled on the structure of the Bhyve patches
> for Ovmf, since it does somewhat similar things.  This patch series
> creates a separate build for an AmdSev OVMF.fd that does nothing
> except combine with grub and boot straight through the internal grub
> to try to mount an encrypted volume.
> 
> Concept: SEV Secure Encrypted Images
> ====================================
> 
> The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
> an encrypted state, but don't really show how this could be done with
> an encrypted image.  Since the key used to decrypt the image must be
> maintained within the SEV encryption envelope, encrypted QCOW is not
> an option because the key would then have to be known to QEMU which is
> outside the encryption envelope.  The proposal here is that an
> encrypted image should be a QCOW image consisting of two partitions,
> the normal unencrypted EFI partition (Identifying it as an OVMF
> bootable image) and a luks encrypted root partition.  The kernel would
> be inside the encrypted root in the /boot directory.  The secret
> injected securely through QEMU is extracted by OVMF and passed to grub
> which uses it to mount the encrypted root and boot the kernel
> normally.  The creator of the secret bundle must be satisfied with the
> SEV attestation before the secret is constructed.  Unfortunately, the
> SEV attestation can only be on the first QEMU firmware volume and
> nothing else, so this patch series builds grub itself into a firmware
> volume and places it inside OVMF so that the entire boot system can be
> attested.  In a normal OVMF KVM system, the variable store is on the
> second flash volume (which is read/write).  Unfortunately, this
> mutable configuration provided by the variables is outside the
> attestation envelope and can significantly alter the boot path,
> possibly leading to secret leak, so encrypted image boot should only
> be done with the OVMF.fd that combines both the code and variables.
> the OVMF.fd is constructed so that it becomes impossible to interrupt
> the boot sequence after attestation and the system will either boot
> the image or fail. The boot sequence runs the grub.efi embedded in the
> OVMF firmware volume so the encrypted image owner knows their own
> version of grub is the only one that will boot before injecting the
> secret.  Note this boot path actually ignores the unencrypted EFI
> partition.  However, as part of this design, the encrypted image may be
> booted by a standard OVMF KVM boot and in that case, the user will
> have to type the encryption password.  This standard boot will be
> insecure but it might be used by the constructor of the encrypted
> images on their own private laptop, for instance.  The standard boot
> path will use the unencrypted EFI partition.
> 
> Patches Required Outside of OVMF
> ================================
> 
> There is a patch set to grub which allows it to extract the SEV secret
> area from the configuration table and use the secret as a password to
> do a luks crypto mount of root (this is the sevsecret grub module).
> 
> There is also a patch to qemu which allows it to search through the
> OVMF.fd and find the SEV secret area which is now described inside the
> Reset Vector using the existing SEV_ES reset block.  This area is the
> place QEMU will inject the encrypted SEV secret bundle.
> 
> Security of the System
> ======================
> 
> Since Grub is now part of the attested OVMF.fd bundle, the VM owner
> knows absolutely that it will proceed straight to partition decryption
> inside the attested code and boot the kernel off the encrypted
> partition.  Even if a different QCOW image is substituted, the boot
> will fail without revealing the secret because the system is designed
> to fail hard in that case and because the secret is always contained
> within the encrypted envelope it should be impossible for the cloud
> operator to obtain it even if they can pause the boot and examine the
> machine memory.
> 
> Putting it All Together
> =======================
> 
> This is somewhat hard.  You must first understand how to boot a QEMU
> system so as to have the VM pause after firmware loading (-S option)
> and use the qmp port to request an attestation.  Only if the
> attestation corresponds to the expected sha256sum of OVMF.fd should
> the secret bundle be constructed and injected using qmp.  The tools
> for constructing the secret bundle are in
> 
> https://github.com/AMDESE/sev-tool/
> 
> James
> 
> ---
> 
> James Bottomley (4):
>   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
>   OvmfPkg/AmdSev: add Grub Firmware Volume Package
>   OvmfPkg: create a SEV secret area in the AmdSev memfd
>   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
> 
>  OvmfPkg/OvmfPkg.dec                           |    6 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
>  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
>  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
>  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
>  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
>  .../PlatformBootManagerLibGrub.inf            |   84 +
>  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
>  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
>  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
>  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
>  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
>  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
>  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
>  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
>  18 files changed, 3846 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
>  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
>  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
> 

queued this thread for review



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67551): https://edk2.groups.io/g/devel/message/67551
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Laszlo Ersek 3 years, 5 months ago
Hi James,

On 11/12/20 01:13, James Bottomley wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> This patch series is modelled on the structure of the Bhyve patches
> for Ovmf, since it does somewhat similar things.  This patch series
> creates a separate build for an AmdSev OVMF.fd that does nothing
> except combine with grub and boot straight through the internal grub
> to try to mount an encrypted volume.

I've opened a feture request BZ at
<https://bugzilla.tianocore.org/show_bug.cgi?id=3077>.

Can you please register in the TianoCore Bugzilla, and assign the bug to
yourself?

I'll post more comments under the individual patches.

Thanks,
Laszlo

> 
> Concept: SEV Secure Encrypted Images
> ====================================
> 
> The SEV patches in Linux and OVMF allow for the booting of SEV VMs in
> an encrypted state, but don't really show how this could be done with
> an encrypted image.  Since the key used to decrypt the image must be
> maintained within the SEV encryption envelope, encrypted QCOW is not
> an option because the key would then have to be known to QEMU which is
> outside the encryption envelope.  The proposal here is that an
> encrypted image should be a QCOW image consisting of two partitions,
> the normal unencrypted EFI partition (Identifying it as an OVMF
> bootable image) and a luks encrypted root partition.  The kernel would
> be inside the encrypted root in the /boot directory.  The secret
> injected securely through QEMU is extracted by OVMF and passed to grub
> which uses it to mount the encrypted root and boot the kernel
> normally.  The creator of the secret bundle must be satisfied with the
> SEV attestation before the secret is constructed.  Unfortunately, the
> SEV attestation can only be on the first QEMU firmware volume and
> nothing else, so this patch series builds grub itself into a firmware
> volume and places it inside OVMF so that the entire boot system can be
> attested.  In a normal OVMF KVM system, the variable store is on the
> second flash volume (which is read/write).  Unfortunately, this
> mutable configuration provided by the variables is outside the
> attestation envelope and can significantly alter the boot path,
> possibly leading to secret leak, so encrypted image boot should only
> be done with the OVMF.fd that combines both the code and variables.
> the OVMF.fd is constructed so that it becomes impossible to interrupt
> the boot sequence after attestation and the system will either boot
> the image or fail. The boot sequence runs the grub.efi embedded in the
> OVMF firmware volume so the encrypted image owner knows their own
> version of grub is the only one that will boot before injecting the
> secret.  Note this boot path actually ignores the unencrypted EFI
> partition.  However, as part of this design, the encrypted image may be
> booted by a standard OVMF KVM boot and in that case, the user will
> have to type the encryption password.  This standard boot will be
> insecure but it might be used by the constructor of the encrypted
> images on their own private laptop, for instance.  The standard boot
> path will use the unencrypted EFI partition.
> 
> Patches Required Outside of OVMF
> ================================
> 
> There is a patch set to grub which allows it to extract the SEV secret
> area from the configuration table and use the secret as a password to
> do a luks crypto mount of root (this is the sevsecret grub module).
> 
> There is also a patch to qemu which allows it to search through the
> OVMF.fd and find the SEV secret area which is now described inside the
> Reset Vector using the existing SEV_ES reset block.  This area is the
> place QEMU will inject the encrypted SEV secret bundle.
> 
> Security of the System
> ======================
> 
> Since Grub is now part of the attested OVMF.fd bundle, the VM owner
> knows absolutely that it will proceed straight to partition decryption
> inside the attested code and boot the kernel off the encrypted
> partition.  Even if a different QCOW image is substituted, the boot
> will fail without revealing the secret because the system is designed
> to fail hard in that case and because the secret is always contained
> within the encrypted envelope it should be impossible for the cloud
> operator to obtain it even if they can pause the boot and examine the
> machine memory.
> 
> Putting it All Together
> =======================
> 
> This is somewhat hard.  You must first understand how to boot a QEMU
> system so as to have the VM pause after firmware loading (-S option)
> and use the qmp port to request an attestation.  Only if the
> attestation corresponds to the expected sha256sum of OVMF.fd should
> the secret bundle be constructed and injected using qmp.  The tools
> for constructing the secret bundle are in
> 
> https://github.com/AMDESE/sev-tool/
> 
> James
> 
> ---
> 
> James Bottomley (4):
>   OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF
>   OvmfPkg/AmdSev: add Grub Firmware Volume Package
>   OvmfPkg: create a SEV secret area in the AmdSev memfd
>   OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table
> 
>  OvmfPkg/OvmfPkg.dec                           |    6 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  | 1035 +++++++++++
>  OvmfPkg/AmdSev/AmdSevX64.fdf                  |  515 ++++++
>  OvmfPkg/AmdSev/Grub/Grub.inf                  |   37 +
>  .../SevLaunchSecret/SecretDxe/SecretDxe.inf   |   38 +
>  .../SevLaunchSecret/SecretPei/SecretPei.inf   |   46 +
>  .../PlatformBootManagerLibGrub.inf            |   84 +
>  OvmfPkg/ResetVector/ResetVector.inf           |    4 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.h  |  179 ++
>  .../SevLaunchSecret/SecretDxe/SecretDxe.c     |   29 +
>  .../SevLaunchSecret/SecretPei/SecretPei.c     |   26 +
>  .../PlatformBootManagerLibGrub/BdsPlatform.c  | 1538 +++++++++++++++++
>  .../PlatformBootManagerLibGrub/PlatformData.c |  213 +++
>  OvmfPkg/AmdSev/Grub/.gitignore                |    1 +
>  OvmfPkg/AmdSev/Grub/grub.cfg                  |   35 +
>  OvmfPkg/AmdSev/Grub/grub.sh                   |   54 +
>  OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |    4 +
>  OvmfPkg/ResetVector/ResetVector.nasmb         |    2 +
>  18 files changed, 3846 insertions(+)
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.dsc
>  create mode 100644 OvmfPkg/AmdSev/AmdSevX64.fdf
>  create mode 100644 OvmfPkg/AmdSev/Grub/Grub.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.inf
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.h
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretDxe/SecretDxe.c
>  create mode 100644 OvmfPkg/AmdSev/SevLaunchSecret/SecretPei/SecretPei.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/BdsPlatform.c
>  create mode 100644 OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformData.c
>  create mode 100644 OvmfPkg/AmdSev/Grub/.gitignore
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.cfg
>  create mode 100644 OvmfPkg/AmdSev/Grub/grub.sh
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67613): https://edk2.groups.io/g/devel/message/67613
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by James Bottomley 3 years, 5 months ago
On Mon, 2020-11-16 at 19:50 +0100, Laszlo Ersek wrote:
> Hi James,
> 
> On 11/12/20 01:13, James Bottomley wrote:
> > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > 
> > This patch series is modelled on the structure of the Bhyve patches
> > for Ovmf, since it does somewhat similar things.  This patch series
> > creates a separate build for an AmdSev OVMF.fd that does nothing
> > except combine with grub and boot straight through the internal
> > grub
> > to try to mount an encrypted volume.
> 
> I've opened a feture request BZ at
> <https://bugzilla.tianocore.org/show_bug.cgi?id=3077>;.
> 
> Can you please register in the TianoCore Bugzilla, and assign the bug
> to yourself?

OK, done.

> I'll post more comments under the individual patches.

Great, thanks!

James




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67617): https://edk2.groups.io/g/devel/message/67617
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH 0/4] SEV Encrypted Boot for Ovmf
Posted by Laszlo Ersek 3 years, 5 months ago
On 11/16/20 19:50, Laszlo Ersek wrote:
> Hi James,
> 
> On 11/12/20 01:13, James Bottomley wrote:
>> From: James Bottomley <James.Bottomley@HansenPartnership.com>
>>
>> This patch series is modelled on the structure of the Bhyve patches
>> for Ovmf, since it does somewhat similar things.  This patch series
>> creates a separate build for an AmdSev OVMF.fd that does nothing
>> except combine with grub and boot straight through the internal grub
>> to try to mount an encrypted volume.
> 
> I've opened a feture request BZ at
> <https://bugzilla.tianocore.org/show_bug.cgi?id=3077>.
> 
> Can you please register in the TianoCore Bugzilla, and assign the bug to
> yourself?
> 
> I'll post more comments under the individual patches.

(1) There are a number of git settings that are useful with edk2 clones.
Most of them are described at

<https://github.com/tianocore/tianocore.github.io/wiki/Laszlo%27s-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-05>

but for convenience, the edk2 repo provides the
"BaseTools/Scripts/SetupGit.py" script. Can you please run it in your
git repo?


(2) Every commit message should reference TianoCore#3077 like this:

"""
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077
"""

just above the S-o-b.

Thanks
Laszlo



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67614): https://edk2.groups.io/g/devel/message/67614
Mute This Topic: https://groups.io/mt/78198617/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-