public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17
@ 2023-03-17  9:00 Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 1/7] Update ReadmeMbedtls Wenxing Hou
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou, Jiewen Yao, Yi Li

The POC is to explore mbedtls as a smaller alternative to OpenSSL.
The Patch enable EC/X509/Pkcs7 base on Mbedtls for CryptoPkg.


Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>

Wenxing Hou (7):
  Update ReadmeMbedtls
  Clear unnecessary API in DH
  Make all BaseCryptLibMbedTls inf files consistent with BaseCryptLib
  Update Pkcs7 api based on MbedTlsLib for CryptoPkg
  Update EC api based on MbedTlsLib for CryptoPkg
  Update X509 api based on MbedTlsLib for CryptoPkg
  Clean SysCall api by adding platform_util.c

 .../BaseCryptLibMbedTls/BaseCryptLib.inf      |   8 +
 .../BaseCryptLibMbedTls/InternalCryptLib.h    |  32 +
 .../Library/BaseCryptLibMbedTls/Pk/CryptDh.c  |  73 --
 .../Library/BaseCryptLibMbedTls/Pk/CryptEc.c  | 634 +++++++++++++++++-
 .../BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c   |   5 +-
 .../Pk/CryptPkcs7VerifyBase.c                 |  40 +-
 .../Pk/CryptPkcs7VerifyCommon.c               | 338 +++++++++-
 .../Pk/CryptPkcs7VerifyEku.c                  | 454 +------------
 .../BaseCryptLibMbedTls/Pk/CryptX509.c        | 163 ++++-
 .../BaseCryptLibMbedTls/Rand/CryptRandTsc.c   |   7 +
 .../BaseCryptLibMbedTls/RuntimeCryptLib.inf   |   2 +-
 .../BaseCryptLibMbedTls/SmmCryptLib.inf       |   4 +-
 .../SysCall/ConstantTimeClock.c               |  14 -
 .../BaseCryptLibMbedTls/SysCall/CrtWrapper.c  |   5 -
 .../SysCall/TimerWrapper.c                    |  14 -
 .../BaseCryptLibMbedTls/TestBaseCryptLib.inf  |   4 +-
 CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf   |   2 +
 CryptoPkg/ReadmeMbedtls.md                    |  55 +-
 18 files changed, 1264 insertions(+), 590 deletions(-)

-- 
2.26.2.windows.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 1/7] Update ReadmeMbedtls
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 2/7] Clear unnecessary API in DH Wenxing Hou
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 CryptoPkg/ReadmeMbedtls.md | 55 +++++++++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/CryptoPkg/ReadmeMbedtls.md b/CryptoPkg/ReadmeMbedtls.md
index 4b5a132fd0..39fc93028c 100644
--- a/CryptoPkg/ReadmeMbedtls.md
+++ b/CryptoPkg/ReadmeMbedtls.md
@@ -1,21 +1,18 @@
 # CryptoMbedTlsPkg(enable mbedtls for EDKII POC)
 
-## background
+## Overview
 This POC is to explore mbedtls as a smaller alternative to OpenSSL.
 
-## MbedTLS version
-Depend on Mbedtls 3.3.0.
-
-## MbedTLS and OpenSSL CryptoPkg size compare
+### MbedTLS and OpenSSL CryptoPkg size compare
 
-|  Driver  | OpenSSL  | OpenSSL(no SM3 and Pkcs7) | MbedTLS |
-|  ----  | ----  | ----  | ----  |
-|  PEI  | 387Kb  | 387kb  | 162kb |
-|  PeiPreMem  | 31Kb  | WIP  | WIP |
-|  DXE  | 804Kb  | WIP  | WIP |
-|  SMM  | 558Kb  | WIP  | WIP |
+|  Driver  | OpenSSL  |  MbedTLS |
+|  ----  | ----  | ----  |
+|  PEI  | 387Kb  | 162Kb |
+|  PeiPreMem  | 31Kb  | 58Kb |
+|  DXE  | 804Kb  | 457Kb  |
+|  SMM  | 558Kb  | 444Kb  |
 
-## Current enabling status
+### Current enabling status
 
 |  FILE  | Build Pass  | Test Pass |
 |  ----  | ----  | ----  |
@@ -33,24 +30,44 @@ Depend on Mbedtls 3.3.0.
 | Pem/CryptPem.c  | YES | YES |
 | Pk/CryptAuthenticode.c  | WIP | WIP |
 | Pk/CryptDh.c  | YES | YES |
-| Pk/CryptEc.c  | WIP | WIP |
+| Pk/CryptEc.c  | YES | YES |
 | Pk/CryptPkcs1Oaep.c  | YES | YES |
 | Pk/CryptPkcs5Pbkdf2.c  | YES | YES |
 | Pk/CryptPkcs7Sign.c  | YES | YES |
-| Pk/CryptPkcs7VerifyBase.c  | YES | WIP |
-| Pk/CryptPkcs7VerifyCommon.c  | YES | WIP |
+| Pk/CryptPkcs7VerifyBase.c  | YES | YES |
+| Pk/CryptPkcs7VerifyCommon.c  | YES | YES |
 | Pk/CryptPkcs7VerifyEku.c  | YES | WIP |
 | Pk/CryptPkcs7VerifyEkuRuntime.c  | YES | YES |
 | Pk/CryptPkcs7VerifyRuntime.c  | YES | YES |
 | Pk/CryptRsaBasic.c  | YES | YES |
 | Pk/CryptRsaExt.c  | YES | YES |
