| /** @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; | |
| } | |
| } |