/** @file
  RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.

  This file implements following APIs which provide basic capabilities for RSA:
  1) RsaNew
  2) RsaFree
  3) RsaSetKey
  4) RsaPkcs1Verify

Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalCryptLib.h"

#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/objects.h>

/**
  Allocates and initializes one RSA context for subsequent use.

  @return  Pointer to the RSA context that has been initialized.
           If the allocations fails, RsaNew() returns NULL.

**/
VOID *
EFIAPI
RsaNew (
  VOID
  )
{
  //
  // Allocates & Initializes RSA Context by OpenSSL RSA_new()
  //
  return (VOID *)RSA_new ();
}

/**
  Release the specified RSA context.

  @param[in]  RsaContext  Pointer to the RSA context to be released.

**/
VOID
EFIAPI
RsaFree (
  IN  VOID  *RsaContext
  )
{
  //
  // Free OpenSSL RSA Context
  //
  RSA_free ((RSA *)RsaContext);
}

/**
  Sets the tag-designated key component into the established RSA context.

  This function sets the tag-designated RSA key component into the established
  RSA context from the user-specified non-negative integer (octet string format
  represented in RSA PKCS#1).
  If BigNumber is NULL, then the specified key component in RSA context is cleared.

  If RsaContext is NULL, then return FALSE.

  @param[in, out]  RsaContext  Pointer to RSA context being set.
  @param[in]       KeyTag      Tag of RSA key component being set.
  @param[in]       BigNumber   Pointer to octet integer buffer.
                               If NULL, then the specified key component in RSA
                               context is cleared.
  @param[in]       BnSize      Size of big number buffer in bytes.
                               If BigNumber is NULL, then it is ignored.

  @retval  TRUE   RSA key component was set successfully.
  @retval  FALSE  Invalid RSA key component tag.

**/
BOOLEAN
EFIAPI
RsaSetKey (
  IN OUT  VOID         *RsaContext,
  IN      RSA_KEY_TAG  KeyTag,
  IN      CONST UINT8  *BigNumber,
  IN      UINTN        BnSize
  )
{
  RSA     *RsaKey;
  BIGNUM  *BnN;
  BIGNUM  *BnE;
  BIGNUM  *BnD;
  BIGNUM  *BnP;
  BIGNUM  *BnQ;
  BIGNUM  *BnDp;
  BIGNUM  *BnDq;
  BIGNUM  *BnQInv;

  //
  // Check input parameters.
  //
  if ((RsaContext == NULL) || (BnSize > INT_MAX)) {
    return FALSE;
  }

  BnN    = NULL;
  BnE    = NULL;
  BnD    = NULL;
  BnP    = NULL;
  BnQ    = NULL;
  BnDp   = NULL;
  BnDq   = NULL;
  BnQInv = NULL;

  //
  // Retrieve the components from RSA object.
  //
  RsaKey = (RSA *)RsaContext;
  RSA_get0_key (RsaKey, (const BIGNUM **)&BnN, (const BIGNUM **)&BnE, (const BIGNUM **)&BnD);
  RSA_get0_factors (RsaKey, (const BIGNUM **)&BnP, (const BIGNUM **)&BnQ);
  RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnDp, (const BIGNUM **)&BnDq, (const BIGNUM **)&BnQInv);

  //
  // Set RSA Key Components by converting octet string to OpenSSL BN representation.
  // NOTE: For RSA public key (used in signature verification), only public components
  //       (N, e) are needed.
  //
  switch (KeyTag) {
    //
    // RSA Public Modulus (N), Public Exponent (e) and Private Exponent (d)
    //
    case RsaKeyN:
    case RsaKeyE:
    case RsaKeyD:
      if (BnN == NULL) {
        BnN = BN_new ();
      }

      if (BnE == NULL) {
        BnE = BN_new ();
      }

      if (BnD == NULL) {
        BnD = BN_new ();
      }

      if ((BnN == NULL) || (BnE == NULL) || (BnD == NULL)) {
        return FALSE;
      }

      switch (KeyTag) {
        case RsaKeyN:
          BnN = BN_bin2bn (BigNumber, (UINT32)BnSize, BnN);
          break;
        case RsaKeyE:
          BnE = BN_bin2bn (BigNumber, (UINT32)BnSize, BnE);
          break;
        case RsaKeyD:
          BnD = BN_bin2bn (BigNumber, (UINT32)BnSize, BnD);
          break;
        default:
          return FALSE;
      }

      if (RSA_set0_key (RsaKey, BN_dup (BnN), BN_dup (BnE), BN_dup (BnD)) == 0) {
        return FALSE;
      }

      break;

    //
    // RSA Secret Prime Factor of Modulus (p and q)
    //
    case RsaKeyP:
    case RsaKeyQ:
      if (BnP == NULL) {
        BnP = BN_new ();
      }

      if (BnQ == NULL) {
        BnQ = BN_new ();
      }

      if ((BnP == NULL) || (BnQ == NULL)) {
        return FALSE;
      }

      switch (KeyTag) {
        case RsaKeyP:
          BnP = BN_bin2bn (BigNumber, (UINT32)BnSize, BnP);
          break;
        case RsaKeyQ:
          BnQ = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQ);
          break;
        default:
          return FALSE;
      }

      if (RSA_set0_factors (RsaKey, BN_dup (BnP), BN_dup (BnQ)) == 0) {
        return FALSE;
      }

      break;

    //
    // p's CRT Exponent (== d mod (p - 1)),  q's CRT Exponent (== d mod (q - 1)),
    // and CRT Coefficient (== 1/q mod p)
    //
    case RsaKeyDp:
    case RsaKeyDq:
    case RsaKeyQInv:
      if (BnDp == NULL) {
        BnDp = BN_new ();
      }

      if (BnDq == NULL) {
        BnDq = BN_new ();
      }

      if (BnQInv == NULL) {
        BnQInv = BN_new ();
      }

      if ((BnDp == NULL) || (BnDq == NULL) || (BnQInv == NULL)) {
        return FALSE;
      }

      switch (KeyTag) {
        case RsaKeyDp:
          BnDp = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDp);
          break;
        case RsaKeyDq:
          BnDq = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDq);
          break;
        case RsaKeyQInv:
          BnQInv = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQInv);
          break;
        default:
          return FALSE;
      }

      if (RSA_set0_crt_params (RsaKey, BN_dup (BnDp), BN_dup (BnDq), BN_dup (BnQInv)) == 0) {
        return FALSE;
      }

      break;

    default:
      return FALSE;
  }

  return TRUE;
}

