/** @file
  Implementation of EFI TLS Protocol Interfaces.

  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TlsImpl.h"

EFI_TLS_PROTOCOL  mTlsProtocol = {
  TlsSetSessionData,
  TlsGetSessionData,
  TlsBuildResponsePacket,
  TlsProcessPacket
};

/**
  Set TLS session data.

  The SetSessionData() function set data for a new TLS session. All session data should
  be set before BuildResponsePacket() invoked.

  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
  @param[in]  DataType            TLS session data type.
  @param[in]  Data                Pointer to session data.
  @param[in]  DataSize            Total size of session data.

  @retval EFI_SUCCESS             The TLS session data is set successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Data is NULL.
                                  DataSize is 0.
                                  DataSize is invalid for DataType.
  @retval EFI_UNSUPPORTED         The DataType is unsupported.
  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
                                  EfiTlsClientRandom
                                  EfiTlsServerRandom
                                  EfiTlsKeyMaterial
  @retval EFI_NOT_READY           Current TLS session state is NOT
                                  EfiTlsSessionStateNotStarted.
  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
**/
EFI_STATUS
EFIAPI
TlsSetSessionData (
  IN     EFI_TLS_PROTOCOL           *This,
  IN     EFI_TLS_SESSION_DATA_TYPE  DataType,
  IN     VOID                       *Data,
  IN     UINTN                      DataSize
  )
{
  EFI_STATUS                 Status;
  TLS_INSTANCE               *Instance;
  UINT16                     *CipherId;
  CONST EFI_TLS_CIPHER       *TlsCipherList;
  UINTN                      CipherCount;
  CONST EFI_TLS_VERIFY_HOST  *TlsVerifyHost;
  EFI_TLS_VERIFY             VerifyMethod;
  UINTN                      VerifyMethodSize;
  UINTN                      Index;

  EFI_TPL  OldTpl;

  Status           = EFI_SUCCESS;
  CipherId         = NULL;
  VerifyMethodSize = sizeof (EFI_TLS_VERIFY);

  if ((This == NULL) || (Data == NULL) || (DataSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = TLS_INSTANCE_FROM_PROTOCOL (This);

  if ((DataType != EfiTlsSessionState) && (Instance->TlsSessionState != EfiTlsSessionNotStarted)) {
    Status = EFI_NOT_READY;
    goto ON_EXIT;
  }

  switch (DataType) {
    //
    // Session Configuration
    //
    case EfiTlsVersion:
      if (DataSize != sizeof (EFI_TLS_VERSION)) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *)Data)->Major, ((EFI_TLS_VERSION *)Data)->Minor);
      break;
    case EfiTlsConnectionEnd:
      if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *)Data));
      break;
    case EfiTlsCipherList:
      if (DataSize % sizeof (EFI_TLS_CIPHER) != 0) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      CipherId = AllocatePool (DataSize);
      if (CipherId == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      TlsCipherList = (CONST EFI_TLS_CIPHER *)Data;
      CipherCount   = DataSize / sizeof (EFI_TLS_CIPHER);
      for (Index = 0; Index < CipherCount; Index++) {
        CipherId[Index] = ((TlsCipherList[Index].Data1 << 8) |
                           TlsCipherList[Index].Data2);
      }

      Status = TlsSetCipherList (Instance->TlsConn, CipherId, CipherCount);

      FreePool (CipherId);
      break;
    case EfiTlsCompressionMethod:
      //
      // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the
      // record protocol will not be compressed.
      // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html
      // The TLS RFC does however not specify compression methods or their corresponding identifiers,
      // so there is currently no compatible way to integrate compression with unknown peers.
      // It is therefore currently not recommended to integrate compression into applications.
      // Applications for non-public use may agree on certain compression methods.
      // Using different compression methods with the same identifier will lead to connection failure.
      //
      for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {
        Status = TlsSetCompressionMethod (*((UINT8 *)Data + Index));
        if (EFI_ERROR (Status)) {
          break;
        }
      }

      break;
    case EfiTlsExtensionData:
      Status = EFI_UNSUPPORTED;
      goto ON_EXIT;
    case EfiTlsVerifyMethod:
      if (DataSize != sizeof (EFI_TLS_VERIFY)) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      TlsSetVerify (Instance->TlsConn, *((UINT32 *)Data));
      break;
    case EfiTlsVerifyHost:
      if (DataSize != sizeof (EFI_TLS_VERIFY_HOST)) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      TlsVerifyHost = (CONST EFI_TLS_VERIFY_HOST *)Data;

      if (((TlsVerifyHost->Flags & EFI_TLS_VERIFY_FLAG_ALWAYS_CHECK_SUBJECT) != 0) &&
          ((TlsVerifyHost->Flags & EFI_TLS_VERIFY_FLAG_NEVER_CHECK_SUBJECT) != 0))
      {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      if (((TlsVerifyHost->Flags & EFI_TLS_VERIFY_FLAG_NO_WILDCARDS) != 0) &&
          (((TlsVerifyHost->Flags & EFI_TLS_VERIFY_FLAG_NO_PARTIAL_WILDCARDS) != 0) ||
           ((TlsVerifyHost->Flags & EFI_TLS_VERIFY_FLAG_MULTI_LABEL_WILDCARDS) != 0)))
      {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = This->GetSessionData (This, EfiTlsVerifyMethod, &VerifyMethod, &VerifyMethodSize);
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      if ((VerifyMethod & EFI_TLS_VERIFY_PEER) == 0) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = TlsSetVerifyHost (Instance->TlsConn, TlsVerifyHost->Flags, TlsVerifyHost->HostName);

      break;
    case EfiTlsSessionID:
      if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = TlsSetSessionId (
                 Instance->TlsConn,
                 ((EFI_TLS_SESSION_ID *)Data)->Data,
                 ((EFI_TLS_SESSION_ID *)Data)->Length
                 );
      break;
    case EfiTlsSessionState:
      if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)Data;
      break;
    //
    // Session information
    //
    case EfiTlsClientRandom:
      Status = EFI_ACCESS_DENIED;
      break;
    case EfiTlsServerRandom:
      Status = EFI_ACCESS_DENIED;
      break;
    case EfiTlsKeyMaterial:
      Status = EFI_ACCESS_DENIED;
      break;
    //
    // Unsupported type.
    //
    default:
      Status = EFI_UNSUPPORTED;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Get TLS session data.

  The GetSessionData() function return the TLS session information.

  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
  @param[in]       DataType       TLS session data type.
  @param[in, out]  Data           Pointer to session data.
  @param[in, out]  DataSize       Total size of session data. On input, it means
                                  the size of Data buffer. On output, it means the size
                                  of copied Data buffer if EFI_SUCCESS, and means the
                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.

  @retval EFI_SUCCESS             The TLS session data is got successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  DataSize is NULL.
                                  Data is NULL if *DataSize is not zero.
  @retval EFI_UNSUPPORTED         The DataType is unsupported.
  @retval EFI_NOT_FOUND           The TLS session data is not found.
  @retval EFI_NOT_READY           The DataType is not ready in current session state.
  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
**/
EFI_STATUS
EFIAPI
TlsGetSessionData (
  IN     EFI_TLS_PROTOCOL           *This,
  IN     EFI_TLS_SESSION_DATA_TYPE  DataType,
  IN OUT VOID                       *Data   OPTIONAL,
  IN OUT UINTN                      *DataSize
  )
{
  EFI_STATUS    Status;
  TLS_INSTANCE  *Instance;

  EFI_TPL  OldTpl;

  Status = EFI_SUCCESS;

  if ((This == NULL) || (DataSize == NULL) || ((Data == NULL) && (*DataSize != 0))) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = TLS_INSTANCE_FROM_PROTOCOL (This);

  if ((Instance->TlsSessionState == EfiTlsSessionNotStarted) &&
      ((DataType == EfiTlsSessionID) || (DataType == EfiTlsClientRandom) ||
       (DataType == EfiTlsServerRandom) || (DataType == EfiTlsKeyMaterial)))
  {
    Status = EFI_NOT_READY;
    goto ON_EXIT;
  }

  switch (DataType) {
    case EfiTlsVersion:
      if (*DataSize < sizeof (EFI_TLS_VERSION)) {
        *DataSize = sizeof (EFI_TLS_VERSION);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize         = sizeof (EFI_TLS_VERSION);
      *((UINT16 *)Data) = HTONS (TlsGetVersion (Instance->TlsConn));
      break;
    case EfiTlsConnectionEnd:
      if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
        *DataSize = sizeof (EFI_TLS_CONNECTION_END);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize        = sizeof (EFI_TLS_CONNECTION_END);
      *((UINT8 *)Data) = TlsGetConnectionEnd (Instance->TlsConn);
      break;
    case EfiTlsCipherList:
      //
      // Get the current session cipher suite.
      //
      if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
        *DataSize = sizeof (EFI_TLS_CIPHER);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize         = sizeof (EFI_TLS_CIPHER);
      Status            = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *)Data);
      *((UINT16 *)Data) = HTONS (*((UINT16 *)Data));
      break;
    case EfiTlsCompressionMethod:
      //
      // Get the current session compression method.
      //
      if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
        *DataSize = sizeof (EFI_TLS_COMPRESSION);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize = sizeof (EFI_TLS_COMPRESSION);
      Status    = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *)Data);
      break;
    case EfiTlsExtensionData:
      Status = EFI_UNSUPPORTED;
      goto ON_EXIT;
    case EfiTlsVerifyMethod:
      if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
        *DataSize = sizeof (EFI_TLS_VERIFY);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize         = sizeof (EFI_TLS_VERIFY);
      *((UINT32 *)Data) = TlsGetVerify (Instance->TlsConn);
      break;
    case EfiTlsSessionID:
      if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
        *DataSize = sizeof (EFI_TLS_SESSION_ID);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize = sizeof (EFI_TLS_SESSION_ID);
      Status    = TlsGetSessionId (
                    Instance->TlsConn,
                    ((EFI_TLS_SESSION_ID *)Data)->Data,
                    &(((EFI_TLS_SESSION_ID *)Data)->Length)
                    );
      break;
    case EfiTlsSessionState:
      if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
        *DataSize = sizeof (EFI_TLS_SESSION_STATE);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize = sizeof (EFI_TLS_SESSION_STATE);
      CopyMem (Data, &Instance->TlsSessionState, *DataSize);
      break;
    case EfiTlsClientRandom:
      if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
        *DataSize = sizeof (EFI_TLS_RANDOM);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize = sizeof (EFI_TLS_RANDOM);
      TlsGetClientRandom (Instance->TlsConn, (UINT8 *)Data);
      break;
    case EfiTlsServerRandom:
      if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
        *DataSize = sizeof (EFI_TLS_RANDOM);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize = sizeof (EFI_TLS_RANDOM);
      TlsGetServerRandom (Instance->TlsConn, (UINT8 *)Data);
      break;
    case EfiTlsKeyMaterial:
      if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
        *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
        Status    = EFI_BUFFER_TOO_SMALL;
        goto ON_EXIT;
      }

      *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
      Status    = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *)Data);
      break;
    //
    // Unsupported type.
    //
    default:
      Status = EFI_UNSUPPORTED;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Build response packet according to TLS state machine. This function is only valid for
  alert, handshake and change_cipher_spec content type.

  The BuildResponsePacket() function builds TLS response packet in response to the TLS
  request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
  will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
  session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
  session has errors and the response packet needs to be Alert message based on error
  type.

  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
  @param[in]       RequestBuffer  Pointer to the most recently received TLS packet. NULL
                                  means TLS need initiate the TLS session and response
                                  packet need to be ClientHello.
  @param[in]       RequestSize    Packet size in bytes for the most recently received TLS
                                  packet. 0 is only valid when RequestBuffer is NULL.
  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
                                  the buffer size provided by the caller. On output, it
                                  is the buffer size in fact needed to contain the
                                  packet.

  @retval EFI_SUCCESS             The required TLS packet is built successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  RequestBuffer is NULL but RequestSize is NOT 0.
                                  RequestSize is 0 but RequestBuffer is NOT NULL.
                                  BufferSize is NULL.
                                  Buffer is NULL if *BufferSize is not zero.
  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.
  @retval EFI_NOT_READY           Current TLS session state is NOT ready to build
                                  ResponsePacket.
  @retval EFI_ABORTED             Something wrong build response packet.
