From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:4001:c06::22d; helo=mail-io0-x22d.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-io0-x22d.google.com (mail-io0-x22d.google.com [IPv6:2607:f8b0:4001:c06::22d]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B46B7224A9EC9 for ; Fri, 30 Mar 2018 04:00:57 -0700 (PDT) Received: by mail-io0-x22d.google.com with SMTP id l3so10759446iog.0 for ; Fri, 30 Mar 2018 04:00:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=CzeaMeCK2An3dcc4p36RVIGOD+mt7PmkL6pqRd3Cf1Q=; b=LTgRqX7i6XpmlqfOvXrTTXXzy5hBKj0IIveyGRzI+YcnYtFF6Mvc+Lr7kDT6OAOQrd ilTzpRq2IOhblOKxzcdh+f/tXSEv64u/xnHTTWSb7C2I9oG1pTZu62aShTQO37KB/HBW tqR3a/qdyoe2QCQv01gJ386e2GNX9qJC279X4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=CzeaMeCK2An3dcc4p36RVIGOD+mt7PmkL6pqRd3Cf1Q=; b=MSSAUuxAcOoArjiytyDCaW6XXITWu/8xoNRMPCWRIfGi0PimrA0tRdOpqvqIUEIuk7 V370Qcqu4+1Jcj49ris4yzihPEjsULnJlt/SRnMu7PgaAeYSrVOvHNvpba2kOxUJh5H9 QZw9p5hW+halJ0/y1U3QEzt46JfleajlWNsx0Tc7BneoBdTaWdQWHBoIfykFi13IgXIz bgavwUYujv3Bqki0QRmuxaWCYOlvQKke7v9BiughSDsLVxBqDHvf9GNYpQc8txnKzBFy W3lQwIRE52BRgkkroMtJ05ToMKZHxOcpOWdTiHv7IWUGulSkY49wexV7io6MoK3y5YEs bEbQ== X-Gm-Message-State: AElRT7H9KAqLBsBTN5kG1BXOOoVF49AahKHytqW2Y9Lvos3y6sh7p3KT 7E/6YH5QVhuOhN3igiBMhwb/LR3SCgVg1c/HeoebrA== X-Google-Smtp-Source: AG47ELuGJdgIt6Hq/+qYtQnufHFrZ5YPorP3FcE7sW5kiO08xHG6CsTSVw3ZXeTjZ5M9PjTJ4zE7ivojbXfX0VGDpPI= X-Received: by 10.107.14.136 with SMTP id 130mr44026576ioo.170.1522407655535; Fri, 30 Mar 2018 04:00:55 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.187.67 with HTTP; Fri, 30 Mar 2018 04:00:55 -0700 (PDT) In-Reply-To: <20180328202651.1478-5-lersek@redhat.com> References: <20180328202651.1478-1-lersek@redhat.com> <20180328202651.1478-5-lersek@redhat.com> From: Ard Biesheuvel Date: Fri, 30 Mar 2018 12:00:55 +0100 Message-ID: To: Laszlo Ersek Cc: edk2-devel-01 , Gary Ching-Pang Lin , Jordan Justen Subject: Re: [PATCH 4/4] OvmfPkg/TlsAuthConfigLib: configure trusted CA certs for HTTPS boot X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Mar 2018 11:00:58 -0000 Content-Type: text/plain; charset="UTF-8" On 28 March 2018 at 21:26, Laszlo Ersek 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 > Cc: Gary Ching-Pang Lin > Cc: Jordan Justen > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek Reviewed-by: Ard Biesheuvel > --- > 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 { > + > + 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 { > + > + 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 { > + > + 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.
> +# > +# 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.
> + > + 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 > +#include > + > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +/** > + 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 >