/** @file
  Implementation of EFI TLS Protocol Interfaces.

  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>

  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.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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.
  @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;
  UINTN                     Index;

  EFI_TPL                   OldTpl;

  Status = EFI_SUCCESS;
  CipherId = NULL;

  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:
    CipherId = AllocatePool (DataSize);
    if (CipherId == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
      *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
    }

    Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));

    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 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;
}

