/** @file
  Unit tests for the Pkcs7Encrypt() API in BaseCryptLib.

  These tests exercise both the OpenSSL- and mbedtls-backed implementations.
  They build envelopedData ContentInfo blobs for one or more recipients with
  each supported AES-CBC cipher and verify the result structurally (DER walk),
  plus the parameter-validation contract documented in BaseCryptLib.h. Proving
  that the content can be recovered is covered by Pkcs7DecryptTests.c.

  Copyright (c) Microsoft Corporation. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "TestBaseCryptLib.h"

#include "Pkcs7EncryptTestCert.h"

//
// Sample plaintext to encrypt. Length is intentionally not a multiple of the
// AES block size to exercise CBC padding within the implementation.
//
STATIC CONST UINT8  mPkcs7EncryptPlaintext[] = {
  'P', 'k', 'c', 's', '7', 'E', 'n', 'c', 'r', 'y', 'p', 't',
  ' ', 'u', 'n', 'i', 't', '-', 't', 'e', 's', 't', ' ', 'p',
  'a', 'y', 'l', 'o', 'a', 'd'
};

//
// DER OIDs (full tag-length-value form) of the values we expect to see inside
// a well-formed envelopedData ContentInfo produced by Pkcs7Encrypt().
//
// id-envelopedData = 1.2.840.113549.1.7.3
//
STATIC CONST UINT8  mOidEnvelopedData[] = {
  0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
};

// aes-128-cbc = 2.16.840.1.101.3.4.1.2
STATIC CONST UINT8  mOidAes128Cbc[] = {
  0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02
};

// aes-192-cbc = 2.16.840.1.101.3.4.1.22
STATIC CONST UINT8  mOidAes192Cbc[] = {
  0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16
};

// aes-256-cbc = 2.16.840.1.101.3.4.1.42
STATIC CONST UINT8  mOidAes256Cbc[] = {
  0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A
};

//
// Minimal ASN.1 / DER walker. Just enough to validate Pkcs7Encrypt output
// without pulling in OpenSSL/mbedtls headers from the test.
//
typedef struct {
  UINT8          Tag;     ///< Identifier octet.
  UINTN          Length;  ///< Decoded content length (excludes T+L bytes).
  CONST UINT8    *Value;  ///< Pointer to the first content octet.
  UINTN          Total;   ///< Total bytes consumed (T + L + V).
} DER_TLV;

/**
  Decode a single ASN.1 BER/DER TLV starting at Buf.

  @param[in]   Buf      Input buffer.
  @param[in]   BufLen   Length of Buf in bytes.
  @param[out]  Tlv      Decoded TLV on success.

  @retval TRUE   Decode succeeded.
  @retval FALSE  Truncated or malformed input.
**/
STATIC
BOOLEAN
DerParseTlv (
  IN CONST UINT8  *Buf,
  IN UINTN        BufLen,
  OUT DER_TLV     *Tlv
  )
{
  UINTN  Pos;
  UINTN  Len;
  UINTN  LenOctets;
  UINTN  Index;

  if ((Buf == NULL) || (Tlv == NULL) || (BufLen < 2)) {
    return FALSE;
  }

  Tlv->Tag = Buf[0];
  Pos      = 1;

  if ((Buf[Pos] & 0x80) == 0) {
    Len  = Buf[Pos];
    Pos += 1;
  } else {
    LenOctets = Buf[Pos] & 0x7Fu;
    Pos      += 1;
    if ((LenOctets == 0) || (LenOctets > sizeof (UINTN)) || (BufLen < Pos + LenOctets)) {
      return FALSE;
    }

    Len = 0;
    for (Index = 0; Index < LenOctets; Index++) {
      Len  = (Len << 8) | Buf[Pos];
      Pos += 1;
    }
  }

  if (Len > BufLen - Pos) {
    return FALSE;
  }

  Tlv->Length = Len;
  Tlv->Value  = Buf + Pos;
  Tlv->Total  = Pos + Len;
  return TRUE;
}

/**
  Compare the leading bytes of the TLV's encoded form (tag+length+value) against
  a reference encoded OID.

  @param[in]  Buf            Buffer containing the encoded OID TLV.
  @param[in]  BufLen         Bytes available at Buf.
  @param[in]  ExpectedOid    Reference DER-encoded OID (T+L+V).
  @param[in]  ExpectedOidLen Length of ExpectedOid.

  @retval TRUE   The first ExpectedOidLen bytes of Buf match ExpectedOid.
  @retval FALSE  Mismatch, or Buf too short.
**/
STATIC
BOOLEAN
DerOidEquals (
  IN CONST UINT8  *Buf,
  IN UINTN        BufLen,
  IN CONST UINT8  *ExpectedOid,
  IN UINTN        ExpectedOidLen
  )
{
  if (BufLen < ExpectedOidLen) {
    return FALSE;
  }

  return (BOOLEAN)(CompareMem (Buf, ExpectedOid, ExpectedOidLen) == 0);
}

