]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/TlsAuthConfigLib: configure trusted cipher suites for HTTPS boot
authorLaszlo Ersek <lersek@redhat.com>
Sat, 31 Mar 2018 23:27:43 +0000 (01:27 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 13 Apr 2018 12:05:10 +0000 (14:05 +0200)
Read the list of trusted cipher suites from fw_cfg and to store it to
EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE.

The fw_cfg file will be formatted by the "update-crypto-policies" utility
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 forwarded by NetworkPkg/HttpDxe (in TlsConfigCipherList()) to
NetworkPkg/TlsDxe (TlsSetSessionData()) and TlsLib (TlsSetCipherList()).

Note: the development of the "update-crypto-policies" feature is underway
at this time. Meanwhile the following script can be used to generate the
binary file for fw_cfg:

  export LC_ALL=C
  openssl ciphers -V \
  | sed -r -n \
      -e 's/^ *0x([0-9A-F]{2}),0x([0-9A-F]{2}) - .*$/\\\\x\1 \\\\x\2/p' \
  | xargs -r -- printf -- '%b' > ciphers.bin

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Gary Ching-Pang Lin <glin@suse.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Gary Lin <glin@suse.com>
Tested-by: Gary Lin <glin@suse.com>
Reviewed-by: Long Qin <qin.long@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
[lersek@redhat.com: update commit msg and add script as requested by Gary]
[lersek@redhat.com: update commit msg as requested by Jiaxin]

OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c
OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf

index b5b33bc4fc6986db8e7135359ed09ccc13907da3..74c393e5462f0abb223f9a293425113979b5f419 100644 (file)
@@ -20,6 +20,7 @@
 #include <Uefi/UefiBaseType.h>\r
 #include <Uefi/UefiSpec.h>\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
 #include <Guid/TlsAuthentication.h>\r
 \r
 #include <Library/BaseLib.h>\r
@@ -121,6 +122,102 @@ FreeHttpsCaCerts:
   FreePool (HttpsCaCerts);\r
 }\r
 \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
 RETURN_STATUS\r
 EFIAPI\r
 TlsAuthConfigInit (\r
@@ -128,6 +225,7 @@ TlsAuthConfigInit (
   )\r
 {\r
   SetCaCerts ();\r
   )\r
 {\r
   SetCaCerts ();\r
+  SetCipherSuites ();\r
 \r
   return RETURN_SUCCESS;\r
 }\r
 \r
   return RETURN_SUCCESS;\r
 }\r
index 5f83582a8313c75191b616c1e6b03e0a3e5ff024..40754ea5a2f3656fd05883771919ad9ad5e494f3 100644 (file)
@@ -49,7 +49,8 @@
   UefiRuntimeServicesTableLib\r
 \r
 [Guids]\r
   UefiRuntimeServicesTableLib\r
 \r
 [Guids]\r
-  gEfiTlsCaCertificateGuid ## PRODUCES ## Variable:L"TlsCaCertificate"\r
+  gEdkiiHttpTlsCipherListGuid ## PRODUCES ## Variable:L"HttpTlsCipherList"\r
+  gEfiTlsCaCertificateGuid    ## PRODUCES ## Variable:L"TlsCaCertificate"\r
 \r
 [Depex]\r
   gEfiVariableWriteArchProtocolGuid\r
 \r
 [Depex]\r
   gEfiVariableWriteArchProtocolGuid\r