#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
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 ("etc/edk2/https/ciphers", &HttpsCiphersItem,\r
+ &HttpsCiphersSize);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_VERBOSE, "%a:%a: not touching cipher suites\n",\r
+ gEfiCallerBaseName, __FUNCTION__));\r
+ return;\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 ((DEBUG_ERROR, "%a:%a: failed to delete %g:\"%s\"\n",\r
+ gEfiCallerBaseName, __FUNCTION__, &gEdkiiHttpTlsCipherListGuid,\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE));\r
+ goto Done;\r
+ }\r
+\r
+ if (HttpsCiphersSize == 0) {\r
+ DEBUG ((DEBUG_ERROR, "%a:%a: list of cipher suites must not be empty\n",\r
+ gEfiCallerBaseName, __FUNCTION__));\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ HttpsCiphers = AllocatePool (HttpsCiphersSize);\r
+ if (HttpsCiphers == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a:%a: failed to allocate HttpsCiphers\n",\r
+ gEfiCallerBaseName, __FUNCTION__));\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 ((DEBUG_ERROR, "%a:%a: failed to set %g:\"%s\"\n",\r
+ gEfiCallerBaseName, __FUNCTION__, &gEdkiiHttpTlsCipherListGuid,\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE));\r
+ goto FreeHttpsCiphers;\r
+ }\r
+\r
+ DEBUG ((DEBUG_VERBOSE, "%a:%a: stored list of cipher suites (%Lu byte(s))\n",\r
+ gEfiCallerBaseName, __FUNCTION__, (UINT64)HttpsCiphersSize));\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