/**
  Walk a PKCS#7 envelopedData ContentInfo produced by Pkcs7Encrypt() and verify
  it carries the expected content-encryption algorithm and recipient count.

  Reference: RFC 5652, Sections 3 and 6.

      ContentInfo ::= SEQUENCE {
        contentType ContentType,                  -- id-envelopedData
        content     [0] EXPLICIT EnvelopedData
      }
      EnvelopedData ::= SEQUENCE {
        version              CMSVersion,
        [originatorInfo  [0] IMPLICIT OriginatorInfo OPTIONAL,]  -- v>=2
        recipientInfos       RecipientInfos,                     -- SET OF
        encryptedContentInfo EncryptedContentInfo
        [, unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL]
      }
      EncryptedContentInfo ::= SEQUENCE {
        contentType                ContentType,
        contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
        encryptedContent       [0] IMPLICIT EncryptedContent OPTIONAL
      }

  @param[in]  Buf                     Encoded ContentInfo.
  @param[in]  BufLen                  Length of Buf.
  @param[in]  ExpectedCipherOid       DER-encoded OID for the expected
                                      content-encryption algorithm.
  @param[in]  ExpectedCipherOidLen    Length of ExpectedCipherOid.
  @param[in]  ExpectedRecipientCount  Number of RecipientInfo entries expected.

  @retval TRUE   The structure parses and matches expectations.
  @retval FALSE  Parse error or unexpected content.
**/
STATIC
BOOLEAN
ValidatePkcs7EnvelopedData (
  IN CONST UINT8  *Buf,
  IN UINTN        BufLen,
  IN CONST UINT8  *ExpectedCipherOid,
  IN UINTN        ExpectedCipherOidLen,
  IN UINTN        ExpectedRecipientCount
  )
{
  DER_TLV      Outer;
  DER_TLV      ContentTypeOid;
  DER_TLV      Explicit0;
  DER_TLV      EnvelopedData;
  DER_TLV      Version;
  DER_TLV      Recipients;
  DER_TLV      EncryptedContentInfo;
  DER_TLV      EncContentTypeOid;
  DER_TLV      AlgorithmId;
  DER_TLV      AlgorithmOid;
  DER_TLV      RecipientInfo;
  CONST UINT8  *Cursor;
  UINTN        Remaining;
  UINTN        Count;
  UINT8        VersionValue;

  //
  // Outer SEQUENCE (ContentInfo).
  //
  if (!DerParseTlv (Buf, BufLen, &Outer) || (Outer.Tag != 0x30)) {
    return FALSE;
  }

  Cursor    = Outer.Value;
  Remaining = Outer.Length;

  //
  // contentType OID.
  //
  if (!DerParseTlv (Cursor, Remaining, &ContentTypeOid) || (ContentTypeOid.Tag != 0x06)) {
    return FALSE;
  }

  if (!DerOidEquals (Cursor, Remaining, mOidEnvelopedData, sizeof (mOidEnvelopedData))) {
    return FALSE;
  }

  Cursor    += ContentTypeOid.Total;
  Remaining -= ContentTypeOid.Total;

  //
  // content [0] EXPLICIT EnvelopedData.
  //
  if (!DerParseTlv (Cursor, Remaining, &Explicit0) || (Explicit0.Tag != 0xA0)) {
    return FALSE;
  }

  if (!DerParseTlv (Explicit0.Value, Explicit0.Length, &EnvelopedData) || (EnvelopedData.Tag != 0x30)) {
    return FALSE;
  }

  Cursor    = EnvelopedData.Value;
  Remaining = EnvelopedData.Length;

  //
  // version INTEGER.
  //
  if (!DerParseTlv (Cursor, Remaining, &Version) || (Version.Tag != 0x02)) {
    return FALSE;
  }

  if ((Version.Length != 1) || (Version.Value == NULL)) {
    return FALSE;
  }

  VersionValue = Version.Value[0];
  if ((VersionValue != 0) && (VersionValue != 2)) {
    return FALSE;
  }

  Cursor    += Version.Total;
  Remaining -= Version.Total;

  //
  // Optional originatorInfo [0] IMPLICIT -- skip if present (v2 producers).
  //
  if ((Remaining > 0) && (Cursor[0] == 0xA0)) {
    DER_TLV  Skip;
    if (!DerParseTlv (Cursor, Remaining, &Skip)) {
      return FALSE;
    }

    Cursor    += Skip.Total;
    Remaining -= Skip.Total;
  }

  //
  // recipientInfos SET OF RecipientInfo.
  //
  if (!DerParseTlv (Cursor, Remaining, &Recipients) || (Recipients.Tag != 0x31)) {
    return FALSE;
  }

  //
  // Count top-level TLVs inside the SET.
  //
  {
    CONST UINT8  *RcptCursor;
    UINTN        RcptRemaining;

    RcptCursor    = Recipients.Value;
    RcptRemaining = Recipients.Length;
    Count         = 0;
    while (RcptRemaining > 0) {
      if (!DerParseTlv (RcptCursor, RcptRemaining, &RecipientInfo)) {
        return FALSE;
      }

      Count         += 1;
      RcptCursor    += RecipientInfo.Total;
      RcptRemaining -= RecipientInfo.Total;
    }
  }

  if (Count != ExpectedRecipientCount) {
    return FALSE;
  }

  Cursor    += Recipients.Total;
  Remaining -= Recipients.Total;

  //
  // encryptedContentInfo SEQUENCE { contentType, contentEncryptionAlgorithm, ... }.
  //
  if (!DerParseTlv (Cursor, Remaining, &EncryptedContentInfo) || (EncryptedContentInfo.Tag != 0x30)) {
    return FALSE;
  }

  Cursor    = EncryptedContentInfo.Value;
  Remaining = EncryptedContentInfo.Length;

  if (!DerParseTlv (Cursor, Remaining, &EncContentTypeOid) || (EncContentTypeOid.Tag != 0x06)) {
    return FALSE;
  }

  Cursor    += EncContentTypeOid.Total;
  Remaining -= EncContentTypeOid.Total;

  //
  // AlgorithmIdentifier SEQUENCE { OID, parameters OPTIONAL }.
  //
  if (!DerParseTlv (Cursor, Remaining, &AlgorithmId) || (AlgorithmId.Tag != 0x30)) {
    return FALSE;
  }

  if (!DerParseTlv (AlgorithmId.Value, AlgorithmId.Length, &AlgorithmOid) || (AlgorithmOid.Tag != 0x06)) {
    return FALSE;
  }

  if (!DerOidEquals (
         AlgorithmId.Value,
         AlgorithmId.Length,
         ExpectedCipherOid,
         ExpectedCipherOidLen
         ))
  {
    return FALSE;
  }

  return TRUE;
}

