From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=jiaxin.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 916192202E49C for ; Mon, 19 Mar 2018 17:30:36 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Mar 2018 17:37:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,332,1517904000"; d="scan'208";a="209637219" Received: from jiaxinwu-mobl2.ccr.corp.intel.com ([10.239.196.39]) by orsmga005.jf.intel.com with ESMTP; 19 Mar 2018 17:37:04 -0700 From: Jiaxin Wu To: edk2-devel@lists.01.org Cc: Karunakar P , Fu Siyuan , Ye Ting Date: Tue, 20 Mar 2018 08:36:57 +0800 Message-Id: <20180320003657.4524-4-jiaxin.wu@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20180320003657.4524-1-jiaxin.wu@intel.com> References: <20180320003657.4524-1-jiaxin.wu@intel.com> Subject: [Patch 3/3] NetworkPkg/HttpDxe: Handle the large data request via HTTPS channel. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Mar 2018 00:30:37 -0000 Cc: Karunakar P Cc: Fu Siyuan Cc: Ye Ting Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu --- NetworkPkg/HttpDxe/HttpProto.c | 121 +++++++++++++++++++++++++++----------- NetworkPkg/HttpDxe/HttpsSupport.c | 17 +++++- NetworkPkg/HttpDxe/HttpsSupport.h | 12 +++- 3 files changed, 111 insertions(+), 39 deletions(-) diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c index d7fe271168..35c4a166c4 100644 --- a/NetworkPkg/HttpDxe/HttpProto.c +++ b/NetworkPkg/HttpDxe/HttpProto.c @@ -1,9 +1,9 @@ /** @file Miscellaneous routines for HttpDxe driver. -Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -1474,64 +1474,101 @@ HttpTransmitTcp ( EFI_STATUS Status; EFI_TCP4_IO_TOKEN *Tx4Token; EFI_TCP4_PROTOCOL *Tcp4; EFI_TCP6_IO_TOKEN *Tx6Token; EFI_TCP6_PROTOCOL *Tcp6; - UINT8 *Buffer; - UINTN BufferSize; + UINT8 *TlsRecord; + UINT16 PayloadSize; NET_FRAGMENT TempFragment; + NET_FRAGMENT Fragment; + UINTN RecordCount; + UINTN RemainingLen; Status = EFI_SUCCESS; - Buffer = NULL; + TlsRecord = NULL; + PayloadSize = 0; TempFragment.Len = 0; TempFragment.Bulk = NULL; + Fragment.Len = 0; + Fragment.Bulk = NULL; + RecordCount = 0; + RemainingLen = 0; // // Need to encrypt data. // if (HttpInstance->UseHttps) { // - // Build BufferOut data + // Allocate enough buffer for each TLS plaintext records. // - BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen; - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { + TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH); + if (TlsRecord == NULL) { Status = EFI_OUT_OF_RESOURCES; return Status; } - ((TLS_RECORD_HEADER *) Buffer)->ContentType = TlsContentTypeApplicationData; - ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major; - ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor; - ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen); - CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen); - + // - // Encrypt Packet. + // Allocate enough buffer for all TLS ciphertext records. // - Status = TlsProcessMessage ( - HttpInstance, - Buffer, - BufferSize, - EfiTlsEncrypt, - &TempFragment - ); - - FreePool (Buffer); + RecordCount = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1; + Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH)); + if (Fragment.Bulk == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } - if (EFI_ERROR (Status)) { - return Status; + // + // Encrypt each TLS plaintext records. + // + RemainingLen = TxStringLen; + while (RemainingLen != 0) { + PayloadSize = (UINT16) MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen); + + ((TLS_RECORD_HEADER *) TlsRecord)->ContentType = TlsContentTypeApplicationData; + ((TLS_RECORD_HEADER *) TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major; + ((TLS_RECORD_HEADER *) TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor; + ((TLS_RECORD_HEADER *) TlsRecord)->Length = PayloadSize; + + CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize); + + Status = TlsProcessMessage ( + HttpInstance, + TlsRecord, + TLS_RECORD_HEADER_LENGTH + PayloadSize, + EfiTlsEncrypt, + &TempFragment + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // Record the processed/encrypted Packet. + // + CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len); + Fragment.Len += TempFragment.Len; + + FreePool (TempFragment.Bulk); + TempFragment.Len = 0; + TempFragment.Bulk = NULL; + + RemainingLen -= (UINTN) PayloadSize; + ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH); } + + FreePool (TlsRecord); + TlsRecord = NULL; } if (!HttpInstance->LocalAddressIsIPv6) { Tcp4 = HttpInstance->Tcp4; Tx4Token = &Wrap->TcpWrap.Tx4Token; if (HttpInstance->UseHttps) { - Tx4Token->Packet.TxData->DataLength = TempFragment.Len; - Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len; - Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk; + Tx4Token->Packet.TxData->DataLength = Fragment.Len; + Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len; + Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk; } else { Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen; Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen; Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString; } @@ -1540,21 +1577,21 @@ HttpTransmitTcp ( Wrap->TcpWrap.IsTxDone = FALSE; Status = Tcp4->Transmit (Tcp4, Tx4Token); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status)); - return Status; + goto ON_ERROR; } } else { Tcp6 = HttpInstance->Tcp6; Tx6Token = &Wrap->TcpWrap.Tx6Token; if (HttpInstance->UseHttps) { - Tx6Token->Packet.TxData->DataLength = TempFragment.Len; - Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len; - Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk; + Tx6Token->Packet.TxData->DataLength = Fragment.Len; + Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len; + Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk; } else { Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen; Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen; Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString; } @@ -1563,14 +1600,30 @@ HttpTransmitTcp ( Wrap->TcpWrap.IsTxDone = FALSE; Status = Tcp6->Transmit (Tcp6, Tx6Token); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status)); - return Status; + goto ON_ERROR; } } + return Status; + +ON_ERROR: + + if (HttpInstance->UseHttps) { + if (TlsRecord != NULL) { + FreePool (TlsRecord); + TlsRecord = NULL; + } + + if (Fragment.Bulk != NULL) { + FreePool (Fragment.Bulk); + Fragment.Bulk = NULL; + } + } + return Status; } /** Check whether the user's token or event has already diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c index f5e5911b86..5105a2014c 100644 --- a/NetworkPkg/HttpDxe/HttpsSupport.c +++ b/NetworkPkg/HttpDxe/HttpsSupport.c @@ -949,11 +949,11 @@ TlsReceiveOnePdu ( InitializeListHead (NbufList); // // Allocate buffer to receive one TLS header. // - Len = sizeof (TLS_RECORD_HEADER); + Len = TLS_RECORD_HEADER_LENGTH; PduHdr = NetbufAlloc (Len); if (PduHdr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } @@ -1389,15 +1389,23 @@ TlsCloseSession ( /** Process one message according to the CryptMode. @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Message Pointer to the message buffer needed to processed. + @param[in] Message Pointer to the message buffer needed to processed. + If ProcessMode is EfiTlsEncrypt, the message contain the TLS + header and plain text TLS APP payload. + If ProcessMode is EfiTlsDecrypt, the message contain the TLS + header and cipher text TLS APP payload. @param[in] MessageSize Pointer to the message buffer size. @param[in] ProcessMode Process mode. @param[in, out] Fragment Only one Fragment returned after the Message is processed successfully. + If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS + header and cipher text TLS APP payload. + If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS + header and plain text TLS APP payload. @retval EFI_SUCCESS Message is processed successfully. @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. @retval Others Other errors as indicated. @@ -1496,10 +1504,13 @@ TlsProcessMessage ( Fragment->Bulk = Buffer; ON_EXIT: if (OriginalFragmentTable != NULL) { + if( FragmentTable == OriginalFragmentTable) { + FragmentTable = NULL; + } FreePool (OriginalFragmentTable); OriginalFragmentTable = NULL; } // @@ -1680,11 +1691,11 @@ HttpsReceive ( if (BufferIn == NULL) { Status = EFI_OUT_OF_RESOURCES; return Status; } - CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize); + CopyMem (BufferIn, TempFragment.Bulk + TLS_RECORD_HEADER_LENGTH, BufferInSize); // // Free the buffer in TempFragment. // FreePool (TempFragment.Bulk); diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h b/NetworkPkg/HttpDxe/HttpsSupport.h index f7a2d303e6..5d4ca01108 100644 --- a/NetworkPkg/HttpDxe/HttpsSupport.h +++ b/NetworkPkg/HttpDxe/HttpsSupport.h @@ -1,9 +1,9 @@ /** @file The header files of miscellaneous routines specific to Https for HttpDxe driver. -Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -215,15 +215,23 @@ TlsCloseSession ( /** Process one message according to the CryptMode. @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Message Pointer to the message buffer needed to processed. + @param[in] Message Pointer to the message buffer needed to processed. + If ProcessMode is EfiTlsEncrypt, the message contain the TLS + header and plain text TLS APP payload. + If ProcessMode is EfiTlsDecrypt, the message contain the TLS + header and cipher text TLS APP payload. @param[in] MessageSize Pointer to the message buffer size. @param[in] ProcessMode Process mode. @param[in, out] Fragment Only one Fragment returned after the Message is processed successfully. + If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS + header and cipher text TLS APP payload. + If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS + header and plain text TLS APP payload. @retval EFI_SUCCESS Message is processed successfully. @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. @retval Others Other errors as indicated. -- 2.16.2.windows.1