/** @file
  PKCS#7 SignedData Sign Wrapper and PKCS#7 SignedData Verification Wrapper
  Implementation over mbedtls.

  RFC 8422 - Elliptic Curve Cryptography (ECC) Cipher Suites
  FIPS 186-4 - Digital Signature Standard (DSS)

Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "CryptPkcs7Internal.h"
#include <mbedtls/ecdh.h>

///
/// Enough to store any signature generated by PKCS7
///
#define MAX_SIGNATURE_SIZE  1024

GLOBAL_REMOVE_IF_UNREFERENCED UINT8  MbedtlsOidDigestAlgSha256[] = MBEDTLS_OID_DIGEST_ALG_SHA256;
GLOBAL_REMOVE_IF_UNREFERENCED UINT8  MbedtlsOidPkcs1Rsa[]        = MBEDTLS_OID_PKCS1_RSA;

/**
  Write DigestAlgorithmIdentifier.

  @param[in, out]  Ptr           The reference to the current position pointer.
  @param[in]       Start       The start of the buffer, for bounds-checking.
  @param[in]       DigestType  Digest Type

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteDigestAlgorithm (
  UINT8              **Ptr,
  UINT8              *Start,
  mbedtls_md_type_t  DigestType
  )
{
  UINT8  *OidPtr;
  UINTN  OidLen;
  INT32  Ret;

  Ret = mbedtls_oid_get_oid_by_md (DigestType, (CONST CHAR8 **)&OidPtr, &OidLen);
  if (Ret == 0) {
    return mbedtls_asn1_write_oid (Ptr, (CONST UINT8 *)Start, (CONST CHAR8 *)OidPtr, OidLen);
  }

  return 0;
}

/**
  DigestAlgorithmIdentifiers ::=
  SET OF DigestAlgorithmIdentifier.

  @param[in, out]  Ptr           The reference to the current position pointer.
  @param[in]       Start       The start of the buffer, for bounds-checking.
  @param[in]       DigestTypes Digest Type array.
  @param[in]       Count       The index for Digest Type.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteDigestAlgorithmSet (
  UINT8              **Ptr,
  UINT8              *Start,
  mbedtls_md_type_t  *DigestTypes,
  INTN               Count
  )
{
  INTN   Idx;
  INT32  Len;
  INT32  Ret;

  Len = 0;
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_null (Ptr, Start));

  for (Idx = 0; Idx < Count; Idx++) {
    EDKII_ASN1_CHK_ADD (
      Len,
      MbedTlsPkcs7WriteDigestAlgorithm (Ptr, Start, DigestTypes[Idx])
      );
  }

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));

  EDKII_ASN1_CHK_ADD (
    Len,
    mbedtls_asn1_write_tag (
      Ptr,
      Start,
      (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)
      )
    );

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));

  EDKII_ASN1_CHK_ADD (
    Len,
    mbedtls_asn1_write_tag (
      Ptr,
      Start,
      (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)
      )
    );

  return Len;
}

/**
   ContentInfo ::= SEQUENCE {
        contentType ContentType,
        content
                [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }.

  @param[in, out]  Ptr           The reference to the current position pointer.
  @param[in]       Start       The start of the buffer, for bounds-checking.
  @param[in]       Content     ContentInfo.
  @param[in]       ContentLen  Size of ContentInfo.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteContentInfo (
  UINT8  **Ptr,
  UINT8  *Start,
  UINT8  *Content,
  INTN   ContentLen
  )
{
  INT32  Ret;
  INT32  Len;

  Len = 0;
  if (Content != NULL) {
    EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, Content, ContentLen));
  }

  EDKII_ASN1_CHK_ADD (
    Len,
    mbedtls_asn1_write_oid (
      Ptr,
      Start,
      MBEDTLS_OID_PKCS7_DATA,
      sizeof (MBEDTLS_OID_PKCS7_DATA) - 1
      )
    );

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));

  return Len;
}

/**
   certificates :: SET OF ExtendedCertificateOrCertificate,
   ExtendedCertificateOrCertificate ::= CHOICE {
        certificate Certificate -- x509,
        extendedCertificate[0] IMPLICIT ExtendedCertificate }.

  @param[in, out]  Ptr           The reference to the current position pointer.
  @param[in]       Start       The start of the buffer, for bounds-checking.
  @param[in]       Cert        Certificate.
  @param[in]       OtherCerts  Ohter Certificate.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteCertificates (
  UINT8             **Ptr,
  UINT8             *Start,
  mbedtls_x509_crt  *Cert,
  mbedtls_x509_crt  *OtherCerts
  )
{
  INT32             Ret;
  INT32             Len;
  mbedtls_x509_crt  *TmpCert;

  Len = 0;

  /// Write OtherCerts
  TmpCert = OtherCerts;
  while (TmpCert != NULL) {
    EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, TmpCert->raw.p, TmpCert->raw.len));
    TmpCert = TmpCert->next;
  }

  /// Write Cert
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, Cert->raw.p, Cert->raw.len));

  /// Write NextContext
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
  return Len;
}

/**
  write Pkcs7 Int.

  @param[in, out]  Ptr            The reference to the current position pointer.
  @param[in]       Start        The start of the buffer, for bounds-checking.
  @param[in]       SerialRaw    SerialRaw.
  @param[in]       SerialRawLen Size of SerialRaw.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteInt (
  UINT8  **Ptr,
  UINT8  *Start,
  UINT8  *SerialRaw,
  INTN   SerialRawLen
  )
{
  INT32  Ret;
  UINT8  *Pt;
  INT32  Len;

  Len = 0;
  Pt  = SerialRaw + SerialRawLen;
  while (Pt > SerialRaw) {
    *--(*Ptr) = *--Pt;
    Len++;
  }

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_INTEGER));

  return Len;
}

/**
  write Pkcs7 Issuer And SerialNumber.

  @param[in, out]  Ptr            The reference to the current position pointer.
  @param[in]       Start        The start of the buffer, for bounds-checking.
  @param[in]       Serial       Serial.
  @param[in]       SerialLen    Size of Serial.
  @param[in]       IssuerRaw    IssuerRawLen.
  @param[in]       IssuerRawLen Size of IssuerRawLen.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteIssuerAndSerialNumber (
  UINT8  **Ptr,
  UINT8  *Start,
  UINT8  *Serial,
  INTN   SerialLen,
  UINT8  *IssuerRaw,
  INTN   IssuerRawLen
  )
{
  INT32  Ret;
  INT32  Len;

  Len = 0;
  EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteInt (Ptr, Start, Serial, SerialLen));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, IssuerRaw, IssuerRawLen));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));

  return Len;
}

/**
   SignerInfo ::= SEQUENCE {
        version Version;
        issuerAndSerialNumber   IssuerAndSerialNumber,
        digestAlgorithm DigestAlgorithmIdentifier,
        authenticatedAttributes
                [0] IMPLICIT Attributes OPTIONAL,
        digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
        encryptedDigest EncryptedDigest,
        unauthenticatedAttributes
                [1] IMPLICIT Attributes OPTIONAL.

  @param[in, out]  Ptr            The reference to the current position pointer.
  @param[in]       Start        The start of the buffer, for bounds-checking.
  @param[in]       SignerInfo    SignerInfo.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteSignerInfo (
  UINT8                   **Ptr,
  UINT8                   *Start,
  MbedtlsPkcs7SignerInfo  *SignerInfo
  )
{
  INT32  Ret;
  INT32  Len;

  Len = 0;

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, SignerInfo->Sig.p, SignerInfo->Sig.len));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->SigAlgIdentifier.p, SignerInfo->SigAlgIdentifier.len, 0));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->AlgIdentifier.p, SignerInfo->AlgIdentifier.len, 0));

  EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteIssuerAndSerialNumber (Ptr, Start, SignerInfo->Serial.p, SignerInfo->Serial.len, SignerInfo->IssuerRaw.p, SignerInfo->IssuerRaw.len));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, SignerInfo->Version));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));

  return Len;
}

/**
  write Pkcs7 Signers Info Set.

  @param[in, out]  Ptr            The reference to the current position pointer.
  @param[in]       Start        The start of the buffer, for bounds-checking.
  @param[in]       SignersSet   SignerInfo Set.

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteSignersInfoSet (
  UINT8                   **Ptr,
  UINT8                   *Start,
  MbedtlsPkcs7SignerInfo  *SignersSet
  )
{
  MbedtlsPkcs7SignerInfo  *SignerInfo;
  INT32                   Ret;
  INT32                   Len;

  SignerInfo = SignersSet;
  Len        = 0;

  while (SignerInfo != NULL) {
    EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignerInfo (Ptr, Start, SignerInfo));
    // move to next
    SignerInfo = SignerInfo->Next;
  }

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET));

  return Len;
}

/**
  Signed Data Type
  SignedData ::= SEQUENCE {
  version Version,
  digestAlgorithms DigestAlgorithmIdentifiers,
  contentInfo ContentInfo,
  certificates
      [0] IMPLICIT ExtendedCertificatesAndCertificates
        OPTIONAL,
  crls
    [1] IMPLICIT CertificateRevocationLists OPTIONAL,
  signerInfos SignerInfos }

  DigestAlgorithmIdentifiers ::=
      SET OF DigestAlgorithmIdentifier

  SignerInfos ::= SET OF SignerInfo.

  @param[in, out]  Ptr            The reference to the current position pointer.
  @param[in]       Start        The start of the buffer, for bounds-checking.
  @param[in]       Pkcs7        MbedtlsPkcs7

  @retval number      The number of bytes written to p on success.
  @retval negative  A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteDer (
  UINT8         **Ptr,
  UINT8         *Start,
  MbedtlsPkcs7  *Pkcs7
  )
{
  INT32              Ret;
  INT32              Len;
  mbedtls_md_type_t  DigestAlg[1];

  DigestAlg[0] = MBEDTLS_MD_SHA256;
  Len          = 0;

  EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignersInfoSet (Ptr, Start, &(Pkcs7->SignedData.SignerInfos)));

  EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteCertificates (Ptr, Start, &(Pkcs7->SignedData.Certificates), Pkcs7->SignedData.Certificates.next));

  EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteContentInfo (Ptr, Start, NULL, 0));

  EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteDigestAlgorithmSet (Ptr, Start, DigestAlg, 1));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, Pkcs7->SignedData.Version));

  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
  EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));

  return Len;
}

/**
  Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
  Syntax Standard, version 1.5". This interface is only intended to be used for
  application to perform PKCS#7 functionality validation.

  If this interface is not supported, then return FALSE.

  @param[in]  PrivateKey       Pointer to the PEM-formatted private key data for
                               data signing.
  @param[in]  PrivateKeySize   Size of the PEM private key data in bytes.
  @param[in]  KeyPassword      NULL-terminated passphrase used for encrypted PEM
                               key data.
  @param[in]  InData           Pointer to the content to be signed.
  @param[in]  InDataSize       Size of InData in bytes.
  @param[in]  SignCert         Pointer to signer's DER-encoded certificate to sign with.
  @param[in]  OtherCerts       Pointer to an optional additional set of certificates to
                               include in the PKCS#7 signedData (e.g. any intermediate
                               CAs in the chain).
  @param[out] SignedData       Pointer to output PKCS#7 signedData. It's caller's
                               responsibility to free the buffer with FreePool().
  @param[out] SignedDataSize   Size of SignedData in bytes.

  @retval     TRUE             PKCS#7 data signing succeeded.
  @retval     FALSE            PKCS#7 data signing failed.
  @retval     FALSE            This interface is not supported.

**/
BOOLEAN
EFIAPI
Pkcs7Sign (
  IN CONST UINT8  *PrivateKey,
  IN UINTN        PrivateKeySize,
  IN CONST UINT8  *KeyPassword,
  IN UINT8        *InData,
  IN UINTN        InDataSize,
  IN UINT8        *SignCert,
  IN UINT8        *OtherCerts OPTIONAL,
  OUT UINT8       **SignedData,
  OUT UINTN       *SignedDataSize
  )
{
  BOOLEAN             Status;
  INT32               Ret;
  mbedtls_pk_context  Pkey;
  UINT8               HashValue[SHA256_DIGEST_SIZE];
  UINT8               Signature[MAX_SIGNATURE_SIZE];
  UINTN               SignatureLen;
  UINT8               *NewPrivateKey;
  mbedtls_x509_crt    *Crt;

  MbedtlsPkcs7            Pkcs7;
  MbedtlsPkcs7SignerInfo  SignerInfo;
  UINT8                   *Buffer;
  INTN                    BufferSize;
  UINT8                   *Ptr;
  INT32                   Len;

  //
  // Check input parameters.
  //
  if ((PrivateKey == NULL) || (KeyPassword == NULL) || (InData == NULL) ||
      (SignCert == NULL) || (SignedData == NULL) || (SignedDataSize == NULL) || (InDataSize > INT_MAX))
  {
    return FALSE;
  }

  Buffer     = NULL;
  BufferSize = 4096;

  SignatureLen = MAX_SIGNATURE_SIZE;
  Crt          = (mbedtls_x509_crt *)SignCert;

  NewPrivateKey = NULL;
  if (PrivateKey[PrivateKeySize - 1] != 0) {
    NewPrivateKey = AllocateZeroPool (PrivateKeySize + 1);
    if (NewPrivateKey == NULL) {
      return FALSE;
    }

    CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
    NewPrivateKey[PrivateKeySize] = 0;
    PrivateKeySize++;
  } else {
    NewPrivateKey = AllocateZeroPool (PrivateKeySize);
    if (NewPrivateKey == NULL) {
      return FALSE;
    }

    CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
  }

  mbedtls_pk_init (&Pkey);
  Ret = mbedtls_pk_parse_key (
          &Pkey,
          NewPrivateKey,
          PrivateKeySize,
          KeyPassword,
          KeyPassword == NULL ? 0 : AsciiStrLen ((CONST CHAR8 *)KeyPassword),
          NULL,
          NULL
          );
  if (Ret != 0) {
    Status = FALSE;
    goto Cleanup;
  }

  /// Calculate InData Digest
  ZeroMem (HashValue, SHA256_DIGEST_SIZE);
  Status = Sha256HashAll (InData, InDataSize, HashValue);
  if (!Status) {
    goto Cleanup;
  }

  /// Pk Sign
  ZeroMem (Signature, MAX_SIGNATURE_SIZE);
  Ret = mbedtls_pk_sign (
          &Pkey,
          MBEDTLS_MD_SHA256,
          HashValue,
          SHA256_DIGEST_SIZE,
          Signature,
          MAX_SIGNATURE_SIZE,
          &SignatureLen,
          MbedtlsRand,
          NULL
          );
  if (Ret != 0) {
    Status = FALSE;
    goto Cleanup;
  }

  ZeroMem (&Pkcs7, sizeof (MbedtlsPkcs7));
  Pkcs7.SignedData.Version = 1;

  Crt->next                     = (mbedtls_x509_crt *)OtherCerts;
  Pkcs7.SignedData.Certificates = *Crt;

  SignerInfo.Next              = NULL;
  SignerInfo.Sig.p             = Signature;
  SignerInfo.Sig.len           = SignatureLen;
  SignerInfo.Version           = 1;
  SignerInfo.AlgIdentifier.p   = MbedtlsOidDigestAlgSha256;
  SignerInfo.AlgIdentifier.len = sizeof (MBEDTLS_OID_DIGEST_ALG_SHA256) - 1;
  if (mbedtls_pk_get_type (&Pkey) == MBEDTLS_PK_RSA) {
    SignerInfo.SigAlgIdentifier.p   = MbedtlsOidPkcs1Rsa;
    SignerInfo.SigAlgIdentifier.len = sizeof (MBEDTLS_OID_PKCS1_RSA) - 1;
  } else {
    Ret = mbedtls_oid_get_oid_by_sig_alg (MBEDTLS_PK_ECDSA, MBEDTLS_MD_SHA256, (CONST CHAR8 **)&SignerInfo.SigAlgIdentifier.p, &SignerInfo.SigAlgIdentifier.len);
    if (Ret != 0) {
      Status = FALSE;
      goto Cleanup;
    }
  }

  SignerInfo.Serial            = ((mbedtls_x509_crt *)SignCert)->serial;
  SignerInfo.IssuerRaw         = ((mbedtls_x509_crt *)SignCert)->issuer_raw;
  Pkcs7.SignedData.SignerInfos = SignerInfo;

  Buffer = AllocateZeroPool (BufferSize);
  if (Buffer == NULL) {
    Status = FALSE;
    goto Cleanup;
  }

  Ptr = Buffer + BufferSize;
  Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);

  /// Enlarge buffer if buffer is too small
  while (Len == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
    BufferSize = BufferSize * 2;
    Ptr        = Buffer + BufferSize;
    FreePool (Buffer);
    Buffer = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      Status = FALSE;
      goto Cleanup;
    }

    Ptr = Buffer + BufferSize;
    Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
  }

  if (Len <= 0) {
    Status = FALSE;
    goto Cleanup;
  }

  *SignedData = AllocateZeroPool (Len);
  if (*SignedData == NULL) {
    Status = FALSE;
    goto Cleanup;
  }

  *SignedDataSize = Len;
  CopyMem (*SignedData, Ptr, Len);
  Status = TRUE;

Cleanup:
  if (&Pkey != NULL) {
    mbedtls_pk_free (&Pkey);
  }

  if (NewPrivateKey != NULL) {
    memset (NewPrivateKey, 0, PrivateKeySize);
    FreePool (NewPrivateKey);
  }

  if (Buffer != NULL) {
    memset (Buffer, 0, BufferSize);
    FreePool (Buffer);
  }

  return Status;
}
