summaryrefslogtreecommitdiffstats
path: root/CryptoPkg
diff options
context:
space:
mode:
authorWenxing Hou <wenxing.hou@intel.com>2023-08-18 16:34:22 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-10-12 05:31:19 +0000
commitc5fedb030a4eee1133358a8c5af9ff05082feb44 (patch)
tree92e1e56ed7977c1a855c68ee1378b687fb3c777d /CryptoPkg
parent4049ca493c4ec8399ba95c06db49e45247fd5ad7 (diff)
downloadedk2-c5fedb030a4eee1133358a8c5af9ff05082feb44.tar.gz
edk2-c5fedb030a4eee1133358a8c5af9ff05082feb44.tar.bz2
edk2-c5fedb030a4eee1133358a8c5af9ff05082feb44.zip
CryptoPkg: Add MD5/SHA1/SHA2 functions based on Mbedtls
Add MD5/SHA1/SHA256/SHA384/SHA512 APIs. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177 Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com> Cc: Guomin Jiang <guomin.jiang@intel.com> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com> Reviewed-by: Yi Li <yi1.li@intel.com>
Diffstat (limited to 'CryptoPkg')
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c226
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c226
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c219
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c431
-rw-r--r--CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c33
5 files changed, 1130 insertions, 5 deletions
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c
new file mode 100644
index 0000000000..35978291ca
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c
@@ -0,0 +1,226 @@
+/** @file
+ MD5 Digest 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/md5.h>
+#include <mbedtls/compat-2.x.h>
+
+#ifdef ENABLE_MD5_DEPRECATED_INTERFACES
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for MD5 hash operations.
+
+ @return The size, in bytes, of the context buffer required for MD5 hash operations.
+
+**/
+UINTN
+EFIAPI
+Md5GetContextSize (
+ VOID
+ )
+{
+ //
+ // Retrieves the MD5 Context Size
+ //
+ return (UINTN)(sizeof (mbedtls_md5_context));
+}
+
+/**
+ Initializes user-supplied memory pointed by Md5Context as MD5 hash context for
+ subsequent use.
+
+ If Md5Context is NULL, then return FALSE.
+
+ @param[out] Md5Context Pointer to MD5 context being initialized.
+
+ @retval TRUE MD5 context initialization succeeded.
+ @retval FALSE MD5 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+Md5Init (
+ OUT VOID *Md5Context
+ )
+{
+ INT32 Ret;
+
+ if (Md5Context == NULL) {
+ return FALSE;
+ }
+
+ mbedtls_md5_init (Md5Context);
+
+ Ret = mbedtls_md5_starts_ret (Md5Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Makes a copy of an existing MD5 context.
+
+ If Md5Context is NULL, then return FALSE.
+ If NewMd5Context is NULL, then return FALSE.
+
+ @param[in] Md5Context Pointer to MD5 context being copied.
+ @param[out] NewMd5Context Pointer to new MD5 context.
+
+ @retval TRUE MD5 context copy succeeded.
+ @retval FALSE MD5 context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+Md5Duplicate (
+ IN CONST VOID *Md5Context,
+ OUT VOID *NewMd5Context
+ )
+{
+ if ((Md5Context == NULL) || (NewMd5Context == NULL)) {
+ return FALSE;
+ }
+
+ mbedtls_md5_clone (NewMd5Context, Md5Context);
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates MD5 context.
+
+ This function performs MD5 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.
+ MD5 context should be already correctly initialized by Md5Init(), and should not be finalized
+ by Md5Final(). Behavior with invalid context is undefined.
+
+ If Md5Context is NULL, then return FALSE.
+
+ @param[in, out] Md5Context Pointer to the MD5 context.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE MD5 data digest succeeded.
+ @retval FALSE MD5 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+Md5Update (
+ IN OUT VOID *Md5Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ INT32 Ret;
+
+ if (Md5Context == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_md5_update_ret (Md5Context, Data, DataSize);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the MD5 digest value.
+
+ This function completes MD5 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the MD5 context cannot
+ be used again.
+ MD5 context should be already correctly initialized by Md5Init(), and should not be
+ finalized by Md5Final(). Behavior with invalid MD5 context is undefined.
+
+ If Md5Context is NULL, then return FALSE.
+ If HashValue is NULL, then return FALSE.
+
+ @param[in, out] Md5Context Pointer to the MD5 context.
+ @param[out] HashValue Pointer to a buffer that receives the MD5 digest
+ value (16 bytes).
+
+ @retval TRUE MD5 digest computation succeeded.
+ @retval FALSE MD5 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+Md5Final (
+ IN OUT VOID *Md5Context,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if ((Md5Context == NULL) || (HashValue == NULL)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_md5_finish_ret (Md5Context, HashValue);
+ mbedtls_md5_free (Md5Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Computes the MD5 message digest of a input data buffer.
+
+ This function performs the MD5 message 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 hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the MD5 digest
+ value (16 bytes).
+
+ @retval TRUE MD5 digest computation succeeded.
+ @retval FALSE MD5 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Md5HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_md5_ret (Data, DataSize, HashValue);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#endif
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c
new file mode 100644
index 0000000000..68b107bd7b
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c
@@ -0,0 +1,226 @@
+/** @file
+ SHA-1 Digest 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/sha1.h>
+#include <mbedtls/compat-2.x.h>
+
+#ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations.
+
+ @return The size, in bytes, of the context buffer required for SHA-1 hash operations.
+
+**/
+UINTN
+EFIAPI
+Sha1GetContextSize (
+ VOID
+ )
+{
+ //
+ // Retrieves MbedTLS SHA Context Size
+ //
+ return (UINTN)(sizeof (mbedtls_sha1_context));
+}
+
+/**
+ Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for
+ subsequent use.
+
+ If Sha1Context is NULL, then return FALSE.
+
+ @param[out] Sha1Context Pointer to SHA-1 context being initialized.
+
+ @retval TRUE SHA-1 context initialization succeeded.
+ @retval FALSE SHA-1 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha1Init (
+ OUT VOID *Sha1Context
+ )
+{
+ INT32 Ret;
+
+ if (Sha1Context == NULL) {
+ return FALSE;
+ }
+
+ mbedtls_sha1_init (Sha1Context);
+
+ Ret = mbedtls_sha1_starts_ret (Sha1Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Makes a copy of an existing SHA-1 context.
+
+ If Sha1Context is NULL, then return FALSE.
+ If NewSha1Context is NULL, then return FALSE.
+
+ @param[in] Sha1Context Pointer to SHA-1 context being copied.
+ @param[out] NewSha1Context Pointer to new SHA-1 context.
+
+ @retval TRUE SHA-1 context copy succeeded.
+ @retval FALSE SHA-1 context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha1Duplicate (
+ IN CONST VOID *Sha1Context,
+ OUT VOID *NewSha1Context
+ )
+{
+ if ((Sha1Context == NULL) || (NewSha1Context == NULL)) {
+ return FALSE;
+ }
+
+ mbedtls_sha1_clone (NewSha1Context, Sha1Context);
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates SHA-1 context.
+
+ This function performs SHA-1 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.
+ SHA-1 context should be already correctly initialized by Sha1Init(), and should not be finalized
+ by Sha1Final(). Behavior with invalid context is undefined.
+
+ If Sha1Context is NULL, then return FALSE.
+
+ @param[in, out] Sha1Context Pointer to the SHA-1 context.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE SHA-1 data digest succeeded.
+ @retval FALSE SHA-1 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha1Update (
+ IN OUT VOID *Sha1Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ INT32 Ret;
+
+ if (Sha1Context == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha1_update_ret (Sha1Context, Data, DataSize);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the SHA-1 digest value.
+
+ This function completes SHA-1 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the SHA-1 context cannot
+ be used again.
+ SHA-1 context should be already correctly initialized by Sha1Init(), and should not be
+ finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.
+
+ If Sha1Context is NULL, then return FALSE.
+ If HashValue is NULL, then return FALSE.
+
+ @param[in, out] Sha1Context Pointer to the SHA-1 context.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-1 digest
+ value (20 bytes).
+
+ @retval TRUE SHA-1 digest computation succeeded.
+ @retval FALSE SHA-1 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha1Final (
+ IN OUT VOID *Sha1Context,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if ((Sha1Context == NULL) || (HashValue == NULL)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha1_finish_ret (Sha1Context, HashValue);
+ mbedtls_sha1_free (Sha1Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Computes the SHA-1 message digest of a input data buffer.
+
+ This function performs the SHA-1 message 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 hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-1 digest
+ value (20 bytes).
+
+ @retval TRUE SHA-1 digest computation succeeded.
+ @retval FALSE SHA-1 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sha1HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha1_ret (Data, DataSize, HashValue);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#endif
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c
new file mode 100644
index 0000000000..007f5c12aa
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c
@@ -0,0 +1,219 @@
+/** @file
+ SHA-256 Digest 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/sha256.h>
+#include <mbedtls/compat-2.x.h>
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.
+
+ @return The size, in bytes, of the context buffer required for SHA-256 hash operations.
+
+**/
+UINTN
+EFIAPI
+Sha256GetContextSize (
+ VOID
+ )
+{
+ return (UINTN)(sizeof (mbedtls_sha256_context));
+}
+
+/**
+ Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for
+ subsequent use.
+
+ If Sha256Context is NULL, then return FALSE.
+
+ @param[out] Sha256Context Pointer to SHA-256 context being initialized.
+
+ @retval TRUE SHA-256 context initialization succeeded.
+ @retval FALSE SHA-256 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha256Init (
+ OUT VOID *Sha256Context
+ )
+{
+ INT32 Ret;
+
+ if (Sha256Context == NULL) {
+ return FALSE;
+ }
+
+ mbedtls_sha256_init (Sha256Context);
+
+ Ret = mbedtls_sha256_starts_ret (Sha256Context, FALSE);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Makes a copy of an existing SHA-256 context.
+
+ If Sha256Context is NULL, then return FALSE.
+ If NewSha256Context is NULL, then return FALSE.
+
+ @param[in] Sha256Context Pointer to SHA-256 context being copied.
+ @param[out] NewSha256Context Pointer to new SHA-256 context.
+
+ @retval TRUE SHA-256 context copy succeeded.
+ @retval FALSE SHA-256 context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha256Duplicate (
+ IN CONST VOID *Sha256Context,
+ OUT VOID *NewSha256Context
+ )
+{
+ if ((Sha256Context == NULL) || (NewSha256Context == NULL)) {
+ return FALSE;
+ }
+
+ mbedtls_sha256_clone (NewSha256Context, Sha256Context);
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates SHA-256 context.
+
+ This function performs SHA-256 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.
+ SHA-256 context should be already correctly initialized by Sha256Init(), and should not be finalized
+ by Sha256Final(). Behavior with invalid context is undefined.
+
+ If Sha256Context is NULL, then return FALSE.
+
+ @param[in, out] Sha256Context Pointer to the SHA-256 context.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE SHA-256 data digest succeeded.
+ @retval FALSE SHA-256 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha256Update (
+ IN OUT VOID *Sha256Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ INT32 Ret;
+
+ if (Sha256Context == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha256_update_ret (Sha256Context, Data, DataSize);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the SHA-256 digest value.
+
+ This function completes SHA-256 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the SHA-256 context cannot
+ be used again.
+ SHA-256 context should be already correctly initialized by Sha256Init(), and should not be
+ finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.
+
+ If Sha256Context is NULL, then return FALSE.
+ If HashValue is NULL, then return FALSE.
+
+ @param[in, out] Sha256Context Pointer to the SHA-256 context.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-256 digest
+ value (32 bytes).
+
+ @retval TRUE SHA-256 digest computation succeeded.
+ @retval FALSE SHA-256 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha256Final (
+ IN OUT VOID *Sha256Context,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if ((Sha256Context == NULL) || (HashValue == NULL)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha256_finish_ret (Sha256Context, HashValue);
+ mbedtls_sha256_free (Sha256Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Computes the SHA-256 message digest of a input data buffer.
+
+ This function performs the SHA-256 message 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 hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-256 digest
+ value (32 bytes).
+
+ @retval TRUE SHA-256 digest computation succeeded.
+ @retval FALSE SHA-256 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sha256HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha256_ret (Data, DataSize, HashValue, FALSE);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c
new file mode 100644
index 0000000000..3c6fc951d3
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c
@@ -0,0 +1,431 @@
+/** @file
+ SHA-384 and SHA-512 Digest Wrapper Implementations over MbedTLS.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+#include <mbedtls/sha512.h>
+#include <mbedtls/compat-2.x.h>
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for SHA-384 hash operations.
+
+ @return The size, in bytes, of the context buffer required for SHA-384 hash operations.
+
+**/
+UINTN
+EFIAPI
+Sha384GetContextSize (
+ VOID
+ )
+{
+ return (UINTN)(sizeof (mbedtls_sha512_context));
+}
+
+/**
+ Initializes user-supplied memory pointed by Sha384Context as SHA-384 hash context for
+ subsequent use.
+
+ If Sha384Context is NULL, then return FALSE.
+
+ @param[out] Sha384Context Pointer to SHA-384 context being initialized.
+
+ @retval TRUE SHA-384 context initialization succeeded.
+ @retval FALSE SHA-384 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha384Init (
+ OUT VOID *Sha384Context
+ )
+{
+ INT32 Ret;
+
+ if (Sha384Context == NULL) {
+ return FALSE;
+ }
+
+ mbedtls_sha512_init (Sha384Context);
+
+ Ret = mbedtls_sha512_starts_ret (Sha384Context, TRUE);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Makes a copy of an existing SHA-384 context.
+
+ If Sha384Context is NULL, then return FALSE.
+ If NewSha384Context is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] Sha384Context Pointer to SHA-384 context being copied.
+ @param[out] NewSha384Context Pointer to new SHA-384 context.
+
+ @retval TRUE SHA-384 context copy succeeded.
+ @retval FALSE SHA-384 context copy failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sha384Duplicate (
+ IN CONST VOID *Sha384Context,
+ OUT VOID *NewSha384Context
+ )
+{
+ if ((Sha384Context == NULL) || (NewSha384Context == NULL)) {
+ return FALSE;
+ }
+
+ mbedtls_sha512_clone (NewSha384Context, Sha384Context);
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates SHA-384 context.
+
+ This function performs SHA-384 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.
+ SHA-384 context should be already correctly initialized by Sha384Init(), and should not be finalized
+ by Sha384Final(). Behavior with invalid context is undefined.
+
+ If Sha384Context is NULL, then return FALSE.
+
+ @param[in, out] Sha384Context Pointer to the SHA-384 context.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE SHA-384 data digest succeeded.
+ @retval FALSE SHA-384 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha384Update (
+ IN OUT VOID *Sha384Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ INT32 Ret;
+
+ if (Sha384Context == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha512_update_ret (Sha384Context, Data, DataSize);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the SHA-384 digest value.
+
+ This function completes SHA-384 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the SHA-384 context cannot
+ be used again.
+ SHA-384 context should be already correctly initialized by Sha384Init(), and should not be
+ finalized by Sha384Final(). Behavior with invalid SHA-384 context is undefined.
+
+ If Sha384Context is NULL, then return FALSE.
+ If HashValue is NULL, then return FALSE.
+
+ @param[in, out] Sha384Context Pointer to the SHA-384 context.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-384 digest
+ value (48 bytes).
+
+ @retval TRUE SHA-384 digest computation succeeded.
+ @retval FALSE SHA-384 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha384Final (
+ IN OUT VOID *Sha384Context,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if ((Sha384Context == NULL) || (HashValue == NULL)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha512_finish_ret (Sha384Context, HashValue);
+ mbedtls_sha512_free (Sha384Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Computes the SHA-384 message digest of a input data buffer.
+
+ This function performs the SHA-384 message 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 hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-384 digest
+ value (48 bytes).
+
+ @retval TRUE SHA-384 digest computation succeeded.
+ @retval FALSE SHA-384 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sha384HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha512_ret (Data, DataSize, HashValue, TRUE);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for SHA-512 hash operations.
+
+ @return The size, in bytes, of the context buffer required for SHA-512 hash operations.
+
+**/
+UINTN
+EFIAPI
+Sha512GetContextSize (
+ VOID
+ )
+{
+ return (UINTN)(sizeof (mbedtls_sha512_context));
+}
+
+/**
+ Initializes user-supplied memory pointed by Sha512Context as SHA-512 hash context for
+ subsequent use.
+
+ If Sha512Context is NULL, then return FALSE.
+
+ @param[out] Sha512Context Pointer to SHA-512 context being initialized.
+
+ @retval TRUE SHA-512 context initialization succeeded.
+ @retval FALSE SHA-512 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha512Init (
+ OUT VOID *Sha512Context
+ )
+{
+ INT32 Ret;
+
+ if (Sha512Context == NULL) {
+ return FALSE;
+ }
+
+ mbedtls_sha512_init (Sha512Context);
+
+ Ret = mbedtls_sha512_starts_ret (Sha512Context, FALSE);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Makes a copy of an existing SHA-512 context.
+
+ If Sha512Context is NULL, then return FALSE.
+ If NewSha512Context is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] Sha512Context Pointer to SHA-512 context being copied.
+ @param[out] NewSha512Context Pointer to new SHA-512 context.
+
+ @retval TRUE SHA-512 context copy succeeded.
+ @retval FALSE SHA-512 context copy failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sha512Duplicate (
+ IN CONST VOID *Sha512Context,
+ OUT VOID *NewSha512Context
+ )
+{
+ if ((Sha512Context == NULL) || (NewSha512Context == NULL)) {
+ return FALSE;
+ }
+
+ mbedtls_sha512_clone (NewSha512Context, Sha512Context);
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates SHA-512 context.
+
+ This function performs SHA-512 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.
+ SHA-512 context should be already correctly initialized by Sha512Init(), and should not be finalized
+ by Sha512Final(). Behavior with invalid context is undefined.
+
+ If Sha512Context is NULL, then return FALSE.
+
+ @param[in, out] Sha512Context Pointer to the SHA-512 context.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE SHA-512 data digest succeeded.
+ @retval FALSE SHA-512 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha512Update (
+ IN OUT VOID *Sha512Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ INT32 Ret;
+
+ if (Sha512Context == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha512_update_ret (Sha512Context, Data, DataSize);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the SHA-512 digest value.
+
+ This function completes SHA-512 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the SHA-512 context cannot
+ be used again.
+ SHA-512 context should be already correctly initialized by Sha512Init(), and should not be
+ finalized by Sha512Final(). Behavior with invalid SHA-512 context is undefined.
+
+ If Sha512Context is NULL, then return FALSE.
+ If HashValue is NULL, then return FALSE.
+
+ @param[in, out] Sha512Context Pointer to the SHA-512 context.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-512 digest
+ value (64 bytes).
+
+ @retval TRUE SHA-512 digest computation succeeded.
+ @retval FALSE SHA-512 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sha512Final (
+ IN OUT VOID *Sha512Context,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if ((Sha512Context == NULL) || (HashValue == NULL)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha512_finish_ret (Sha512Context, HashValue);
+ mbedtls_sha512_free (Sha512Context);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Computes the SHA-512 message digest of a input data buffer.
+
+ This function performs the SHA-512 message 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 hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the SHA-512 digest
+ value (64 bytes).
+
+ @retval TRUE SHA-512 digest computation succeeded.
+ @retval FALSE SHA-512 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sha512HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ INT32 Ret;
+
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ Ret = mbedtls_sha512_ret (Data, DataSize, HashValue, FALSE);
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c
index e7e67b645b..dc5820227a 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c
@@ -84,6 +84,13 @@ BOOLEAN
typedef
BOOLEAN
+(EFIAPI *EFI_HASH_DUP)(
+ IN CONST VOID *HashContext,
+ OUT VOID *NewHashContext
+ );
+
+typedef
+BOOLEAN
(EFIAPI *EFI_HASH_FINAL)(
IN OUT VOID *HashContext,
OUT UINT8 *HashValue
@@ -102,6 +109,7 @@ typedef struct {
EFI_HASH_GET_CONTEXT_SIZE GetContextSize;
EFI_HASH_INIT HashInit;
EFI_HASH_UPDATE HashUpdate;
+ EFI_HASH_DUP HashDup;
EFI_HASH_FINAL HashFinal;
EFI_HASH_ALL HashAll;
CONST UINT8 *Digest;
@@ -109,12 +117,12 @@ typedef struct {
} HASH_TEST_CONTEXT;
#ifdef ENABLE_MD5_DEPRECATED_INTERFACES
-HASH_TEST_CONTEXT mMd5TestCtx = { MD5_DIGEST_SIZE, Md5GetContextSize, Md5Init, Md5Update, Md5Final, Md5HashAll, Md5Digest };
+HASH_TEST_CONTEXT mMd5TestCtx = { MD5_DIGEST_SIZE, Md5GetContextSize, Md5Init, Md5Update, Md5Duplicate, Md5Final, Md5HashAll, Md5Digest };
#endif
-HASH_TEST_CONTEXT mSha1TestCtx = { SHA1_DIGEST_SIZE, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final, Sha1HashAll, Sha1Digest };
-HASH_TEST_CONTEXT mSha256TestCtx = { SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final, Sha256HashAll, Sha256Digest };
-HASH_TEST_CONTEXT mSha384TestCtx = { SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final, Sha384HashAll, Sha384Digest };
-HASH_TEST_CONTEXT mSha512TestCtx = { SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final, Sha512HashAll, Sha512Digest };
+HASH_TEST_CONTEXT mSha1TestCtx = { SHA1_DIGEST_SIZE, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Duplicate, Sha1Final, Sha1HashAll, Sha1Digest };
+HASH_TEST_CONTEXT mSha256TestCtx = { SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Duplicate, Sha256Final, Sha256HashAll, Sha256Digest };
+HASH_TEST_CONTEXT mSha384TestCtx = { SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Duplicate, Sha384Final, Sha384HashAll, Sha384Digest };
+HASH_TEST_CONTEXT mSha512TestCtx = { SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Duplicate, Sha512Final, Sha512HashAll, Sha512Digest };
UNIT_TEST_STATUS
EFIAPI
@@ -157,25 +165,40 @@ TestVerifyHash (
{
UINTN DataSize;
UINT8 Digest[MAX_DIGEST_SIZE];
+ UINT8 DigestCopy[MAX_DIGEST_SIZE];
BOOLEAN Status;
HASH_TEST_CONTEXT *HashTestContext;
+ VOID *HashCopyContext;
HashTestContext = Context;
DataSize = AsciiStrLen (HashData);
ZeroMem (Digest, MAX_DIGEST_SIZE);
+ ZeroMem (DigestCopy, MAX_DIGEST_SIZE);
+
+ HashCopyContext = AllocatePool (HashTestContext->GetContextSize ());
Status = HashTestContext->HashInit (HashTestContext->HashCtx);
UT_ASSERT_TRUE (Status);
+ Status = HashTestContext->HashInit (HashCopyContext);
+ UT_ASSERT_TRUE (Status);
+
Status = HashTestContext->HashUpdate (HashTestContext->HashCtx, HashData, DataSize);
UT_ASSERT_TRUE (Status);
+ Status = HashTestContext->HashDup (HashTestContext->HashCtx, HashCopyContext);
+ UT_ASSERT_TRUE (Status);
+
Status = HashTestContext->HashFinal (HashTestContext->HashCtx, Digest);
UT_ASSERT_TRUE (Status);
+ Status = HashTestContext->HashFinal (HashCopyContext, DigestCopy);
+ UT_ASSERT_TRUE (Status);
+
UT_ASSERT_MEM_EQUAL (Digest, HashTestContext->Digest, HashTestContext->DigestSize);
+ UT_ASSERT_MEM_EQUAL (Digest, DigestCopy, HashTestContext->DigestSize);
ZeroMem (Digest, MAX_DIGEST_SIZE);
Status = HashTestContext->HashAll (HashData, DataSize, Digest);