/** @file
  SSL/TLS Process Library Wrapper Implementation over OpenSSL.
  The process includes the TLS handshake and packet I/O.

Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalTlsLib.h"

#define MAX_BUFFER_SIZE  32768

/**
  Checks if the TLS handshake was done.

  This function will check if the specified TLS handshake was done.

  @param[in]  Tls    Pointer to the TLS object for handshake state checking.

  @retval  TRUE     The TLS handshake was done.
  @retval  FALSE    The TLS handshake was not done.

**/
BOOLEAN
EFIAPI
TlsInHandshake (
  IN     VOID  *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return FALSE;
  }

  //
  // Return the status which indicates if the TLS handshake was done.
  //
  return !SSL_is_init_finished (TlsConn->Ssl);
}

/**
  Perform a TLS/SSL handshake.

  This function will perform a TLS/SSL handshake.

  @param[in]       Tls            Pointer to the TLS object for handshake operation.
  @param[in]       BufferIn       Pointer to the most recently received TLS Handshake packet.
  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
                                  Handshake packet.
  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferOutSize  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:
                                  Tls is NULL.
                                  BufferIn is NULL but BufferInSize is NOT 0.
                                  BufferInSize is 0 but BufferIn is NOT NULL.
                                  BufferOutSize is NULL.
                                  BufferOut is NULL if *BufferOutSize is not zero.
  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.
  @retval EFI_ABORTED             Something wrong during handshake.

**/
EFI_STATUS
EFIAPI
TlsDoHandshake (
  IN     VOID   *Tls,
  IN     UINT8  *BufferIn  OPTIONAL,
  IN     UINTN  BufferInSize  OPTIONAL,
  OUT UINT8     *BufferOut  OPTIONAL,
  IN OUT UINTN  *BufferOutSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;
  INTN            Ret;

  TlsConn           = (TLS_CONNECTION *)Tls;
  PendingBufferSize = 0;
  Ret               = 1;

  if ((TlsConn == NULL) || \
      (TlsConn->Ssl == NULL) || (TlsConn->InBio == NULL) || (TlsConn->OutBio == NULL) || \
      (BufferOutSize == NULL) || \
      ((BufferIn == NULL) && (BufferInSize != 0)) || \
      ((BufferIn != NULL) && (BufferInSize == 0)) || \
      ((BufferOut == NULL) && (*BufferOutSize != 0)))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((BufferIn == NULL) && (BufferInSize == 0)) {
    //
    // 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.
    //
    PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
    if (PendingBufferSize == 0) {
      SSL_set_connect_state (TlsConn->Ssl);
      Ret               = SSL_do_handshake (TlsConn->Ssl);
      PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
    }
  } else {
    PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
    if (PendingBufferSize == 0) {
      BIO_write (TlsConn->InBio, BufferIn, (UINT32)BufferInSize);
      Ret               = SSL_do_handshake (TlsConn->Ssl);
      PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
    }
  }

  if (Ret < 1) {
    Ret = SSL_get_error (TlsConn->Ssl, (int)Ret);
    if ((Ret == SSL_ERROR_SSL) ||
        (Ret == SSL_ERROR_SYSCALL) ||
        (Ret == SSL_ERROR_ZERO_RETURN))
    {
      DEBUG ((
        DEBUG_ERROR,
        "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n",
        __func__,
        SSL_get_state (TlsConn->Ssl),
        Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ? "SYSCALL" : "ZERO_RETURN"
        ));
      DEBUG_CODE_BEGIN ();
      while (TRUE) {
        unsigned long  ErrorCode;

        ErrorCode = ERR_get_error ();
        if (ErrorCode == 0) {
          break;
        }

        DEBUG ((
          DEBUG_ERROR,
          "%a ERROR 0x%x=L%x:R%x\n",
          __func__,
          ErrorCode,
          ERR_GET_LIB (ErrorCode),
          ERR_GET_REASON (ErrorCode)
          ));
      }

      DEBUG_CODE_END ();
      return EFI_ABORTED;
    }
  }

  if (PendingBufferSize > *BufferOutSize) {
    *BufferOutSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32)PendingBufferSize);
  } else {
    *BufferOutSize = 0;
  }

  return EFI_SUCCESS;
}

