diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index 2a9664ad3e..a1785f3423 100644 --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -38,6 +38,7 @@ Hmac/CryptHmac.c Kdf/CryptHkdf.c Cipher/CryptAes.c + Cipher/CryptAeadAesGcm.c Pk/CryptRsaBasic.c Pk/CryptRsaExt.c Pk/CryptPkcs1Oaep.c diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAeadAesGcm.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAeadAesGcm.c new file mode 100644 index 0000000000..b4c93d47a9 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAeadAesGcm.c @@ -0,0 +1,279 @@ +/** @file + AEAD (AES-GCM) Wrapper Implementation over OpenSSL. + + RFC 5116 - An Interface and Algorithms for Authenticated Encryption + NIST SP800-38d - Cipher Modes of Operation: Galois / Counter Mode(GCM) and GMAC + +Copyright (c) 2022, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include +#include + +/** + Performs AEAD AES-GCM authenticated encryption on a data buffer and additional authenticated data (AAD). + + IvSize must be 12, otherwise FALSE is returned. + KeySize must be 16, 24 or 32, otherwise FALSE is returned. + TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned. + + @param[in] Key Pointer to the encryption key. + @param[in] KeySize Size of the encryption key in bytes. + @param[in] Iv Pointer to the IV value. + @param[in] IvSize Size of the IV value in bytes. + @param[in] AData Pointer to the additional authenticated data (AAD). + @param[in] ADataSize Size of the additional authenticated data (AAD) in bytes. + @param[in] DataIn Pointer to the input data buffer to be encrypted. + @param[in] DataInSize Size of the input data buffer in bytes. + @param[out] TagOut Pointer to a buffer that receives the authentication tag output. + @param[in] TagSize Size of the authentication tag in bytes. + @param[out] DataOut Pointer to a buffer that receives the encryption output. + @param[out] DataOutSize Size of the output data buffer in bytes. + + @retval TRUE AEAD AES-GCM authenticated encryption succeeded. + @retval FALSE AEAD AES-GCM authenticated encryption failed. + +**/ +BOOLEAN +EFIAPI +AeadAesGcmEncrypt ( + IN CONST UINT8 *Key, + IN UINTN KeySize, + IN CONST UINT8 *Iv, + IN UINTN IvSize, + IN CONST UINT8 *AData, + IN UINTN ADataSize, + IN CONST UINT8 *DataIn, + IN UINTN DataInSize, + OUT UINT8 *TagOut, + IN UINTN TagSize, + OUT UINT8 *DataOut, + OUT UINTN *DataOutSize + ) +{ + EVP_CIPHER_CTX *Ctx; + CONST EVP_CIPHER *Cipher; + UINTN TempOutSize; + BOOLEAN RetValue; + + if (DataInSize > INT_MAX) { + return FALSE; + } + + if (ADataSize > INT_MAX) { + return FALSE; + } + + if (IvSize != 12) { + return FALSE; + } + + switch (KeySize) { + case 16: + Cipher = EVP_aes_128_gcm (); + break; + case 24: + Cipher = EVP_aes_192_gcm (); + break; + case 32: + Cipher = EVP_aes_256_gcm (); + break; + default: + return FALSE; + } + + if ((TagSize != 12) && (TagSize != 13) && (TagSize != 14) && (TagSize != 15) && (TagSize != 16)) { + return FALSE; + } + + if (DataOutSize != NULL) { + if ((*DataOutSize > INT_MAX) || (*DataOutSize < DataInSize)) { + return FALSE; + } + } + + Ctx = EVP_CIPHER_CTX_new (); + if (Ctx == NULL) { + return FALSE; + } + + RetValue = (BOOLEAN)EVP_EncryptInit_ex (Ctx, Cipher, NULL, NULL, NULL); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_CIPHER_CTX_ctrl (Ctx, EVP_CTRL_GCM_SET_IVLEN, (INT32)IvSize, NULL); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_EncryptInit_ex (Ctx, NULL, NULL, Key, Iv); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_EncryptUpdate (Ctx, NULL, (INT32 *)&TempOutSize, AData, (INT32)ADataSize); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_EncryptUpdate (Ctx, DataOut, (INT32 *)&TempOutSize, DataIn, (INT32)DataInSize); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_EncryptFinal_ex (Ctx, DataOut, (INT32 *)&TempOutSize); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_CIPHER_CTX_ctrl (Ctx, EVP_CTRL_GCM_GET_TAG, (INT32)TagSize, (VOID *)TagOut); + +Done: + EVP_CIPHER_CTX_free (Ctx); + if (!RetValue) { + return RetValue; + } + + if (DataOutSize != NULL) { + *DataOutSize = DataInSize; + } + + return RetValue; +} + +/** + Performs AEAD AES-GCM authenticated decryption on a data buffer and additional authenticated data (AAD). + + IvSize must be 12, otherwise FALSE is returned. + KeySize must be 16, 24 or 32, otherwise FALSE is returned. + TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned. + If additional authenticated data verification fails, FALSE is returned. + + @param[in] Key Pointer to the encryption key. + @param[in] KeySize Size of the encryption key in bytes. + @param[in] Iv Pointer to the IV value. + @param[in] IvSize Size of the IV value in bytes. + @param[in] AData Pointer to the additional authenticated data (AAD). + @param[in] ADataSize Size of the additional authenticated data (AAD) in bytes. + @param[in] DataIn Pointer to the input data buffer to be decrypted. + @param[in] DataInSize Size of the input data buffer in bytes. + @param[in] Tag Pointer to a buffer that contains the authentication tag. + @param[in] TagSize Size of the authentication tag in bytes. + @param[out] DataOut Pointer to a buffer that receives the decryption output. + @param[out] DataOutSize Size of the output data buffer in bytes. + + @retval TRUE AEAD AES-GCM authenticated decryption succeeded. + @retval FALSE AEAD AES-GCM authenticated decryption failed. + +**/ +BOOLEAN +EFIAPI +AeadAesGcmDecrypt ( + IN CONST UINT8 *Key, + IN UINTN KeySize, + IN CONST UINT8 *Iv, + IN UINTN IvSize, + IN CONST UINT8 *AData, + IN UINTN ADataSize, + IN CONST UINT8 *DataIn, + IN UINTN DataInSize, + IN CONST UINT8 *Tag, + IN UINTN TagSize, + OUT UINT8 *DataOut, + OUT UINTN *DataOutSize + ) +{ + EVP_CIPHER_CTX *Ctx; + CONST EVP_CIPHER *Cipher; + UINTN TempOutSize; + BOOLEAN RetValue; + + if (DataInSize > INT_MAX) { + return FALSE; + } + + if (ADataSize > INT_MAX) { + return FALSE; + } + + if (IvSize != 12) { + return FALSE; + } + + switch (KeySize) { + case 16: + Cipher = EVP_aes_128_gcm (); + break; + case 24: + Cipher = EVP_aes_192_gcm (); + break; + case 32: + Cipher = EVP_aes_256_gcm (); + break; + default: + return FALSE; + } + + if ((TagSize != 12) && (TagSize != 13) && (TagSize != 14) && (TagSize != 15) && (TagSize != 16)) { + return FALSE; + } + + if (DataOutSize != NULL) { + if ((*DataOutSize > INT_MAX) || (*DataOutSize < DataInSize)) { + return FALSE; + } + } + + Ctx = EVP_CIPHER_CTX_new (); + if (Ctx == NULL) { + return FALSE; + } + + RetValue = (BOOLEAN)EVP_DecryptInit_ex (Ctx, Cipher, NULL, NULL, NULL); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_CIPHER_CTX_ctrl (Ctx, EVP_CTRL_GCM_SET_IVLEN, (INT32)IvSize, NULL); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_DecryptInit_ex (Ctx, NULL, NULL, Key, Iv); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_DecryptUpdate (Ctx, NULL, (INT32 *)&TempOutSize, AData, (INT32)ADataSize); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_DecryptUpdate (Ctx, DataOut, (INT32 *)&TempOutSize, DataIn, (INT32)DataInSize); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_CIPHER_CTX_ctrl (Ctx, EVP_CTRL_GCM_SET_TAG, (INT32)TagSize, (VOID *)Tag); + if (!RetValue) { + goto Done; + } + + RetValue = (BOOLEAN)EVP_DecryptFinal_ex (Ctx, DataOut, (INT32 *)&TempOutSize); + +Done: + EVP_CIPHER_CTX_free (Ctx); + if (!RetValue) { + return RetValue; + } + + if (DataOutSize != NULL) { + *DataOutSize = DataInSize; + } + + return RetValue; +} diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAeadAesGcmNull.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAeadAesGcmNull.c new file mode 100644 index 0000000000..b9f9d16ff9 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAeadAesGcmNull.c @@ -0,0 +1,100 @@ +/** @file + AEAD Wrapper Implementation which does not provide real capabilities. + +Copyright (c) 2022, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" + +/** + Performs AEAD AES-GCM authenticated encryption on a data buffer and additional authenticated data (AAD). + + IvSize must be 12, otherwise FALSE is returned. + KeySize must be 16, 24 or 32, otherwise FALSE is returned. + TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned. + + @param[in] Key Pointer to the encryption key. + @param[in] KeySize Size of the encryption key in bytes. + @param[in] Iv Pointer to the IV value. + @param[in] IvSize Size of the IV value in bytes. + @param[in] AData Pointer to the additional authenticated data (AAD). + @param[in] ADataSize Size of the additional authenticated data (AAD) in bytes. + @param[in] DataIn Pointer to the input data buffer to be encrypted. + @param[in] DataInSize Size of the input data buffer in bytes. + @param[out] TagOut Pointer to a buffer that receives the authentication tag output. + @param[in] TagSize Size of the authentication tag in bytes. + @param[out] DataOut Pointer to a buffer that receives the encryption output. + @param[out] DataOutSize Size of the output data buffer in bytes. + + @retval TRUE AEAD AES-GCM authenticated encryption succeeded. + @retval FALSE AEAD AES-GCM authenticated encryption failed. + +**/ +BOOLEAN +EFIAPI +AeadAesGcmEncrypt ( + IN CONST UINT8 *Key, + IN UINTN KeySize, + IN CONST UINT8 *Iv, + IN UINTN IvSize, + IN CONST UINT8 *AData, + IN UINTN ADataSize, + IN CONST UINT8 *DataIn, + IN UINTN DataInSize, + OUT UINT8 *TagOut, + IN UINTN TagSize, + OUT UINT8 *DataOut, + OUT UINTN *DataOutSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Performs AEAD AES-GCM authenticated decryption on a data buffer and additional authenticated data (AAD). + + IvSize must be 12, otherwise FALSE is returned. + KeySize must be 16, 24 or 32, otherwise FALSE is returned. + TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned. + If additional authenticated data verification fails, FALSE is returned. + + @param[in] Key Pointer to the encryption key. + @param[in] KeySize Size of the encryption key in bytes. + @param[in] Iv Pointer to the IV value. + @param[in] IvSize Size of the IV value in bytes. + @param[in] AData Pointer to the additional authenticated data (AAD). + @param[in] ADataSize Size of the additional authenticated data (AAD) in bytes. + @param[in] DataIn Pointer to the input data buffer to be decrypted. + @param[in] DataInSize Size of the input data buffer in bytes. + @param[in] Tag Pointer to a buffer that contains the authentication tag. + @param[in] TagSize Size of the authentication tag in bytes. + @param[out] DataOut Pointer to a buffer that receives the decryption output. + @param[out] DataOutSize Size of the output data buffer in bytes. + + @retval TRUE AEAD AES-GCM authenticated decryption succeeded. + @retval FALSE AEAD AES-GCM authenticated decryption failed. + +**/ +BOOLEAN +EFIAPI +AeadAesGcmDecrypt ( + IN CONST UINT8 *Key, + IN UINTN KeySize, + IN CONST UINT8 *Iv, + IN UINTN IvSize, + IN CONST UINT8 *AData, + IN UINTN ADataSize, + IN CONST UINT8 *DataIn, + IN UINTN DataInSize, + IN CONST UINT8 *Tag, + IN UINTN TagSize, + OUT UINT8 *DataOut, + OUT UINTN *DataOutSize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf index f88f8312f6..84efeb246e 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -44,6 +44,7 @@ Hmac/CryptHmac.c Kdf/CryptHkdf.c Cipher/CryptAesNull.c + Cipher/CryptAeadAesGcmNull.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c Pk/CryptPkcs1OaepNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf index 9213952701..845708bf1a 100644 --- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf @@ -44,6 +44,7 @@ Hmac/CryptHmac.c Kdf/CryptHkdf.c Cipher/CryptAes.c + Cipher/CryptAeadAesGcmNull.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c Pk/CryptPkcs1OaepNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf index ed76520fcc..c81e9d5bb4 100644 --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf @@ -45,6 +45,7 @@ Hmac/CryptHmac.c Kdf/CryptHkdfNull.c Cipher/CryptAes.c + Cipher/CryptAeadAesGcmNull.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c Pk/CryptPkcs1Oaep.c diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf index 728e0793ac..80a432dfe1 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf @@ -38,6 +38,7 @@ Hmac/CryptHmacNull.c Kdf/CryptHkdfNull.c Cipher/CryptAesNull.c + Cipher/CryptAeadAesGcmNull.c Pk/CryptRsaBasicNull.c Pk/CryptRsaExtNull.c Pk/CryptPkcs1OaepNull.c diff --git a/CryptoPkg/Library/BaseCryptLibNull/Cipher/CryptAeadAesGcmNull.c b/CryptoPkg/Library/BaseCryptLibNull/Cipher/CryptAeadAesGcmNull.c new file mode 100644 index 0000000000..b9f9d16ff9 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibNull/Cipher/CryptAeadAesGcmNull.c @@ -0,0 +1,100 @@ +/** @file + AEAD Wrapper Implementation which does not provide real capabilities. + +Copyright (c) 2022, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" + +/** + Performs AEAD AES-GCM authenticated encryption on a data buffer and additional authenticated data (AAD). + + IvSize must be 12, otherwise FALSE is returned. + KeySize must be 16, 24 or 32, otherwise FALSE is returned. + TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned. + + @param[in] Key Pointer to the encryption key. + @param[in] KeySize Size of the encryption key in bytes. + @param[in] Iv Pointer to the IV value. + @param[in] IvSize Size of the IV value in bytes. + @param[in] AData Pointer to the additional authenticated data (AAD). + @param[in] ADataSize Size of the additional authenticated data (AAD) in bytes. + @param[in] DataIn Pointer to the input data buffer to be encrypted. + @param[in] DataInSize Size of the input data buffer in bytes. + @param[out] TagOut Pointer to a buffer that receives the authentication tag output. + @param[in] TagSize Size of the authentication tag in bytes. + @param[out] DataOut Pointer to a buffer that receives the encryption output. + @param[out] DataOutSize Size of the output data buffer in bytes. + + @retval TRUE AEAD AES-GCM authenticated encryption succeeded. + @retval FALSE AEAD AES-GCM authenticated encryption failed. + +**/ +BOOLEAN +EFIAPI +AeadAesGcmEncrypt ( + IN CONST UINT8 *Key, + IN UINTN KeySize, + IN CONST UINT8 *Iv, + IN UINTN IvSize, + IN CONST UINT8 *AData, + IN UINTN ADataSize, + IN CONST UINT8 *DataIn, + IN UINTN DataInSize, + OUT UINT8 *TagOut, + IN UINTN TagSize, + OUT UINT8 *DataOut, + OUT UINTN *DataOutSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Performs AEAD AES-GCM authenticated decryption on a data buffer and additional authenticated data (AAD). + + IvSize must be 12, otherwise FALSE is returned. + KeySize must be 16, 24 or 32, otherwise FALSE is returned. + TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned. + If additional authenticated data verification fails, FALSE is returned. + + @param[in] Key Pointer to the encryption key. + @param[in] KeySize Size of the encryption key in bytes. + @param[in] Iv Pointer to the IV value. + @param[in] IvSize Size of the IV value in bytes. + @param[in] AData Pointer to the additional authenticated data (AAD). + @param[in] ADataSize Size of the additional authenticated data (AAD) in bytes. + @param[in] DataIn Pointer to the input data buffer to be decrypted. + @param[in] DataInSize Size of the input data buffer in bytes. + @param[in] Tag Pointer to a buffer that contains the authentication tag. + @param[in] TagSize Size of the authentication tag in bytes. + @param[out] DataOut Pointer to a buffer that receives the decryption output. + @param[out] DataOutSize Size of the output data buffer in bytes. + + @retval TRUE AEAD AES-GCM authenticated decryption succeeded. + @retval FALSE AEAD AES-GCM authenticated decryption failed. + +**/ +BOOLEAN +EFIAPI +AeadAesGcmDecrypt ( + IN CONST UINT8 *Key, + IN UINTN KeySize, + IN CONST UINT8 *Iv, + IN UINTN IvSize, + IN CONST UINT8 *AData, + IN UINTN ADataSize, + IN CONST UINT8 *DataIn, + IN UINTN DataInSize, + IN CONST UINT8 *Tag, + IN UINTN TagSize, + OUT UINT8 *DataOut, + OUT UINTN *DataOutSize + ) +{ + ASSERT (FALSE); + return FALSE; +}