/**
  Run an end-to-end encryption with a single recipient and validate the output.

  The resulting envelopedData is checked structurally. Recovering the plaintext
  is covered separately by the Pkcs7Decrypt() tests.

  @param[in]  CipherNid             Symmetric cipher NID to request.
  @param[in]  ExpectedCipherOid     Reference DER-encoded OID.
  @param[in]  ExpectedCipherOidLen  Length of ExpectedCipherOid.

  @retval UNIT_TEST_PASSED            All assertions held.
  @retval UNIT_TEST_ERROR_TEST_FAILED Stack build, encrypt, or validation failed.
**/
STATIC
UNIT_TEST_STATUS
RunPkcs7EncryptSingleRecipient (
  IN UINT32       CipherNid,
  IN CONST UINT8  *ExpectedCipherOid,
  IN UINTN        ExpectedCipherOidLen
  )
{
  UINT8    *X509Stack;
  UINT8    *ContentInfo;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  X509Stack       = NULL;
  ContentInfo     = NULL;
  ContentInfoSize = 0;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);
  UT_ASSERT_NOT_NULL (X509Stack);

  Result = Pkcs7Encrypt (
             X509Stack,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             CipherNid,
             CRYPTO_PKCS7_DEFAULT,
             &ContentInfo,
             &ContentInfoSize
             );

  X509StackFree (X509Stack);

  UT_ASSERT_TRUE (Result);
  UT_ASSERT_NOT_NULL (ContentInfo);
  UT_ASSERT_NOT_EQUAL (ContentInfoSize, 0);

  Result = ValidatePkcs7EnvelopedData (
             ContentInfo,
             ContentInfoSize,
             ExpectedCipherOid,
             ExpectedCipherOidLen,
             1
             );

  FreePool (ContentInfo);

  UT_ASSERT_TRUE (Result);
  return UNIT_TEST_PASSED;
}