/**
  Handle Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
  TLS session has errors and the response packet needs to be Alert message based on error type.

  @param[in]       Tls            Pointer to the TLS object for state checking.
  @param[in]       BufferIn       Pointer to the most recently received TLS Alert packet.
  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
                                  Alert packet.
  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferOutSize  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:
                                  Tls is NULL.
                                  BufferIn is NULL but BufferInSize is NOT 0.
                                  BufferInSize is 0 but BufferIn is NOT NULL.
                                  BufferOutSize is NULL.
                                  BufferOut is NULL if *BufferOutSize is not zero.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.

**/
EFI_STATUS
EFIAPI
TlsHandleAlert (
  IN     VOID   *Tls,
  IN     UINT8  *BufferIn  OPTIONAL,
  IN     UINTN  BufferInSize  OPTIONAL,
  OUT UINT8     *BufferOut  OPTIONAL,
  IN OUT UINTN  *BufferOutSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;
  UINT8           *TempBuffer;
  INTN            Ret;

  TlsConn           = (TLS_CONNECTION *)Tls;
  PendingBufferSize = 0;
  TempBuffer        = NULL;
  Ret               = 0;

  if ((TlsConn == NULL) || \
      (TlsConn->Ssl == NULL) || (TlsConn->InBio == NULL) || (TlsConn->OutBio == NULL) || \
      (BufferOutSize == NULL) || \
      ((BufferIn == NULL) && (BufferInSize != 0)) || \
      ((BufferIn != NULL) && (BufferInSize == 0)) || \
      ((BufferOut == NULL) && (*BufferOutSize != 0)))
  {
    return EFI_INVALID_PARAMETER;
  }

  PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
  if ((PendingBufferSize == 0) && (BufferIn != NULL) && (BufferInSize != 0)) {
    Ret = BIO_write (TlsConn->InBio, BufferIn, (UINT32)BufferInSize);
    if (Ret != (INTN)BufferInSize) {
      return EFI_ABORTED;
    }

    TempBuffer = (UINT8 *)OPENSSL_malloc (MAX_BUFFER_SIZE);

    //
    // ssl3_send_alert() will be called in ssl3_read_bytes() function.
    // TempBuffer is invalid since it's a Alert message, so just ignore it.
    //
    SSL_read (TlsConn->Ssl, TempBuffer, MAX_BUFFER_SIZE);

    OPENSSL_free (TempBuffer);

    PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
  }

  if (PendingBufferSize > *BufferOutSize) {
    *BufferOutSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32)PendingBufferSize);
  } else {
    *BufferOutSize = 0;
  }

  return EFI_SUCCESS;
}

/**
  Build the CloseNotify packet.

  @param[in]       Tls            Pointer to the TLS object for state checking.
  @param[in, 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:
                                  Tls is 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.

**/
EFI_STATUS
EFIAPI
TlsCloseNotify (
  IN     VOID   *Tls,
  IN OUT UINT8  *Buffer,
  IN OUT UINTN  *BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;

  TlsConn           = (TLS_CONNECTION *)Tls;
  PendingBufferSize = 0;

  if ((TlsConn == NULL) || \
      (TlsConn->Ssl == NULL) || (TlsConn->InBio == NULL) || (TlsConn->OutBio == NULL) || \
      (BufferSize == NULL) || \
      ((Buffer == NULL) && (*BufferSize != 0)))
  {
    return EFI_INVALID_PARAMETER;
  }

  PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
  if (PendingBufferSize == 0) {
    //
    // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
    //
    SSL_shutdown (TlsConn->Ssl);
    PendingBufferSize = (UINTN)BIO_ctrl_pending (TlsConn->OutBio);
  }

  if (PendingBufferSize > *BufferSize) {
    *BufferSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32)PendingBufferSize);
  } else {
    *BufferSize = 0;
  }

  return EFI_SUCCESS;
}

