]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c
OvmfPkg/TlsAuthConfigLib: configure trusted cipher suites for HTTPS boot
[mirror_edk2.git] / OvmfPkg / Library / TlsAuthConfigLib / TlsAuthConfigLib.c
index b5b33bc4fc6986db8e7135359ed09ccc13907da3..74c393e5462f0abb223f9a293425113979b5f419 100644 (file)
@@ -20,6 +20,7 @@
 #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
@@ -121,6 +122,102 @@ FreeHttpsCaCerts:
   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
@@ -128,6 +225,7 @@ TlsAuthConfigInit (
   )\r
 {\r
   SetCaCerts ();\r
+  SetCipherSuites ();\r
 \r
   return RETURN_SUCCESS;\r
 }\r