/**
  Happy-path test for AES-128-CBC content encryption.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptAes128Cbc (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  return RunPkcs7EncryptSingleRecipient (
           CRYPTO_NID_AES128CBC,
           mOidAes128Cbc,
           sizeof (mOidAes128Cbc)
           );
}

/**
  Happy-path test for AES-192-CBC content encryption.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptAes192Cbc (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  return RunPkcs7EncryptSingleRecipient (
           CRYPTO_NID_AES192CBC,
           mOidAes192Cbc,
           sizeof (mOidAes192Cbc)
           );
}

/**
  Happy-path test for AES-256-CBC content encryption.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptAes256Cbc (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  return RunPkcs7EncryptSingleRecipient (
           CRYPTO_NID_AES256CBC,
           mOidAes256Cbc,
           sizeof (mOidAes256Cbc)
           );
}

/**
  Build a stack with two distinct recipients and verify the resulting
  envelopedData carries two RecipientInfo entries.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptMultipleRecipients (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *X509Stack;
  UINT8    *ContentInfo;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  X509Stack       = NULL;
  ContentInfo     = NULL;
  ContentInfoSize = 0;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             mPkcs7TestRecipient2Cert,
             (UINTN)sizeof (mPkcs7TestRecipient2Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);
  UT_ASSERT_NOT_NULL (X509Stack);

  Result = Pkcs7Encrypt (
             X509Stack,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             CRYPTO_NID_AES256CBC,
             CRYPTO_PKCS7_DEFAULT,
             &ContentInfo,
             &ContentInfoSize
             );

  X509StackFree (X509Stack);

  UT_ASSERT_TRUE (Result);
  UT_ASSERT_NOT_NULL (ContentInfo);
  UT_ASSERT_NOT_EQUAL (ContentInfoSize, 0);

  Result = ValidatePkcs7EnvelopedData (
             ContentInfo,
             ContentInfoSize,
             mOidAes256Cbc,
             sizeof (mOidAes256Cbc),
             2
             );

  FreePool (ContentInfo);

  UT_ASSERT_TRUE (Result);
  return UNIT_TEST_PASSED;
}

/**
  NULL X509Stack must be rejected.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptNullX509Stack (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *ContentInfo;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  ContentInfo     = (UINT8 *)(UINTN)0xDEADBEEF;
  ContentInfoSize = 0xA5A5A5;

  Result = Pkcs7Encrypt (
             NULL,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             CRYPTO_NID_AES256CBC,
             CRYPTO_PKCS7_DEFAULT,
             &ContentInfo,
             &ContentInfoSize
             );

  UT_ASSERT_FALSE (Result);
  UT_ASSERT_TRUE (ContentInfo == NULL);
  UT_ASSERT_EQUAL (ContentInfoSize, 0);
  return UNIT_TEST_PASSED;
}

/**
  NULL InData must be rejected.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptNullInData (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *X509Stack;
  UINT8    *ContentInfo;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  X509Stack       = NULL;
  ContentInfo     = NULL;
  ContentInfoSize = 0;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);

  Result = Pkcs7Encrypt (
             X509Stack,
             NULL,
             sizeof (mPkcs7EncryptPlaintext),
             CRYPTO_NID_AES256CBC,
             CRYPTO_PKCS7_DEFAULT,
             &ContentInfo,
             &ContentInfoSize
             );

  X509StackFree (X509Stack);

  UT_ASSERT_FALSE (Result);
  UT_ASSERT_TRUE (ContentInfo == NULL);
  UT_ASSERT_EQUAL (ContentInfoSize, 0);
  return UNIT_TEST_PASSED;
}

/**
  NULL ContentInfo output pointer must be rejected.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptNullContentInfo (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *X509Stack;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  X509Stack       = NULL;
  ContentInfoSize = 0;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);

  Result = Pkcs7Encrypt (
             X509Stack,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             CRYPTO_NID_AES256CBC,
             CRYPTO_PKCS7_DEFAULT,
             NULL,
             &ContentInfoSize
             );

  X509StackFree (X509Stack);

  UT_ASSERT_FALSE (Result);
  UT_ASSERT_EQUAL (ContentInfoSize, 0);
  return UNIT_TEST_PASSED;
}

/**
  NULL ContentInfoSize output pointer must be rejected.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptNullContentInfoSize (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *X509Stack;
  UINT8    *ContentInfo;
  BOOLEAN  Result;

  X509Stack   = NULL;
  ContentInfo = NULL;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);

  Result = Pkcs7Encrypt (
             X509Stack,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             CRYPTO_NID_AES256CBC,
             CRYPTO_PKCS7_DEFAULT,
             &ContentInfo,
             NULL
             );

  X509StackFree (X509Stack);

  UT_ASSERT_FALSE (Result);
  UT_ASSERT_TRUE (ContentInfo == NULL);
  return UNIT_TEST_PASSED;
}

/**
  An unsupported CipherNid (e.g. 0) must be rejected.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptUnsupportedCipher (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *X509Stack;
  UINT8    *ContentInfo;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  X509Stack       = NULL;
  ContentInfo     = NULL;
  ContentInfoSize = 0;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);

  Result = Pkcs7Encrypt (
             X509Stack,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             0,
             CRYPTO_PKCS7_DEFAULT,
             &ContentInfo,
             &ContentInfoSize
             );

  X509StackFree (X509Stack);

  UT_ASSERT_FALSE (Result);
  UT_ASSERT_TRUE (ContentInfo == NULL);
  UT_ASSERT_EQUAL (ContentInfoSize, 0);
  return UNIT_TEST_PASSED;
}

/**
  Any Flags value other than CRYPTO_PKCS7_DEFAULT must be rejected.
**/
STATIC
UNIT_TEST_STATUS
EFIAPI
TestPkcs7EncryptUnsupportedFlags (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UINT8    *X509Stack;
  UINT8    *ContentInfo;
  UINTN    ContentInfoSize;
  BOOLEAN  Result;

  X509Stack       = NULL;
  ContentInfo     = NULL;
  ContentInfoSize = 0;

  Result = X509ConstructCertificateStack (
             &X509Stack,
             mPkcs7TestRecipient1Cert,
             (UINTN)sizeof (mPkcs7TestRecipient1Cert),
             NULL
             );
  UT_ASSERT_TRUE (Result);

  Result = Pkcs7Encrypt (
             X509Stack,
             (UINT8 *)mPkcs7EncryptPlaintext,
             sizeof (mPkcs7EncryptPlaintext),
             CRYPTO_NID_AES256CBC,
             0xDEADBEEF,
             &ContentInfo,
             &ContentInfoSize
             );

  X509StackFree (X509Stack);

  UT_ASSERT_FALSE (Result);
  UT_ASSERT_TRUE (ContentInfo == NULL);
  UT_ASSERT_EQUAL (ContentInfoSize, 0);
  return UNIT_TEST_PASSED;
}

