mirror of https://github.com/acidanthera/audk.git
226 lines
6.4 KiB
C
226 lines
6.4 KiB
C
|
/** @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;
|
||
|
}
|
||
|
}
|