-| Pk/CryptTs.c  | YES | YES |
-| Pk/CryptX509.c  | WIP | WIP |
-
+| Pk/CryptTs.c  | YES | WIP |
+| Pk/CryptX509.c  | YES | YES |
 
 ## Build command
 
    ```
    edksetup.bat Rebuild VS2019
    build -a X64 -p CryptoPkg/CryptoPkgMbedTls.dsc -DCRYPTO_IMG_TYPE=PEI_DEFAULT -t VS2019
-   ```
\ No newline at end of file
+   ```
+## Risk
+
+|  Risk  | Soluton  | Time required |
+|  ----  | ----  | ----  |
+| SM3 and SHA3 are missing in Mbedtls  | Wait Mbedtls enable SM3 and SHA3 | Unkown |
+| Following API implementation is WIP  | Implement API | 2 weeks |
+
+### API need to complete
+|  API  | Time required |
+|  ----  | ----  |
+| VerifyEKUsInPkcs7Signature  | 3 days |
+| AuthenticodeVerify  | 3 days |
+| EcPointSetCompressedCoordinates  | 2 days |
+| ImageTimestampVerify  | 3 days |
+
+## Timeline
+Target for 2023 Q1
+## Owner
+The branch owner: Wenxing Hou <wenxing.hou@intel.com>  
+## MbedTls Version
+Depend on Mbedtls 3.3.0.
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 2/7] Clear unnecessary API in DH
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 1/7] Update ReadmeMbedtls Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 3/7] Make all BaseCryptLibMbedTls inf files consistent with BaseCryptLib Wenxing Hou
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../Library/BaseCryptLibMbedTls/Pk/CryptDh.c  | 73 -------------------
 1 file changed, 73 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptDh.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptDh.c
index cd0f3bd023..a2683721c3 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptDh.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptDh.c
@@ -12,13 +12,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <mbedtls/dhm.h>
 #include <mbedtls/bignum.h>
 
-static const unsigned char mffehde2048_P[] = MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
-static const unsigned char mffehde3072_P[] = MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
-static const unsigned char mffehde4096_P[] = MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
-static const unsigned char mffehde2048_G[] = MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
-static const unsigned char mffehde3072_G[] = MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
-static const unsigned char mffehde4096_G[] = MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
-
 /**
   Allocates and Initializes one Diffie-Hellman Context for subsequent use.
 
@@ -44,72 +37,6 @@ DhNew (
   return ctx;
 }
 
-/**
-  Allocates and Initializes one Diffie-Hellman Context for subsequent use
-  with the NID.
-
-  @param Nid cipher NID
-
-  @return  Pointer to the Diffie-Hellman Context that has been initialized.
-           If the allocations fails, DhNew() returns NULL.
-
-**/
-VOID *
-EFIAPI
-DhNewByNid (
-  IN UINTN  Nid
-  )
-{
-  mbedtls_dhm_context *ctx;
-  INT32               Ret;
-
-  ctx = AllocateZeroPool (sizeof(mbedtls_dhm_context));
-  if (ctx == NULL) {
-    return NULL;
-  }
-
-  mbedtls_dhm_init (ctx);
-
-  switch (Nid) {
-  case CRYPTO_NID_FFDHE2048:
-    Ret = mbedtls_mpi_read_binary (&ctx->P, mffehde2048_P, sizeof(mffehde2048_P));
-    if (Ret != 0) {
-      goto Error;
-    }
-    Ret = mbedtls_mpi_read_binary (&ctx->G, mffehde2048_G, sizeof(mffehde2048_G));
-    if (Ret != 0) {
-      goto Error;
-    }
-    break;
-  case CRYPTO_NID_FFDHE3072:
-    Ret = mbedtls_mpi_read_binary (&ctx->P, mffehde3072_P, sizeof(mffehde3072_P));
-    if (Ret != 0) {
-      goto Error;
-    }
-    Ret = mbedtls_mpi_read_binary (&ctx->G, mffehde3072_G, sizeof(mffehde3072_G));
-    if (Ret != 0) {
-      goto Error;
-    }
-    break;
-  case CRYPTO_NID_FFDHE4096:
-    Ret = mbedtls_mpi_read_binary (&ctx->P, mffehde4096_P, sizeof(mffehde4096_P));
-    if (Ret != 0) {
-      goto Error;
-    }
-    Ret = mbedtls_mpi_read_binary (&ctx->G, mffehde4096_G, sizeof(mffehde4096_G));
-    if (Ret != 0) {
-      goto Error;
-    }
-    break;
-  default:
-    goto Error;
-  }
-  return ctx;
-Error:
-  FreePool (ctx);
-  return NULL;
-}
-
 /**
   Release the specified DH context.
 
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 3/7] Make all BaseCryptLibMbedTls inf files consistent with BaseCryptLib
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 1/7] Update ReadmeMbedtls Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 2/7] Clear unnecessary API in DH Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 4/7] Update Pkcs7 api based on MbedTlsLib for CryptoPkg Wenxing Hou
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf    | 8 ++++++++
 CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf | 2 +-
 CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf     | 4 ++--
 .../Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf      | 4 +++-
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
index 582b6a074f..98b4f5ae2e 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
@@ -32,6 +32,7 @@
   Cipher/CryptAes.c
   Hash/CryptSha256.c
   Hash/CryptSha512.c
+  Hash/CryptParallelHashNull.c
   Hash/CryptSha3.c
   Hash/CryptSm3.c
   Hash/CryptMd5.c
@@ -46,7 +47,14 @@
   Pk/CryptRsaExt.c
   Pk/CryptPkcs1Oaep.c
   Pk/CryptPkcs5Pbkdf2.c
+  Pk/CryptPkcs7Sign.c
+  Pk/CryptPkcs7VerifyCommon.c
+  Pk/CryptPkcs7VerifyBase.c
+  Pk/CryptPkcs7VerifyEku.c
+  Pk/CryptDh.c
   Pk/CryptX509.c
+  Pk/CryptAuthenticode.c
+  Pk/CryptTs.c
   Rand/CryptRand.c
   SysCall/BaseMemAllocation.c
   SysCall/CrtWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
index d7c7100ff3..83862cf6bd 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
@@ -42,7 +42,7 @@
   Hash/CryptSm3.c
   Hash/CryptSha512.c
   Hash/CryptParallelHashNull.c
-  # Hmac/CryptHmac.c
+  Hmac/CryptHmac.c
   Kdf/CryptHkdf.c
   Cipher/CryptAes.c
   Cipher/CryptAeadAesGcmNull.c
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
index 92e89ad0a7..68824f4a2b 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
@@ -41,9 +41,9 @@
   Hash/CryptSha3.c
   Hash/CryptXkcp.c
   # Hash/CryptCShake256.c
-  # Hash/CryptParallelHash.c
+  Hash/CryptParallelHashNull.c
   # Hash/CryptDispatchApMm.c
-  # Hmac/CryptHmac.c
+  Hmac/CryptHmac.c
   Kdf/CryptHkdf.c
   Cipher/CryptAes.c
   Cipher/CryptAeadAesGcmNull.c
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf
index fd71eb5e18..cf86e0ef68 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/TestBaseCryptLib.inf
@@ -46,11 +46,13 @@
   Pk/CryptRsaExt.c
   Pk/CryptPkcs1Oaep.c
   Pk/CryptPkcs5Pbkdf2.c
+  Pk/CryptPkcs7VerifyBase.c
+  Pk/CryptPkcs7Sign.c
+  Pk/CryptPkcs7VerifyCommon.c
   Pk/CryptX509.c
   Rand/CryptRand.c
   SysCall/BaseMemAllocation.c
   SysCall/CrtWrapper.c
-  SysCall/TimerWrapper.c
 
 [Packages]
   MdePkg/MdePkg.dec
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 4/7] Update Pkcs7 api based on MbedTlsLib for CryptoPkg
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
                   ` (2 preceding siblings ...)
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 3/7] Make all BaseCryptLibMbedTls inf files consistent with BaseCryptLib Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 5/7] Update EC " Wenxing Hou
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../BaseCryptLibMbedTls/InternalCryptLib.h    |  32 ++
 .../BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c   |   5 +-
 .../Pk/CryptPkcs7VerifyBase.c                 |  40 +-
 .../Pk/CryptPkcs7VerifyCommon.c               | 338 ++++++++++++-
 .../Pk/CryptPkcs7VerifyEku.c                  | 454 ++----------------
 CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf   |   1 +
 6 files changed, 424 insertions(+), 446 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
index 674242cfeb..6871785575 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
@@ -24,4 +24,36 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 int myrand( void *rng_state, unsigned char *output, size_t len );
 
