]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpDxe/HttpProto.c
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" with PatchInstructionX86()
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpProto.c
index 925281a9c067fe6851c3b646773d55354b84cf05..35c4a166c445a47ae785e02f23f6fdc904006056 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Miscellaneous routines for HttpDxe driver.\r
 \r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -867,7 +867,7 @@ HttpCleanProtocol (
   if (HttpInstance->TlsSb != NULL && HttpInstance->TlsChildHandle != NULL) {\r
     //\r
     // Destroy the TLS instance.   \r
-    //
+    //\r
     HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);\r
   }\r
 \r
@@ -1476,50 +1476,87 @@ HttpTransmitTcp (
   EFI_TCP4_PROTOCOL             *Tcp4;\r
   EFI_TCP6_IO_TOKEN             *Tx6Token;\r
   EFI_TCP6_PROTOCOL             *Tcp6;\r
-  UINT8                         *Buffer;  \r
-  UINTN                         BufferSize;\r
+  UINT8                         *TlsRecord;  \r
+  UINT16                        PayloadSize;\r
   NET_FRAGMENT                  TempFragment;\r
+  NET_FRAGMENT                  Fragment;\r
+  UINTN                         RecordCount;\r
+  UINTN                         RemainingLen;\r
 \r
   Status                = EFI_SUCCESS;\r
-  Buffer                = NULL;\r
+  TlsRecord             = NULL;\r
+  PayloadSize           = 0;\r
   TempFragment.Len      = 0;\r
   TempFragment.Bulk     = NULL;\r
+  Fragment.Len          = 0;\r
+  Fragment.Bulk         = NULL;\r
+  RecordCount           = 0;\r
+  RemainingLen          = 0;\r
 \r
   //\r
   // Need to encrypt data.\r
   //\r
   if (HttpInstance->UseHttps) {\r
     //\r
-    // Build BufferOut data\r
+    // Allocate enough buffer for each TLS plaintext records.\r
     //\r
-    BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;\r
-    Buffer     = AllocateZeroPool (BufferSize);\r
-    if (Buffer == NULL) {\r
+    TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
+    if (TlsRecord == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       return Status;\r
     }\r
-    ((TLS_RECORD_HEADER *) Buffer)->ContentType = TlsContentTypeApplicationData;\r
-    ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
-    ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
-    ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);\r
-    CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);\r
-    \r
+\r
     //\r
-    // Encrypt Packet.\r
+    // Allocate enough buffer for all TLS ciphertext records.\r
     //\r
-    Status = TlsProcessMessage (\r
-               HttpInstance, \r
-               Buffer, \r
-               BufferSize, \r
-               EfiTlsEncrypt, \r
-               &TempFragment\r
-               );\r
-    \r
-    FreePool (Buffer);\r
+    RecordCount = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1;\r
+    Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));\r
+    if (Fragment.Bulk == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ON_ERROR;\r
+    }\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
+    //\r
+    // Encrypt each TLS plaintext records.\r
+    //\r
+    RemainingLen = TxStringLen;\r
+    while (RemainingLen != 0) {\r
+      PayloadSize = (UINT16) MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen);\r
+      \r
+      ((TLS_RECORD_HEADER *) TlsRecord)->ContentType = TlsContentTypeApplicationData;\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->Length = PayloadSize;\r
+\r
+      CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize);\r
+      \r
+      Status = TlsProcessMessage (\r
+                 HttpInstance, \r
+                 TlsRecord, \r
+                 TLS_RECORD_HEADER_LENGTH + PayloadSize, \r
+                 EfiTlsEncrypt, \r
+                 &TempFragment\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_ERROR;\r
+      }\r
+\r
+      //\r
+      // Record the processed/encrypted Packet. \r
+      //\r
+      CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len);\r
+      Fragment.Len += TempFragment.Len;\r
+\r
+      FreePool (TempFragment.Bulk);\r
+      TempFragment.Len  = 0;\r
+      TempFragment.Bulk = NULL;\r
+      \r
+      RemainingLen -= (UINTN) PayloadSize;\r
+      ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
     }\r
+\r
+    FreePool (TlsRecord);\r
+    TlsRecord = NULL;\r
   }\r
   \r
   if (!HttpInstance->LocalAddressIsIPv6) {\r
@@ -1527,9 +1564,9 @@ HttpTransmitTcp (
     Tx4Token = &Wrap->TcpWrap.Tx4Token;\r
 \r
     if (HttpInstance->UseHttps) {\r
-      Tx4Token->Packet.TxData->DataLength = TempFragment.Len;\r
-      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
-      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;\r
+      Tx4Token->Packet.TxData->DataLength = Fragment.Len;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk;\r
     } else {\r
       Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
       Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
@@ -1542,7 +1579,7 @@ HttpTransmitTcp (
     Status  = Tcp4->Transmit (Tcp4, Tx4Token);\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
-      return Status;\r
+      goto ON_ERROR;\r
     }\r
 \r
   } else {\r
@@ -1550,9 +1587,9 @@ HttpTransmitTcp (
     Tx6Token = &Wrap->TcpWrap.Tx6Token;\r
     \r
     if (HttpInstance->UseHttps) {\r
-      Tx6Token->Packet.TxData->DataLength = TempFragment.Len;\r
-      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
-      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;\r
+      Tx6Token->Packet.TxData->DataLength = Fragment.Len;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk;\r
     } else {\r
       Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
       Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
@@ -1565,10 +1602,26 @@ HttpTransmitTcp (
     Status = Tcp6->Transmit (Tcp6, Tx6Token);\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
-      return Status;\r
+      goto ON_ERROR;\r
     }\r
   }\r
   \r
+  return Status;\r
+\r
+ON_ERROR:\r
+  \r
+  if (HttpInstance->UseHttps) {\r
+    if (TlsRecord != NULL) {\r
+      FreePool (TlsRecord);\r
+      TlsRecord = NULL;\r
+    }\r
+    \r
+    if (Fragment.Bulk != NULL) {\r
+      FreePool (Fragment.Bulk);\r
+      Fragment.Bulk = NULL;\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r