**/
EFI_STATUS
EFIAPI
TlsBuildResponsePacket (
  IN     EFI_TLS_PROTOCOL  *This,
  IN     UINT8             *RequestBuffer  OPTIONAL,
  IN     UINTN             RequestSize  OPTIONAL,
  OUT UINT8                *Buffer  OPTIONAL,
  IN OUT UINTN             *BufferSize
  )
{
  EFI_STATUS    Status;
  TLS_INSTANCE  *Instance;
  EFI_TPL       OldTpl;

  Status = EFI_SUCCESS;

  if ((This == NULL) || (BufferSize == NULL) ||
      ((RequestBuffer == NULL) && (RequestSize != 0)) ||
      ((RequestBuffer != NULL) && (RequestSize == 0)) ||
      ((Buffer == NULL) && (*BufferSize != 0)))
  {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = TLS_INSTANCE_FROM_PROTOCOL (This);

  if ((RequestBuffer == NULL) && (RequestSize == 0)) {
    switch (Instance->TlsSessionState) {
      case EfiTlsSessionNotStarted:
        //
        // ClientHello.
        //
        Status = TlsDoHandshake (
                   Instance->TlsConn,
                   NULL,
                   0,
                   Buffer,
                   BufferSize
                   );
        if (EFI_ERROR (Status)) {
          goto ON_EXIT;
        }

        //
        // *BufferSize should not be zero when ClientHello.
        //
        if (*BufferSize == 0) {
          Status = EFI_ABORTED;
          goto ON_EXIT;
        }

        Instance->TlsSessionState = EfiTlsSessionHandShaking;

        break;
      case EfiTlsSessionClosing:
        //
        // TLS session will be closed and response packet needs to be CloseNotify.
        //
        Status = TlsCloseNotify (
                   Instance->TlsConn,
                   Buffer,
                   BufferSize
                   );
        if (EFI_ERROR (Status)) {
          goto ON_EXIT;
        }

        //
        // *BufferSize should not be zero when build CloseNotify message.
        //
        if (*BufferSize == 0) {
          Status = EFI_ABORTED;
          goto ON_EXIT;
        }

        break;
      case EfiTlsSessionError:
        //
        // TLS session has errors and the response packet needs to be Alert
        // message based on error type.
        //
        Status = TlsHandleAlert (
                   Instance->TlsConn,
                   NULL,
                   0,
                   Buffer,
                   BufferSize
                   );
        if (EFI_ERROR (Status)) {
          goto ON_EXIT;
        }

        break;
      default:
        //
        // Current TLS session state is NOT ready to build ResponsePacket.
        //
        Status = EFI_NOT_READY;
    }
  } else {
    //
    // 1. Received packet may have multiple TLS record messages.
    // 2. One TLS record message may have multiple handshake protocol.
    // 3. Some errors may be happened in handshake.
    // TlsDoHandshake() can handle all of those cases.
    //
    if (TlsInHandshake (Instance->TlsConn)) {
      Status = TlsDoHandshake (
                 Instance->TlsConn,
                 RequestBuffer,
                 RequestSize,
                 Buffer,
                 BufferSize
                 );
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      if (!TlsInHandshake (Instance->TlsConn)) {
        Instance->TlsSessionState = EfiTlsSessionDataTransferring;
      }
    } else {
      //
      // Must be alert message, Decrypt it and build the ResponsePacket.
      //
      ASSERT (((TLS_RECORD_HEADER *)RequestBuffer)->ContentType == TlsContentTypeAlert);

      Status = TlsHandleAlert (
                 Instance->TlsConn,
                 RequestBuffer,
                 RequestSize,
                 Buffer,
                 BufferSize
                 );
      if (EFI_ERROR (Status)) {
        if (Status != EFI_BUFFER_TOO_SMALL) {
          Instance->TlsSessionState = EfiTlsSessionError;
        }

        goto ON_EXIT;
      }
    }
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Decrypt or encrypt TLS packet during session. This function is only valid after
  session connected and for application_data content type.

  The ProcessPacket () function process each inbound or outbound TLS APP packet.

  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller will take
                                  responsible to handle the original FragmentTable while
                                  it may be reallocated in TLS driver. If CryptMode is
                                  EfiTlsEncrypt, on input these fragments contain the TLS
                                  header and plain text TLS APP payload; on output these
                                  fragments contain the TLS header and cipher text TLS
                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
                                  these fragments contain the TLS header and cipher text
                                  TLS APP payload; on output these fragments contain the
                                  TLS header and plain text TLS APP payload.
  @param[in]       FragmentCount  Number of fragment.
  @param[in]       CryptMode      Crypt mode.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  FragmentTable is NULL.
                                  FragmentCount is NULL.
                                  CryptoMode is invalid.
  @retval EFI_NOT_READY           Current TLS session state is NOT
                                  EfiTlsSessionDataTransferring.
  @retval EFI_ABORTED             Something wrong decryption the message. TLS session
                                  status will become EfiTlsSessionError. The caller need
                                  call BuildResponsePacket() to generate Error Alert
                                  message and send it out.
  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the operation.
**/
EFI_STATUS
EFIAPI
TlsProcessPacket (
  IN     EFI_TLS_PROTOCOL       *This,
  IN OUT EFI_TLS_FRAGMENT_DATA  **FragmentTable,
  IN     UINT32                 *FragmentCount,
  IN     EFI_TLS_CRYPT_MODE     CryptMode
  )
{
  EFI_STATUS    Status;
  TLS_INSTANCE  *Instance;

  EFI_TPL  OldTpl;

  Status = EFI_SUCCESS;

  if ((This == NULL) || (FragmentTable == NULL) || (FragmentCount == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = TLS_INSTANCE_FROM_PROTOCOL (This);

  if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
    Status = EFI_NOT_READY;
    goto ON_EXIT;
  }

  //
  // Packet sent or received may have multiple TLS record messages (Application data type).
  // So,on input these fragments contain the TLS header and TLS APP payload;
  // on output these fragments also contain the TLS header and TLS APP payload.
  //
  switch (CryptMode) {
    case EfiTlsEncrypt:
      Status = TlsEncryptPacket (Instance, FragmentTable, FragmentCount);
      break;
    case EfiTlsDecrypt:
      Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
      break;
    default:
      return EFI_INVALID_PARAMETER;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}