/**
  Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
  RSA PKCS#1.

  If RsaContext is NULL, then return FALSE.
  If MessageHash is NULL, then return FALSE.
  If Signature is NULL, then return FALSE.
  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-384 or SHA-512 digest, then return FALSE.

  @param[in]  RsaContext   Pointer to RSA context for signature verification.
  @param[in]  MessageHash  Pointer to octet message hash to be checked.
  @param[in]  HashSize     Size of the message hash in bytes.
  @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.
  @param[in]  SigSize      Size of signature in bytes.

  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.
  @retval  FALSE  Invalid signature or invalid RSA context.

**/
BOOLEAN
EFIAPI
RsaPkcs1Verify (
  IN  VOID         *RsaContext,
  IN  CONST UINT8  *MessageHash,
  IN  UINTN        HashSize,
  IN  CONST UINT8  *Signature,
  IN  UINTN        SigSize
  )
{
  INT32  DigestType;
  UINT8  *SigBuf;

  //
  // Check input parameters.
  //
  if ((RsaContext == NULL) || (MessageHash == NULL) || (Signature == NULL)) {
    return FALSE;
  }

  if ((SigSize > INT_MAX) || (SigSize == 0)) {
    return FALSE;
  }

  //
  // Determine the message digest algorithm according to digest size.
  //   Only MD5, SHA-1, SHA-256, SHA-384 or SHA-512 algorithm is supported.
  //
  switch (HashSize) {
    case MD5_DIGEST_SIZE:
      DigestType = NID_md5;
      break;

    case SHA1_DIGEST_SIZE:
      DigestType = NID_sha1;
      break;

    case SHA256_DIGEST_SIZE:
      DigestType = NID_sha256;
      break;

    case SHA384_DIGEST_SIZE:
      DigestType = NID_sha384;
      break;

    case SHA512_DIGEST_SIZE:
      DigestType = NID_sha512;
      break;

    default:
      return FALSE;
  }

  SigBuf = (UINT8 *)Signature;
  return (BOOLEAN)RSA_verify (
                    DigestType,
                    MessageHash,
                    (UINT32)HashSize,
                    SigBuf,
                    (UINT32)SigSize,
                    (RSA *)RsaContext
                    );
}
