summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/AmdSev
diff options
context:
space:
mode:
authorJames Bottomley <jejb@linux.ibm.com>2020-11-30 12:28:16 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-12-14 19:56:18 +0000
commitb261a30c900a81b76c18bcc71841aab13849d069 (patch)
tree92a4a12dd7e1e3628d17dbfeb330d6ba8bff8c59 /OvmfPkg/AmdSev
parent30d277ed7a820891b0d85ccc223d05789b1d6148 (diff)
downloadedk2-b261a30c900a81b76c18bcc71841aab13849d069.tar.gz
edk2-b261a30c900a81b76c18bcc71841aab13849d069.tar.bz2
edk2-b261a30c900a81b76c18bcc71841aab13849d069.zip
OvmfPkg/AmdSev: add Grub Firmware Volume Package
This is used to package up the grub bootloader into a firmware volume where it can be executed as a shell like the UEFI Shell. Grub itself is built as a minimal entity into a Fv and then added as a boot option. By default the UEFI shell isn't built but for debugging purposes it can be enabled and will then be presented as a boot option (This should never be allowed for secure boot in an external data centre but may be useful for local debugging). Finally all other boot options except grub and possibly the shell are stripped and the boot timeout forced to 0 so the system will not enter a setup menu and will only boot to grub. This is done by copying the Library/PlatformBootManagerLib into Library/PlatformBootManagerLibGrub and then customizing it. Boot failure is fatal to try to prevent secret theft. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3077 Signed-off-by: James Bottomley <jejb@linux.ibm.com> Message-Id: <20201130202819.3910-4-jejb@linux.ibm.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com> [lersek@redhat.com: replace local variable initialization with assignment] Reviewed-by: Laszlo Ersek <lersek@redhat.com> [lersek@redhat.com: squash 'OvmfPkg: add "gGrubFileGuid=Grub" to GuidCheck.IgnoreDuplicates', reviewed stand-alone by Phil (msgid <e6eae551-8563-ccfb-5547-7a97da6d46e5@redhat.com>) and Ard (msgid <10aeda37-def6-d9a4-6e02-4c66c1492f57@arm.com>)]
Diffstat (limited to 'OvmfPkg/AmdSev')
-rw-r--r--OvmfPkg/AmdSev/AmdSevX64.dsc21
-rw-r--r--OvmfPkg/AmdSev/AmdSevX64.fdf7
-rw-r--r--OvmfPkg/AmdSev/Grub/.gitignore1
-rw-r--r--OvmfPkg/AmdSev/Grub/Grub.inf39
-rw-r--r--OvmfPkg/AmdSev/Grub/grub.cfg46
-rw-r--r--OvmfPkg/AmdSev/Grub/grub.sh93
6 files changed, 198 insertions, 9 deletions
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 59778c4954..18707725b3 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -25,6 +25,7 @@
BUILD_TARGETS = NOOPT|DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = OvmfPkg/AmdSev/AmdSevX64.fdf
+ PREBUILD = sh OvmfPkg/AmdSev/Grub/grub.sh
#
# Defines for default states. These can be changed on the command line.
@@ -35,6 +36,11 @@
DEFINE TPM_CONFIG_ENABLE = FALSE
#
+ # Shell can be useful for debugging but should not be enabled for production
+ #
+ DEFINE BUILD_SHELL = FALSE
+
+ #
# Device drivers
#
DEFINE PVSCSI_ENABLE = TRUE
@@ -149,7 +155,6 @@
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
- NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
@@ -184,9 +189,11 @@
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+!if $(BUILD_SHELL) == TRUE
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+!endif
+
SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
@@ -343,7 +350,7 @@
!else
DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
!endif
- PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+ PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLibGrub/PlatformBootManagerLibGrub.inf
PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -507,6 +514,7 @@
# Point to the MdeModulePkg/Application/UiApp/UiApp.inf
gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|TRUE
################################################################################
#
# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
@@ -751,8 +759,6 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
OvmfPkg/AcpiTables/AcpiTables.inf
- MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
- MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
#
@@ -765,12 +771,14 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
-!if $(TOOL_CHAIN_TAG) != "XCODE5"
+!if $(TOOL_CHAIN_TAG) != "XCODE5" && $(BUILD_SHELL) == TRUE
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
!endif
+ OvmfPkg/AmdSev/Grub/Grub.inf
+!if $(BUILD_SHELL) == TRUE
ShellPkg/Application/Shell/Shell.inf {
<LibraryClasses>
ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
@@ -789,6 +797,7 @@
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
}
+!endif
OvmfPkg/PlatformDxe/Platform.inf
OvmfPkg/AmdSevDxe/AmdSevDxe.inf
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index b884166771..1aa9582638 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -257,17 +257,18 @@ INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
INF RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
-INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
-INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
-!if $(TOOL_CHAIN_TAG) != "XCODE5"
+!if $(TOOL_CHAIN_TAG) != "XCODE5" && $(BUILD_SHELL) == TRUE
INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
!endif
+INF OvmfPkg/AmdSev/Grub/Grub.inf
+!if $(BUILD_SHELL) == TRUE
INF ShellPkg/Application/Shell/Shell.inf
+!endif
INF MdeModulePkg/Logo/LogoDxe.inf
diff --git a/OvmfPkg/AmdSev/Grub/.gitignore b/OvmfPkg/AmdSev/Grub/.gitignore
new file mode 100644
index 0000000000..779a865c4b
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/.gitignore
@@ -0,0 +1 @@
+grub.efi
diff --git a/OvmfPkg/AmdSev/Grub/Grub.inf b/OvmfPkg/AmdSev/Grub/Grub.inf
new file mode 100644
index 0000000000..90dc6c7b1e
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/Grub.inf
@@ -0,0 +1,39 @@
+## @file
+# Create a Firmware Volume based Grub Bootloader
+#
+# Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = Grub
+ # This is gGrubFileGuid
+ FILE_GUID = b5ae312c-bc8a-43b1-9c62-ebb826dd5d07
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+[Packages]
+ OvmfPkg/OvmfPkg.dec
+
+#
+# The following information is for reference only and not required by
+# the build tools.
+#
+# VALID_ARCHITECTURES = X64
+#
+
+##
+# Note: The version of grub.efi this picks up can be generated by
+# grub.sh which must be specified as a PREBUILD in the .dsc file. If
+# grub.efi is newer than either grub.sh or grub.cfg then grub.sh will
+# exit with success meaning that if you move your own version of grub
+# in here (after checking out grub.sh and grub.cfg), PREBUILD won't
+# overwrite it.
+##
+[Binaries]
+ PE32|grub.efi|*
+
diff --git a/OvmfPkg/AmdSev/Grub/grub.cfg b/OvmfPkg/AmdSev/Grub/grub.cfg
new file mode 100644
index 0000000000..17be94277a
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/grub.cfg
@@ -0,0 +1,46 @@
+## @file
+# Execute a script to recover the SEV supplied secret and use it to
+# decrypt a luks volume. For security, the kernel must be on an encrypted
+# volume so reboot if none are found.
+#
+# Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+echo "Entering grub config"
+sevsecret
+if [ $? -ne 0 ]; then
+ echo "Failed to locate anything in the SEV secret area, prompting for password"
+ cryptomount -a
+else
+ cryptomount -s
+ if [ $? -ne 0 ]; then
+ echo "Failed to mount root securely, retrying with password prompt"
+ cryptomount -a
+ fi
+fi
+set root=
+for f in (crypto*); do
+ if [ -e $f/boot/grub/grub.cfg ]; then
+ set root=$f
+ set prefix=($root)/boot/grub
+ break;
+ fi
+done
+if [ x$root = x ]; then
+ echo "Failed to find any grub configuration on the encrypted volume"
+ sleep 5
+ reboot
+fi
+# rest of modules to get boot to work
+set modules="
+ boot
+ loadenv
+ "
+for f in $modules; do
+ insmod $f
+done
+echo "Transferring to ${prefix}/grub.cfg"
+source $prefix/grub.cfg
diff --git a/OvmfPkg/AmdSev/Grub/grub.sh b/OvmfPkg/AmdSev/Grub/grub.sh
new file mode 100644
index 0000000000..99807d7291
--- /dev/null
+++ b/OvmfPkg/AmdSev/Grub/grub.sh
@@ -0,0 +1,93 @@
+## @file
+# Build a version of grub capable of decrypting a luks volume with a SEV
+# Supplied secret
+#
+# Copyright (C) 2020 James Bottomley, IBM Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+set -e
+remove_efi=1
+
+cleanup() {
+ # remove the intermediates
+ for f in disk.fat grub-bootstrap.cfg; do
+ rm -f -- "${basedir}/$f"
+ done
+ if [ $remove_efi -eq 1 ]; then
+ rm -f -- "${basedir}/grub.efi"
+ fi
+}
+
+trap cleanup EXIT
+
+GRUB_MODULES="
+ part_msdos
+ part_gpt
+ cryptodisk
+ luks
+ gcry_rijndael
+ gcry_sha256
+ ext2
+ btrfs
+ xfs
+ fat
+ configfile
+ memdisk
+ sleep
+ normal
+ echo
+ test
+ regexp
+ linux
+ linuxefi
+ reboot
+ sevsecret
+ "
+basedir=$(dirname -- "$0")
+
+# don't run a build if grub.efi exists and is newer than the config files
+if [ -e "${basedir}/grub.efi" ] && \
+ [ "${basedir}/grub.efi" -nt "${basedir}/grub.cfg" ] && \
+ [ "${basedir}/grub.efi" -nt "${basedir}/grub.sh" ]; then
+ remove_efi=0
+ echo "preserving existing grub.efi" >&2
+ exit 0
+fi
+
+##
+# different distributions have different names for grub-mkimage, so
+# search all the known ones
+##
+mkimage=
+for b in grub2-mkimage grub-mkimage; do
+ if which "$b" > /dev/null 2>&1; then
+ mkimage="$b"
+ break
+ fi
+done
+if [ -z "$mkimage" ]; then
+ echo "Can't find grub mkimage" >&2
+ exit 1
+fi
+
+# GRUB's rescue parser doesn't understand 'if'.
+echo 'normal (memdisk)/grub.cfg' > "${basedir}/grub-bootstrap.cfg"
+
+# Now build a memdisk with the correct grub.cfg
+rm -f -- "${basedir}/disk.fat"
+mkfs.msdos -C -- "${basedir}/disk.fat" 64
+mcopy -i "${basedir}/disk.fat" -- "${basedir}/grub.cfg" ::grub.cfg
+
+
+${mkimage} -O x86_64-efi \
+ -p '(crypto0)' \
+ -c "${basedir}/grub-bootstrap.cfg" \
+ -m "${basedir}/disk.fat" \
+ -o "${basedir}/grub.efi" \
+ ${GRUB_MODULES}
+
+remove_efi=0
+echo "grub.efi generated in ${basedir}"