Copyright (C) 2013, 2015, 2018, Red Hat, Inc.\r
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials are licensed and made available\r
- under the terms and conditions of the BSD License which accompanies this\r
- distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Uefi/UefiBaseType.h>\r
#include <Uefi/UefiSpec.h>\r
\r
+#include <Guid/HttpTlsCipherList.h>\r
#include <Guid/TlsAuthentication.h>\r
\r
#include <Library/BaseLib.h>\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
- FIRMWARE_CONFIG_ITEM HttpsCaCertsItem;\r
- UINTN HttpsCaCertsSize;\r
- VOID *HttpsCaCerts;\r
+ EFI_STATUS Status;\r
+ FIRMWARE_CONFIG_ITEM HttpsCaCertsItem;\r
+ UINTN HttpsCaCertsSize;\r
+ VOID *HttpsCaCerts;\r
\r
- Status = QemuFwCfgFindFile ("etc/edk2/https/cacerts", &HttpsCaCertsItem,\r
- &HttpsCaCertsSize);\r
+ Status = QemuFwCfgFindFile (\r
+ "etc/edk2/https/cacerts",\r
+ &HttpsCaCertsItem,\r
+ &HttpsCaCertsSize\r
+ );\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_VERBOSE, "%a:%a: not touching CA cert list\n",\r
- gEfiCallerBaseName, __FUNCTION__));\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a:%a: not touching CA cert list\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__\r
+ ));\r
return;\r
}\r
\r
//\r
// This is fatal.\r
//\r
- DEBUG ((DEBUG_ERROR, "%a:%a: failed to delete %g:\"%s\"\n",\r
- gEfiCallerBaseName, __FUNCTION__, &gEfiTlsCaCertificateGuid,\r
- EFI_TLS_CA_CERTIFICATE_VARIABLE));\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to delete %g:\"%s\"\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ &gEfiTlsCaCertificateGuid,\r
+ EFI_TLS_CA_CERTIFICATE_VARIABLE\r
+ ));\r
ASSERT_EFI_ERROR (Status);\r
CpuDeadLoop ();\r
}\r
\r
if (HttpsCaCertsSize == 0) {\r
- DEBUG ((DEBUG_VERBOSE, "%a:%a: applied empty CA cert list\n",\r
- gEfiCallerBaseName, __FUNCTION__));\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a:%a: applied empty CA cert list\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__\r
+ ));\r
return;\r
}\r
\r
HttpsCaCerts = AllocatePool (HttpsCaCertsSize);\r
if (HttpsCaCerts == NULL) {\r
- DEBUG ((DEBUG_ERROR, "%a:%a: failed to allocate HttpsCaCerts\n",\r
- gEfiCallerBaseName, __FUNCTION__));\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to allocate HttpsCaCerts\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__\r
+ ));\r
return;\r
}\r
\r
HttpsCaCerts // Data\r
);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "%a:%a: failed to set %g:\"%s\": %r\n",\r
- gEfiCallerBaseName, __FUNCTION__, &gEfiTlsCaCertificateGuid,\r
- EFI_TLS_CA_CERTIFICATE_VARIABLE, Status));\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to set %g:\"%s\": %r\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ &gEfiTlsCaCertificateGuid,\r
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,\r
+ Status\r
+ ));\r
goto FreeHttpsCaCerts;\r
}\r
\r
- DEBUG ((DEBUG_VERBOSE, "%a:%a: stored CA cert list (%Lu byte(s))\n",\r
- gEfiCallerBaseName, __FUNCTION__, (UINT64)HttpsCaCertsSize));\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a:%a: stored CA cert list (%Lu byte(s))\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ (UINT64)HttpsCaCertsSize\r
+ ));\r
\r
FreeHttpsCaCerts:\r
FreePool (HttpsCaCerts);\r
}\r
\r
+/**\r
+ Read the list of trusted cipher suites from the fw_cfg file\r
+ "etc/edk2/https/ciphers", and store it to\r
+ gEdkiiHttpTlsCipherListGuid:EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE.\r
+\r
+ The contents are propagated by NetworkPkg/HttpDxe to NetworkPkg/TlsDxe; the\r
+ list is processed by the latter.\r
+**/\r
+STATIC\r
+VOID\r
+SetCipherSuites (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ FIRMWARE_CONFIG_ITEM HttpsCiphersItem;\r
+ UINTN HttpsCiphersSize;\r
+ VOID *HttpsCiphers;\r
+\r
+ Status = QemuFwCfgFindFile (\r
+ "etc/edk2/https/ciphers",\r
+ &HttpsCiphersItem,\r
+ &HttpsCiphersSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a:%a: not touching cipher suites\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__\r
+ ));\r
+ return;\r
+ }\r
+\r
+ //\r
+ // From this point on, any failure is fatal. An ordered cipher preference\r
+ // list is available from QEMU, thus we cannot let the firmware attempt HTTPS\r
+ // boot with either pre-existent or non-existent preferences. An empty set of\r
+ // cipher suites does not fail HTTPS boot automatically; the default cipher\r
+ // suite preferences would take effect, and we must prevent that.\r
+ //\r
+ // Delete the current EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE if it exists. If\r
+ // the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we cannot\r
+ // make it volatile without deleting it first.\r
+ //\r
+ Status = gRT->SetVariable (\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName\r
+ &gEdkiiHttpTlsCipherListGuid, // VendorGuid\r
+ 0, // Attributes\r
+ 0, // DataSize\r
+ NULL // Data\r
+ );\r
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to delete %g:\"%s\"\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ &gEdkiiHttpTlsCipherListGuid,\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE\r
+ ));\r
+ goto Done;\r
+ }\r
+\r
+ if (HttpsCiphersSize == 0) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: list of cipher suites must not be empty\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__\r
+ ));\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ HttpsCiphers = AllocatePool (HttpsCiphersSize);\r
+ if (HttpsCiphers == NULL) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to allocate HttpsCiphers\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__\r
+ ));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ QemuFwCfgSelectItem (HttpsCiphersItem);\r
+ QemuFwCfgReadBytes (HttpsCiphersSize, HttpsCiphers);\r
+\r
+ Status = gRT->SetVariable (\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName\r
+ &gEdkiiHttpTlsCipherListGuid, // VendorGuid\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes\r
+ HttpsCiphersSize, // DataSize\r
+ HttpsCiphers // Data\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to set %g:\"%s\"\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ &gEdkiiHttpTlsCipherListGuid,\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE\r
+ ));\r
+ goto FreeHttpsCiphers;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a:%a: stored list of cipher suites (%Lu byte(s))\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ (UINT64)HttpsCiphersSize\r
+ ));\r
+\r
+FreeHttpsCiphers:\r
+ FreePool (HttpsCiphers);\r
+\r
+Done:\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT_EFI_ERROR (Status);\r
+ CpuDeadLoop ();\r
+ }\r
+}\r
+\r
RETURN_STATUS\r
EFIAPI\r
TlsAuthConfigInit (\r
)\r
{\r
SetCaCerts ();\r
+ SetCipherSuites ();\r
\r
return RETURN_SUCCESS;\r
}\r