On 28 March 2018 at 21:26, Laszlo Ersek <[email protected]> wrote: > Introduce TlsAuthConfigLib to read the list of trusted CA certificates > from fw_cfg and to store it to EFI_TLS_CA_CERTIFICATE_VARIABLE. > > The fw_cfg file is formatted by the "p11-kit" and "update-ca-trust" > utilities on the host side, so that the host settings take effect in guest > HTTPS boot as well. QEMU forwards the file intact to the firmware. The > contents are sanity-checked by NetworkPkg/HttpDxe code that was added in > commit 0fd13678a681. > > Link TlsAuthConfigLib via NULL resolution into TlsAuthConfigDxe. This sets > EFI_TLS_CA_CERTIFICATE_VARIABLE in time for both > NetworkPkg/TlsAuthConfigDxe (for possible HII interaction with the user) > and for NetworkPkg/HttpDxe (for the effective TLS configuration). > > The file formatted by "p11-kit" can be large. On a RHEL-7 host, the the > Mozilla CA root certificate bundle -- installed with the "ca-certificates" > package -- is processed into a 182KB file. Thus, create > EFI_TLS_CA_CERTIFICATE_VARIABLE as a volatile & boot-time only variable. > Also, in TLS_ENABLE builds, set the cumulative limit for volatile > variables (PcdVariableStoreSize) to 512KB, and the individual limit for > the same (PcdMaxVolatileVariableSize) to 256KB. > > Cc: Ard Biesheuvel <[email protected]> > Cc: Gary Ching-Pang Lin <[email protected]> > Cc: Jordan Justen <[email protected]> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek <[email protected]>
Reviewed-by: Ard Biesheuvel <[email protected]> > --- > OvmfPkg/OvmfPkgIa32.dsc | 13 +- > OvmfPkg/OvmfPkgIa32X64.dsc | 13 +- > OvmfPkg/OvmfPkgX64.dsc | 13 +- > OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf | 55 ++++++++ > OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c | 133 > ++++++++++++++++++++ > 5 files changed, 224 insertions(+), 3 deletions(-) > > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc > index 7664b50ddef9..c9eb248506c5 100644 > --- a/OvmfPkg/OvmfPkgIa32.dsc > +++ b/OvmfPkg/OvmfPkgIa32.dsc > @@ -439,15 +439,23 @@ [PcdsFixedAtBuild] > !if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048) > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 > +!if $(TLS_ENABLE) == FALSE > # match PcdFlashNvStorageVariableSize purely for convenience > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000 > !endif > +!endif > !if $(FD_SIZE_IN_KB) == 4096 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400 > +!if $(TLS_ENABLE) == FALSE > # match PcdFlashNvStorageVariableSize purely for convenience > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000 > !endif > +!endif > +!if $(TLS_ENABLE) == TRUE > + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000 > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000 > +!endif > > gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 > > @@ -796,7 +804,10 @@ [Components] > !endif > !if $(TLS_ENABLE) == TRUE > NetworkPkg/TlsDxe/TlsDxe.inf > - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf > + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { > + <LibraryClasses> > + NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf > + } > !endif > OvmfPkg/VirtioNetDxe/VirtioNet.inf > > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc > index e5969090d437..17aef2d4830f 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.dsc > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc > @@ -444,15 +444,23 @@ [PcdsFixedAtBuild] > !if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048) > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 > +!if $(TLS_ENABLE) == FALSE > # match PcdFlashNvStorageVariableSize purely for convenience > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000 > !endif > +!endif > !if $(FD_SIZE_IN_KB) == 4096 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400 > +!if $(TLS_ENABLE) == FALSE > # match PcdFlashNvStorageVariableSize purely for convenience > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000 > !endif > +!endif > +!if $(TLS_ENABLE) == TRUE > + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000 > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000 > +!endif > > gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 > > @@ -805,7 +813,10 @@ [Components.X64] > !endif > !if $(TLS_ENABLE) == TRUE > NetworkPkg/TlsDxe/TlsDxe.inf > - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf > + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { > + <LibraryClasses> > + NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf > + } > !endif > OvmfPkg/VirtioNetDxe/VirtioNet.inf > > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc > index 7197c1984a7c..8af763ea9e9e 100644 > --- a/OvmfPkg/OvmfPkgX64.dsc > +++ b/OvmfPkg/OvmfPkgX64.dsc > @@ -444,15 +444,23 @@ [PcdsFixedAtBuild] > !if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048) > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 > +!if $(TLS_ENABLE) == FALSE > # match PcdFlashNvStorageVariableSize purely for convenience > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000 > !endif > +!endif > !if $(FD_SIZE_IN_KB) == 4096 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400 > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400 > +!if $(TLS_ENABLE) == FALSE > # match PcdFlashNvStorageVariableSize purely for convenience > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000 > !endif > +!endif > +!if $(TLS_ENABLE) == TRUE > + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000 > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000 > +!endif > > gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 > > @@ -803,7 +811,10 @@ [Components] > !endif > !if $(TLS_ENABLE) == TRUE > NetworkPkg/TlsDxe/TlsDxe.inf > - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf > + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { > + <LibraryClasses> > + NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf > + } > !endif > OvmfPkg/VirtioNetDxe/VirtioNet.inf > > diff --git a/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf > b/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf > new file mode 100644 > index 000000000000..5f83582a8313 > --- /dev/null > +++ b/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf > @@ -0,0 +1,55 @@ > +## @file > +# > +# A hook-in library for NetworkPkg/TlsAuthConfigDxe, in order to set volatile > +# variables related to TLS configuration, before TlsAuthConfigDxe or HttpDxe > +# (which is a UEFI_DRIVER) consume them. > +# > +# Copyright (C) 2013, 2015, 2018, Red Hat, Inc. > +# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR> > +# > +# This program and the accompanying materials are licensed and made available > +# under the terms and conditions of the BSD License which accompanies this > +# distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > WITHOUT > +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +# > +## > + > +[Defines] > + INF_VERSION = 1.26 > + BASE_NAME = TlsAuthConfigLib > + FILE_GUID = 660AB627-4C5F-4D42-A3B6-BD021E9028BD > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = TlsAuthConfigLib|DXE_DRIVER > + CONSTRUCTOR = TlsAuthConfigInit > + > +# > +# The following information is for reference only and not required by the > build > +# tools. > +# > +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 > +# > + > +[Sources] > + TlsAuthConfigLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + NetworkPkg/NetworkPkg.dec > + OvmfPkg/OvmfPkg.dec > + > +[LibraryClasses] > + BaseLib > + DebugLib > + MemoryAllocationLib > + QemuFwCfgLib > + UefiRuntimeServicesTableLib > + > +[Guids] > + gEfiTlsCaCertificateGuid ## PRODUCES ## Variable:L"TlsCaCertificate" > + > +[Depex] > + gEfiVariableWriteArchProtocolGuid > diff --git a/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c > b/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c > new file mode 100644 > index 000000000000..b5b33bc4fc69 > --- /dev/null > +++ b/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c > @@ -0,0 +1,133 @@ > +/** @file > + > + A hook-in library for NetworkPkg/TlsAuthConfigDxe, in order to set volatile > + variables related to TLS configuration, before TlsAuthConfigDxe or HttpDxe > + (which is a UEFI_DRIVER) consume them. > + > + Copyright (C) 2013, 2015, 2018, Red Hat, Inc. > + Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR> > + > + This program and the accompanying materials are licensed and made available > + under the terms and conditions of the BSD License which accompanies this > + distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > WITHOUT > + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > +**/ > + > +#include <Uefi/UefiBaseType.h> > +#include <Uefi/UefiSpec.h> > + > +#include <Guid/TlsAuthentication.h> > + > +#include <Library/BaseLib.h> > +#include <Library/DebugLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/QemuFwCfgLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > + > +/** > + Read the list of trusted CA certificates from the fw_cfg file > + "etc/edk2/https/cacerts", and store it to > + gEfiTlsCaCertificateGuid:EFI_TLS_CA_CERTIFICATE_VARIABLE. > + > + The contents are validated (for well-formedness) by NetworkPkg/HttpDxe. > +**/ > +STATIC > +VOID > +SetCaCerts ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + FIRMWARE_CONFIG_ITEM HttpsCaCertsItem; > + UINTN HttpsCaCertsSize; > + VOID *HttpsCaCerts; > + > + Status = QemuFwCfgFindFile ("etc/edk2/https/cacerts", &HttpsCaCertsItem, > + &HttpsCaCertsSize); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_VERBOSE, "%a:%a: not touching CA cert list\n", > + gEfiCallerBaseName, __FUNCTION__)); > + return; > + } > + > + // > + // Delete the current EFI_TLS_CA_CERTIFICATE_VARIABLE if it exists. This > + // serves two purposes: > + // > + // (a) If the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we > + // cannot make it volatile without deleting it first. > + // > + // (b) If we fail to recreate the variable later, deleting the current one > is > + // still justified if the fw_cfg file exists. Emptying the set of > trusted > + // CA certificates will fail HTTPS boot, which is better than trusting > + // any certificate that's possibly missing from the fw_cfg file. > + // > + Status = gRT->SetVariable ( > + EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName > + &gEfiTlsCaCertificateGuid, // VendorGuid > + 0, // Attributes > + 0, // DataSize > + NULL // Data > + ); > + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { > + // > + // This is fatal. > + // > + DEBUG ((DEBUG_ERROR, "%a:%a: failed to delete %g:\"%s\"\n", > + gEfiCallerBaseName, __FUNCTION__, &gEfiTlsCaCertificateGuid, > + EFI_TLS_CA_CERTIFICATE_VARIABLE)); > + ASSERT_EFI_ERROR (Status); > + CpuDeadLoop (); > + } > + > + if (HttpsCaCertsSize == 0) { > + DEBUG ((DEBUG_VERBOSE, "%a:%a: applied empty CA cert list\n", > + gEfiCallerBaseName, __FUNCTION__)); > + return; > + } > + > + HttpsCaCerts = AllocatePool (HttpsCaCertsSize); > + if (HttpsCaCerts == NULL) { > + DEBUG ((DEBUG_ERROR, "%a:%a: failed to allocate HttpsCaCerts\n", > + gEfiCallerBaseName, __FUNCTION__)); > + return; > + } > + > + QemuFwCfgSelectItem (HttpsCaCertsItem); > + QemuFwCfgReadBytes (HttpsCaCertsSize, HttpsCaCerts); > + > + Status = gRT->SetVariable ( > + EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName > + &gEfiTlsCaCertificateGuid, // VendorGuid > + EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes > + HttpsCaCertsSize, // DataSize > + HttpsCaCerts // Data > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a:%a: failed to set %g:\"%s\": %r\n", > + gEfiCallerBaseName, __FUNCTION__, &gEfiTlsCaCertificateGuid, > + EFI_TLS_CA_CERTIFICATE_VARIABLE, Status)); > + goto FreeHttpsCaCerts; > + } > + > + DEBUG ((DEBUG_VERBOSE, "%a:%a: stored CA cert list (%Lu byte(s))\n", > + gEfiCallerBaseName, __FUNCTION__, (UINT64)HttpsCaCertsSize)); > + > +FreeHttpsCaCerts: > + FreePool (HttpsCaCerts); > +} > + > +RETURN_STATUS > +EFIAPI > +TlsAuthConfigInit ( > + VOID > + ) > +{ > + SetCaCerts (); > + > + return RETURN_SUCCESS; > +} > -- > 2.14.1.3.gb7cf6e02401b > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

