* [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