From eebd446875a4b1e4879e03764f63c6c358fd64f5 Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Tue, 19 Sep 2023 18:54:06 +0800 Subject: CryptoPkg: Add CryptAes functions based on Mbedtls Add CryptAes APIS. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177 Cc: Jiewen Yao Cc: Yi Li Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Wenxing Hou Reviewed-by: Yi Li --- .../Library/BaseCryptLibMbedTls/Cipher/CryptAes.c | 225 +++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Cipher/CryptAes.c (limited to 'CryptoPkg/Library') diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Cipher/CryptAes.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Cipher/CryptAes.c new file mode 100644 index 0000000000..274d2fa471 --- /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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include + +/** + 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; + } +} -- cgit v1.2.3