+/**
+  Check input P7Data is a wrapped ContentInfo structure or not. If not construct
+  a new structure to wrap P7Data.
+
+  Caution: This function may receive untrusted input.
+  UEFI Authenticated Variable is external input, so this function will do basic
+  check for PKCS#7 data structure.
+
+  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
+  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
+  @param[out] WrapFlag     If TRUE P7Data is a ContentInfo structure, otherwise
+                           return FALSE.
+  @param[out] WrapData     If return status of this function is TRUE:
+                           1) when WrapFlag is TRUE, pointer to P7Data.
+                           2) when WrapFlag is FALSE, pointer to a new ContentInfo
+                           structure. It's caller's responsibility to free this
+                           buffer.
+  @param[out] WrapDataSize Length of ContentInfo structure in bytes.
+
+  @retval     TRUE         The operation is finished successfully.
+  @retval     FALSE        The operation is failed due to lack of resources.
+
+**/
+BOOLEAN
+WrapPkcs7Data (
+  IN  CONST UINT8  *P7Data,
+  IN  UINTN        P7Length,
+  OUT BOOLEAN      *WrapFlag,
+  OUT UINT8        **WrapData,
+  OUT UINTN        *WrapDataSize
+  );
+
 #endif
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
index 0c7a1d009f..21d06264d5 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
@@ -388,7 +388,8 @@ Pkcs7Sign (
   mbedtls_pk_init (&Pkey);
   Ret = mbedtls_pk_parse_key (
     &Pkey, NewPrivateKey, PrivateKeySize,
-    KeyPassword, KeyPassword == NULL ? 0 : AsciiStrLen (KeyPassword)
+    KeyPassword, KeyPassword == NULL ? 0 : AsciiStrLen (KeyPassword),
+    NULL, NULL
   );
   if (Ret != 0) {
     Status = FALSE;
@@ -406,7 +407,7 @@ Pkcs7Sign (
   ZeroMem (Signature, MAX_SIGNATURE_SIZE);
   Ret = mbedtls_pk_sign (
     &Pkey, MBEDTLS_MD_SHA256, HashValue, SHA256_DIGEST_SIZE,
-    Signature, &SignatureLen, myrand, NULL);
+    Signature, MAX_SIGNATURE_SIZE, &SignatureLen, myrand, NULL);
   if (Ret != 0) {
     Status = FALSE;
     goto Cleanup;
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c
index 01fcba5513..4daea4982f 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c
@@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
 #include "InternalCryptLib.h"
+#include <mbedtls/pkcs7.h>
 
 /**
   Extracts the attached content from a PKCS#7 signed data if existed. The input signed
@@ -38,12 +39,13 @@ Pkcs7GetAttachedContent (
   )
 {
   BOOLEAN            Status;
-  PKCS7              *Pkcs7;
   UINT8              *SignedData;
   UINTN              SignedDataSize;
   BOOLEAN            Wrapped;
-  CONST UINT8        *Temp;
-  ASN1_OCTET_STRING  *OctStr;
+  INTN               Ret;
+  mbedtls_pkcs7      Pkcs7;
+
+  mbedtls_pkcs7_init(&Pkcs7);
 
   //
   // Check input parameter.
@@ -53,9 +55,7 @@ Pkcs7GetAttachedContent (
   }
 
   *Content   = NULL;
-  Pkcs7      = NULL;
   SignedData = NULL;
-  OctStr     = NULL;
 
   Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
   if (!Status || (SignedDataSize > INT_MAX)) {
@@ -64,26 +64,23 @@ Pkcs7GetAttachedContent (
 
   Status = FALSE;
 
-  //
-  // Decoding PKCS#7 SignedData
-  //
-  Temp  = SignedData;
-  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
-  if (Pkcs7 == NULL) {
-    goto _Exit;
-  }
+  Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
 
   //
   // The type of Pkcs7 must be signedData
   //
-  if (!PKCS7_type_is_signed (Pkcs7)) {
+  if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
     goto _Exit;
   }
 
   //
   // Check for detached or attached content
   //
-  if (PKCS7_get_detached (Pkcs7)) {
+
+  mbedtls_pkcs7_data *MbedtlsContent;
+  MbedtlsContent = &(Pkcs7.signed_data.content);
+
+  if (MbedtlsContent == NULL) {
     //
     // No Content supplied for PKCS7 detached signedData
     //
@@ -93,15 +90,14 @@ Pkcs7GetAttachedContent (
     //
     // Retrieve the attached content in PKCS7 signedData
     //
-    OctStr = Pkcs7->d.sign->contents->d.data;
-    if ((OctStr->length > 0) && (OctStr->data != NULL)) {
-      *ContentSize = OctStr->length;
+    if ((MbedtlsContent->data.len > 0) && (MbedtlsContent->data.p != NULL)) {
+      *ContentSize = MbedtlsContent->data.len;
       *Content     = AllocatePool (*ContentSize);
       if (*Content == NULL) {
         *ContentSize = 0;
         goto _Exit;
       }
-      CopyMem (*Content, OctStr->data, *ContentSize);
+      CopyMem (*Content, MbedtlsContent->data.p, *ContentSize);
     }
   }
   Status = TRUE;
@@ -110,11 +106,7 @@ _Exit:
   //
   // Release Resources
   //
-  PKCS7_free (Pkcs7);
-
-  if (!Wrapped) {
-    OPENSSL_free (SignedData);
-  }
+  mbedtls_pkcs7_free (&Pkcs7);
 
   return Status;
 }
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c
index 5291f2454d..14c9d447e6 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c
@@ -656,7 +656,7 @@ Pkcs7Verify (
 
   Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &WrapData, &WrapDataSize);
 
-  if (Status) {
+  if (!Status) {
     Ret = 0;
     Status = FALSE;
   } else {
@@ -741,5 +741,339 @@ Pkcs7GetSigners (
   OUT UINTN        *CertLength
   )
 {
-return FALSE;
+  BOOLEAN      Status;
+  UINT8        *SignedData;
+  UINTN        SignedDataSize;
+  BOOLEAN      Wrapped;
+  INTN               Ret;
+  mbedtls_pkcs7      Pkcs7;
+  mbedtls_x509_crt   *Cert;
+  UINT8  Index;
+  UINT8  *CertBuf;
+  UINT8  *OldBuf;
+  UINTN  BufferSize;
+  UINTN  OldSize;
+  UINT8  *SingleCert;
+  UINTN  SingleCertSize;
+
+
+  mbedtls_pkcs7_init(&Pkcs7);
+
+  //
+  // Check input parameter.
+  //
+  if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||
+      (TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX))
+  {
+    return FALSE;
+  }
+
+  SignedData = NULL;
+
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
+  if (!Status || (SignedDataSize > INT_MAX)) {
+    goto _Exit;
+  }
+
+  Status = FALSE;
+
+  //
+  // Retrieve PKCS#7 Data (DER encoding)
+  //
+  if (SignedDataSize > INT_MAX) {
+    goto _Exit;
+  }
+
+  Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
+
+  //
+  // The type of Pkcs7 must be signedData
+  //
+  if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
+    goto _Exit;
+  }
+
+
+  Cert      = NULL;
+  CertBuf    = NULL;
+  OldBuf     = NULL;
+  SingleCert = NULL;
+
+
+  Cert = &Pkcs7.signed_data.certs;
+  if (Cert == NULL) {
+    goto _Exit;
+  }
+
+  //
+  // Convert CertStack to buffer in following format:
+  // UINT8  CertNumber;
+  // UINT32 Cert1Length;
+  // UINT8  Cert1[];
+  // UINT32 Cert2Length;
+  // UINT8  Cert2[];
+  // ...
+  // UINT32 CertnLength;
+  // UINT8  Certn[];
+  //
+  BufferSize = sizeof (UINT8);
+  OldSize    = BufferSize;
+
+  for (Index = 0; ; Index++) {
+
+    SingleCertSize = Cert->raw.len;
+
+    OldSize    = BufferSize;
+    OldBuf     = CertBuf;
+    BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
+    CertBuf    = AllocateZeroPool (BufferSize);
+
+    if (CertBuf == NULL) {
+      goto _Exit;
+    }
+
+    if (OldBuf != NULL) {
+      CopyMem (CertBuf, OldBuf, OldSize);
+      FreePool (OldBuf);
+      OldBuf = NULL;
+    }
+
+    WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSize);
+    CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);
+
+    FreePool (SingleCert);
+    SingleCert = NULL;
+
+    if (Cert->next == NULL) {
+      break;
+    }
+  }
+
+  if (CertBuf != NULL) {
+    //
+    // Update CertNumber.
+    //
+    CertBuf[0] = Index;
+
+    *CertLength  = BufferSize - OldSize - sizeof (UINT32);
+    *TrustedCert = AllocateZeroPool (*CertLength);
+    if (*TrustedCert == NULL) {
+      goto _Exit;
+    }
+
+    CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);
+    *CertStack   = CertBuf;
+    *StackLength = BufferSize;
+    Status       = TRUE;
+  }
+
+_Exit:
+  //
+  // Release Resources
+  //
+  if (!Wrapped) {
+    FreePool (SignedData);
+  }
+
+  mbedtls_pkcs7_free (&Pkcs7);
+
+  if (SingleCert !=  NULL) {
+    FreePool (SingleCert);
+  }
+
+  if (!Status && (CertBuf != NULL)) {
+    FreePool (CertBuf);
+    *CertStack = NULL;
+  }
+
+  if (OldBuf != NULL) {
+    FreePool (OldBuf);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieves all embedded certificates from PKCS#7 signed data as described in "PKCS #7:
+  Cryptographic Message Syntax Standard", and outputs two certificate lists chained and
+  unchained to the signer's certificates.
+  The input signed data could be wrapped in a ContentInfo structure.
+
+  @param[in]  P7Data            Pointer to the PKCS#7 message.
+  @param[in]  P7Length          Length of the PKCS#7 message in bytes.
+  @param[out] SignerChainCerts  Pointer to the certificates list chained to signer's
+                                certificate. It's caller's responsibility to free the buffer
+                                with Pkcs7FreeSigners().
+                                This data structure is EFI_CERT_STACK type.
+  @param[out] ChainLength       Length of the chained certificates list buffer in bytes.
+  @param[out] UnchainCerts      Pointer to the unchained certificates lists. It's caller's
+                                responsibility to free the buffer with Pkcs7FreeSigners().
+                                This data structure is EFI_CERT_STACK type.
+  @param[out] UnchainLength     Length of the unchained certificates list buffer in bytes.
+
+  @retval  TRUE         The operation is finished successfully.
+  @retval  FALSE        Error occurs during the operation.
+
+**/
+BOOLEAN
+EFIAPI
+Pkcs7GetCertificatesList (
+  IN  CONST UINT8  *P7Data,
+  IN  UINTN        P7Length,
+  OUT UINT8        **SignerChainCerts,
+  OUT UINTN        *ChainLength,
+  OUT UINT8        **UnchainCerts,
+  OUT UINTN        *UnchainLength
+  )
+{
+  BOOLEAN      Status;
+  UINT8        *SignedData;
+  UINTN        SignedDataSize;
+  BOOLEAN      Wrapped;
+  INTN               Ret;
+  mbedtls_pkcs7      Pkcs7;
+  mbedtls_x509_crt   *Cert;
+  UINT8  Index;
+  UINT8  *CertBuf;
+  UINT8  *OldBuf;
+  UINTN  BufferSize;
+  UINTN  OldSize;
+  UINT8  *SingleCert;
+  UINTN  SingleCertSize;
+
+
+  mbedtls_pkcs7_init(&Pkcs7);
+
+  //
+  // Check input parameter.
+  //
+  if ((P7Data == NULL) || (SignerChainCerts == NULL) || (ChainLength == NULL) ||
+      (UnchainCerts == NULL) || (UnchainLength == NULL) || (P7Length > INT_MAX))
+  {
+    return FALSE;
+  }
+
+  SignedData = NULL;
+
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
+  if (!Status || (SignedDataSize > INT_MAX)) {
+    goto _Exit;
+  }
+
+  Status = FALSE;
+
+  //
+  // Retrieve PKCS#7 Data (DER encoding)
+  //
+  if (SignedDataSize > INT_MAX) {
+    goto _Exit;
+  }
+
+  Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
+
+  //
+  // The type of Pkcs7 must be signedData
+  //
+  if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
+    goto _Exit;
+  }
+
+
+  Cert      = NULL;
+  CertBuf    = NULL;
+  OldBuf     = NULL;
+  SingleCert = NULL;
+
+
+  Cert = &Pkcs7.signed_data.certs;
+  if (Cert == NULL) {
+    goto _Exit;
+  }
+
+  //
+  // Converts Chained and Untrusted Certificate to Certificate Buffer in following format:
+  //      UINT8  CertNumber;
+  //      UINT32 Cert1Length;
+  //      UINT8  Cert1[];
+  //      UINT32 Cert2Length;
+  //      UINT8  Cert2[];
+  //      ...
+  //      UINT32 CertnLength;
+  //      UINT8  Certn[];
+  //
+  BufferSize = sizeof (UINT8);
+  OldSize    = BufferSize;
+
+  for (Index = 0; ; Index++) {
+
+    SingleCertSize = Cert->raw.len;
+
+    OldSize    = BufferSize;
+    OldBuf     = CertBuf;
+    BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
+    CertBuf    = AllocateZeroPool (BufferSize);
+
+    if (CertBuf == NULL) {
+      goto _Exit;
+    }
+
+    if (OldBuf != NULL) {
+      CopyMem (CertBuf, OldBuf, OldSize);
+      FreePool (OldBuf);
+      OldBuf = NULL;
+    }
+
+    WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSize);
+    CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);
+
+    FreePool (SingleCert);
+    SingleCert = NULL;
+
+    if (Cert->next == NULL) {
+      break;
+    }
+  }
+
+  if (CertBuf != NULL) {
+    //
+    // Update CertNumber.
+    //
+    CertBuf[0] = Index;
+
+    *UnchainLength  = BufferSize - OldSize - sizeof (UINT32);
+    *UnchainCerts = AllocateZeroPool (*UnchainLength);
+    if (*UnchainCerts == NULL) {
+      goto _Exit;
+    }
+
+    CopyMem (*UnchainCerts, CertBuf + OldSize + sizeof (UINT32), *UnchainLength);
+    *SignerChainCerts   = CertBuf;
+    *ChainLength = BufferSize;
+    Status       = TRUE;
+  }
+
+_Exit:
+  //
+  // Release Resources
+  //
+  if (!Wrapped) {
+    FreePool (SignedData);
+  }
+
+  mbedtls_pkcs7_free (&Pkcs7);
+
+  if (SingleCert !=  NULL) {
+    FreePool (SingleCert);
+  }
+
+  if (!Status && (CertBuf != NULL)) {
+    FreePool (CertBuf);
+    *SignerChainCerts = NULL;
+  }
+
+  if (OldBuf != NULL) {
+    FreePool (OldBuf);
+  }
+
+  return Status;
 }
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c
index 1bc4a5db13..484255830a 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c
@@ -11,311 +11,8 @@
 
 #include <Base.h>
 #include "InternalCryptLib.h"