//
// Test descriptor table consumed by BaseCryptLibUnitTests and
// BaseCryptLibUnitTestsMbedTls.
//
TEST_DESC  mPkcs7EncryptTest[] = {
  //
  // -----Description--------------------------------------Class-----------------------Function-----------------------------------PreReq-Post-Context
  //
  { "TestPkcs7EncryptAes128Cbc()",           "CryptoPkg.BaseCryptLib", TestPkcs7EncryptAes128Cbc,           NULL, NULL, NULL },
  { "TestPkcs7EncryptAes192Cbc()",           "CryptoPkg.BaseCryptLib", TestPkcs7EncryptAes192Cbc,           NULL, NULL, NULL },
  { "TestPkcs7EncryptAes256Cbc()",           "CryptoPkg.BaseCryptLib", TestPkcs7EncryptAes256Cbc,           NULL, NULL, NULL },
  { "TestPkcs7EncryptMultipleRecipients()",  "CryptoPkg.BaseCryptLib", TestPkcs7EncryptMultipleRecipients,  NULL, NULL, NULL },
  { "TestPkcs7EncryptNullX509Stack()",       "CryptoPkg.BaseCryptLib", TestPkcs7EncryptNullX509Stack,       NULL, NULL, NULL },
  { "TestPkcs7EncryptNullInData()",          "CryptoPkg.BaseCryptLib", TestPkcs7EncryptNullInData,          NULL, NULL, NULL },
  { "TestPkcs7EncryptNullContentInfo()",     "CryptoPkg.BaseCryptLib", TestPkcs7EncryptNullContentInfo,     NULL, NULL, NULL },
  { "TestPkcs7EncryptNullContentInfoSize()", "CryptoPkg.BaseCryptLib", TestPkcs7EncryptNullContentInfoSize, NULL, NULL, NULL },
  { "TestPkcs7EncryptUnsupportedCipher()",   "CryptoPkg.BaseCryptLib", TestPkcs7EncryptUnsupportedCipher,   NULL, NULL, NULL },
  { "TestPkcs7EncryptUnsupportedFlags()",    "CryptoPkg.BaseCryptLib", TestPkcs7EncryptUnsupportedFlags,    NULL, NULL, NULL },
};

UINTN  mPkcs7EncryptTestNum = ARRAY_SIZE (mPkcs7EncryptTest);
