123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- /** @file
- The Miscellaneous Routines for TlsDxe driver.
- Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "TlsImpl.h"
- /**
- Encrypt the message listed in fragment.
- @param[in] TlsInstance The pointer to the TLS instance.
- @param[in, out] FragmentTable Pointer to a list of fragment.
- On input these fragments contain the TLS header and
- plain text TLS payload;
- On output these fragments contain the TLS header and
- cipher text TLS payload.
- @param[in] FragmentCount Number of fragment.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
- @retval EFI_ABORTED TLS session state is incorrect.
- @retval Others Other errors as indicated.
- **/
- EFI_STATUS
- TlsEncryptPacket (
- IN TLS_INSTANCE *TlsInstance,
- IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
- IN UINT32 *FragmentCount
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- UINT32 BytesCopied;
- UINT32 BufferInSize;
- UINT8 *BufferIn;
- UINT8 *BufferInPtr;
- TLS_RECORD_HEADER *RecordHeaderIn;
- UINT16 ThisPlainMessageSize;
- TLS_RECORD_HEADER *TempRecordHeader;
- UINT16 ThisMessageSize;
- UINT32 BufferOutSize;
- UINT8 *BufferOut;
- UINT32 RecordCount;
- INTN Ret;
- Status = EFI_SUCCESS;
- BytesCopied = 0;
- BufferInSize = 0;
- BufferIn = NULL;
- BufferInPtr = NULL;
- RecordHeaderIn = NULL;
- TempRecordHeader = NULL;
- BufferOutSize = 0;
- BufferOut = NULL;
- RecordCount = 0;
- Ret = 0;
- //
- // Calculate the size according to the fragment table.
- //
- for (Index = 0; Index < *FragmentCount; Index++) {
- BufferInSize += (*FragmentTable)[Index].FragmentLength;
- }
- //
- // Allocate buffer for processing data.
- //
- BufferIn = AllocateZeroPool (BufferInSize);
- if (BufferIn == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ERROR;
- }
- //
- // Copy all TLS plain record header and payload into BufferIn.
- //
- for (Index = 0; Index < *FragmentCount; Index++) {
- CopyMem (
- (BufferIn + BytesCopied),
- (*FragmentTable)[Index].FragmentBuffer,
- (*FragmentTable)[Index].FragmentLength
- );
- BytesCopied += (*FragmentTable)[Index].FragmentLength;
- }
- //
- // Count TLS record number.
- //
- BufferInPtr = BufferIn;
- while ((UINTN)BufferInPtr < (UINTN)BufferIn + BufferInSize) {
- RecordHeaderIn = (TLS_RECORD_HEADER *)BufferInPtr;
- if ((RecordHeaderIn->ContentType != TlsContentTypeApplicationData) || (RecordHeaderIn->Length > TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH)) {
- Status = EFI_INVALID_PARAMETER;
- goto ERROR;
- }
- BufferInPtr += TLS_RECORD_HEADER_LENGTH + RecordHeaderIn->Length;
- RecordCount++;
- }
- //
- // Allocate enough buffer to hold TLS Ciphertext.
- //
- BufferOut = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));
- if (BufferOut == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ERROR;
- }
- //
- // Parsing buffer. Received packet may have multiple TLS record messages.
- //
- BufferInPtr = BufferIn;
- TempRecordHeader = (TLS_RECORD_HEADER *)BufferOut;
- while ((UINTN)BufferInPtr < (UINTN)BufferIn + BufferInSize) {
- RecordHeaderIn = (TLS_RECORD_HEADER *)BufferInPtr;
- ThisPlainMessageSize = RecordHeaderIn->Length;
- TlsWrite (TlsInstance->TlsConn, (UINT8 *)(RecordHeaderIn + 1), ThisPlainMessageSize);
- Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH);
- if (Ret > 0) {
- ThisMessageSize = (UINT16)Ret;
- } else {
- //
- // No data was successfully encrypted, continue to encrypt other messages.
- //
- DEBUG ((DEBUG_WARN, "TlsEncryptPacket: No data read from TLS object.\n"));
- ThisMessageSize = 0;
- }
- BufferOutSize += ThisMessageSize;
- BufferInPtr += TLS_RECORD_HEADER_LENGTH + ThisPlainMessageSize;
- TempRecordHeader = (TLS_RECORD_HEADER *)((UINT8 *)TempRecordHeader + ThisMessageSize);
- }
- FreePool (BufferIn);
- BufferIn = NULL;
- //
- // The caller will be responsible to handle the original fragment table.
- //
- *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
- if (*FragmentTable == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ERROR;
- }
- (*FragmentTable)[0].FragmentBuffer = BufferOut;
- (*FragmentTable)[0].FragmentLength = BufferOutSize;
- *FragmentCount = 1;
- return Status;
- ERROR:
- if (BufferIn != NULL) {
- FreePool (BufferIn);
- BufferIn = NULL;
- }
- if (BufferOut != NULL) {
- FreePool (BufferOut);
- BufferOut = NULL;
- }
- return Status;
- }
- /**
- Decrypt the message listed in fragment.
- @param[in] TlsInstance The pointer to the TLS instance.
- @param[in, out] FragmentTable Pointer to a list of fragment.
- On input these fragments contain the TLS header and
- cipher text TLS payload;
- On output these fragments contain the TLS header and
- plain text TLS payload.
- @param[in] FragmentCount Number of fragment.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
- @retval EFI_ABORTED TLS session state is incorrect.
- @retval Others Other errors as indicated.
- **/
- EFI_STATUS
- TlsDecryptPacket (
- IN TLS_INSTANCE *TlsInstance,
- IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
- IN UINT32 *FragmentCount
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- UINT32 BytesCopied;
- UINT8 *BufferIn;
- UINT32 BufferInSize;
- UINT8 *BufferInPtr;
- TLS_RECORD_HEADER *RecordHeaderIn;
- UINT16 ThisCipherMessageSize;
- TLS_RECORD_HEADER *TempRecordHeader;
- UINT16 ThisPlainMessageSize;
- UINT8 *BufferOut;
- UINT32 BufferOutSize;
- UINT32 RecordCount;
- INTN Ret;
- Status = EFI_SUCCESS;
- BytesCopied = 0;
- BufferIn = NULL;
- BufferInSize = 0;
- BufferInPtr = NULL;
- RecordHeaderIn = NULL;
- TempRecordHeader = NULL;
- BufferOut = NULL;
- BufferOutSize = 0;
- RecordCount = 0;
- Ret = 0;
- //
- // Calculate the size according to the fragment table.
- //
- for (Index = 0; Index < *FragmentCount; Index++) {
- BufferInSize += (*FragmentTable)[Index].FragmentLength;
- }
- //
- // Allocate buffer for processing data
- //
- BufferIn = AllocateZeroPool (BufferInSize);
- if (BufferIn == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ERROR;
- }
- //
- // Copy all TLS plain record header and payload to BufferIn
- //
- for (Index = 0; Index < *FragmentCount; Index++) {
- CopyMem (
- (BufferIn + BytesCopied),
- (*FragmentTable)[Index].FragmentBuffer,
- (*FragmentTable)[Index].FragmentLength
- );
- BytesCopied += (*FragmentTable)[Index].FragmentLength;
- }
- //
- // Count TLS record number.
- //
- BufferInPtr = BufferIn;
- while ((UINTN)BufferInPtr < (UINTN)BufferIn + BufferInSize) {
- RecordHeaderIn = (TLS_RECORD_HEADER *)BufferInPtr;
- if ((RecordHeaderIn->ContentType != TlsContentTypeApplicationData) || (NTOHS (RecordHeaderIn->Length) > TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH)) {
- Status = EFI_INVALID_PARAMETER;
- goto ERROR;
- }
- BufferInPtr += TLS_RECORD_HEADER_LENGTH + NTOHS (RecordHeaderIn->Length);
- RecordCount++;
- }
- //
- // Allocate enough buffer to hold TLS Plaintext.
- //
- BufferOut = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH));
- if (BufferOut == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ERROR;
- }
- //
- // Parsing buffer. Received packet may have multiple TLS record messages.
- //
- BufferInPtr = BufferIn;
- TempRecordHeader = (TLS_RECORD_HEADER *)BufferOut;
- while ((UINTN)BufferInPtr < (UINTN)BufferIn + BufferInSize) {
- RecordHeaderIn = (TLS_RECORD_HEADER *)BufferInPtr;
- ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
- Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *)(RecordHeaderIn), TLS_RECORD_HEADER_LENGTH + ThisCipherMessageSize);
- if (Ret != TLS_RECORD_HEADER_LENGTH + ThisCipherMessageSize) {
- TlsInstance->TlsSessionState = EfiTlsSessionError;
- Status = EFI_ABORTED;
- goto ERROR;
- }
- Ret = 0;
- Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader + 1), TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);
- if (Ret > 0) {
- ThisPlainMessageSize = (UINT16)Ret;
- } else {
- //
- // No data was successfully decrypted, continue to decrypt other messages.
- //
- DEBUG ((DEBUG_WARN, "TlsDecryptPacket: No data read from TLS object.\n"));
- ThisPlainMessageSize = 0;
- }
- CopyMem (TempRecordHeader, RecordHeaderIn, TLS_RECORD_HEADER_LENGTH);
- TempRecordHeader->Length = ThisPlainMessageSize;
- BufferOutSize += TLS_RECORD_HEADER_LENGTH + ThisPlainMessageSize;
- BufferInPtr += TLS_RECORD_HEADER_LENGTH + ThisCipherMessageSize;
- TempRecordHeader = (TLS_RECORD_HEADER *)((UINT8 *)TempRecordHeader + TLS_RECORD_HEADER_LENGTH + ThisPlainMessageSize);
- }
- FreePool (BufferIn);
- BufferIn = NULL;
- //
- // The caller will be responsible to handle the original fragment table
- //
- *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
- if (*FragmentTable == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ERROR;
- }
- (*FragmentTable)[0].FragmentBuffer = BufferOut;
- (*FragmentTable)[0].FragmentLength = BufferOutSize;
- *FragmentCount = 1;
- return Status;
- ERROR:
- if (BufferIn != NULL) {
- FreePool (BufferIn);
- BufferIn = NULL;
- }
- if (BufferOut != NULL) {
- FreePool (BufferOut);
- BufferOut = NULL;
- }
- return Status;
- }
|