From 731aa708813774fe0fdfe3f1e2f5b9032f689449 Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Wed, 16 Aug 2023 12:30:01 +0800 Subject: CryptoPkg: Add HMAC functions based on Mbedtls Add HMAC 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 --- .../Library/BaseCryptLibMbedTls/Hmac/CryptHmac.c | 678 +++++++++++++++++++++ .../BaseCryptLibMbedTls/Hmac/CryptHmacNull.c | 359 +++++++++++ .../Test/UnitTest/Library/BaseCryptLib/HmacTests.c | 60 +- 3 files changed, 1084 insertions(+), 13 deletions(-) create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmac.c create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmacNull.c diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmac.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmac.c new file mode 100644 index 0000000000..c4cda57b4d --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmac.c @@ -0,0 +1,678 @@ +/** @file + HMAC-SHA256 Wrapper Implementation over MbedTLS. + +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include + +/** + Allocates and initializes one HMAC_CTX context for subsequent HMAC-MD use. + + @return Pointer to the HMAC_CTX context that has been initialized. + If the allocations fails, HmacShaMdNew() returns NULL. + +**/ +STATIC +VOID * +HmacMdNew ( + VOID + ) +{ + VOID *HmacMdCtx; + + HmacMdCtx = AllocateZeroPool (sizeof (mbedtls_md_context_t)); + if (HmacMdCtx == NULL) { + return NULL; + } + + return HmacMdCtx; +} + +/** + Release the specified HMAC_CTX context. + + @param[in] HmacMdCtx Pointer to the HMAC_CTX context to be released. + +**/ +VOID +HmacMdFree ( + IN VOID *HmacMdCtx + ) +{ + mbedtls_md_free (HmacMdCtx); + if (HmacMdCtx != NULL) { + FreePool (HmacMdCtx); + } +} + +/** + Set user-supplied key for subsequent use. It must be done before any + calling to HmacMdUpdate(). + + If HmacMdContext is NULL, then return FALSE. + + @param[in] MdType Message Digest Type. + @param[out] HmacMdContext Pointer to HMAC-MD context. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + + @retval TRUE The Key is set successfully. + @retval FALSE The Key is set unsuccessfully. + +**/ +STATIC +BOOLEAN +HmacMdSetKey ( + IN mbedtls_md_type_t MdType, + OUT VOID *HmacMdContext, + IN CONST UINT8 *Key, + IN UINTN KeySize + ) +{ + const mbedtls_md_info_t *md_info; + INT32 Ret; + + if ((HmacMdContext == NULL) || (KeySize > INT_MAX)) { + return FALSE; + } + + ZeroMem (HmacMdContext, sizeof (mbedtls_md_context_t)); + mbedtls_md_init (HmacMdContext); + + md_info = mbedtls_md_info_from_type (MdType); + ASSERT (md_info != NULL); + + Ret = mbedtls_md_setup (HmacMdContext, md_info, 1); + if (Ret != 0) { + return FALSE; + } + + Ret = mbedtls_md_hmac_starts (HmacMdContext, Key, KeySize); + if (Ret != 0) { + return FALSE; + } + + return TRUE; +} + +/** + Return block size in md_type. + + @param[in] MdType message digest Type. + + @retval blocksize in md_type. + +**/ +int +HmacMdGetBlockSize ( + mbedtls_md_type_t MdType + ) +{ + switch (MdType) { + case MBEDTLS_MD_SHA256: + return 64; + case MBEDTLS_MD_SHA384: + return 128; + default: + ASSERT (FALSE); + return 0; + } +} + +/** + Makes a copy of an existing HMAC-MD context. + + If HmacMdContext is NULL, then return FALSE. + If NewHmacMdContext is NULL, then return FALSE. + + @param[in] MdType message digest Type. + @param[in] HmacMdContext Pointer to HMAC-MD context being copied. + @param[out] NewHmacMdContext Pointer to new HMAC-MD context. + + @retval TRUE HMAC-MD context copy succeeded. + @retval FALSE HMAC-MD context copy failed. + +**/ +STATIC +BOOLEAN +HmacMdDuplicate ( + IN CONST mbedtls_md_type_t MdType, + IN CONST VOID *HmacMdContext, + OUT VOID *NewHmacMdContext + ) +{ + INT32 Ret; + CONST mbedtls_md_info_t *md_info; + mbedtls_md_context_t *MdContext; + + if ((HmacMdContext == NULL) || (NewHmacMdContext == NULL)) { + return FALSE; + } + + ZeroMem (NewHmacMdContext, sizeof (mbedtls_md_context_t)); + mbedtls_md_init (NewHmacMdContext); + md_info = mbedtls_md_info_from_type (MdType); + ASSERT (md_info != NULL); + + Ret = mbedtls_md_setup (NewHmacMdContext, md_info, 1); + if (Ret != 0) { + return FALSE; + } + + MdContext = (mbedtls_md_context_t *)NewHmacMdContext; + + Ret = mbedtls_md_clone (NewHmacMdContext, HmacMdContext); + if (Ret != 0) { + if (MdContext->md_ctx != NULL) { + mbedtls_free (MdContext->md_ctx); + } + + if (MdContext->hmac_ctx != NULL) { + mbedtls_free (MdContext->hmac_ctx); + } + + return FALSE; + } + + CopyMem ( + ((mbedtls_md_context_t *)NewHmacMdContext)->hmac_ctx, + ((CONST mbedtls_md_context_t *)HmacMdContext)->hmac_ctx, + HmacMdGetBlockSize (MdType) * 2 + ); + + return TRUE; +} + +/** + Digests the input data and updates HMAC-MD context. + + This function performs HMAC-MD digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + HMAC-MD context should be initialized by HmacMdNew(), and should not be finalized + by HmacMdFinal(). Behavior with invalid context is undefined. + + If HmacMdContext is NULL, then return FALSE. + + @param[in, out] HmacMdContext Pointer to the HMAC-MD context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE HMAC-MD data digest succeeded. + @retval FALSE HMAC-MD data digest failed. + +**/ +STATIC +BOOLEAN +HmacMdUpdate ( + IN OUT VOID *HmacMdContext, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + INT32 Ret; + + if (HmacMdContext == NULL) { + return FALSE; + } + + if ((Data == NULL) && (DataSize != 0)) { + return FALSE; + } + + if (DataSize > INT_MAX) { + return FALSE; + } + + Ret = mbedtls_md_hmac_update (HmacMdContext, Data, DataSize); + if (Ret != 0) { + return FALSE; + } + + return TRUE; +} + +/** + Completes computation of the HMAC-MD digest value. + + This function completes HMAC-MD hash computation and retrieves the digest value into + the specified memory. After this function has been called, the HMAC-MD context cannot + be used again. + HMAC-MD context should be initialized by HmacMdNew(), and should not be finalized + by HmacMdFinal(). Behavior with invalid HMAC-MD context is undefined. + + If HmacMdContext is NULL, then return FALSE. + If HmacValue is NULL, then return FALSE. + + @param[in, out] HmacMdContext Pointer to the HMAC-MD context. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-MD digest + value. + + @retval TRUE HMAC-MD digest computation succeeded. + @retval FALSE HMAC-MD digest computation failed. + +**/ +STATIC +BOOLEAN +HmacMdFinal ( + IN OUT VOID *HmacMdContext, + OUT UINT8 *HmacValue + ) +{ + INT32 Ret; + + if ((HmacMdContext == NULL) || (HmacValue == NULL)) { + return FALSE; + } + + Ret = mbedtls_md_hmac_finish (HmacMdContext, HmacValue); + if (Ret != 0) { + return FALSE; + } + + Ret = mbedtls_md_hmac_reset (HmacMdContext); + if (Ret != 0) { + return FALSE; + } + + return TRUE; +} + +/** + Computes the HMAC-MD digest of a input data buffer. + + This function performs the HMAC-MD digest of a given data buffer, and places + the digest value into the specified memory. + + If this interface is not supported, then return FALSE. + + @param[in] MdType Message Digest Type. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-MD digest + value. + + @retval TRUE HMAC-MD digest computation succeeded. + @retval FALSE HMAC-MD digest computation failed. + @retval FALSE This interface is not supported. + +**/ +STATIC +BOOLEAN +HmacMdAll ( + IN mbedtls_md_type_t MdType, + IN CONST VOID *Data, + IN UINTN DataSize, + IN CONST UINT8 *Key, + IN UINTN KeySize, + OUT UINT8 *HmacValue + ) +{ + const mbedtls_md_info_t *md_info; + INT32 Ret; + + md_info = mbedtls_md_info_from_type (MdType); + ASSERT (md_info != NULL); + + Ret = mbedtls_md_hmac (md_info, Key, KeySize, Data, DataSize, HmacValue); + if (Ret != 0) { + return FALSE; + } + + return TRUE; +} + +/** + Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use. + + @return Pointer to the HMAC_CTX context that has been initialized. + If the allocations fails, HmacSha256New() returns NULL. + +**/ +VOID * +EFIAPI +HmacSha256New ( + VOID + ) +{ + return HmacMdNew (); +} + +/** + Release the specified HMAC_CTX context. + + @param[in] HmacSha256Ctx Pointer to the HMAC_CTX context to be released. + +**/ +VOID +EFIAPI +HmacSha256Free ( + IN VOID *HmacSha256Ctx + ) +{ + HmacMdFree (HmacSha256Ctx); +} + +/** + Set user-supplied key for subsequent use. It must be done before any + calling to HmacSha256Update(). + + If HmacSha256Context is NULL, then return FALSE. + + @param[out] HmacSha256Context Pointer to HMAC-SHA256 context. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + + @retval TRUE The Key is set successfully. + @retval FALSE The Key is set unsuccessfully. + +**/ +BOOLEAN +EFIAPI +HmacSha256SetKey ( + OUT VOID *HmacSha256Context, + IN CONST UINT8 *Key, + IN UINTN KeySize + ) +{ + return HmacMdSetKey (MBEDTLS_MD_SHA256, HmacSha256Context, Key, KeySize); +} + +/** + Makes a copy of an existing HMAC-SHA256 context. + + If HmacSha256Context is NULL, then return FALSE. + If NewHmacSha256Context is NULL, then return FALSE. + + @param[in] HmacSha256Context Pointer to HMAC-SHA256 context being copied. + @param[out] NewHmacSha256Context Pointer to new HMAC-SHA256 context. + + @retval TRUE HMAC-SHA256 context copy succeeded. + @retval FALSE HMAC-SHA256 context copy failed. + +**/ +BOOLEAN +EFIAPI +HmacSha256Duplicate ( + IN CONST VOID *HmacSha256Context, + OUT VOID *NewHmacSha256Context + ) +{ + return HmacMdDuplicate (MBEDTLS_MD_SHA256, HmacSha256Context, NewHmacSha256Context); +} + +/** + Digests the input data and updates HMAC-SHA256 context. + + This function performs HMAC-SHA256 digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + HMAC-SHA256 context should be initialized by HmacSha256New(), and should not be finalized + by HmacSha256Final(). Behavior with invalid context is undefined. + + If HmacSha256Context is NULL, then return FALSE. + + @param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE HMAC-SHA256 data digest succeeded. + @retval FALSE HMAC-SHA256 data digest failed. + +**/ +BOOLEAN +EFIAPI +HmacSha256Update ( + IN OUT VOID *HmacSha256Context, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + return HmacMdUpdate (HmacSha256Context, Data, DataSize); +} + +/** + Completes computation of the HMAC-SHA256 digest value. + + This function completes HMAC-SHA256 hash computation and retrieves the digest value into + the specified memory. After this function has been called, the HMAC-SHA256 context cannot + be used again. + HMAC-SHA256 context should be initialized by HmacSha256New(), and should not be finalized + by HmacSha256Final(). Behavior with invalid HMAC-SHA256 context is undefined. + + If HmacSha256Context is NULL, then return FALSE. + If HmacValue is NULL, then return FALSE. + + @param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest + value (32 bytes). + + @retval TRUE HMAC-SHA256 digest computation succeeded. + @retval FALSE HMAC-SHA256 digest computation failed. + +**/ +BOOLEAN +EFIAPI +HmacSha256Final ( + IN OUT VOID *HmacSha256Context, + OUT UINT8 *HmacValue + ) +{ + return HmacMdFinal (HmacSha256Context, HmacValue); +} + +/** + Computes the HMAC-SHA256 digest of a input data buffer. + + This function performs the HMAC-SHA256 digest of a given data buffer, and places + the digest value into the specified memory. + + If this interface is not supported, then return FALSE. + + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest + value (32 bytes). + + @retval TRUE HMAC-SHA256 digest computation succeeded. + @retval FALSE HMAC-SHA256 digest computation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha256All ( + IN CONST VOID *Data, + IN UINTN DataSize, + IN CONST UINT8 *Key, + IN UINTN KeySize, + OUT UINT8 *HmacValue + ) +{ + return HmacMdAll (MBEDTLS_MD_SHA256, Data, DataSize, Key, KeySize, HmacValue); +} + +/** + Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA384 use. + + @return Pointer to the HMAC_CTX context that has been initialized. + If the allocations fails, HmacSha384New() returns NULL. + +**/ +VOID * +EFIAPI +HmacSha384New ( + VOID + ) +{ + return HmacMdNew (); +} + +/** + Release the specified HMAC_CTX context. + + @param[in] HmacSha384Ctx Pointer to the HMAC_CTX context to be released. + +**/ +VOID +EFIAPI +HmacSha384Free ( + IN VOID *HmacSha384Ctx + ) +{ + HmacMdFree (HmacSha384Ctx); +} + +/** + Set user-supplied key for subsequent use. It must be done before any + calling to HmacSha384Update(). + + If HmacSha384Context is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[out] HmacSha384Context Pointer to HMAC-SHA384 context. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + + @retval TRUE The Key is set successfully. + @retval FALSE The Key is set unsuccessfully. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384SetKey ( + OUT VOID *HmacSha384Context, + IN CONST UINT8 *Key, + IN UINTN KeySize + ) +{ + return HmacMdSetKey (MBEDTLS_MD_SHA384, HmacSha384Context, Key, KeySize); +} + +/** + Makes a copy of an existing HMAC-SHA384 context. + + If HmacSha384Context is NULL, then return FALSE. + If NewHmacSha384Context is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in] HmacSha384Context Pointer to HMAC-SHA384 context being copied. + @param[out] NewHmacSha384Context Pointer to new HMAC-SHA384 context. + + @retval TRUE HMAC-SHA384 context copy succeeded. + @retval FALSE HMAC-SHA384 context copy failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384Duplicate ( + IN CONST VOID *HmacSha384Context, + OUT VOID *NewHmacSha384Context + ) +{ + return HmacMdDuplicate (MBEDTLS_MD_SHA384, HmacSha384Context, NewHmacSha384Context); +} + +/** + Digests the input data and updates HMAC-SHA384 context. + + This function performs HMAC-SHA384 digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + HMAC-SHA384 context should be initialized by HmacSha384New(), and should not be finalized + by HmacSha384Final(). Behavior with invalid context is undefined. + + If HmacSha384Context is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in, out] HmacSha384Context Pointer to the HMAC-SHA384 context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE HMAC-SHA384 data digest succeeded. + @retval FALSE HMAC-SHA384 data digest failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384Update ( + IN OUT VOID *HmacSha384Context, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + return HmacMdUpdate (HmacSha384Context, Data, DataSize); +} + +/** + Completes computation of the HMAC-SHA384 digest value. + + This function completes HMAC-SHA384 hash computation and retrieves the digest value into + the specified memory. After this function has been called, the HMAC-SHA384 context cannot + be used again. + HMAC-SHA384 context should be initialized by HmacSha384New(), and should not be finalized + by HmacSha384Final(). Behavior with invalid HMAC-SHA384 context is undefined. + + If HmacSha384Context is NULL, then return FALSE. + If HmacValue is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in, out] HmacSha384Context Pointer to the HMAC-SHA384 context. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA384 digest + value (48 bytes). + + @retval TRUE HMAC-SHA384 digest computation succeeded. + @retval FALSE HMAC-SHA384 digest computation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384Final ( + IN OUT VOID *HmacSha384Context, + OUT UINT8 *HmacValue + ) +{ + return HmacMdFinal (HmacSha384Context, HmacValue); +} + +/** + Computes the HMAC-SHA384 digest of a input data buffer. + + This function performs the HMAC-SHA384 digest of a given data buffer, and places + the digest value into the specified memory. + + If this interface is not supported, then return FALSE. + + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA384 digest + value (48 bytes). + + @retval TRUE HMAC-SHA384 digest computation succeeded. + @retval FALSE HMAC-SHA384 digest computation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384All ( + IN CONST VOID *Data, + IN UINTN DataSize, + IN CONST UINT8 *Key, + IN UINTN KeySize, + OUT UINT8 *HmacValue + ) +{ + return HmacMdAll (MBEDTLS_MD_SHA384, Data, DataSize, Key, KeySize, HmacValue); +} diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmacNull.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmacNull.c new file mode 100644 index 0000000000..37bf3ea486 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hmac/CryptHmacNull.c @@ -0,0 +1,359 @@ +/** @file + HMAC-SHA256/SHA384 Wrapper Implementation which does not provide real capabilities. + +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" + +/** + Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use. + + Return NULL to indicate this interface is not supported. + + @return NULL This interface is not supported.. + +**/ +VOID * +EFIAPI +HmacSha256New ( + VOID + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified HMAC_CTX context. + + This function will do nothing. + + @param[in] HmacSha256Ctx Pointer to the HMAC_CTX context to be released. + +**/ +VOID +EFIAPI +HmacSha256Free ( + IN VOID *HmacSha256Ctx + ) +{ + ASSERT (FALSE); + return; +} + +/** + Set user-supplied key for subsequent use. It must be done before any + calling to HmacSha256Update(). + + Return FALSE to indicate this interface is not supported. + + @param[out] HmacSha256Context Pointer to HMAC-SHA256 context. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha256SetKey ( + OUT VOID *HmacSha256Context, + IN CONST UINT8 *Key, + IN UINTN KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Makes a copy of an existing HMAC-SHA256 context. + + Return FALSE to indicate this interface is not supported. + + @param[in] HmacSha256Context Pointer to HMAC-SHA256 context being copied. + @param[out] NewHmacSha256Context Pointer to new HMAC-SHA256 context. + + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha256Duplicate ( + IN CONST VOID *HmacSha256Context, + OUT VOID *NewHmacSha256Context + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Digests the input data and updates HMAC-SHA256 context. + + Return FALSE to indicate this interface is not supported. + + @param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha256Update ( + IN OUT VOID *HmacSha256Context, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Completes computation of the HMAC-SHA256 digest value. + + Return FALSE to indicate this interface is not supported. + + @param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest + value (32 bytes). + + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha256Final ( + IN OUT VOID *HmacSha256Context, + OUT UINT8 *HmacValue + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes the HMAC-SHA256 digest of a input data buffer. + + This function performs the HMAC-SHA256 digest of a given data buffer, and places + the digest value into the specified memory. + + If this interface is not supported, then return FALSE. + + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest + value (32 bytes). + + @retval TRUE HMAC-SHA256 digest computation succeeded. + @retval FALSE HMAC-SHA256 digest computation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha256All ( + IN CONST VOID *Data, + IN UINTN DataSize, + IN CONST UINT8 *Key, + IN UINTN KeySize, + OUT UINT8 *HmacValue + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA384 use. + + @return Pointer to the HMAC_CTX context that has been initialized. + If the allocations fails, HmacSha384New() returns NULL. + +**/ +VOID * +EFIAPI +HmacSha384New ( + VOID + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified HMAC_CTX context. + + @param[in] HmacSha384Ctx Pointer to the HMAC_CTX context to be released. + +**/ +VOID +EFIAPI +HmacSha384Free ( + IN VOID *HmacSha384Ctx + ) +{ + ASSERT (FALSE); + return; +} + +/** + Set user-supplied key for subsequent use. It must be done before any + calling to HmacSha384Update(). + + If HmacSha384Context is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[out] HmacSha384Context Pointer to HMAC-SHA384 context. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + + @retval TRUE The Key is set successfully. + @retval FALSE The Key is set unsuccessfully. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384SetKey ( + OUT VOID *HmacSha384Context, + IN CONST UINT8 *Key, + IN UINTN KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Makes a copy of an existing HMAC-SHA384 context. + + If HmacSha384Context is NULL, then return FALSE. + If NewHmacSha384Context is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in] HmacSha384Context Pointer to HMAC-SHA384 context being copied. + @param[out] NewHmacSha384Context Pointer to new HMAC-SHA384 context. + + @retval TRUE HMAC-SHA384 context copy succeeded. + @retval FALSE HMAC-SHA384 context copy failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384Duplicate ( + IN CONST VOID *HmacSha384Context, + OUT VOID *NewHmacSha384Context + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Digests the input data and updates HMAC-SHA384 context. + + This function performs HMAC-SHA384 digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + HMAC-SHA384 context should be initialized by HmacSha384New(), and should not be finalized + by HmacSha384Final(). Behavior with invalid context is undefined. + + If HmacSha384Context is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in, out] HmacSha384Context Pointer to the HMAC-SHA384 context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE HMAC-SHA384 data digest succeeded. + @retval FALSE HMAC-SHA384 data digest failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384Update ( + IN OUT VOID *HmacSha384Context, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Completes computation of the HMAC-SHA384 digest value. + + This function completes HMAC-SHA384 hash computation and retrieves the digest value into + the specified memory. After this function has been called, the HMAC-SHA384 context cannot + be used again. + HMAC-SHA384 context should be initialized by HmacSha384New(), and should not be finalized + by HmacSha384Final(). Behavior with invalid HMAC-SHA384 context is undefined. + + If HmacSha384Context is NULL, then return FALSE. + If HmacValue is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in, out] HmacSha384Context Pointer to the HMAC-SHA384 context. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA384 digest + value (48 bytes). + + @retval TRUE HMAC-SHA384 digest computation succeeded. + @retval FALSE HMAC-SHA384 digest computation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384Final ( + IN OUT VOID *HmacSha384Context, + OUT UINT8 *HmacValue + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes the HMAC-SHA384 digest of a input data buffer. + + This function performs the HMAC-SHA384 digest of a given data buffer, and places + the digest value into the specified memory. + + If this interface is not supported, then return FALSE. + + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + @param[in] Key Pointer to the user-supplied key. + @param[in] KeySize Key size in bytes. + @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA384 digest + value (48 bytes). + + @retval TRUE HMAC-SHA384 digest computation succeeded. + @retval FALSE HMAC-SHA384 digest computation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +HmacSha384All ( + IN CONST VOID *Data, + IN UINTN DataSize, + IN CONST UINT8 *Key, + IN UINTN KeySize, + OUT UINT8 *HmacValue + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HmacTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HmacTests.c index b347cb4cb4..c0d15b34ff 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HmacTests.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HmacTests.c @@ -82,19 +82,19 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacSha384Digest[] = { }; typedef -VOID * + VOID * (EFIAPI *EFI_HMAC_NEW)( VOID ); typedef -VOID + VOID (EFIAPI *EFI_HMAC_FREE)( IN VOID *HashContext ); typedef -BOOLEAN + BOOLEAN (EFIAPI *EFI_HMAC_INIT)( IN OUT VOID *HashContext, IN CONST UINT8 *Key, @@ -102,7 +102,14 @@ BOOLEAN ); typedef -BOOLEAN + BOOLEAN +(EFIAPI *EFI_HMAC_DUP)( + IN CONST VOID *HashContext, + OUT VOID *NewHashContext + ); + +typedef + BOOLEAN (EFIAPI *EFI_HMAC_UPDATE)( IN OUT VOID *HashContext, IN CONST VOID *Data, @@ -110,30 +117,39 @@ BOOLEAN ); typedef -BOOLEAN + BOOLEAN (EFIAPI *EFI_HMAC_FINAL)( IN OUT VOID *HashContext, OUT UINT8 *HashValue ); +typedef + BOOLEAN +(EFIAPI *EFI_HMAC_ALL)( + IN CONST VOID *Data, + IN UINTN DataSize, + IN CONST UINT8 *Key, + IN UINTN KeySize, + OUT UINT8 *HashValue + ); + typedef struct { UINT32 DigestSize; EFI_HMAC_NEW HmacNew; EFI_HMAC_FREE HmacFree; EFI_HMAC_INIT HmacInit; + EFI_HMAC_DUP HmacDup; EFI_HMAC_UPDATE HmacUpdate; EFI_HMAC_FINAL HmacFinal; + EFI_HMAC_ALL HmacAll; CONST UINT8 *Key; UINTN KeySize; CONST UINT8 *Digest; VOID *HmacCtx; } HMAC_TEST_CONTEXT; -// These functions have been deprecated but they've been left commented out for future reference -// HMAC_TEST_CONTEXT mHmacMd5TestCtx = {MD5_DIGEST_SIZE, HmacMd5New, HmacMd5Free, HmacMd5SetKey, HmacMd5Update, HmacMd5Final, HmacMd5Key, sizeof(HmacMd5Key), HmacMd5Digest}; -// HMAC_TEST_CONTEXT mHmacSha1TestCtx = {SHA1_DIGEST_SIZE, HmacSha1New, HmacSha1Free, HmacSha1SetKey, HmacSha1Update, HmacSha1Final, HmacSha1Key, sizeof(HmacSha1Key), HmacSha1Digest}; -HMAC_TEST_CONTEXT mHmacSha256TestCtx = { SHA256_DIGEST_SIZE, HmacSha256New, HmacSha256Free, HmacSha256SetKey, HmacSha256Update, HmacSha256Final, HmacSha256Key, sizeof (HmacSha256Key), HmacSha256Digest }; -HMAC_TEST_CONTEXT mHmacSha384TestCtx = { SHA384_DIGEST_SIZE, HmacSha384New, HmacSha384Free, HmacSha384SetKey, HmacSha384Update, HmacSha384Final, HmacSha384Key, sizeof (HmacSha384Key), HmacSha384Digest }; +HMAC_TEST_CONTEXT mHmacSha256TestCtx = { SHA256_DIGEST_SIZE, HmacSha256New, HmacSha256Free, HmacSha256SetKey, HmacSha256Duplicate, HmacSha256Update, HmacSha256Final, HmacSha256All, HmacSha256Key, sizeof (HmacSha256Key), HmacSha256Digest }; +HMAC_TEST_CONTEXT mHmacSha384TestCtx = { SHA384_DIGEST_SIZE, HmacSha384New, HmacSha384Free, HmacSha384SetKey, HmacSha384Duplicate, HmacSha384Update, HmacSha384Final, HmacSha384All, HmacSha384Key, sizeof (HmacSha384Key), HmacSha384Digest }; UNIT_TEST_STATUS EFIAPI @@ -173,23 +189,44 @@ TestVerifyHmac ( ) { UINT8 Digest[MAX_DIGEST_SIZE]; + UINT8 DigestCopy[MAX_DIGEST_SIZE]; + UINT8 DigestByAll[MAX_DIGEST_SIZE]; + VOID *HmacCopyContext; BOOLEAN Status; HMAC_TEST_CONTEXT *HmacTestContext; HmacTestContext = Context; ZeroMem (Digest, MAX_DIGEST_SIZE); + ZeroMem (DigestCopy, MAX_DIGEST_SIZE); + ZeroMem (DigestByAll, MAX_DIGEST_SIZE); + + HmacCopyContext = HmacTestContext->HmacNew (); Status = HmacTestContext->HmacInit (HmacTestContext->HmacCtx, HmacTestContext->Key, HmacTestContext->KeySize); UT_ASSERT_TRUE (Status); + Status = HmacTestContext->HmacInit (HmacCopyContext, HmacTestContext->Key, HmacTestContext->KeySize); + UT_ASSERT_TRUE (Status); + Status = HmacTestContext->HmacUpdate (HmacTestContext->HmacCtx, HmacData, 8); UT_ASSERT_TRUE (Status); + Status = HmacTestContext->HmacDup (HmacTestContext->HmacCtx, HmacCopyContext); + UT_ASSERT_TRUE (Status); + Status = HmacTestContext->HmacFinal (HmacTestContext->HmacCtx, Digest); UT_ASSERT_TRUE (Status); + Status = HmacTestContext->HmacFinal (HmacCopyContext, DigestCopy); + UT_ASSERT_TRUE (Status); + + Status = HmacTestContext->HmacAll (HmacData, 8, HmacTestContext->Key, HmacTestContext->KeySize, DigestByAll); + UT_ASSERT_TRUE (Status); + UT_ASSERT_MEM_EQUAL (Digest, HmacTestContext->Digest, HmacTestContext->DigestSize); + UT_ASSERT_MEM_EQUAL (Digest, DigestCopy, HmacTestContext->DigestSize); + UT_ASSERT_MEM_EQUAL (Digest, DigestByAll, HmacTestContext->DigestSize); return UNIT_TEST_PASSED; } @@ -200,9 +237,6 @@ TEST_DESC mHmacTest[] = { // { "TestVerifyHmacSha256()", "CryptoPkg.BaseCryptLib.Hmac", TestVerifyHmac, TestVerifyHmacPreReq, TestVerifyHmacCleanUp, &mHmacSha256TestCtx }, { "TestVerifyHmacSha384()", "CryptoPkg.BaseCryptLib.Hmac", TestVerifyHmac, TestVerifyHmacPreReq, TestVerifyHmacCleanUp, &mHmacSha384TestCtx }, - // These functions have been deprecated but they've been left commented out for future reference - // {"TestVerifyHmacMd5()", "CryptoPkg.BaseCryptLib.Hmac", TestVerifyHmac, TestVerifyHmacPreReq, TestVerifyHmacCleanUp, &mHmacMd5TestCtx}, - // {"TestVerifyHmacSha1()", "CryptoPkg.BaseCryptLib.Hmac", TestVerifyHmac, TestVerifyHmacPreReq, TestVerifyHmacCleanUp, &mHmacSha1TestCtx}, }; UINTN mHmacTestNum = ARRAY_SIZE (mHmacTest); -- cgit v1.2.3