CryptoPkg: Add CryptAes functions based on Mbedtls Add CryptAes APIS.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Cipher/CryptAes.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Cipher/CryptAes.c
new file mode 100644
index 0000000..274d2fa
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Cipher/CryptAes.c
@@ -0,0 +1,225 @@
+/** @file

+  AES Wrapper Implementation over MbedTLS.

+

+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>

+SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+#include "InternalCryptLib.h"

+#include <mbedtls/aes.h>

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for AES operations.

+

+  @return  The size, in bytes, of the context buffer required for AES operations.

+

+**/

+UINTN

+EFIAPI

+AesGetContextSize (

+  VOID

+  )

+{

+  //

+  // AES uses different key contexts for encryption and decryption, so here memory

+  // for 2 copies of mbedtls_aes_context is allocated.

+  //

+  return (UINTN)(2 * sizeof (mbedtls_aes_context));

+}

+

+/**

+  Initializes user-supplied memory as AES context for subsequent use.

+

+  This function initializes user-supplied memory pointed by AesContext as AES context.

+  In addition, it sets up all AES key materials for subsequent encryption and decryption

+  operations.

+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.

+

+  If AesContext is NULL, then return FALSE.

+  If Key is NULL, then return FALSE.

+  If KeyLength is not valid, then return FALSE.

+

+  @param[out]  AesContext  Pointer to AES context being initialized.

+  @param[in]   Key         Pointer to the user-supplied AES key.

+  @param[in]   KeyLength   Length of AES key in bits.

+

+  @retval TRUE   AES context initialization succeeded.

+  @retval FALSE  AES context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesInit (

+  OUT  VOID         *AesContext,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeyLength

+  )

+{

+  mbedtls_aes_context  *AesCtx;

+

+  //

+  // Check input parameters.

+  //

+  if ((AesContext == NULL) || (Key == NULL) || ((KeyLength != 128) && (KeyLength != 192) && (KeyLength != 256))) {

+    return FALSE;

+  }

+

+  //

+  // Initialize AES encryption & decryption key schedule.

+  //

+  AesCtx = (mbedtls_aes_context *)AesContext;

+  if (mbedtls_aes_setkey_enc (AesCtx, Key, (UINT32)KeyLength) != 0) {

+    return FALSE;

+  }

+

+  if (mbedtls_aes_setkey_dec (AesCtx + 1, Key, (UINT32)KeyLength) != 0) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Performs AES encryption on a data buffer of the specified size in CBC mode.

+

+  This function performs AES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (16 bytes).

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then return FALSE.

+  If Input is NULL, then return FALSE.

+  If InputSize is not multiple of block size (16 bytes), then return FALSE.

+  If Ivec is NULL, then return FALSE.

+  If Output is NULL, then return FALSE.

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[in]   Ivec        Pointer to initialization vector.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES encryption succeeded.

+  @retval FALSE  AES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesCbcEncrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  )

+{

+  mbedtls_aes_context  *AesCtx;

+  UINT8                IvecBuffer[AES_BLOCK_SIZE];

+

+  //

+  // Check input parameters.

+  //

+  if ((AesContext == NULL) || (Input == NULL) || ((InputSize % AES_BLOCK_SIZE) != 0)) {

+    return FALSE;

+  }

+

+  if ((Ivec == NULL) || (Output == NULL) || (InputSize > INT_MAX)) {

+    return FALSE;

+  }

+

+  AesCtx = (mbedtls_aes_context *)AesContext;

+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);

+

+  //

+  // Perform AES data encryption with CBC mode

+  //

+  if (mbedtls_aes_crypt_cbc (

+        AesCtx,

+        MBEDTLS_AES_ENCRYPT,

+        (UINT32)InputSize,

+        IvecBuffer,

+        Input,

+        Output

+        ) != 0)

+  {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+}

+

+/**

+  Performs AES decryption on a data buffer of the specified size in CBC mode.

+

+  This function performs AES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (16 bytes).

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then return FALSE.

+  If Input is NULL, then return FALSE.

+  If InputSize is not multiple of block size (16 bytes), then return FALSE.

+  If Ivec is NULL, then return FALSE.

+  If Output is NULL, then return FALSE.

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[in]   Ivec        Pointer to initialization vector.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES decryption succeeded.

+  @retval FALSE  AES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesCbcDecrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  )

+{

+  mbedtls_aes_context  *AesCtx;

+  UINT8                IvecBuffer[AES_BLOCK_SIZE];

+

+  //

+  // Check input parameters.

+  //

+  if ((AesContext == NULL) || (Input == NULL) || ((InputSize % AES_BLOCK_SIZE) != 0)) {

+    return FALSE;

+  }

+

+  if ((Ivec == NULL) || (Output == NULL) || (InputSize > INT_MAX)) {

+    return FALSE;

+  }

+

+  AesCtx = (mbedtls_aes_context *)AesContext;

+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);

+

+  //

+  // Perform AES data encryption with CBC mode

+  //

+  if (mbedtls_aes_crypt_cbc (

+        AesCtx + 1,

+        MBEDTLS_AES_DECRYPT,

+        (UINT32)InputSize,

+        IvecBuffer,

+        Input,

+        Output

+        ) != 0)

+  {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+}