+#include <mbedtls/pkcs7.h>
 
-/**
-  This function will return the leaf signer certificate in a chain.  This is
-  required because certificate chains are not guaranteed to have the
-  certificates in the order that they were issued.
-
-  A typical certificate chain looks like this:
-
-
-                 ----------------------------
-                |            Root            |
-                 ----------------------------
-                               ^
-                               |
-                 ----------------------------
-                |          Policy CA         | <-- Typical Trust Anchor.
-                 ----------------------------
-                               ^
-                               |
-                 ----------------------------
-                |         Issuing CA         |
-                 ----------------------------
-                               ^
-                               |
-                 -----------------------------
-                /  End-Entity (leaf) signer  / <-- Bottom certificate.
-                -----------------------------  EKU: "1.3.6.1.4.1.311.76.9.21.1"
-                                                    (Firmware Signing)
-
-
-  @param[in]   CertChain            Certificate chain.
-
-  @param[out]  SignerCert           Last certificate in the chain.  For PKCS7 signatures,
-                                    this will be the end-entity (leaf) signer cert.
-
-  @retval EFI_SUCCESS               The required EKUs were found in the signature.
-  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
-  @retval EFI_NOT_FOUND             The number of signers found was not 1.
-
-**/
-EFI_STATUS
-GetSignerCertificate (
-  IN CONST PKCS7 *CertChain,
-  OUT X509       **SignerCert
-  )
-{
-  EFI_STATUS      Status;
-  STACK_OF(X509)  *Signers;
-  INT32           NumberSigners;
-
-  Status         = EFI_SUCCESS;
-  Signers        = NULL;
-  NumberSigners  = 0;
-
-  if (CertChain == NULL || SignerCert == NULL) {
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
-
-  //
-  // Get the signers from the chain.
-  //
-  Signers = PKCS7_get0_signers ((PKCS7*) CertChain, NULL, PKCS7_BINARY);
-  if (Signers == NULL) {
-    //
-    // Fail to get signers form PKCS7
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
-
-  //
-  // There should only be one signer in the PKCS7 stack.
-  //
-  NumberSigners = sk_X509_num (Signers);
-  if (NumberSigners != 1) {
-    //
-    // The number of singers should have been 1
-    //
-    Status = EFI_NOT_FOUND;
-    goto Exit;
-  }
-
-  *SignerCert = sk_X509_value (Signers, 0);
-
-Exit:
-  //
-  // Release Resources
-  //
-  if (Signers != NULL) {
-    sk_X509_free (Signers);
-  }
-
-  return Status;
-}
-
-
-/**
-  Determines if the specified EKU represented in ASN1 form is present
-  in a given certificate.
-
-  @param[in]  Cert                  The certificate to check.
-
-  @param[in]  Asn1ToFind            The EKU to look for.
-
-  @retval EFI_SUCCESS               We successfully identified the signing type.
-  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
-  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.
-
-**/
-EFI_STATUS
-IsEkuInCertificate (
-  IN CONST X509  *Cert,
-  IN ASN1_OBJECT *Asn1ToFind
-  )
-{
-  EFI_STATUS          Status;
-  X509                *ClonedCert;
-  X509_EXTENSION      *Extension;
-  EXTENDED_KEY_USAGE  *Eku;
-  INT32               ExtensionIndex;
-  INTN                NumExtensions;
-  ASN1_OBJECT         *Asn1InCert;
-  INTN                Index;
-
-  Status            = EFI_NOT_FOUND;
-  ClonedCert        = NULL;
-  Extension         = NULL;
-  Eku               = NULL;
-  ExtensionIndex    = -1;
-  NumExtensions     = 0;
-  Asn1InCert        = NULL;
-
-  if (Cert == NULL || Asn1ToFind == NULL) {
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
-
-  //
-  // Clone the certificate.  This is required because the Extension API's
-  // only work once per instance of an X509 object.
-  //
-  ClonedCert = X509_dup ((X509*)Cert);
-  if (ClonedCert == NULL) {
-    //
-    // Fail to duplicate cert.
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
-
-  //
-  // Look for the extended key usage.
-  //
-  ExtensionIndex = X509_get_ext_by_NID (ClonedCert, NID_ext_key_usage, -1);
-
-  if (ExtensionIndex < 0) {
-    //
-    // Fail to find 'NID_ext_key_usage' in Cert.
-    //
-    goto Exit;
-  }
-
-  Extension = X509_get_ext (ClonedCert, ExtensionIndex);
-  if (Extension == NULL) {
-    //
-    // Fail to get Extension form cert.
-    //
-    goto Exit;
-  }
-
-  Eku = (EXTENDED_KEY_USAGE*)X509V3_EXT_d2i (Extension);
-  if (Eku == NULL) {
-    //
-    // Fail to get Eku from extension.
-    //
-    goto Exit;
-  }
-
-  NumExtensions = sk_ASN1_OBJECT_num (Eku);
-
-  //
-  // Now loop through the extensions, looking for the specified Eku.
-  //
-  for (Index = 0; Index < NumExtensions; Index++) {
-    Asn1InCert = sk_ASN1_OBJECT_value (Eku, (INT32)Index);
-    if (Asn1InCert == NULL) {
-      //
-      // Fail to get ASN object from Eku.
-      //
-      goto Exit;
-    }
-
-    if (Asn1InCert->length == Asn1ToFind->length &&
-        CompareMem (Asn1InCert->data, Asn1ToFind->data, Asn1InCert->length) == 0) {
-      //
-      // Found Eku in certificate.
-      //
-      Status = EFI_SUCCESS;
-      goto Exit;
-    }
-  }
-
-Exit:
-
-  //
-  // Release Resources
-  //
-  if (ClonedCert != NULL) {
-    X509_free (ClonedCert);
-  }
-
-  if (Eku != NULL) {
-    sk_ASN1_OBJECT_pop_free (Eku, ASN1_OBJECT_free);
-  }
-
-  return Status;
-}
-
-
-/**
-  Determines if the specified EKUs are present in a signing certificate.
-
-  @param[in]  SignerCert            The certificate to check.
-  @param[in]  RequiredEKUs          The EKUs to look for.
-  @param[in]  RequiredEKUsSize      The number of EKUs
-  @param[in]  RequireAllPresent     If TRUE, then all the specified EKUs
-                                    must be present in the certificate.
-
-  @retval EFI_SUCCESS               We successfully identified the signing type.
-  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
-  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.
-**/
-EFI_STATUS
-CheckEKUs(
-  IN CONST X509     *SignerCert,
-  IN CONST CHAR8    *RequiredEKUs[],
-  IN CONST UINT32   RequiredEKUsSize,
-  IN BOOLEAN        RequireAllPresent
-  )
-{
-  EFI_STATUS    Status;
-  ASN1_OBJECT   *Asn1ToFind;
-  UINT32        NumEkusFound;
-  UINT32        Index;
-
-  Status       = EFI_SUCCESS;
-  Asn1ToFind   = NULL;
-  NumEkusFound = 0;
-
-  if (SignerCert == NULL || RequiredEKUs == NULL || RequiredEKUsSize == 0) {
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
-
-  for (Index = 0; Index < RequiredEKUsSize; Index++) {
-    //
-    // Finding required EKU in cert.
-    //
-    if (Asn1ToFind != NULL) {
-      ASN1_OBJECT_free(Asn1ToFind);
-      Asn1ToFind = NULL;
-    }
-
-    Asn1ToFind = OBJ_txt2obj (RequiredEKUs[Index], 0);
-    if (Asn1ToFind == NULL) {
-      //
-      // Fail to convert required EKU to ASN1.
-      //
-      Status = EFI_INVALID_PARAMETER;
-      goto Exit;
-    }
-
-    Status = IsEkuInCertificate (SignerCert, Asn1ToFind);
-    if (Status == EFI_SUCCESS) {
-      NumEkusFound++;
-      if (!RequireAllPresent) {
-        //
-        // Found at least one, so we are done.
-        //
-        goto Exit;
-      }
-    } else {
-      //
-      // Fail to find Eku in cert
-      break;
-    }
-  }
-
-Exit:
-
-  if (Asn1ToFind != NULL) {
-    ASN1_OBJECT_free(Asn1ToFind);
-  }
-
-  if (RequireAllPresent &&
-      NumEkusFound == RequiredEKUsSize) {
-    //
-    // Found all required EKUs in certificate.
-    //
-    Status = EFI_SUCCESS;
-  }
-
-  return Status;
-}
 
 /**
   This function receives a PKCS#7 formatted signature blob,
@@ -357,135 +54,62 @@ VerifyEKUsInPkcs7Signature (
   IN BOOLEAN        RequireAllPresent
   )
 {
-  EFI_STATUS        Status;
-  PKCS7             *Pkcs7;
-  STACK_OF(X509)    *CertChain;
-  INT32             SignatureType;
-  INT32             NumberCertsInSignature;
-  X509              *SignerCert;
-  UINT8             *SignedData;
-  UINT8             *Temp;
-  UINTN             SignedDataSize;
-  BOOLEAN           IsWrapped;
-  BOOLEAN           Ok;
+  BOOLEAN      Status;
+  UINT8        *SignedData;
+  UINTN        SignedDataSize;
+  BOOLEAN      Wrapped;
+  INTN               Ret;
+  mbedtls_pkcs7      Pkcs7;
+  mbedtls_x509_crt   *Cert;
+  UINT8  *SingleCert;
 
-  Status                    = EFI_SUCCESS;
-  Pkcs7                     = NULL;
-  CertChain                 = NULL;
-  SignatureType             = 0;
-  NumberCertsInSignature    = 0;
-  SignerCert                = NULL;
-  SignedData                = NULL;
-  SignedDataSize            = 0;
-  IsWrapped                 = FALSE;
-  Ok                        = FALSE;
+  mbedtls_pkcs7_init(&Pkcs7);
 
   //
-  //Validate the input parameters.
+  // Check input parameter.
   //
-  if (Pkcs7Signature   == NULL ||
-      SignatureSize    == 0    ||
-      RequiredEKUs     == NULL ||
-      RequiredEKUsSize == 0) {
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
+  if ((RequiredEKUs == NULL) || (Pkcs7Signature == NULL))
+  {
+    return FALSE;
   }
 
-  if (RequiredEKUsSize == 1) {
-    RequireAllPresent = TRUE;
-  }
+  SignedData = NULL;
 
-  //
-  // Wrap the PKCS7 data if needed.
-  //
-  Ok = WrapPkcs7Data (Pkcs7Signature,
-                      SignatureSize,
-                      &IsWrapped,
-                      &SignedData,
-                      &SignedDataSize);
-  if (!Ok) {
-    //
-    // Fail to Wrap the PKCS7 data.
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
+  Status = WrapPkcs7Data (Pkcs7Signature, SignatureSize, &Wrapped, &SignedData, &SignedDataSize);
+  if (!Status || (SignedDataSize > INT_MAX)) {
+    goto _Exit;
   }
 
-  Temp = SignedData;
+  Status = FALSE;
 
   //
-  // Create the PKCS7 object.
+  // Retrieve PKCS#7 Data (DER encoding)
   //
-  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (INT32)SignedDataSize);
-  if (Pkcs7 == NULL) {
-    //
-    // Fail to read PKCS7 data.
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
+  if (SignedDataSize > INT_MAX) {
+    goto _Exit;
   }
 
-  //
-  // Get the certificate chain.
-  //
-  SignatureType = OBJ_obj2nid (Pkcs7->type);
-  switch (SignatureType) {
-  case NID_pkcs7_signed:
-    if (Pkcs7->d.sign != NULL) {
-      CertChain = Pkcs7->d.sign->cert;
-    }
-    break;
-  case NID_pkcs7_signedAndEnveloped:
-    if (Pkcs7->d.signed_and_enveloped != NULL) {
-      CertChain = Pkcs7->d.signed_and_enveloped->cert;
-    }
-    break;
-  default:
-    break;
-  }
+  Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
 
   //
-  // Ensure we have a certificate stack
+  // The type of Pkcs7 must be signedData
   //
-  if (CertChain == NULL) {
-    //
-    // Fail to get the certificate stack from signature.
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
+  if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
+    goto _Exit;
   }
 
-  //
-  // Find out how many certificates were in the PKCS7 signature.
-  //
-  NumberCertsInSignature = sk_X509_num (CertChain);
 
-  if (NumberCertsInSignature == 0) {
-    //
-    // Fail to find any certificates in signature.
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
+  Cert      = NULL;
+  SingleCert = NULL;
 
-  //
-  // Get the leaf signer.
-  //
-  Status = GetSignerCertificate (Pkcs7, &SignerCert);
-  if (Status != EFI_SUCCESS || SignerCert == NULL) {
-    //
-    // Fail to get the end-entity leaf signer certificate.
-    //
-    Status = EFI_INVALID_PARAMETER;
-    goto Exit;
-  }
 
-  Status = CheckEKUs (SignerCert, RequiredEKUs, RequiredEKUsSize, RequireAllPresent);
-  if (Status != EFI_SUCCESS) {
-    goto Exit;
+  Cert = &Pkcs7.signed_data.certs;
+  if (Cert == NULL) {
+    goto _Exit;
   }
 
-Exit:
+
+_Exit:
 
   //
   // Release Resources
@@ -493,17 +117,11 @@ Exit:
   // If the signature was not wrapped, then the call to WrapData() will allocate
   // the data and add a header to it
   //
-  if (!IsWrapped && SignedData) {
-    free (SignedData);
+  if (!Wrapped && SignedData) {
+    FreePool (SignedData);
   }
 
-  if (SignerCert != NULL) {
-    X509_free (SignerCert);
-  }
-
-  if (Pkcs7 != NULL) {
-    PKCS7_free (Pkcs7);
-  }
+  mbedtls_pkcs7_free (&Pkcs7);
 
   return Status;
 }
diff --git a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
index b735fef49e..69d712b9c6 100644
--- a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
+++ b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
@@ -108,6 +108,7 @@
   mbedtls/library/x509_crl.c
   mbedtls/library/x509_crt.c
   mbedtls/library/x509_csr.c
+  mbedtls/library/pkcs7.c
 
 [Packages]
   MdePkg/MdePkg.dec
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 5/7] Update EC api based on MbedTlsLib for CryptoPkg
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
                   ` (3 preceding siblings ...)
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 4/7] Update Pkcs7 api based on MbedTlsLib for CryptoPkg Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 6/7] Update X509 " Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 7/7] Clean SysCall api by adding platform_util.c Wenxing Hou
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../Library/BaseCryptLibMbedTls/Pk/CryptEc.c  | 634 +++++++++++++++++-
 1 file changed, 621 insertions(+), 13 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c
index 88684c9fa2..36bc294c20 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c
@@ -15,6 +15,532 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <mbedtls/ecdsa.h>
 #include <mbedtls/bignum.h>
 
+// =====================================================================================
+//    Basic Elliptic Curve Primitives
+// =====================================================================================
+
+/**
+  Return the Nid of certain ECC curve.
+
+  @param[in]  CryptoNid   Identifying number for the ECC curve (Defined in
+                          BaseCryptLib.h).
+
+  @retval !=-1    On success.
+  @retval -1      ECC curve not supported.
+**/
+STATIC
+INT32
+CryptoNidToMbedtlsNid (
+  IN UINTN  CryptoNid
+  )
+{
+  INT32  Nid;
+
+  switch (CryptoNid) {
+    case CRYPTO_NID_SECP256R1:
+      Nid = MBEDTLS_ECP_DP_SECP256R1;
+      break;
+    case CRYPTO_NID_SECP384R1:
+      Nid = MBEDTLS_ECP_DP_SECP384R1;
+      break;
+    case CRYPTO_NID_SECP521R1:
+      Nid = MBEDTLS_ECP_DP_SECP521R1;
+      break;
+    default:
+      return -1;
+  }
+
+  return Nid;
+}
+
+/**
+  Initialize new opaque EcGroup object. This object represents an EC curve and
+  and is used for calculation within this group. This object should be freed
+  using EcGroupFree() function.
+
+  @param[in]  CryptoNid   Identifying number for the ECC curve (Defined in
+                          BaseCryptLib.h).
+
+  @retval EcGroup object  On success.
+  @retval NULL            On failure.
+**/
+VOID *
+EFIAPI
+EcGroupInit (
+  IN UINTN  CryptoNid
+  )
+{
+  INT32  Nid;
+  mbedtls_ecp_group *grp;
+
+  Nid = CryptoNidToMbedtlsNid (CryptoNid);
+
+  if (Nid < 0) {
+    return NULL;
+  }
+
+  grp = AllocateZeroPool (sizeof(mbedtls_ecp_group));
+  if (grp == NULL) {
+    return NULL;
+  }
+
+  mbedtls_ecp_group_init(grp);
+
+  mbedtls_ecp_group_load(grp, Nid);
+
+  return grp;
+}
+
+/**
+  Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P.
+  This function will set the provided Big Number objects  to the corresponding
+  values. The caller needs to make sure all the "out" BigNumber parameters
+  are properly initialized.
+
+  @param[in]  EcGroup    EC group object.
+  @param[out] BnPrime    Group prime number.
+  @param[out] BnA        A coefficient.
+  @param[out] BnB        B coefficient..
+  @param[in]  BnCtx      BN context.
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcGroupGetCurve (
+  IN CONST VOID  *EcGroup,
+  OUT VOID       *BnPrime,
+  OUT VOID       *BnA,
+  OUT VOID       *BnB,
+  IN VOID        *BnCtx
+  )
+{
+  mbedtls_ecp_group *grp;
+
+  grp = ( mbedtls_ecp_group *)EcGroup;
+
+  if (mbedtls_mpi_copy((mbedtls_mpi *)BnPrime, &grp->P) != 0) {
+    return FALSE;
+  }
+
+  if (BnA != NULL) {
+    if (mbedtls_mpi_copy((mbedtls_mpi *)BnA, &grp->A) != 0) {
+      return FALSE;
+    }
+  }
+
+  if (BnB != NULL) {
+    if (mbedtls_mpi_copy((mbedtls_mpi *)BnB, &grp->B) != 0) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+  Get EC group order.
+  This function will set the provided Big Number object to the corresponding
+  value. The caller needs to make sure that the "out" BigNumber parameter
+  is properly initialized.
+
+  @param[in]  EcGroup   EC group object.
+  @param[out] BnOrder   Group prime number.
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcGroupGetOrder (
+  IN VOID   *EcGroup,
+  OUT VOID  *BnOrder
+  )
+{
+  mbedtls_ecp_group *grp;
+
+  grp = ( mbedtls_ecp_group *)EcGroup;
+
+  if (mbedtls_mpi_copy((mbedtls_mpi *)BnOrder, &grp->N) != 0) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Free previously allocated EC group object using EcGroupInit().
+
+  @param[in]  EcGroup   EC group object to free.
+**/
+VOID
+EFIAPI
+EcGroupFree (
+  IN VOID  *EcGroup
+  )
+{
+  mbedtls_ecp_group_free(EcGroup);
+}
+
+/**
+  Initialize new opaque EC Point object. This object represents an EC point
+  within the given EC group (curve).
+
+  @param[in]  EC Group, properly initialized using EcGroupInit().
+
+  @retval EC Point object  On success.
+  @retval NULL             On failure.
+**/
+VOID *
+EFIAPI
+EcPointInit (
+  IN CONST VOID  *EcGroup
+  )
+{
+  mbedtls_ecp_point *pt;
+
+  pt = AllocateZeroPool (sizeof(mbedtls_ecp_point));
+  if (pt == NULL) {
+    return NULL;
+  }
+
+  mbedtls_ecp_point_init (pt);
+
+  return pt;
+}
+
+/**
+  Free previously allocated EC Point object using EcPointInit().
+
+  @param[in]  EcPoint   EC Point to free.
+  @param[in]  Clear     TRUE iff the memory should be cleared.
+**/
+VOID
+EFIAPI
+EcPointDeInit (
+  IN VOID     *EcPoint,
+  IN BOOLEAN  Clear
+  )
+{
+  mbedtls_ecp_point_free(EcPoint);
+}
+
+/**
+  Get EC point affine (x,y) coordinates.
+  This function will set the provided Big Number objects to the corresponding
+  values. The caller needs to make sure all the "out" BigNumber parameters
+  are properly initialized.
+
+  @param[in]  EcGroup    EC group object.
+  @param[in]  EcPoint    EC point object.
+  @param[out] BnX        X coordinate.
+  @param[out] BnY        Y coordinate.
+  @param[in]  BnCtx      BN context, created with BigNumNewContext().
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointGetAffineCoordinates (
+  IN CONST VOID  *EcGroup,
+  IN CONST VOID  *EcPoint,
+  OUT VOID       *BnX,
+  OUT VOID       *BnY,
+  IN VOID        *BnCtx
+  )
+{
+  mbedtls_ecp_point *pt;
+
+  pt = ( mbedtls_ecp_point *)EcPoint;
+
+  if (mbedtls_mpi_copy((mbedtls_mpi *)BnX, &pt->X) != 0) {
+    return FALSE;
+  }
+
+  if (mbedtls_mpi_copy((mbedtls_mpi *)BnY, &pt->Y) != 0) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Set EC point affine (x,y) coordinates.
+
+  @param[in]  EcGroup    EC group object.
+  @param[in]  EcPoint    EC point object.
+  @param[in]  BnX        X coordinate.
+  @param[in]  BnY        Y coordinate.
+  @param[in]  BnCtx      BN context, created with BigNumNewContext().
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointSetAffineCoordinates (
+  IN CONST VOID  *EcGroup,
+  IN VOID        *EcPoint,
+  IN CONST VOID  *BnX,
+  IN CONST VOID  *BnY,
+  IN VOID        *BnCtx
+  )
+{
+  mbedtls_ecp_point *pt;
+
+  pt = ( mbedtls_ecp_point *)EcPoint;
+
+  if (mbedtls_mpi_copy(&pt->X, (mbedtls_mpi *)BnX) != 0) {
+    return FALSE;
+  }
+
+  if (mbedtls_mpi_copy(&pt->Y, (mbedtls_mpi *)BnY) != 0) {
+    return FALSE;
+  }
+
+  mbedtls_mpi_lset( &pt->Z , 1);
+
+  return TRUE;
+}
+
+/**
+  EC Point addition. EcPointResult = EcPointA + EcPointB.
+
+  @param[in]  EcGroup          EC group object.
+  @param[out] EcPointResult    EC point to hold the result. The point should
+                               be properly initialized.
+  @param[in]  EcPointA         EC Point.
+  @param[in]  EcPointB         EC Point.
+  @param[in]  BnCtx            BN context, created with BigNumNewContext().
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointAdd (
+  IN CONST VOID  *EcGroup,
+  OUT VOID       *EcPointResult,
+  IN CONST VOID  *EcPointA,
+  IN CONST VOID  *EcPointB,
+  IN VOID        *BnCtx
+  )
+{
+  mbedtls_mpi *m;
+  mbedtls_mpi *n;
+
+  m = AllocateZeroPool(sizeof(mbedtls_mpi));
+  n = AllocateZeroPool(sizeof(mbedtls_mpi));
+
+  if(mbedtls_mpi_lset(m, 1) != 0 ) {
+    FreePool(m);
+    FreePool(n);
+     return FALSE;
+  }
+  if(mbedtls_mpi_lset(n, 1) != 0 ) {
+    FreePool(m);
+    FreePool(n);
+   return FALSE;
+  }
+
+  if (mbedtls_ecp_muladd((mbedtls_ecp_group *)EcGroup, (mbedtls_ecp_point *)EcPointResult, (const mbedtls_mpi *)m,
+      (const mbedtls_ecp_point *)EcPointA, (const mbedtls_mpi *)n, (const mbedtls_ecp_point *)EcPointB) != 0) {
+    return FALSE;
+  }
+
+  FreePool(m);
+  FreePool(n);
+
+  return TRUE;
+}
+
+/**
+  Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar.
+
+  @param[in]  EcGroup          EC group object.
+  @param[out] EcPointResult    EC point to hold the result. The point should
+                               be properly initialized.
+  @param[in]  EcPoint          EC Point.
+  @param[in]  BnPScalar        P Scalar.
+  @param[in]  BnCtx            BN context, created with BigNumNewContext().
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointMul (
+  IN CONST VOID  *EcGroup,
+  OUT VOID       *EcPointResult,
+  IN CONST VOID  *EcPoint,
+  IN CONST VOID  *BnPScalar,
+  IN VOID        *BnCtx
+  )
+{
+  return (mbedtls_ecp_mul((mbedtls_ecp_group *)EcGroup, EcPointResult, BnPScalar, EcPoint, myrand, NULL) == 0);
+}
+
+/**
+  Calculate the inverse of the supplied EC point.
+
+  @param[in]     EcGroup   EC group object.
+  @param[in,out] EcPoint   EC point to invert.
+  @param[in]     BnCtx     BN context, created with BigNumNewContext().
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointInvert (
+  IN CONST VOID  *EcGroup,
+  IN OUT VOID    *EcPoint,
+  IN VOID        *BnCtx
+  )
+{
+  mbedtls_ecp_point *pt;
+  mbedtls_ecp_group *grp;
+  mbedtls_mpi InvBnY;
+
+  mbedtls_mpi_init(&InvBnY);
+
+  pt = ( mbedtls_ecp_point *)EcPoint;
+  grp = ( mbedtls_ecp_group *)EcGroup;
+
+  if (mbedtls_mpi_copy(&InvBnY, &pt->Y) != 0) {
+    mbedtls_mpi_free(&InvBnY);
+    return FALSE;
+  }
+
+  mbedtls_mpi P;
+
+  mbedtls_mpi_init(&P);
+
+  if (mbedtls_mpi_copy(&P, &grp->P) != 0) {
+    mbedtls_mpi_free(&P);
+    return FALSE;
+  }
+
+
+  InvBnY.s = 0 - InvBnY.s;
+
+  if (mbedtls_mpi_mod_mpi(&InvBnY, &InvBnY, &P) != 0) {
+    mbedtls_mpi_free(&InvBnY);
+    return FALSE;
+  }
+
+  if (mbedtls_mpi_copy(&pt->Y, &InvBnY) != 0) {
+    mbedtls_mpi_free(&InvBnY);
+    return FALSE;
+  }
+
+  mbedtls_mpi_free(&InvBnY);
+  return TRUE;
+}
+
+/**
+  Check if the supplied point is on EC curve.
+
+  @param[in]  EcGroup   EC group object.
+  @param[in]  EcPoint   EC point to check.
+  @param[in]  BnCtx     BN context, created with BigNumNewContext().
+
+  @retval TRUE          On curve.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointIsOnCurve (
+  IN CONST VOID  *EcGroup,
+  IN CONST VOID  *EcPoint,
+  IN VOID        *BnCtx
+  )
+{
+  return (mbedtls_ecp_check_pubkey(EcGroup, EcPoint) == 0);
+}
+
+/**
+  Check if the supplied point is at infinity.
+
+  @param[in]  EcGroup   EC group object.
+  @param[in]  EcPoint   EC point to check.
+
+  @retval TRUE          At infinity.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointIsAtInfinity (
+  IN CONST VOID  *EcGroup,
+  IN CONST VOID  *EcPoint
+  )
+{
+  mbedtls_ecp_point *pt;
+
+  pt = ( mbedtls_ecp_point *)EcPoint;
+
+  return (mbedtls_ecp_is_zero(pt) == 1);
+}
+
+/**
+  Check if EC points are equal.
+
+  @param[in]  EcGroup   EC group object.
+  @param[in]  EcPointA  EC point A.
+  @param[in]  EcPointB  EC point B.
+  @param[in]  BnCtx     BN context, created with BigNumNewContext().
+
+  @retval TRUE          A == B.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointEqual (
+  IN CONST VOID  *EcGroup,
+  IN CONST VOID  *EcPointA,
+  IN CONST VOID  *EcPointB,
+  IN VOID        *BnCtx
+  )
+{
+  return mbedtls_ecp_point_cmp (EcPointA, EcPointB) == 0;
+}
+
+/**
+  Set EC point compressed coordinates. Points can be described in terms of
+  their compressed coordinates. For a point (x, y), for any given value for x
+  such that the point is on the curve there will only ever be two possible
+  values for y. Therefore, a point can be set using this function where BnX is
+  the x coordinate and YBit is a value 0 or 1 to identify which of the two
+  possible values for y should be used.
+
+  @param[in]  EcGroup    EC group object.
+  @param[in]  EcPoint    EC Point.
+  @param[in]  BnX        X coordinate.
+  @param[in]  YBit       0 or 1 to identify which Y value is used.
+  @param[in]  BnCtx      BN context, created with BigNumNewContext().
+
+  @retval TRUE          On success.
+  @retval FALSE         Otherwise.
+**/
+BOOLEAN
+EFIAPI
+EcPointSetCompressedCoordinates (
+  IN CONST VOID  *EcGroup,
+  IN VOID        *EcPoint,
+  IN CONST VOID  *BnX,
+  IN UINT8       YBit,
+  IN VOID        *BnCtx
+  )
+{
+  return FALSE;
+}
+
+// =====================================================================================
+//    Elliptic Curve Diffie Hellman Primitives
+// =====================================================================================
+
 /**
   Allocates and Initializes one Elliptic Curve Context for subsequent use
   with the NID.
@@ -220,26 +746,108 @@ EcGetPubKey (
 }
 
 /**
-  Validates key components of EC context.
-  NOTE: This function performs integrity checks on all the EC key material, so
-        the EC key structure must contain all the private key data.
-
+  Computes exchanged common key.
+  Given peer's public key (X, Y), this function computes the exchanged common key,
+  based on its own context including value of curve parameter and random secret.
+  X is the first half of PeerPublic with size being PeerPublicSize / 2,
+  Y is the second half of PeerPublic with size being PeerPublicSize / 2.
+  If public key is compressed, the PeerPublic will only contain half key (X).
   If EcContext is NULL, then return FALSE.
-
-  @param[in]  EcContext  Pointer to EC context to check.
-
-  @retval  TRUE   EC key components are valid.
-  @retval  FALSE  EC key components are not valid.
-
+  If PeerPublic is NULL, then return FALSE.
+  If PeerPublicSize is 0, then return FALSE.
+  If Key is NULL, then return FALSE.
+  If KeySize is not large enough, then return FALSE.
+  For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y.
+  For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y.
+  For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y.
+  @param[in, out]  EcContext          Pointer to the EC context.
+  @param[in]       PeerPublic         Pointer to the peer's public X,Y.
+  @param[in]       PeerPublicSize     Size of peer's public X,Y in bytes.
+  @param[in]       CompressFlag       Flag of PeerPublic is compressed or not.
+  @param[out]      Key                Pointer to the buffer to receive generated key.
+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.
+                                      On output, the size of data returned in Key buffer in bytes.
+  @retval TRUE   EC exchanged key generation succeeded.
+  @retval FALSE  EC exchanged key generation failed.
+  @retval FALSE  KeySize is not large enough.
 **/
 BOOLEAN
 EFIAPI
-EcCheckKey (
-  IN  VOID  *EcContext
+EcDhComputeKey (
+  IN OUT  VOID         *EcContext,
+  IN      CONST UINT8  *PeerPublic,
+  IN      UINTN        PeerPublicSize,
+  IN      CONST INT32  *CompressFlag,
+  OUT     UINT8        *Key,
+  IN OUT  UINTN        *KeySize
   )
 {
-  // TBD
+  UINTN           HalfSize;
+  mbedtls_ecdh_context *EcdCtx;
+  INT32             Ret;
+
+  if ((EcContext == NULL) || (PeerPublic == NULL) || (KeySize == NULL)) {
+    return FALSE;
+  }
+
+  if ((Key == NULL) && (*KeySize != 0)) {
+    return FALSE;
+  }
+
+  if (PeerPublicSize > INT_MAX) {
+    return FALSE;
+  }
+
+  EcdCtx = EcContext;
+  switch (EcdCtx->grp.id) {
+  case MBEDTLS_ECP_DP_SECP256R1:
+      HalfSize = 32;
+      break;
+  case MBEDTLS_ECP_DP_SECP384R1:
+      HalfSize = 48;
+      break;
+  case MBEDTLS_ECP_DP_SECP521R1:
+      HalfSize = 66;
+      break;
+  default:
+      return FALSE;
+  }
+  if (PeerPublicSize != HalfSize * 2) {
+      return FALSE;
+  }
+
+  Ret = mbedtls_mpi_read_binary(&EcdCtx->Qp.X, PeerPublic, HalfSize);
+  if (Ret != 0) {
+      return FALSE;
+  }
+  Ret = mbedtls_mpi_read_binary(&EcdCtx->Qp.Y, PeerPublic + HalfSize,
+                                HalfSize);
+  if (Ret != 0) {
+      return FALSE;
+  }
+  Ret = mbedtls_mpi_lset(&EcdCtx->Qp.Z, 1);
+  if (Ret != 0) {
+      return FALSE;
+  }
+
+  Ret = mbedtls_ecdh_compute_shared(&EcdCtx->grp, &EcdCtx->z, &EcdCtx->Qp, &EcdCtx->d,
+                                    myrand, NULL);
+  if (Ret != 0) {
+      return FALSE;
+  }
+
+  if (mbedtls_mpi_size(&EcdCtx->z) > *KeySize) {
+      return FALSE;
+  }
+
+  *KeySize = EcdCtx->grp.pbits / 8 + ((EcdCtx->grp.pbits % 8) != 0);
+  Ret = mbedtls_mpi_write_binary(&EcdCtx->z, Key, *KeySize);
+  if (Ret != 0) {
+      return FALSE;
+  }
+
   return TRUE;
+
 }
 
 /**
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 6/7] Update X509 api based on MbedTlsLib for CryptoPkg
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
                   ` (4 preceding siblings ...)
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 5/7] Update EC " Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 7/7] Clean SysCall api by adding platform_util.c Wenxing Hou
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../BaseCryptLibMbedTls/Pk/CryptX509.c        | 163 +++++++++++++++++-
 1 file changed, 161 insertions(+), 2 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c
index 6e4a898572..957703a3eb 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c
@@ -26,6 +26,9 @@ STATIC CONST UINT8 OID_organizationName[] = {
 STATIC CONST UINT8 OID_extKeyUsage[] = {
   0x55, 0x1D, 0x25
 };
+STATIC CONST UINT8 OID_BasicConstraints[] = {
+  0x55, 0x1D, 0x13
+};
 
 /**
   Construct a X509 object from DER-encoded certificate data.
@@ -857,9 +860,61 @@ X509GetTBSCert (
   OUT UINTN        *TBSCertSize
   )
 {
-  return FALSE;
-}
+  UINTN        Length;
+  UINTN        Ret;
+  UINT8        *Ptr;
+  CONST UINT8        *Temp;
+  CONST UINT8        *End;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (TBSCert == NULL) ||
+      (TBSCertSize == NULL) || (CertSize > INT_MAX))
+  {
+    return FALSE;
+  }
+
+  //
+  // An X.509 Certificate is: (defined in RFC3280)
+  //   Certificate  ::=  SEQUENCE  {
+  //     tbsCertificate       TBSCertificate,
+  //     signatureAlgorithm   AlgorithmIdentifier,
+  //     signature            BIT STRING }
+  //
+  // and
+  //
+  //  TBSCertificate  ::=  SEQUENCE  {
+  //    version         [0]  Version DEFAULT v1,
+  //    ...
+  //    }
+  //
+  // So we can just ASN1-parse the x.509 DER-encoded data. If we strip
+  // the first SEQUENCE, the second SEQUENCE is the TBSCertificate.
+  //
+
+  Length = 0;
+
+  Ptr = (UINT8 *)Cert;
+  End = Cert + CertSize;
+
+  Ret = mbedtls_asn1_get_tag(&Ptr, End, &Length, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+  if (Ret != 0) {
+    return FALSE;
+  }
 
+  Temp = Ptr;
+  End = Ptr + Length;
+  Ret = mbedtls_asn1_get_tag(&Ptr, End, &Length, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+  if (Ret != 0) {
+    return FALSE;
+  }
+
+  *TBSCert = (UINT8 *)Temp;
+  *TBSCertSize = Length + (Ptr - Temp);
+
+  return TRUE;
+}
 
 /**
   Retrieve the version from one X.509 certificate.
@@ -1666,3 +1721,107 @@ X509CompareDateTime (
     return 1;
   }
 }
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints(
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  BOOLEAN  Status;
+
+  if ((Cert == NULL) || (CertSize == 0) || (BasicConstraintsSize == NULL)) {
+    return FALSE;
+  }
+
+  Status = X509GetExtensionData (
+             (UINT8 *)Cert,
+             CertSize,
+             OID_BasicConstraints,
+             sizeof (OID_BasicConstraints),
+             BasicConstraints,
+             BasicConstraintsSize
+             );
+
+  return Status;
+}
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509FormatDateTime (
+  IN  CONST  CHAR8  *DateTimeStr,
+  OUT VOID          *DateTime,
+  IN OUT UINTN      *DateTimeSize
+  )
+{
+  mbedtls_x509_time *tm;
+
+  if (*DateTimeSize < sizeof(mbedtls_x509_time)){
+    return FALSE;
+  }
+
+  if (DateTime == NULL) {
+    return FALSE;
+  }
+
+  tm = (mbedtls_x509_time *)DateTime;
+
+  tm->year = (DateTimeStr[0] + '0') * 1000 + (DateTimeStr[1] + '0') * 100 +
+    (DateTimeStr[2] + '0') * 10 + (DateTimeStr[3] + '0') * 1;
+
+  tm->mon = (DateTimeStr[4] + '0') * 10 + (DateTimeStr[5] + '0') * 1;
+
+  tm->day = (DateTimeStr[6] + '0') * 10 + (DateTimeStr[7] + '0') * 1;
+
+  tm->hour = (DateTimeStr[8] + '0') * 10 + (DateTimeStr[9] + '0') * 1;
+
+  tm->min = (DateTimeStr[10] + '0') * 10 + (DateTimeStr[11] + '0') * 1;
+
+  tm->sec = (DateTimeStr[12] + '0') * 10 + (DateTimeStr[13] + '0') * 1;
+
+  return TRUE;
+}
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [edk2-staging/OpenSSL11_EOL PATCH 7/7] Clean SysCall api by adding platform_util.c
  2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
                   ` (5 preceding siblings ...)
  2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 6/7] Update X509 " Wenxing Hou
@ 2023-03-17  9:00 ` Wenxing Hou
  6 siblings, 0 replies; 8+ messages in thread
From: Wenxing Hou @ 2023-03-17  9:00 UTC (permalink / raw)
  To: devel; +Cc: Wenxing Hou

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../BaseCryptLibMbedTls/Rand/CryptRandTsc.c        |  7 +++++++
 .../SysCall/ConstantTimeClock.c                    | 14 --------------
 .../BaseCryptLibMbedTls/SysCall/CrtWrapper.c       |  5 -----
 .../BaseCryptLibMbedTls/SysCall/TimerWrapper.c     | 14 --------------
 CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf        |  1 +
 5 files changed, 8 insertions(+), 33 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c
index 96d18eb7aa..a4ece17680 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c
@@ -59,3 +59,10 @@ RandomBytes (
 
   return TRUE;
 }
+
+int myrand( void *rng_state, unsigned char *output, size_t len )
+{
+  RandomBytes (output, len);
+
+  return 0;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/ConstantTimeClock.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/ConstantTimeClock.c
index 41a1fdd634..6c1d8a400d 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/ConstantTimeClock.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/ConstantTimeClock.c
@@ -59,17 +59,3 @@ struct tm * gmtime (const time_t *timer)
 time_t _time64 (time_t* t) {
   return time (t);
 }
-
-struct tm *mbedtls_platform_gmtime_r( const time_t *tt,
-                                      struct tm *tm_buf )
-{
-  struct tm * lt;
-
-  lt = gmtime (tt);
-
-  if (lt != NULL) {
-    CopyMem (tm_buf, lt, sizeof(struct tm));
-  }
-
-  return ((lt == NULL) ? NULL : tm_buf);
-}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/CrtWrapper.c
index c401dae861..25074d3bfb 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/CrtWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/CrtWrapper.c
@@ -31,11 +31,6 @@ int mbedtls_vsnprintf(char *str, size_t size, const char *format, ...)
   return 0;
 }
 
-void mbedtls_platform_zeroize( void *buf, unsigned int len )
-{
-    ZeroMem (buf, len);
-}
-
 int rand ()
 {
   // TBD
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/TimerWrapper.c
index abb9a2226c..d940abb7f0 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/TimerWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/TimerWrapper.c
@@ -190,17 +190,3 @@ struct tm * gmtime (const time_t *timer)
 time_t _time64 (time_t* t) {
   return time (t);
 }
-
-struct tm *mbedtls_platform_gmtime_r( const time_t *tt,
-                                      struct tm *tm_buf )
-{
-  struct tm * lt;
-
-  lt = gmtime (tt);
-
-  if (lt != NULL) {
-    CopyMem (tm_buf, lt, sizeof(struct tm));
-  }
-
-  return ((lt == NULL) ? NULL : tm_buf);
-}
diff --git a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
index 69d712b9c6..e2fd9e6e1e 100644
--- a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
+++ b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
@@ -109,6 +109,7 @@
   mbedtls/library/x509_crt.c
   mbedtls/library/x509_csr.c
   mbedtls/library/pkcs7.c
+  mbedtls/library/platform_util.c
 
 [Packages]
   MdePkg/MdePkg.dec
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-03-17  9:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-17  9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 1/7] Update ReadmeMbedtls Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 2/7] Clear unnecessary API in DH Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 3/7] Make all BaseCryptLibMbedTls inf files consistent with BaseCryptLib Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 4/7] Update Pkcs7 api based on MbedTlsLib for CryptoPkg Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 5/7] Update EC " Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 6/7] Update X509 " Wenxing Hou
2023-03-17  9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 7/7] Clean SysCall api by adding platform_util.c Wenxing Hou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox