REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1898 Aes Ecb mode is not secure any longer. Remove the Aes Ecb mode support from edk2. Change the Aes Ecb mode field name in EDKII_CRYPTO_PROTOCOL to indicate the function is unsupported any longer. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Xiaoyu Lu <xiaoyux.lu@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Philippe Mathieu-Daude <philmd@redhat.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com> Signed-off-by: Zhichao Gao <zhichao.gao@intel.com>
		
			
				
	
	
		
			204 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  AES Wrapper Implementation over OpenSSL.
 | 
						|
 | 
						|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "InternalCryptLib.h"
 | 
						|
#include <openssl/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 AES_KEY is allocated.
 | 
						|
  //
 | 
						|
  return (UINTN) (2 * sizeof (AES_KEY));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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
 | 
						|
  )
 | 
						|
{
 | 
						|
  AES_KEY  *AesKey;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check input parameters.
 | 
						|
  //
 | 
						|
  if (AesContext == NULL || Key == NULL || (KeyLength != 128 && KeyLength != 192 && KeyLength != 256)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize AES encryption & decryption key schedule.
 | 
						|
  //
 | 
						|
  AesKey = (AES_KEY *) AesContext;
 | 
						|
  if (AES_set_encrypt_key (Key, (UINT32) KeyLength, AesKey) != 0) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  if (AES_set_decrypt_key (Key, (UINT32) KeyLength, AesKey + 1) != 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
 | 
						|
  )
 | 
						|
{
 | 
						|
  AES_KEY  *AesKey;
 | 
						|
  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;
 | 
						|
  }
 | 
						|
 | 
						|
  AesKey = (AES_KEY *) AesContext;
 | 
						|
  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);
 | 
						|
 | 
						|
  //
 | 
						|
  // Perform AES data encryption with CBC mode
 | 
						|
  //
 | 
						|
  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);
 | 
						|
 | 
						|
  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
 | 
						|
  )
 | 
						|
{
 | 
						|
  AES_KEY  *AesKey;
 | 
						|
  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;
 | 
						|
  }
 | 
						|
 | 
						|
  AesKey = (AES_KEY *) AesContext;
 | 
						|
  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);
 | 
						|
 | 
						|
  //
 | 
						|
  // Perform AES data decryption with CBC mode
 | 
						|
  //
 | 
						|
  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 |