/**
  Attempts to read bytes from one TLS object and places the data in Buffer.

  This function will attempt to read BufferSize bytes from the TLS object
  and places the data in Buffer.

  @param[in]      Tls           Pointer to the TLS object.
  @param[in,out]  Buffer        Pointer to the buffer to store the data.
  @param[in]      BufferSize    The size of Buffer in bytes.

  @retval  >0    The amount of data successfully read from the TLS object.
  @retval  <=0   No data was successfully read.

**/
INTN
EFIAPI
TlsCtrlTrafficOut (
  IN     VOID   *Tls,
  IN OUT VOID   *Buffer,
  IN     UINTN  BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->OutBio == 0)) {
    return -1;
  }

  //
  // Read and return the amount of data from the BIO.
  //
  return BIO_read (TlsConn->OutBio, Buffer, (UINT32)BufferSize);
}

/**
  Attempts to write data from the buffer to TLS object.

  This function will attempt to write BufferSize bytes data from the Buffer
  to the TLS object.

  @param[in]  Tls           Pointer to the TLS object.
  @param[in]  Buffer        Pointer to the data buffer.
  @param[in]  BufferSize    The size of Buffer in bytes.

  @retval  >0    The amount of data successfully written to the TLS object.
  @retval <=0    No data was successfully written.

**/
INTN
EFIAPI
TlsCtrlTrafficIn (
  IN     VOID   *Tls,
  IN     VOID   *Buffer,
  IN     UINTN  BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->InBio == 0)) {
    return -1;
  }

  //
  // Write and return the amount of data to the BIO.
  //
  return BIO_write (TlsConn->InBio, Buffer, (UINT32)BufferSize);
}

/**
  Attempts to read bytes from the specified TLS connection into the buffer.

  This function tries to read BufferSize bytes data from the specified TLS
  connection into the Buffer.

  @param[in]      Tls           Pointer to the TLS connection for data reading.
  @param[in,out]  Buffer        Pointer to the data buffer.
  @param[in]      BufferSize    The size of Buffer in bytes.

  @retval  >0    The read operation was successful, and return value is the
                 number of bytes actually read from the TLS connection.
  @retval  <=0   The read operation was not successful.

**/
INTN
EFIAPI
TlsRead (
  IN     VOID   *Tls,
  IN OUT VOID   *Buffer,
  IN     UINTN  BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return -1;
  }

  //
  // Read bytes from the specified TLS connection.
  //
  return SSL_read (TlsConn->Ssl, Buffer, (UINT32)BufferSize);
}

/**
  Attempts to write data to a TLS connection.

  This function tries to write BufferSize bytes data from the Buffer into the
  specified TLS connection.

  @param[in]  Tls           Pointer to the TLS connection for data writing.
  @param[in]  Buffer        Pointer to the data buffer.
  @param[in]  BufferSize    The size of Buffer in bytes.

  @retval  >0    The write operation was successful, and return value is the
                 number of bytes actually written to the TLS connection.
  @retval <=0    The write operation was not successful.

**/
INTN
EFIAPI
TlsWrite (
  IN     VOID   *Tls,
  IN     VOID   *Buffer,
  IN     UINTN  BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return -1;
  }

  //
  // Write bytes to the specified TLS connection.
  //
  return SSL_write (TlsConn->Ssl, Buffer, (UINT32)BufferSize);
}

/**
  Shutdown a TLS connection.

  Shutdown the TLS connection without releasing the resources, meaning a new
  connection can be started without calling TlsNew() and without setting
  certificates etc.

  @param[in]       Tls            Pointer to the TLS object to shutdown.

  @retval EFI_SUCCESS             The TLS is shutdown successfully.
  @retval EFI_INVALID_PARAMETER   Tls is NULL.
  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
**/
EFI_STATUS
EFIAPI
TlsShutdown (
  IN     VOID  *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || ((TlsConn->Ssl) == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  SSL_set_quiet_shutdown (TlsConn->Ssl, 1);
  SSL_shutdown (TlsConn->Ssl);
  return SSL_clear (TlsConn->Ssl) == 1 ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
}
