summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenxing Hou <wenxing.hou@intel.com>2024-03-11 21:07:14 +0800
committerLiming Gao <gaoliming@byosoft.com.cn>2024-05-27 17:24:30 +0800
commit08281572aab5b1f7e05bf26de4148af19eddc8b7 (patch)
treefdce31183b694fbc36424e9540dd38311f7a2049
parented7a3143b7fd5d4f116355d4c799748aa008329b (diff)
downloadedk2-08281572aab5b1f7e05bf26de4148af19eddc8b7.tar.gz
edk2-08281572aab5b1f7e05bf26de4148af19eddc8b7.tar.bz2
edk2-08281572aab5b1f7e05bf26de4148af19eddc8b7.zip
Add SM3 functions with openssl for Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177 Because the Mbedlts 3.3.0 doesn't have Sm3, the Sm3 implementaion is based on Openssl. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com> Reviewed-by: Yi Li <yi1.li@intel.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
-rw-r--r--CryptoPkg/CryptoPkgMbedTls.dsc1
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf7
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSm3.c235
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf5
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf4
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf1
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf5
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/BaseMemAllocation.c122
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c571
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/UnitTestHostCrtWrapper.c63
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf4
11 files changed, 1010 insertions, 8 deletions
diff --git a/CryptoPkg/CryptoPkgMbedTls.dsc b/CryptoPkg/CryptoPkgMbedTls.dsc
index 5d0ae6ff3f..c97b28c0b5 100644
--- a/CryptoPkg/CryptoPkgMbedTls.dsc
+++ b/CryptoPkg/CryptoPkgMbedTls.dsc
@@ -88,6 +88,7 @@
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
index cb282fe648..b76b4e6067 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
@@ -31,10 +31,8 @@
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSha512.c
- Hash/CryptSm3Null.c
-
Hash/CryptParallelHashNull.c
-
+ Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
@@ -59,6 +57,8 @@
Rand/CryptRand.c
SysCall/CrtWrapper.c
+ SysCall/DummyOpensslSupport.c
+ SysCall/BaseMemAllocation.c
SysCall/TimerWrapper.c
[Packages]
@@ -72,6 +72,7 @@
UefiRuntimeServicesTableLib
DebugLib
MbedTlsLib
+ OpensslLib
PrintLib
IntrinsicLib
RngLib
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSm3.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSm3.c
new file mode 100644
index 0000000000..1a442d714e
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSm3.c
@@ -0,0 +1,235 @@
+/** @file
+ SM3 Digest Wrapper Implementations over openssl.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+#include "internal/sm3.h"
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for SM3 hash operations.
+
+ @return The size, in bytes, of the context buffer required for SM3 hash operations.
+
+**/
+UINTN
+EFIAPI
+Sm3GetContextSize (
+ VOID
+ )
+{
+ //
+ // Retrieves Openssl SM3 Context Size
+ //
+ return (UINTN)(sizeof (SM3_CTX));
+}
+
+/**
+ Initializes user-supplied memory pointed by Sm3Context as SM3 hash context for
+ subsequent use.
+
+ If Sm3Context is NULL, then return FALSE.
+
+ @param[out] Sm3Context Pointer to SM3 context being initialized.
+
+ @retval TRUE SM3 context initialization succeeded.
+ @retval FALSE SM3 context initialization failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sm3Init (
+ OUT VOID *Sm3Context
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (Sm3Context == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Openssl SM3 Context Initialization
+ //
+ ossl_sm3_init ((SM3_CTX *)Sm3Context);
+ return TRUE;
+}
+
+/**
+ Makes a copy of an existing SM3 context.
+
+ If Sm3Context is NULL, then return FALSE.
+ If NewSm3Context is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] Sm3Context Pointer to SM3 context being copied.
+ @param[out] NewSm3Context Pointer to new SM3 context.
+
+ @retval TRUE SM3 context copy succeeded.
+ @retval FALSE SM3 context copy failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sm3Duplicate (
+ IN CONST VOID *Sm3Context,
+ OUT VOID *NewSm3Context
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if ((Sm3Context == NULL) || (NewSm3Context == NULL)) {
+ return FALSE;
+ }
+
+ CopyMem (NewSm3Context, Sm3Context, sizeof (SM3_CTX));
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates SM3 context.
+
+ This function performs SM3 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.
+ SM3 context should be already correctly initialized by Sm3Init(), and should not be finalized
+ by Sm3Final(). Behavior with invalid context is undefined.
+
+ If Sm3Context is NULL, then return FALSE.
+
+ @param[in, out] Sm3Context Pointer to the SM3 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 SM3 data digest succeeded.
+ @retval FALSE SM3 data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sm3Update (
+ IN OUT VOID *Sm3Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (Sm3Context == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Check invalid parameters, in case that only DataLength was checked in Openssl
+ //
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ //
+ // Openssl SM3 Hash Update
+ //
+ ossl_sm3_update ((SM3_CTX *)Sm3Context, Data, DataSize);
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the SM3 digest value.
+
+ This function completes SM3 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the SM3 context cannot
+ be used again.
+ SM3 context should be already correctly initialized by Sm3Init(), and should not be
+ finalized by Sm3Final(). Behavior with invalid SM3 context is undefined.
+
+ If Sm3Context is NULL, then return FALSE.
+ If HashValue is NULL, then return FALSE.
+
+ @param[in, out] Sm3Context Pointer to the SM3 context.
+ @param[out] HashValue Pointer to a buffer that receives the SM3 digest
+ value (32 bytes).
+
+ @retval TRUE SM3 digest computation succeeded.
+ @retval FALSE SM3 digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+Sm3Final (
+ IN OUT VOID *Sm3Context,
+ OUT UINT8 *HashValue
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if ((Sm3Context == NULL) || (HashValue == NULL)) {
+ return FALSE;
+ }
+
+ //
+ // Openssl SM3 Hash Finalization
+ //
+ ossl_sm3_final (HashValue, (SM3_CTX *)Sm3Context);
+
+ return TRUE;
+}
+
+/**
+ Computes the SM3 message digest of a input data buffer.
+
+ This function performs the SM3 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 SM3 digest
+ value (32 bytes).
+
+ @retval TRUE SM3 digest computation succeeded.
+ @retval FALSE SM3 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Sm3HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ SM3_CTX Ctx;
+
+ //
+ // Check input parameters.
+ //
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+
+ if ((Data == NULL) && (DataSize != 0)) {
+ return FALSE;
+ }
+
+ //
+ // SM3 Hash Computation.
+ //
+ ossl_sm3_init (&Ctx);
+
+ ossl_sm3_update (&Ctx, Data, DataSize);
+
+ ossl_sm3_final (HashValue, &Ctx);
+
+ return TRUE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
index 660e11a96e..3c057660d8 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
@@ -38,9 +38,9 @@
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
- Hash/CryptSm3Null.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
+ Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
@@ -65,6 +65,8 @@
Bn/CryptBnNull.c
SysCall/CrtWrapper.c
+ SysCall/DummyOpensslSupport.c
+ SysCall/BaseMemAllocation.c
SysCall/ConstantTimeClock.c
[Packages]
@@ -77,6 +79,7 @@
MemoryAllocationLib
DebugLib
MbedTlsLib
+ OpensslLib
IntrinsicLib
PrintLib
PeiServicesTablePointerLib
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
index 280b1a9c29..824aa4fa5d 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
@@ -37,9 +37,9 @@
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
- Hash/CryptSm3Null.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
+ Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
@@ -65,6 +65,7 @@
SysCall/CrtWrapper.c
SysCall/TimerWrapper.c
+ SysCall/DummyOpensslSupport.c
SysCall/RuntimeMemAllocation.c
[Packages]
@@ -77,6 +78,7 @@
UefiRuntimeServicesTableLib
DebugLib
MbedTlsLib
+ OpensslLib
IntrinsicLib
PrintLib
RngLib
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf
index 6fc073aac6..e61e07dfa4 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf
@@ -29,7 +29,6 @@
[Sources]
InternalCryptLib.h
Hash/CryptSha512.c
-
Hash/CryptMd5Null.c
Hash/CryptSha1Null.c
Hash/CryptSha256Null.c
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
index 4a519b06ee..649c2a3c0c 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
@@ -36,9 +36,9 @@
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
- Hash/CryptSm3Null.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
+ Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
@@ -63,6 +63,8 @@
Rand/CryptRand.c
SysCall/CrtWrapper.c
+ SysCall/DummyOpensslSupport.c
+ SysCall/BaseMemAllocation.c
SysCall/ConstantTimeClock.c
[Packages]
@@ -74,6 +76,7 @@
BaseMemoryLib
MemoryAllocationLib
MbedTlsLib
+ OpensslLib
IntrinsicLib
PrintLib
MmServicesTableLib
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/BaseMemAllocation.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/BaseMemAllocation.c
new file mode 100644
index 0000000000..10fb75cd98
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/BaseMemAllocation.c
@@ -0,0 +1,122 @@
+/** @file
+ Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL
+ during PEI & DXE phases.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <CrtLibSupport.h>
+#include <Library/MemoryAllocationLib.h>
+
+//
+// Extra header to record the memory buffer size from malloc routine.
+//
+#define CRYPTMEM_HEAD_SIGNATURE SIGNATURE_32('c','m','h','d')
+typedef struct {
+ UINT32 Signature;
+ UINT32 Reserved;
+ UINTN Size;
+} CRYPTMEM_HEAD;
+
+#define CRYPTMEM_OVERHEAD sizeof(CRYPTMEM_HEAD)
+
+//
+// -- Memory-Allocation Routines --
+//
+
+/* Allocates memory blocks */
+void *
+malloc (
+ size_t size
+ )
+{
+ CRYPTMEM_HEAD *PoolHdr;
+ UINTN NewSize;
+ VOID *Data;
+
+ //
+ // Adjust the size by the buffer header overhead
+ //
+ NewSize = (UINTN)(size) + CRYPTMEM_OVERHEAD;
+
+ Data = AllocatePool (NewSize);
+ if (Data != NULL) {
+ PoolHdr = (CRYPTMEM_HEAD *)Data;
+ //
+ // Record the memory brief information
+ //
+ PoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE;
+ PoolHdr->Size = size;
+
+ return (VOID *)(PoolHdr + 1);
+ } else {
+ //
+ // The buffer allocation failed.
+ //
+ return NULL;
+ }
+}
+
+/* Reallocate memory blocks */
+void *
+realloc (
+ void *ptr,
+ size_t size
+ )
+{
+ CRYPTMEM_HEAD *OldPoolHdr;
+ CRYPTMEM_HEAD *NewPoolHdr;
+ UINTN OldSize;
+ UINTN NewSize;
+ VOID *Data;
+
+ NewSize = (UINTN)size + CRYPTMEM_OVERHEAD;
+ Data = AllocatePool (NewSize);
+ if (Data != NULL) {
+ NewPoolHdr = (CRYPTMEM_HEAD *)Data;
+ NewPoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE;
+ NewPoolHdr->Size = size;
+ if (ptr != NULL) {
+ //
+ // Retrieve the original size from the buffer header.
+ //
+ OldPoolHdr = (CRYPTMEM_HEAD *)ptr - 1;
+ ASSERT (OldPoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE);
+ OldSize = OldPoolHdr->Size;
+
+ //
+ // Duplicate the buffer content.
+ //
+ CopyMem ((VOID *)(NewPoolHdr + 1), ptr, MIN (OldSize, size));
+ FreePool ((VOID *)OldPoolHdr);
+ }
+
+ return (VOID *)(NewPoolHdr + 1);
+ } else {
+ //
+ // The buffer allocation failed.
+ //
+ return NULL;
+ }
+}
+
+/* De-allocates or frees a memory block */
+void
+free (
+ void *ptr
+ )
+{
+ CRYPTMEM_HEAD *PoolHdr;
+
+ //
+ // In Standard C, free() handles a null pointer argument transparently. This
+ // is not true of FreePool() below, so protect it.
+ //
+ if (ptr != NULL) {
+ PoolHdr = (CRYPTMEM_HEAD *)ptr - 1;
+ ASSERT (PoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE);
+ FreePool (PoolHdr);
+ }
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c
new file mode 100644
index 0000000000..d3786f0e2a
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c
@@ -0,0 +1,571 @@
+/**
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <CrtLibSupport.h>
+
+int errno = 0;
+
+FILE *stderr = NULL;
+FILE *stdin = NULL;
+FILE *stdout = NULL;
+
+typedef
+ int
+(*SORT_COMPARE)(
+ IN VOID *Buffer1,
+ IN VOID *Buffer2
+ );
+
+//
+// Duplicated from EDKII BaseSortLib for qsort() wrapper
+//
+STATIC
+VOID
+QuickSortWorker (
+ IN OUT VOID *BufferToSort,
+ IN CONST UINTN Count,
+ IN CONST UINTN ElementSize,
+ IN SORT_COMPARE CompareFunction,
+ IN VOID *Buffer
+ )
+{
+ VOID *Pivot;
+ UINTN LoopCount;
+ UINTN NextSwapLocation;
+
+ ASSERT (BufferToSort != NULL);
+ ASSERT (CompareFunction != NULL);
+ ASSERT (Buffer != NULL);
+
+ if ((Count < 2) || (ElementSize < 1)) {
+ return;
+ }
+
+ NextSwapLocation = 0;
+
+ //
+ // Pick a pivot (we choose last element)
+ //
+ Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize));
+
+ //
+ // Now get the pivot such that all on "left" are below it
+ // and everything "right" are above it
+ //
+ for (LoopCount = 0; LoopCount < Count - 1; LoopCount++) {
+ //
+ // If the element is less than the pivot
+ //
+ if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) {
+ //
+ // Swap
+ //
+ CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
+ CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) * ElementSize), ElementSize);
+ CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize);
+
+ //
+ // Increment NextSwapLocation
+ //
+ NextSwapLocation++;
+ }
+ }
+
+ //
+ // Swap pivot to its final position (NextSwapLocation)
+ //
+ CopyMem (Buffer, Pivot, ElementSize);
+ CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
+ CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize);
+
+ //
+ // Now recurse on 2 partial lists. Neither of these will have the 'pivot' element.
+ // IE list is sorted left half, pivot element, sorted right half...
+ //
+ QuickSortWorker (
+ BufferToSort,
+ NextSwapLocation,
+ ElementSize,
+ CompareFunction,
+ Buffer
+ );
+
+ QuickSortWorker (
+ (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
+ Count - NextSwapLocation - 1,
+ ElementSize,
+ CompareFunction,
+ Buffer
+ );
+
+ return;
+}
+
+// ---------------------------------------------------------
+// Standard C Run-time Library Interface Wrapper
+// ---------------------------------------------------------
+
+//
+// -- String Manipulation Routines --
+//
+
+/* Scan a string for the last occurrence of a character */
+char *
+strrchr (
+ const char *str,
+ int c
+ )
+{
+ char *save;
+
+ for (save = NULL; ; ++str) {
+ if (*str == c) {
+ save = (char *)str;
+ }
+
+ if (*str == 0) {
+ return (save);
+ }
+ }
+}
+
+/* Compare first n bytes of string s1 with string s2, ignoring case */
+int
+strncasecmp (
+ const char *s1,
+ const char *s2,
+ size_t n
+ )
+{
+ int Val;
+
+ ASSERT (s1 != NULL);
+ ASSERT (s2 != NULL);
+
+ if (n != 0) {
+ do {
+ Val = tolower (*s1) - tolower (*s2);
+ if (Val != 0) {
+ return Val;
+ }
+
+ ++s1;
+ ++s2;
+ if (*s1 == '\0') {
+ break;
+ }
+ } while (--n != 0);
+ }
+
+ return 0;
+}
+
+/* Read formatted data from a string */
+int
+sscanf (
+ const char *buffer,
+ const char *format,
+ ...
+ )
+{
+ //
+ // Null sscanf() function implementation to satisfy the linker, since
+ // no direct functionality logic dependency in present UEFI cases.
+ //
+ return 0;
+}
+
+/* Maps errnum to an error-message string */
+char *
+strerror (
+ int errnum
+ )
+{
+ return NULL;
+}
+
+/* Computes the length of the maximum initial segment of the string pointed to by s1
+ which consists entirely of characters from the string pointed to by s2. */
+size_t
+strspn (
+ const char *s1,
+ const char *s2
+ )
+{
+ UINT8 Map[32];
+ UINT32 Index;
+ size_t Count;
+
+ for (Index = 0; Index < 32; Index++) {
+ Map[Index] = 0;
+ }
+
+ while (*s2) {
+ Map[*s2 >> 3] |= (1 << (*s2 & 7));
+ s2++;
+ }
+
+ if (*s1) {
+ Count = 0;
+ while (Map[*s1 >> 3] & (1 << (*s1 & 7))) {
+ Count++;
+ s1++;
+ }
+
+ return Count;
+ }
+
+ return 0;
+}
+
+/* Computes the length of the maximum initial segment of the string pointed to by s1
+ which consists entirely of characters not from the string pointed to by s2. */
+size_t
+strcspn (
+ const char *s1,
+ const char *s2
+ )
+{
+ UINT8 Map[32];
+ UINT32 Index;
+ size_t Count;
+
+ for (Index = 0; Index < 32; Index++) {
+ Map[Index] = 0;
+ }
+
+ while (*s2) {
+ Map[*s2 >> 3] |= (1 << (*s2 & 7));
+ s2++;
+ }
+
+ Map[0] |= 1;
+
+ Count = 0;
+ while (!(Map[*s1 >> 3] & (1 << (*s1 & 7)))) {
+ Count++;
+ s1++;
+ }
+
+ return Count;
+}
+
+char *
+strcpy (
+ char *strDest,
+ const char *strSource
+ )
+{
+ // AsciiStrCpyS (strDest, MAX_STRING_SIZE, strSource);
+ // return strDest;
+ return NULL;
+}
+
+//
+// -- Character Classification Routines --
+//
+
+/* Determines if a particular character is a decimal-digit character */
+int
+isdigit (
+ int c
+ )
+{
+ //
+ // <digit> ::= [0-9]
+ //
+ return (('0' <= (c)) && ((c) <= '9'));
+}
+
+/* Determine if an integer represents character that is a hex digit */
+int
+isxdigit (
+ int c
+ )
+{
+ //
+ // <hexdigit> ::= [0-9] | [a-f] | [A-F]
+ //
+ return ((('0' <= (c)) && ((c) <= '9')) ||
+ (('a' <= (c)) && ((c) <= 'f')) ||
+ (('A' <= (c)) && ((c) <= 'F')));
+}
+
+/* Determines if a particular character represents a space character */
+int
+isspace (
+ int c
+ )
+{
+ //
+ // <space> ::= [ ]
+ //
+ return ((c) == ' ');
+}
+
+/* Determine if a particular character is an alphanumeric character */
+int
+isalnum (
+ int c
+ )
+{
+ //
+ // <alnum> ::= [0-9] | [a-z] | [A-Z]
+ //
+ return ((('0' <= (c)) && ((c) <= '9')) ||
+ (('a' <= (c)) && ((c) <= 'z')) ||
+ (('A' <= (c)) && ((c) <= 'Z')));
+}
+
+/* Determines if a particular character is in upper case */
+int
+isupper (
+ int c
+ )
+{
+ //
+ // <uppercase letter> := [A-Z]
+ //
+ return (('A' <= (c)) && ((c) <= 'Z'));
+}
+
+//
+// -- Data Conversion Routines --
+//
+
+/* Convert strings to a long-integer value */
+long
+strtol (
+ const char *nptr,
+ char **endptr,
+ int base
+ )
+{
+ //
+ // Null strtol() function implementation to satisfy the linker, since there is
+ // no direct functionality logic dependency in present UEFI cases.
+ //
+ return 0;
+}
+
+/* Convert strings to an unsigned long-integer value */
+unsigned long
+strtoul (
+ const char *nptr,
+ char **endptr,
+ int base
+ )
+{
+ //
+ // Null strtoul() function implementation to satisfy the linker, since there is
+ // no direct functionality logic dependency in present UEFI cases.
+ //
+ return 0;
+}
+
+/* Convert character to lowercase */
+int
+tolower (
+ int c
+ )
+{
+ if (('A' <= (c)) && ((c) <= 'Z')) {
+ return (c - ('A' - 'a'));
+ }
+
+ return (c);
+}
+
+//
+// -- Searching and Sorting Routines --
+//
+
+/* Performs a quick sort */
+void
+qsort (
+ void *base,
+ size_t num,
+ size_t width,
+ int ( *compare )(const void *, const void *)
+ )
+{
+ VOID *Buffer;
+
+ ASSERT (base != NULL);
+ ASSERT (compare != NULL);
+
+ //
+ // Use CRT-style malloc to cover BS and RT memory allocation.
+ //
+ Buffer = malloc (width);
+ ASSERT (Buffer != NULL);
+
+ //
+ // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib.
+ //
+ QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer);
+
+ free (Buffer);
+ return;
+}
+
+//
+// -- Process and Environment Control Routines --
+//
+
+/* Get a value from the current environment */
+char *
+getenv (
+ const char *varname
+ )
+{
+ //
+ // Null getenv() function implementation to satisfy the linker, since there is
+ // no direct functionality logic dependency in present UEFI cases.
+ //
+ return NULL;
+}
+
+/* Get a value from the current environment */
+char *
+secure_getenv (
+ const char *varname
+ )
+{
+ //
+ // Null secure_getenv() function implementation to satisfy the linker, since
+ // there is no direct functionality logic dependency in present UEFI cases.
+ //
+ // From the secure_getenv() manual: 'just like getenv() except that it
+ // returns NULL in cases where "secure execution" is required'.
+ //
+ return NULL;
+}
+
+//
+// -- Stream I/O Routines --
+//
+
+/* Write data to a stream */
+size_t
+fwrite (
+ const void *buffer,
+ size_t size,
+ size_t count,
+ FILE *stream
+ )
+{
+ return 0;
+}
+
+#ifdef __GNUC__
+
+typedef
+ VOID
+(EFIAPI *NoReturnFuncPtr)(
+ VOID
+ ) __attribute__ ((__noreturn__));
+
+STATIC
+VOID
+EFIAPI
+NopFunction (
+ VOID
+ )
+{
+}
+
+void
+abort (
+ void
+ )
+{
+ NoReturnFuncPtr NoReturnFunc;
+
+ NoReturnFunc = (NoReturnFuncPtr)NopFunction;
+
+ NoReturnFunc ();
+}
+
+#else
+
+void
+abort (
+ void
+ )
+{
+ // Do nothing
+}
+
+#endif
+
+int
+fclose (
+ FILE *f
+ )
+{
+ return 0;
+}
+
+FILE *
+fopen (
+ const char *c,
+ const char *m
+ )
+{
+ return NULL;
+}
+
+size_t
+fread (
+ void *b,
+ size_t c,
+ size_t i,
+ FILE *f
+ )
+{
+ return 0;
+}
+
+uid_t
+getuid (
+ void
+ )
+{
+ return 0;
+}
+
+uid_t
+geteuid (
+ void
+ )
+{
+ return 0;
+}
+
+gid_t
+getgid (
+ void
+ )
+{
+ return 0;
+}
+
+gid_t
+getegid (
+ void
+ )
+{
+ return 0;
+}
+
+int
+printf (
+ char const *fmt,
+ ...
+ )
+{
+ return 0;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/UnitTestHostCrtWrapper.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/UnitTestHostCrtWrapper.c
new file mode 100644
index 0000000000..cd20309a6d
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/UnitTestHostCrtWrapper.c
@@ -0,0 +1,63 @@
+/** @file
+ C Run-Time Libraries (CRT) Wrapper Implementation for OpenSSL-based
+ Cryptographic Library.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+
+/* Read formatted data from a string */
+int
+sscanf (
+ const char *buffer,
+ const char *format,
+ ...
+ )
+{
+ //
+ // Null sscanf() function implementation to satisfy the linker, since
+ // no direct functionality logic dependency in present UEFI cases.
+ //
+ return 0;
+}
+
+uid_t
+getuid (
+ void
+ )
+{
+ return 0;
+}
+
+uid_t
+geteuid (
+ void
+ )
+{
+ return 0;
+}
+
+gid_t
+getgid (
+ void
+ )
+{
+ return 0;
+}
+
+gid_t
+getegid (
+ void
+ )
+{
+ return 0;
+}
+
+int errno = 0;
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf
index 4e2fb73cd6..30d15a8eff 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf
@@ -31,7 +31,7 @@
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSha512.c
- Hash/CryptSm3Null.c
+ Hash/CryptSm3.c
Hash/CryptParallelHashNull.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
@@ -56,6 +56,7 @@
Pk/CryptEcNull.c
Rand/CryptRand.c
SysCall/CrtWrapper.c
+ SysCall/UnitTestHostCrtWrapper.c
[Packages]
MdePkg/MdePkg.dec
@@ -68,6 +69,7 @@
UefiRuntimeServicesTableLib
DebugLib
MbedTlsLib
+ OpensslLib
PrintLib
RngLib