* [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
@ 2020-09-15 0:57 Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 1/3] " Zurcher, Christopher J
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Zurcher, Christopher J @ 2020-09-15 0:57 UTC (permalink / raw)
To: devel; +Cc: Laszlo Ersek, Jiewen Yao, Jian J Wang, Xiaoyu Lu
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
V2 changes:
Added NullLib implementation
Added Crypto Service implementation
Rebased Hash2DxeCrypto to use EVP interface instead of low-level functions
Removed unnecessary casts
Added "HashAll" utility function
Merged "New" and "Init" functions as well as "Final" and "Free" functions
Retained "Init/Update/Final" naming instead of "New/Update/Free" as this
conforms with common usage
Low-level interfaces to message digest (hash) functions have been deprecated
in OpenSSL 3. In order to upgrade to OpenSSL 3, all direct calls to
low-level functions (such as SHA256_Init() in CryptSha256.c) will need to
be replaced by EVP inteface calls.
References:
https://www.openssl.org/docs/manmaster/man7/evp.html
https://www.openssl.org/docs/manmaster/man3/SHA256_Init.html
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Christopher J Zurcher (3):
CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
CryptoPkg: Add EVP to Crypto Service driver interface
SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP
interface
CryptoPkg/CryptoPkg.dsc | 3 +
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
CryptoPkg/Include/Library/BaseCryptLib.h | 125 +++++++
CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 +
CryptoPkg/Private/Protocol/Crypto.h | 127 +++++++
SecurityPkg/Hash2DxeCrypto/Driver.h | 1 -
CryptoPkg/Driver/Crypto.c | 148 ++++++++-
CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c | 253 ++++++++++++++
CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c | 124 +++++++
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 140 ++++++++
SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c | 345 ++------------------
15 files changed, 965 insertions(+), 316 deletions(-)
create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c
create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c
--
2.28.0.windows.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
2020-09-15 0:57 [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Zurcher, Christopher J
@ 2020-09-15 0:57 ` Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 2/3] CryptoPkg: Add EVP to Crypto Service driver interface Zurcher, Christopher J
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Zurcher, Christopher J @ 2020-09-15 0:57 UTC (permalink / raw)
To: devel; +Cc: Laszlo Ersek, Jiewen Yao, Jian J Wang, Xiaoyu Lu
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
The EVP interface should be used in place of discrete digest function
calls.
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Signed-off-by: Christopher J Zurcher <christopher.j.zurcher@intel.com>
---
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
CryptoPkg/Include/Library/BaseCryptLib.h | 125 ++++++++++
CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c | 253 ++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c | 124 ++++++++++
8 files changed, 507 insertions(+)
diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 4aae2aba95..3968f29412 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -50,6 +50,7 @@
Pk/CryptAuthenticode.c
Pk/CryptTs.c
Pem/CryptPem.c
+ Evp/CryptEvpMd.c
SysCall/CrtWrapper.c
SysCall/TimerWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index dc28e3a11d..d0b91716d0 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -57,6 +57,7 @@
Pk/CryptTsNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
+ Evp/CryptEvpMd.c
SysCall/CrtWrapper.c
SysCall/ConstantTimeClock.c
diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index 5005beed02..9f3accd35b 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -56,6 +56,7 @@
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Pem/CryptPem.c
+ Evp/CryptEvpMd.c
SysCall/CrtWrapper.c
SysCall/TimerWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index 91ec3e03bf..420623cdc6 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -54,6 +54,7 @@
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Pem/CryptPem.c
+ Evp/CryptEvpMd.c
SysCall/CrtWrapper.c
SysCall/ConstantTimeClock.c
diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
index 689af4fedd..542ac2e2e1 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
@@ -50,6 +50,7 @@
Pk/CryptTsNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
+ Evp/CryptEvpMdNull.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index ae9bde9e37..a92e5e5766 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1012,6 +1012,131 @@ HmacSha256Final (
OUT UINT8 *HmacValue
);
+//=====================================================================================
+// EVP (Envelope) Primitive
+//=====================================================================================
+
+/**
+ Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use.
+
+ If DigestName is NULL, then return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+
+ @return Pointer to the EVP_MD_CTX context that has been allocated and initialized.
+ If DigestName is invalid, returns NULL.
+ If the allocations fails, returns NULL.
+ If initialization fails, returns NULL.
+
+**/
+VOID *
+EFIAPI
+EvpMdInit (
+ IN CONST CHAR8 *DigestName
+ );
+
+/**
+ Makes a copy of an existing EVP_MD context.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If NewEvpMdContext is NULL, then return FALSE.
+
+ @param[in] EvpMdContext Pointer to EVP_MD context being copied.
+ @param[out] NewEvpMdContext Pointer to new EVP_MD context.
+
+ @retval TRUE EVP_MD context copy succeeded.
+ @retval FALSE EVP_MD context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdDuplicate (
+ IN CONST VOID *EvpMdContext,
+ OUT VOID *NewEvpMdContext
+ );
+
+/**
+ Digests the input data and updates EVP_MD context.
+
+ This function performs EVP digest on a data buffer of the specified size.
+ It can be called multiple times to compute the digest of long or discontinuous data streams.
+ EVP_MD context should be already correctly initialized by EvpMdInit(), and should not
+ be finalized by EvpMdFinal(). Behavior with invalid context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP_MD context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE EVP data digest succeeded.
+ @retval FALSE EVP data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdUpdate (
+ IN OUT VOID *EvpMdContext,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Completes computation of the EVP digest value.
+ Releases the specified EVP_MD_CTX context.
+
+ This function completes EVP hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the EVP context cannot
+ be used again.
+ EVP context should be already correctly initialized by EvpMdInit(), and should
+ not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If DigestValue is NULL, free the Context then return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP context.
+ @param[out] Digest Pointer to a buffer that receives the EVP digest value.
+
+ @retval TRUE EVP digest computation succeeded.
+ @retval FALSE EVP digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdFinal (
+ IN OUT VOID *EvpMdContext,
+ OUT UINT8 *DigestValue
+ );
+
+/**
+ Computes the message digest of an input data buffer.
+
+ This function performs the message digest of a given data buffer, and places
+ the digest value into the specified memory.
+
+ If DigestName is NULL, return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+ If HashValue is NULL, return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the digest value.
+
+ @retval TRUE Digest computation succeeded.
+ @retval FALSE Digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdHashAll (
+ IN CONST CHAR8 *DigestName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ );
+
//=====================================================================================
// Symmetric Cryptography Primitive
//=====================================================================================
diff --git a/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c
new file mode 100644
index 0000000000..3ec7b33b67
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c
@@ -0,0 +1,253 @@
+/** @file
+ EVP MD Wrapper Implementation for OpenSSL.
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+#include <openssl/evp.h>
+
+/**
+ Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use.
+
+ If DigestName is NULL, then return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+
+ @return Pointer to the EVP_MD_CTX context that has been allocated and initialized.
+ If DigestName is invalid, returns NULL.
+ If the allocations fails, returns NULL.
+ If initialization fails, returns NULL.
+
+**/
+VOID *
+EFIAPI
+EvpMdInit (
+ IN CONST CHAR8 *DigestName
+ )
+{
+ EVP_MD *Digest;
+ VOID *EvpMdContext;
+
+ //
+ // Check input parameters.
+ //
+ if (DigestName == NULL) {
+ return NULL;
+ }
+
+ //
+ // Allocate EVP_MD_CTX Context
+ //
+ EvpMdContext = EVP_MD_CTX_new ();
+ if (EvpMdContext == NULL) {
+ return NULL;
+ }
+
+ Digest = EVP_get_digestbyname (DigestName);
+ if (Digest == NULL) {
+ return NULL;
+ }
+
+ //
+ // Initialize Context
+ //
+ if (EVP_DigestInit_ex (EvpMdContext, Digest, NULL) != 1) {
+ EVP_MD_CTX_free (EvpMdContext);
+ return NULL;
+ }
+
+ return EvpMdContext;
+}
+
+/**
+ Makes a copy of an existing EVP_MD context.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If NewEvpMdContext is NULL, then return FALSE.
+
+ @param[in] EvpMdContext Pointer to EVP_MD context being copied.
+ @param[out] NewEvpMdContext Pointer to new EVP_MD context.
+
+ @retval TRUE EVP_MD context copy succeeded.
+ @retval FALSE EVP_MD context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdDuplicate (
+ IN CONST VOID *EvpMdContext,
+ OUT VOID *NewEvpMdContext
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (EvpMdContext == NULL || NewEvpMdContext == NULL) {
+ return FALSE;
+ }
+
+ if (EVP_MD_CTX_copy (NewEvpMdContext, EvpMdContext) != 1) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates EVP_MD context.
+
+ This function performs EVP digest on a data buffer of the specified size.
+ It can be called multiple times to compute the digest of long or discontinuous data streams.
+ EVP_MD context should be already correctly initialized by EvpMdInit(), and should not
+ be finalized by EvpMdFinal(). Behavior with invalid context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP_MD context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE EVP data digest succeeded.
+ @retval FALSE EVP data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdUpdate (
+ IN OUT VOID *EvpMdContext,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (EvpMdContext == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Check invalid parameters, in case only DataLength was checked in OpenSSL
+ //
+ if (Data == NULL && DataSize != 0) {
+ return FALSE;
+ }
+
+ //
+ // OpenSSL EVP digest update
+ //
+ if (EVP_DigestUpdate (EvpMdContext, Data, DataSize) != 1) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Completes computation of the EVP digest value.
+ Releases the specified EVP_MD_CTX context.
+
+ This function completes EVP hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the EVP context cannot
+ be used again.
+ EVP context should be already correctly initialized by EvpMdInit(), and should
+ not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If DigestValue is NULL, free the Context then return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP context.
+ @param[out] Digest Pointer to a buffer that receives the EVP digest value.
+
+ @retval TRUE EVP digest computation succeeded.
+ @retval FALSE EVP digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdFinal (
+ IN OUT VOID *EvpMdContext,
+ OUT UINT8 *DigestValue
+ )
+{
+ UINT32 Length;
+ BOOLEAN ReturnValue;
+
+ ReturnValue = TRUE;
+
+ //
+ // Check input parameters.
+ //
+ if (EvpMdContext == NULL) {
+ return FALSE;
+ }
+ if (DigestValue == NULL) {
+ EVP_MD_CTX_free (EvpMdContext);
+ return FALSE;
+ }
+
+ //
+ // OpenSSL EVP digest finalization
+ //
+ if (EVP_DigestFinal_ex (EvpMdContext, DigestValue, &Length) != 1) {
+ ReturnValue = FALSE;
+ }
+
+ //
+ // Free OpenSSL EVP_MD_CTX Context
+ //
+ EVP_MD_CTX_free (EvpMdContext);
+
+ return ReturnValue;
+}
+
+/**
+ Computes the message digest of an input data buffer.
+
+ This function performs the message digest of a given data buffer, and places
+ the digest value into the specified memory.
+
+ If DigestName is NULL, return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+ If HashValue is NULL, return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the digest value.
+
+ @retval TRUE Digest computation succeeded.
+ @retval FALSE Digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdHashAll (
+ IN CONST CHAR8 *DigestName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ BOOLEAN Result;
+ VOID *EvpMdContext;
+
+ EvpMdContext = EvpMdInit (DigestName);
+ if (EvpMdContext == NULL) {
+ return FALSE;
+ }
+
+ Result = EvpMdUpdate (EvpMdContext, Data, DataSize);
+ if (Result == FALSE) {
+ EvpMdFinal (EvpMdContext, NULL);
+ return FALSE;
+ }
+
+ Result = EvpMdFinal (EvpMdContext, HashValue);
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c
new file mode 100644
index 0000000000..b9b0bd1572
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c
@@ -0,0 +1,124 @@
+/** @file
+ EVP MD Wrapper Null Library.
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+ Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in] DigestName Pointer to the digest name.
+
+ @return NULL This interface is not supported.
+
+**/
+VOID *
+EFIAPI
+EvpMdInit (
+ IN CONST CHAR8 *DigestName
+ )
+{
+ ASSERT (FALSE);
+ return NULL;
+}
+
+/**
+ Makes a copy of an existing EVP_MD context.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in] EvpMdContext Pointer to EVP_MD context being copied.
+ @param[out] NewEvpMdContext Pointer to new EVP_MD context.
+
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdDuplicate (
+ IN CONST VOID *EvpMdContext,
+ OUT VOID *NewEvpMdContext
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
+
+/**
+ Digests the input data and updates EVP_MD context.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in, out] EvpMdContext Pointer to the EVP_MD context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdUpdate (
+ IN OUT VOID *EvpMdContext,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
+
+/**
+ Completes computation of the EVP digest value.
+ Releases the specified EVP_MD_CTX context.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in, out] EvpMdContext Pointer to the EVP context.
+ @param[out] Digest Pointer to a buffer that receives the EVP digest value.
+
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdFinal (
+ IN OUT VOID *EvpMdContext,
+ OUT UINT8 *DigestValue
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
+
+/**
+ Computes the message digest of an input data buffer.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in] DigestName Pointer to the digest name.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the digest value.
+
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdHashAll (
+ IN CONST CHAR8 *DigestName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] CryptoPkg: Add EVP to Crypto Service driver interface
2020-09-15 0:57 [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 1/3] " Zurcher, Christopher J
@ 2020-09-15 0:57 ` Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 3/3] SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP interface Zurcher, Christopher J
2020-09-15 1:21 ` [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Yao, Jiewen
3 siblings, 0 replies; 8+ messages in thread
From: Zurcher, Christopher J @ 2020-09-15 0:57 UTC (permalink / raw)
To: devel; +Cc: Laszlo Ersek, Jiewen Yao, Jian J Wang, Xiaoyu Lu
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Signed-off-by: Christopher J Zurcher <christopher.j.zurcher@intel.com>
---
CryptoPkg/CryptoPkg.dsc | 3 +
CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 ++
CryptoPkg/Private/Protocol/Crypto.h | 127 +++++++++++++++++
CryptoPkg/Driver/Crypto.c | 148 +++++++++++++++++++-
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 140 ++++++++++++++++++
5 files changed, 427 insertions(+), 1 deletion(-)
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 1af78468a1..af3fceb99f 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -159,6 +159,7 @@
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Tls.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsSet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsGet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
+ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
!endif
!if $(CRYPTO_SERVICES) == MIN_PEI
@@ -173,6 +174,7 @@
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.Free | TRUE
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.SetKey | TRUE
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Pkcs.Services.Pkcs5HashPassword | TRUE
+ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
!endif
!if $(CRYPTO_SERVICES) == MIN_DXE_MIN_SMM
@@ -203,6 +205,7 @@
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.Init | TRUE
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.CbcEncrypt | TRUE
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.CbcDecrypt | TRUE
+ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
!endif
###################################################################################################
diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
index 44fb0262f4..b79c98d679 100644
--- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
+++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
@@ -288,6 +288,16 @@ typedef struct {
} Services;
UINT32 Family;
} TlsGet;
+ union {
+ struct {
+ UINT8 Init:1;
+ UINT8 Duplicate:1;
+ UINT8 Update:1;
+ UINT8 Final:1;
+ UINT8 HashAll:1;
+ } Services;
+ UINT32 Family;
+ } EvpMd;
} PCD_CRYPTO_SERVICE_FAMILY_ENABLE;
#endif
diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
index c399e0d67a..84f1bc3f50 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -3434,6 +3434,127 @@ EFI_STATUS
IN OUT UINTN *DataSize
);
+/**
+ Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use.
+
+ If DigestName is NULL, then return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+
+ @return Pointer to the EVP_MD_CTX context that has been allocated and initialized.
+ If DigestName is invalid, returns NULL.
+ If the allocations fails, returns NULL.
+ If initialization fails, returns NULL.
+
+**/
+typedef
+VOID *
+(EFIAPI* EDKII_CRYPTO_EVPMD_INIT)(
+ IN CONST CHAR8 *DigestName
+ );
+
+/**
+ Makes a copy of an existing EVP_MD context.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If NewEvpMdContext is NULL, then return FALSE.
+
+ @param[in] EvpMdContext Pointer to EVP_MD context being copied.
+ @param[out] NewEvpMdContext Pointer to new EVP_MD context.
+
+ @retval TRUE EVP_MD context copy succeeded.
+ @retval FALSE EVP_MD context copy failed.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_EVPMD_DUPLICATE)(
+ IN CONST VOID *EvpMdContext,
+ OUT VOID *NewEvpMdContext
+ );
+
+/**
+ Digests the input data and updates EVP_MD context.
+
+ This function performs EVP digest on a data buffer of the specified size.
+ It can be called multiple times to compute the digest of long or discontinuous data streams.
+ EVP_MD context should be already correctly initialized by EvpMdInit(), and should not
+ be finalized by EvpMdFinal(). Behavior with invalid context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP_MD context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE EVP data digest succeeded.
+ @retval FALSE EVP data digest failed.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_EVPMD_UPDATE)(
+ IN OUT VOID *EvpMdContext,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Completes computation of the EVP digest value.
+ Releases the specified EVP_MD_CTX context.
+
+ This function completes EVP hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the EVP context cannot
+ be used again.
+ EVP context should be already correctly initialized by EvpMdInit(), and should
+ not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If DigestValue is NULL, free the Context then return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP context.
+ @param[out] Digest Pointer to a buffer that receives the EVP digest value.
+
+ @retval TRUE EVP digest computation succeeded.
+ @retval FALSE EVP digest computation failed.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_EVPMD_FINAL)(
+ IN OUT VOID *EvpMdContext,
+ OUT UINT8 *DigestValue
+ );
+
+/**
+ Computes the message digest of an input data buffer.
+
+ This function performs the message digest of a given data buffer, and places
+ the digest value into the specified memory.
+
+ If DigestName is NULL, return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+ If HashValue is NULL, return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the digest value.
+
+ @retval TRUE Digest computation succeeded.
+ @retval FALSE Digest computation failed.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI* EDKII_CRYPTO_EVPMD_HASH_ALL)(
+ IN CONST CHAR8 *DigestName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ );
+
///
/// EDK II Crypto Protocol
@@ -3619,6 +3740,12 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert;
EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey;
EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocationList;
+ /// Digest Envelope (EVP MD)
+ EDKII_CRYPTO_EVPMD_INIT EvpMdInit;
+ EDKII_CRYPTO_EVPMD_DUPLICATE EvpMdDuplicate;
+ EDKII_CRYPTO_EVPMD_UPDATE EvpMdUpdate;
+ EDKII_CRYPTO_EVPMD_FINAL EvpMdFinal;
+ EDKII_CRYPTO_EVPMD_HASH_ALL EvpMdHashAll;
};
extern GUID gEdkiiCryptoProtocolGuid;
diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c
index d9096ea603..a49af46e38 100644
--- a/CryptoPkg/Driver/Crypto.c
+++ b/CryptoPkg/Driver/Crypto.c
@@ -4463,6 +4463,146 @@ CryptoServiceTlsGetCertRevocationList (
return CALL_BASECRYPTLIB (TlsGet.Services.CertRevocationList, TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED);
}
+//=====================================================================================
+// EVP (Envelope) Primitive
+//=====================================================================================
+
+/**
+ Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use.
+
+ If DigestName is NULL, then return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+
+ @return Pointer to the EVP_MD_CTX context that has been allocated and initialized.
+ If DigestName is invalid, returns NULL.
+ If the allocations fails, returns NULL.
+ If initialization fails, returns NULL.
+
+**/
+VOID *
+EFIAPI
+CryptoServiceEvpMdInit (
+ IN CONST CHAR8 *DigestName
+ )
+{
+ return CALL_BASECRYPTLIB (EvpMd.Services.Init, EvpMdInit, (DigestName), NULL);
+}
+
+/**
+ Makes a copy of an existing EVP_MD context.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If NewEvpMdContext is NULL, then return FALSE.
+
+ @param[in] EvpMdContext Pointer to EVP_MD context being copied.
+ @param[out] NewEvpMdContext Pointer to new EVP_MD context.
+
+ @retval TRUE EVP_MD context copy succeeded.
+ @retval FALSE EVP_MD context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceEvpMdDuplicate (
+ IN CONST VOID *EvpMdContext,
+ OUT VOID *NewEvpMdContext
+ )
+{
+ return CALL_BASECRYPTLIB (EvpMd.Services.Duplicate, EvpMdDuplicate, (EvpMdContext, NewEvpMdContext), FALSE);
+}
+
+/**
+ Digests the input data and updates EVP_MD context.
+
+ This function performs EVP digest on a data buffer of the specified size.
+ It can be called multiple times to compute the digest of long or discontinuous data streams.
+ EVP_MD context should be already correctly initialized by EvpMdInit(), and should not
+ be finalized by EvpMdFinal(). Behavior with invalid context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP_MD context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE EVP data digest succeeded.
+ @retval FALSE EVP data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceEvpMdUpdate (
+ IN OUT VOID *EvpMdContext,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ return CALL_BASECRYPTLIB (EvpMd.Services.Update, EvpMdUpdate, (EvpMdContext, Data, DataSize), FALSE);
+}
+
+/**
+ Completes computation of the EVP digest value.
+ Releases the specified EVP_MD_CTX context.
+
+ This function completes EVP hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the EVP context cannot
+ be used again.
+ EVP context should be already correctly initialized by EvpMdInit(), and should
+ not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If DigestValue is NULL, free the Context then return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP context.
+ @param[out] Digest Pointer to a buffer that receives the EVP digest value.
+
+ @retval TRUE EVP digest computation succeeded.
+ @retval FALSE EVP digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceEvpMdFinal (
+ IN OUT VOID *EvpMdContext,
+ OUT UINT8 *DigestValue
+ )
+{
+ return CALL_BASECRYPTLIB (EvpMd.Services.Final, EvpMdFinal, (EvpMdContext, DigestValue), FALSE);
+}
+
+/**
+ Computes the message digest of an input data buffer.
+
+ This function performs the message digest of a given data buffer, and places
+ the digest value into the specified memory.
+
+ If DigestName is NULL, return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+ If HashValue is NULL, return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the digest value.
+
+ @retval TRUE Digest computation succeeded.
+ @retval FALSE Digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceEvpMdHashAll (
+ IN CONST CHAR8 *DigestName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ return CALL_BASECRYPTLIB (EvpMd.Services.HashAll, EvpMdHashAll, (DigestName, Data, DataSize, HashValue), FALSE);
+}
+
const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
/// Version
CryptoServiceGetCryptoVersion,
@@ -4663,5 +4803,11 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
CryptoServiceTlsGetCaCertificate,
CryptoServiceTlsGetHostPublicCert,
CryptoServiceTlsGetHostPrivateKey,
- CryptoServiceTlsGetCertRevocationList
+ CryptoServiceTlsGetCertRevocationList,
+ /// Digest Envelope (EVP MD)
+ CryptoServiceEvpMdInit,
+ CryptoServiceEvpMdDuplicate,
+ CryptoServiceEvpMdUpdate,
+ CryptoServiceEvpMdFinal,
+ CryptoServiceEvpMdHashAll
};
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index 3f14c6d262..0d98bcb09c 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -3499,3 +3499,143 @@ TlsGetCertRevocationList (
{
CALL_CRYPTO_SERVICE (TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED);
}
+
+//=====================================================================================
+// EVP (Envelope) Primitive
+//=====================================================================================
+
+/**
+ Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use.
+
+ If DigestName is NULL, then return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+
+ @return Pointer to the EVP_MD_CTX context that has been allocated and initialized.
+ If DigestName is invalid, returns NULL.
+ If the allocations fails, returns NULL.
+ If initialization fails, returns NULL.
+
+**/
+VOID *
+EFIAPI
+EvpMdInit (
+ IN CONST CHAR8 *DigestName
+ )
+{
+ CALL_CRYPTO_SERVICE (EvpMdInit, (DigestName), NULL);
+}
+
+/**
+ Makes a copy of an existing EVP_MD context.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If NewEvpMdContext is NULL, then return FALSE.
+
+ @param[in] EvpMdContext Pointer to EVP_MD context being copied.
+ @param[out] NewEvpMdContext Pointer to new EVP_MD context.
+
+ @retval TRUE EVP_MD context copy succeeded.
+ @retval FALSE EVP_MD context copy failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdDuplicate (
+ IN CONST VOID *EvpMdContext,
+ OUT VOID *NewEvpMdContext
+ )
+{
+ CALL_CRYPTO_SERVICE (EvpMdDuplicate, (EvpMdContext, NewEvpMdContext), FALSE);
+}
+
+/**
+ Digests the input data and updates EVP_MD context.
+
+ This function performs EVP digest on a data buffer of the specified size.
+ It can be called multiple times to compute the digest of long or discontinuous data streams.
+ EVP_MD context should be already correctly initialized by EvpMdInit(), and should not
+ be finalized by EvpMdFinal(). Behavior with invalid context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP_MD context.
+ @param[in] Data Pointer to the buffer containing the data to be digested.
+ @param[in] DataSize Size of Data buffer in bytes.
+
+ @retval TRUE EVP data digest succeeded.
+ @retval FALSE EVP data digest failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdUpdate (
+ IN OUT VOID *EvpMdContext,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ CALL_CRYPTO_SERVICE (EvpMdUpdate, (EvpMdContext, Data, DataSize), FALSE);
+}
+
+/**
+ Completes computation of the EVP digest value.
+ Releases the specified EVP_MD_CTX context.
+
+ This function completes EVP hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the EVP context cannot
+ be used again.
+ EVP context should be already correctly initialized by EvpMdInit(), and should
+ not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined.
+
+ If EvpMdContext is NULL, then return FALSE.
+ If DigestValue is NULL, free the Context then return FALSE.
+
+ @param[in, out] EvpMdContext Pointer to the EVP context.
+ @param[out] Digest Pointer to a buffer that receives the EVP digest value.
+
+ @retval TRUE EVP digest computation succeeded.
+ @retval FALSE EVP digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdFinal (
+ IN OUT VOID *EvpMdContext,
+ OUT UINT8 *DigestValue
+ )
+{
+ CALL_CRYPTO_SERVICE (EvpMdFinal, (EvpMdContext, DigestValue), FALSE);
+}
+
+/**
+ Computes the message digest of an input data buffer.
+
+ This function performs the message digest of a given data buffer, and places
+ the digest value into the specified memory.
+
+ If DigestName is NULL, return FALSE.
+ If Data is NULL and DataSize is not zero, return FALSE.
+ If HashValue is NULL, return FALSE.
+
+ @param[in] DigestName Pointer to the digest name.
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the digest value.
+
+ @retval TRUE Digest computation succeeded.
+ @retval FALSE Digest computation failed.
+
+**/
+BOOLEAN
+EFIAPI
+EvpMdHashAll (
+ IN CONST CHAR8 *DigestName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *HashValue
+ )
+{
+ CALL_CRYPTO_SERVICE (EvpMdHashAll, (DigestName, Data, DataSize, HashValue), FALSE);
+}
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP interface
2020-09-15 0:57 [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 1/3] " Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 2/3] CryptoPkg: Add EVP to Crypto Service driver interface Zurcher, Christopher J
@ 2020-09-15 0:57 ` Zurcher, Christopher J
2020-09-15 1:21 ` [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Yao, Jiewen
3 siblings, 0 replies; 8+ messages in thread
From: Zurcher, Christopher J @ 2020-09-15 0:57 UTC (permalink / raw)
To: devel; +Cc: Laszlo Ersek, Jiewen Yao, Jian J Wang
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Christopher J Zurcher <christopher.j.zurcher@intel.com>
---
SecurityPkg/Hash2DxeCrypto/Driver.h | 1 -
SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c | 345 ++------------------
2 files changed, 31 insertions(+), 315 deletions(-)
diff --git a/SecurityPkg/Hash2DxeCrypto/Driver.h b/SecurityPkg/Hash2DxeCrypto/Driver.h
index 7b8996912a..ac811b3977 100644
--- a/SecurityPkg/Hash2DxeCrypto/Driver.h
+++ b/SecurityPkg/Hash2DxeCrypto/Driver.h
@@ -50,7 +50,6 @@ typedef struct {
LIST_ENTRY InstEntry;
EFI_HASH2_PROTOCOL Hash2Protocol;
VOID *HashContext;
- VOID *HashInfoContext;
BOOLEAN Updated;
} HASH2_INSTANCE_DATA;
diff --git a/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c
index d96bc136e2..f31bc79f04 100644
--- a/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c
+++ b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c
@@ -2,7 +2,7 @@
This module implements Hash2 Protocol.
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
-Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -18,241 +18,18 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "Driver.h"
-/**
- Retrieves the size, in bytes, of the context buffer required for hash operations.
-
- If this interface is not supported, then return zero.
-
- @return The size, in bytes, of the context buffer required for hash operations.
- @retval 0 This interface is not supported.
-
-**/
-typedef
-UINTN
-(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE) (
- VOID
- );
-
-/**
- Initializes user-supplied memory pointed by Sha1Context as hash context for
- subsequent use.
-
- If HashContext is NULL, then return FALSE.
- If this interface is not supported, then return FALSE.
-
- @param[out] HashContext Pointer to Hashcontext being initialized.
-
- @retval TRUE Hash context initialization succeeded.
- @retval FALSE Hash context initialization failed.
- @retval FALSE This interface is not supported.
-
-**/
-typedef
-BOOLEAN
-(EFIAPI *EFI_HASH_INIT) (
- OUT VOID *HashContext
- );
-
-/**
- Digests the input data and updates Hash context.
-
- This function performs Hash digest on a data buffer of the specified size.
- It can be called multiple times to compute the digest of long or discontinuous data streams.
- Hash context should be already correctly initialized by HashInit(), and should not be finalized
- by HashFinal(). Behavior with invalid context is undefined.
-
- If HashContext is NULL, then return FALSE.
- If this interface is not supported, then return FALSE.
-
- @param[in, out] HashContext Pointer to the Hash context.
- @param[in] Data Pointer to the buffer containing the data to be hashed.
- @param[in] DataSize Size of Data buffer in bytes.
-
- @retval TRUE SHA-1 data digest succeeded.
- @retval FALSE SHA-1 data digest failed.
- @retval FALSE This interface is not supported.
-
-**/
-typedef
-BOOLEAN
-(EFIAPI *EFI_HASH_UPDATE) (
- IN OUT VOID *HashContext,
- IN CONST VOID *Data,
- IN UINTN DataSize
- );
-
-/**
- Completes computation of the Hash digest value.
-
- This function completes hash computation and retrieves the digest value into
- the specified memory. After this function has been called, the Hash context cannot
- be used again.
- Hash context should be already correctly initialized by HashInit(), and should not be
- finalized by HashFinal(). Behavior with invalid Hash context is undefined.
-
- If HashContext is NULL, then return FALSE.
- If HashValue is NULL, then return FALSE.
- If this interface is not supported, then return FALSE.
-
- @param[in, out] HashContext Pointer to the Hash context.
- @param[out] HashValue Pointer to a buffer that receives the Hash digest
- value.
-
- @retval TRUE Hash digest computation succeeded.
- @retval FALSE Hash digest computation failed.
- @retval FALSE This interface is not supported.
-
-**/
-typedef
-BOOLEAN
-(EFIAPI *EFI_HASH_FINAL) (
- IN OUT VOID *HashContext,
- OUT UINT8 *HashValue
- );
-
typedef struct {
- EFI_GUID *Guid;
- UINT32 HashSize;
- EFI_HASH_GET_CONTEXT_SIZE GetContextSize;
- EFI_HASH_INIT Init;
- EFI_HASH_UPDATE Update;
- EFI_HASH_FINAL Final;
+ EFI_GUID *Guid;
+ UINT32 HashSize;
+ CONST CHAR8 *DigestName;
} EFI_HASH_INFO;
EFI_HASH_INFO mHashInfo[] = {
- {&gEfiHashAlgorithmMD5Guid, sizeof(EFI_MD5_HASH2), Md5GetContextSize, Md5Init, Md5Update, Md5Final },
- {&gEfiHashAlgorithmSha1Guid, sizeof(EFI_SHA1_HASH2), Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },
- {&gEfiHashAlgorithmSha256Guid, sizeof(EFI_SHA256_HASH2), Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final },
- {&gEfiHashAlgorithmSha384Guid, sizeof(EFI_SHA384_HASH2), Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final },
- {&gEfiHashAlgorithmSha512Guid, sizeof(EFI_SHA512_HASH2), Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final },
-};
-
-/**
- Returns the size of the hash which results from a specific algorithm.
-
- @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
- @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
- @param[out] HashSize Holds the returned size of the algorithm's hash.
-
- @retval EFI_SUCCESS Hash size returned successfully.
- @retval EFI_INVALID_PARAMETER This or HashSize is NULL.
- @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
- or HashAlgorithm is null.
-
-**/
-EFI_STATUS
-EFIAPI
-BaseCrypto2GetHashSize (
- IN CONST EFI_HASH2_PROTOCOL *This,
- IN CONST EFI_GUID *HashAlgorithm,
- OUT UINTN *HashSize
- );
-
-/**
- Creates a hash for the specified message text. The hash is not extendable.
- The output is final with any algorithm-required padding added by the function.
-
- @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
- @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
- @param[in] Message Points to the start of the message.
- @param[in] MessageSize The size of Message, in bytes.
- @param[in,out] Hash On input, points to a caller-allocated buffer of the size
- returned by GetHashSize() for the specified HashAlgorithm.
- On output, the buffer holds the resulting hash computed from the message.
-
- @retval EFI_SUCCESS Hash returned successfully.
- @retval EFI_INVALID_PARAMETER This or Hash is NULL.
- @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
- or HashAlgorithm is Null.
- @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
- or MessageSize is greater than platform maximum.
-
-**/
-EFI_STATUS
-EFIAPI
-BaseCrypto2Hash (
- IN CONST EFI_HASH2_PROTOCOL *This,
- IN CONST EFI_GUID *HashAlgorithm,
- IN CONST UINT8 *Message,
- IN UINTN MessageSize,
- IN OUT EFI_HASH2_OUTPUT *Hash
- );
-
-/**
- This function must be called to initialize a digest calculation to be subsequently performed using the
- EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().
-
- @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
- @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
-
- @retval EFI_SUCCESS Initialized successfully.
- @retval EFI_INVALID_PARAMETER This is NULL.
- @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
- or HashAlgorithm is Null.
- @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource.
- @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(),
- or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.
-
-**/
-EFI_STATUS
-EFIAPI
-BaseCrypto2HashInit (
- IN CONST EFI_HASH2_PROTOCOL *This,
- IN CONST EFI_GUID *HashAlgorithm
- );
-
-/**
- Updates the hash of a computation in progress by adding a message text.
-
- @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
- @param[in] Message Points to the start of the message.
- @param[in] MessageSize The size of Message, in bytes.
-
- @retval EFI_SUCCESS Digest in progress updated successfully.
- @retval EFI_INVALID_PARAMETER This or Hash is NULL.
- @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
- or MessageSize is greater than platform maximum.
- @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(),
- or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.
-
-**/
-EFI_STATUS
-EFIAPI
-BaseCrypto2HashUpdate (
- IN CONST EFI_HASH2_PROTOCOL *This,
- IN CONST UINT8 *Message,
- IN UINTN MessageSize
- );
-
-/**
- Finalizes a hash operation in progress and returns calculation result.
- The output is final with any necessary padding added by the function.
- The hash may not be further updated or extended after HashFinal().
-
- @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
- @param[in,out] Hash On input, points to a caller-allocated buffer of the size
- returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().
- On output, the buffer holds the resulting hash computed from the message.
-
- @retval EFI_SUCCESS Hash returned successfully.
- @retval EFI_INVALID_PARAMETER This or Hash is NULL.
- @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),
- or the operation in progress was canceled by a call to Hash() on the same instance.
-
-**/
-EFI_STATUS
-EFIAPI
-BaseCrypto2HashFinal (
- IN CONST EFI_HASH2_PROTOCOL *This,
- IN OUT EFI_HASH2_OUTPUT *Hash
- );
-
-EFI_HASH2_PROTOCOL mHash2Protocol = {
- BaseCrypto2GetHashSize,
- BaseCrypto2Hash,
- BaseCrypto2HashInit,
- BaseCrypto2HashUpdate,
- BaseCrypto2HashFinal,
+ {&gEfiHashAlgorithmMD5Guid, sizeof(EFI_MD5_HASH2), "MD5"},
+ {&gEfiHashAlgorithmSha1Guid, sizeof(EFI_SHA1_HASH2), "SHA1"},
+ {&gEfiHashAlgorithmSha256Guid, sizeof(EFI_SHA256_HASH2), "SHA256"},
+ {&gEfiHashAlgorithmSha384Guid, sizeof(EFI_SHA384_HASH2), "SHA384"},
+ {&gEfiHashAlgorithmSha512Guid, sizeof(EFI_SHA512_HASH2), "SHA512"},
};
/**
@@ -347,12 +124,7 @@ BaseCrypto2Hash (
IN OUT EFI_HASH2_OUTPUT *Hash
)
{
- EFI_HASH_INFO *HashInfo;
- VOID *HashCtx;
- UINTN CtxSize;
- BOOLEAN Ret;
EFI_STATUS Status;
- HASH2_INSTANCE_DATA *Instance;
Status = EFI_SUCCESS;
@@ -364,60 +136,18 @@ BaseCrypto2Hash (
return EFI_UNSUPPORTED;
}
- HashInfo = GetHashInfo (HashAlgorithm);
- if (HashInfo == NULL) {
- return EFI_UNSUPPORTED;
- }
-
- Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
- if (Instance->HashContext != NULL) {
- FreePool (Instance->HashContext);
- }
- Instance->HashInfoContext = NULL;
- Instance->HashContext = NULL;
-
- //
- // Start hash sequence
- //
- CtxSize = HashInfo->GetContextSize ();
- if (CtxSize == 0) {
- return EFI_UNSUPPORTED;
- }
- HashCtx = AllocatePool (CtxSize);
- if (HashCtx == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = This->HashInit (This, HashAlgorithm);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
- Ret = HashInfo->Init (HashCtx);
- if (!Ret) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
+ Status = This->HashUpdate (This, Message, MessageSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
- //
- // Setup the context
- //
- Instance->HashContext = HashCtx;
- Instance->HashInfoContext = HashInfo;
-
- Ret = HashInfo->Update (HashCtx, Message, MessageSize);
- if (!Ret) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
+ Status = This->HashFinal (This, Hash);
- Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash);
- if (!Ret) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-Done:
- //
- // Cleanup the context
- //
- FreePool (HashCtx);
- Instance->HashInfoContext = NULL;
- Instance->HashContext = NULL;
return Status;
}
@@ -446,8 +176,6 @@ BaseCrypto2HashInit (
{
EFI_HASH_INFO *HashInfo;
VOID *HashCtx;
- UINTN CtxSize;
- BOOLEAN Ret;
HASH2_INSTANCE_DATA *Instance;
if (This == NULL) {
@@ -466,34 +194,23 @@ BaseCrypto2HashInit (
//
// Consistency Check
//
- Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
- if ((Instance->HashContext != NULL) || (Instance->HashInfoContext != NULL)) {
+ Instance = HASH2_INSTANCE_DATA_FROM_THIS (This);
+ if (Instance->HashContext != NULL) {
return EFI_ALREADY_STARTED;
}
//
// Start hash sequence
//
- CtxSize = HashInfo->GetContextSize ();
- if (CtxSize == 0) {
- return EFI_UNSUPPORTED;
- }
- HashCtx = AllocatePool (CtxSize);
+ HashCtx = EvpMdInit (HashInfo->DigestName);
if (HashCtx == NULL) {
return EFI_OUT_OF_RESOURCES;
}
- Ret = HashInfo->Init (HashCtx);
- if (!Ret) {
- FreePool (HashCtx);
- return EFI_OUT_OF_RESOURCES;
- }
-
//
// Setup the context
//
Instance->HashContext = HashCtx;
- Instance->HashInfoContext = HashInfo;
Instance->Updated = FALSE;
return EFI_SUCCESS;
@@ -522,7 +239,6 @@ BaseCrypto2HashUpdate (
IN UINTN MessageSize
)
{
- EFI_HASH_INFO *HashInfo;
VOID *HashCtx;
BOOLEAN Ret;
HASH2_INSTANCE_DATA *Instance;
@@ -535,13 +251,12 @@ BaseCrypto2HashUpdate (
// Consistency Check
//
Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
- if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL)) {
+ if (Instance->HashContext == NULL) {
return EFI_NOT_READY;
}
- HashInfo = Instance->HashInfoContext;
HashCtx = Instance->HashContext;
- Ret = HashInfo->Update (HashCtx, Message, MessageSize);
+ Ret = EvpMdUpdate (HashCtx, Message, MessageSize);
if (!Ret) {
return EFI_OUT_OF_RESOURCES;
}
@@ -574,8 +289,6 @@ BaseCrypto2HashFinal (
IN OUT EFI_HASH2_OUTPUT *Hash
)
{
- EFI_HASH_INFO *HashInfo;
- VOID *HashCtx;
BOOLEAN Ret;
HASH2_INSTANCE_DATA *Instance;
@@ -587,20 +300,16 @@ BaseCrypto2HashFinal (
// Consistency Check
//
Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
- if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL) ||
+ if ((Instance->HashContext == NULL) ||
(!Instance->Updated)) {
return EFI_NOT_READY;
}
- HashInfo = Instance->HashInfoContext;
- HashCtx = Instance->HashContext;
- Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash);
+ Ret = EvpMdFinal (Instance->HashContext, (UINT8 *)Hash->Sha1Hash);
//
// Cleanup the context
//
- FreePool (HashCtx);
- Instance->HashInfoContext = NULL;
Instance->HashContext = NULL;
Instance->Updated = FALSE;
@@ -610,3 +319,11 @@ BaseCrypto2HashFinal (
return EFI_SUCCESS;
}
+
+EFI_HASH2_PROTOCOL mHash2Protocol = {
+ BaseCrypto2GetHashSize,
+ BaseCrypto2Hash,
+ BaseCrypto2HashInit,
+ BaseCrypto2HashUpdate,
+ BaseCrypto2HashFinal,
+};
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
2020-09-15 0:57 [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Zurcher, Christopher J
` (2 preceding siblings ...)
2020-09-15 0:57 ` [PATCH v2 3/3] SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP interface Zurcher, Christopher J
@ 2020-09-15 1:21 ` Yao, Jiewen
2020-09-15 2:54 ` Zurcher, Christopher J
3 siblings, 1 reply; 8+ messages in thread
From: Yao, Jiewen @ 2020-09-15 1:21 UTC (permalink / raw)
To: Zurcher, Christopher J, devel@edk2.groups.io
Cc: Laszlo Ersek, Wang, Jian J, Lu, XiaoyuX
Hi Zurcher:
Thanks for your work.
1) Please share with us what unit test you have done for all new APIs.
2) Please add comment on what is the valid DigestName in EvpMdInit(). Otherwise, people will have no idea on that.
3) I assume the size will be unchanged if a module does not use the new EVPMD API, such as UEFI secure boot, TCG trusted boot. Please double confirm if that is right understanding.
Hi all:
I would like collect feedback on below:
-- "I replaced the MD5 and SHAx functions with EVP functions in Hash2DxeCrypto, and it grew from ~26k to ~253k."
If there is negative size impact for the platform BIOS that is using Hash2DxeCrypto, please share with the community.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Christopher J Zurcher <christopher.j.zurcher@intel.com>
> Sent: Tuesday, September 15, 2020 8:58 AM
> To: devel@edk2.groups.io
> Cc: Laszlo Ersek <lersek@redhat.com>; Yao, Jiewen <jiewen.yao@intel.com>;
> Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>
> Subject: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest
> interface
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
>
> V2 changes:
> Added NullLib implementation
> Added Crypto Service implementation
> Rebased Hash2DxeCrypto to use EVP interface instead of low-level functions
> Removed unnecessary casts
> Added "HashAll" utility function
> Merged "New" and "Init" functions as well as "Final" and "Free" functions
> Retained "Init/Update/Final" naming instead of "New/Update/Free" as this
> conforms with common usage
>
> Low-level interfaces to message digest (hash) functions have been deprecated
> in OpenSSL 3. In order to upgrade to OpenSSL 3, all direct calls to
> low-level functions (such as SHA256_Init() in CryptSha256.c) will need to
> be replaced by EVP inteface calls.
>
> References:
> https://www.openssl.org/docs/manmaster/man7/evp.html
> https://www.openssl.org/docs/manmaster/man3/SHA256_Init.html
>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
>
> Christopher J Zurcher (3):
> CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
> CryptoPkg: Add EVP to Crypto Service driver interface
> SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP
> interface
>
> CryptoPkg/CryptoPkg.dsc | 3 +
> CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
> CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
> CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
> CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
> CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
> CryptoPkg/Include/Library/BaseCryptLib.h | 125 +++++++
> CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 +
> CryptoPkg/Private/Protocol/Crypto.h | 127 +++++++
> SecurityPkg/Hash2DxeCrypto/Driver.h | 1 -
> CryptoPkg/Driver/Crypto.c | 148 ++++++++-
> CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c | 253 ++++++++++++++
> CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c | 124 +++++++
> CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 140 ++++++++
> SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c | 345 ++------------------
> 15 files changed, 965 insertions(+), 316 deletions(-)
> create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c
> create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c
>
> --
> 2.28.0.windows.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
2020-09-15 1:21 ` [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Yao, Jiewen
@ 2020-09-15 2:54 ` Zurcher, Christopher J
2020-09-15 2:58 ` Yao, Jiewen
2020-09-15 8:01 ` [edk2-devel] " Laszlo Ersek
0 siblings, 2 replies; 8+ messages in thread
From: Zurcher, Christopher J @ 2020-09-15 2:54 UTC (permalink / raw)
To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Laszlo Ersek, Wang, Jian J, Lu, XiaoyuX
Replies inline
> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Monday, September 14, 2020 18:22
> To: Zurcher, Christopher J <christopher.j.zurcher@intel.com>;
> devel@edk2.groups.io
> Cc: Laszlo Ersek <lersek@redhat.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Lu, XiaoyuX <xiaoyux.lu@intel.com>
> Subject: RE: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest
> interface
>
> Hi Zurcher:
> Thanks for your work.
> 1) Please share with us what unit test you have done for all new APIs.
I unit tested both the native and Crypto Service implementations through the modified Hash2DxeCrypto protocol.
I tested the Init/Update/Final flow as well as the HashAll function.
>
> 2) Please add comment on what is the valid DigestName in EvpMdInit().
> Otherwise, people will have no idea on that.
I will add valid options in a comment.
I have to send another patch anyway to add a file in my commit (missed the second copy of CryptEvpMdNull.c in the NullLib folder).
>
> 3) I assume the size will be unchanged if a module does not use the new EVPMD
> API, such as UEFI secure boot, TCG trusted boot. Please double confirm if
> that is right understanding.
Yes, if a module does not call the EVPMD API, it should not grow in size.
The Crypto Service build output CryptoDxe.efi grew less than 1% after enabling the EvpMd function family through PcdCryptoServiceFamilyEnable.
I suspect this is because the HmacSha256 Family was already enabled, and inside OpenSSL the HMAC functions are wrappers for EVP functions.
So even with library-mode BaseCryptLib, any module that already calls the HMAC functions should not see any size change by adding EVP.
>
> Hi all:
> I would like collect feedback on below:
> -- "I replaced the MD5 and SHAx functions with EVP functions in
> Hash2DxeCrypto, and it grew from ~26k to ~253k."
>
> If there is negative size impact for the platform BIOS that is using
> Hash2DxeCrypto, please share with the community.
The size change in Hash2DxeCrypto was seen while using the library-mode BaseCryptLib implementation, not the Crypto Services driver.
We cannot move to OpenSSL 3 without replacing all low-level algorithm functions with EVP calls, so platforms using Hash2DxeCrypto will have to eat the size increase eventually.
For platforms using Hash2DxeCrypto, moving to the Crypto Services model should help offset this increase.
Thanks,
Christopher Zurcher
>
> Thank you
> Yao Jiewen
>
> > -----Original Message-----
> > From: Christopher J Zurcher <christopher.j.zurcher@intel.com>
> > Sent: Tuesday, September 15, 2020 8:58 AM
> > To: devel@edk2.groups.io
> > Cc: Laszlo Ersek <lersek@redhat.com>; Yao, Jiewen <jiewen.yao@intel.com>;
> > Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>
> > Subject: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest
> > interface
> >
> > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
> >
> > V2 changes:
> > Added NullLib implementation
> > Added Crypto Service implementation
> > Rebased Hash2DxeCrypto to use EVP interface instead of low-level functions
> > Removed unnecessary casts
> > Added "HashAll" utility function
> > Merged "New" and "Init" functions as well as "Final" and "Free" functions
> > Retained "Init/Update/Final" naming instead of "New/Update/Free" as this
> > conforms with common usage
> >
> > Low-level interfaces to message digest (hash) functions have been
> deprecated
> > in OpenSSL 3. In order to upgrade to OpenSSL 3, all direct calls to
> > low-level functions (such as SHA256_Init() in CryptSha256.c) will need to
> > be replaced by EVP inteface calls.
> >
> > References:
> > https://www.openssl.org/docs/manmaster/man7/evp.html
> > https://www.openssl.org/docs/manmaster/man3/SHA256_Init.html
> >
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
> >
> > Christopher J Zurcher (3):
> > CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
> > CryptoPkg: Add EVP to Crypto Service driver interface
> > SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP
> > interface
> >
> > CryptoPkg/CryptoPkg.dsc | 3 +
> > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
> > CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
> > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
> > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
> > CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
> > CryptoPkg/Include/Library/BaseCryptLib.h | 125 +++++++
> > CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 +
> > CryptoPkg/Private/Protocol/Crypto.h | 127 +++++++
> > SecurityPkg/Hash2DxeCrypto/Driver.h | 1 -
> > CryptoPkg/Driver/Crypto.c | 148 ++++++++-
> > CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c | 253
> ++++++++++++++
> > CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c | 124 +++++++
> > CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 140 ++++++++
> > SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c | 345 ++----------
> --------
> > 15 files changed, 965 insertions(+), 316 deletions(-)
> > create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c
> > create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c
> >
> > --
> > 2.28.0.windows.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
2020-09-15 2:54 ` Zurcher, Christopher J
@ 2020-09-15 2:58 ` Yao, Jiewen
2020-09-15 8:01 ` [edk2-devel] " Laszlo Ersek
1 sibling, 0 replies; 8+ messages in thread
From: Yao, Jiewen @ 2020-09-15 2:58 UTC (permalink / raw)
To: Zurcher, Christopher J, devel@edk2.groups.io
Cc: Laszlo Ersek, Wang, Jian J, Lu, XiaoyuX
Comments below:
> -----Original Message-----
> From: Zurcher, Christopher J <christopher.j.zurcher@intel.com>
> Sent: Tuesday, September 15, 2020 10:54 AM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Laszlo Ersek <lersek@redhat.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Lu, XiaoyuX <xiaoyux.lu@intel.com>
> Subject: RE: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest
> interface
>
> Replies inline
>
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: Monday, September 14, 2020 18:22
> > To: Zurcher, Christopher J <christopher.j.zurcher@intel.com>;
> > devel@edk2.groups.io
> > Cc: Laszlo Ersek <lersek@redhat.com>; Wang, Jian J <jian.j.wang@intel.com>;
> > Lu, XiaoyuX <xiaoyux.lu@intel.com>
> > Subject: RE: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope)
> Digest
> > interface
> >
> > Hi Zurcher:
> > Thanks for your work.
> > 1) Please share with us what unit test you have done for all new APIs.
>
> I unit tested both the native and Crypto Service implementations through the
> modified Hash2DxeCrypto protocol.
> I tested the Init/Update/Final flow as well as the HashAll function.
>
> >
> > 2) Please add comment on what is the valid DigestName in EvpMdInit().
> > Otherwise, people will have no idea on that.
>
> I will add valid options in a comment.
> I have to send another patch anyway to add a file in my commit (missed the
> second copy of CryptEvpMdNull.c in the NullLib folder).
>
> >
> > 3) I assume the size will be unchanged if a module does not use the new
> EVPMD
> > API, such as UEFI secure boot, TCG trusted boot. Please double confirm if
> > that is right understanding.
>
> Yes, if a module does not call the EVPMD API, it should not grow in size.
> The Crypto Service build output CryptoDxe.efi grew less than 1% after enabling
> the EvpMd function family through PcdCryptoServiceFamilyEnable.
> I suspect this is because the HmacSha256 Family was already enabled, and inside
> OpenSSL the HMAC functions are wrappers for EVP functions.
> So even with library-mode BaseCryptLib, any module that already calls the
> HMAC functions should not see any size change by adding EVP.
>
> >
> > Hi all:
> > I would like collect feedback on below:
> > -- "I replaced the MD5 and SHAx functions with EVP functions in
> > Hash2DxeCrypto, and it grew from ~26k to ~253k."
> >
> > If there is negative size impact for the platform BIOS that is using
> > Hash2DxeCrypto, please share with the community.
>
> The size change in Hash2DxeCrypto was seen while using the library-mode
> BaseCryptLib implementation, not the Crypto Services driver.
> We cannot move to OpenSSL 3 without replacing all low-level algorithm
> functions with EVP calls, so platforms using Hash2DxeCrypto will have to eat the
> size increase eventually.
> For platforms using Hash2DxeCrypto, moving to the Crypto Services model
> should help offset this increase.
[Jiewen] I think we need evaluate the size impact to decide if/when/how to move to OpenSSL 3 later.
We can cross the bridge when we come to it.
>
> Thanks,
> Christopher Zurcher
>
> >
> > Thank you
> > Yao Jiewen
> >
> > > -----Original Message-----
> > > From: Christopher J Zurcher <christopher.j.zurcher@intel.com>
> > > Sent: Tuesday, September 15, 2020 8:58 AM
> > > To: devel@edk2.groups.io
> > > Cc: Laszlo Ersek <lersek@redhat.com>; Yao, Jiewen
> <jiewen.yao@intel.com>;
> > > Wang, Jian J <jian.j.wang@intel.com>; Lu, XiaoyuX <xiaoyux.lu@intel.com>
> > > Subject: [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest
> > > interface
> > >
> > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
> > >
> > > V2 changes:
> > > Added NullLib implementation
> > > Added Crypto Service implementation
> > > Rebased Hash2DxeCrypto to use EVP interface instead of low-level functions
> > > Removed unnecessary casts
> > > Added "HashAll" utility function
> > > Merged "New" and "Init" functions as well as "Final" and "Free" functions
> > > Retained "Init/Update/Final" naming instead of "New/Update/Free" as this
> > > conforms with common usage
> > >
> > > Low-level interfaces to message digest (hash) functions have been
> > deprecated
> > > in OpenSSL 3. In order to upgrade to OpenSSL 3, all direct calls to
> > > low-level functions (such as SHA256_Init() in CryptSha256.c) will need to
> > > be replaced by EVP inteface calls.
> > >
> > > References:
> > > https://www.openssl.org/docs/manmaster/man7/evp.html
> > > https://www.openssl.org/docs/manmaster/man3/SHA256_Init.html
> > >
> > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
> > >
> > > Christopher J Zurcher (3):
> > > CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
> > > CryptoPkg: Add EVP to Crypto Service driver interface
> > > SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP
> > > interface
> > >
> > > CryptoPkg/CryptoPkg.dsc | 3 +
> > > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 +
> > > CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 +
> > > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 +
> > > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 +
> > > CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
> > > CryptoPkg/Include/Library/BaseCryptLib.h | 125 +++++++
> > > CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 +
> > > CryptoPkg/Private/Protocol/Crypto.h | 127 +++++++
> > > SecurityPkg/Hash2DxeCrypto/Driver.h | 1 -
> > > CryptoPkg/Driver/Crypto.c | 148 ++++++++-
> > > CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c | 253
> > ++++++++++++++
> > > CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c | 124 +++++++
> > > CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 140 ++++++++
> > > SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c | 345 ++----------
> > --------
> > > 15 files changed, 965 insertions(+), 316 deletions(-)
> > > create mode 100644 CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c
> > > create mode 100644
> CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c
> > >
> > > --
> > > 2.28.0.windows.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface
2020-09-15 2:54 ` Zurcher, Christopher J
2020-09-15 2:58 ` Yao, Jiewen
@ 2020-09-15 8:01 ` Laszlo Ersek
1 sibling, 0 replies; 8+ messages in thread
From: Laszlo Ersek @ 2020-09-15 8:01 UTC (permalink / raw)
To: devel, christopher.j.zurcher, Yao, Jiewen; +Cc: Wang, Jian J, Lu, XiaoyuX
Hello Christopher,
On 09/15/20 04:54, Zurcher, Christopher J wrote:
> I have to send another patch anyway to add a file in my commit (missed the second copy of CryptEvpMdNull.c in the NullLib folder).
Thank you for the updates. I'll only be capable of a quick skim of the
first patch in the series. It seems you're planning a v3, so I prefer to
check that version.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-09-15 8:01 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-15 0:57 [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 1/3] " Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 2/3] CryptoPkg: Add EVP to Crypto Service driver interface Zurcher, Christopher J
2020-09-15 0:57 ` [PATCH v2 3/3] SecurityPkg/Hash2DxeCrypto: Rebase Hash2DxeCrypto onto the EVP interface Zurcher, Christopher J
2020-09-15 1:21 ` [PATCH v2 0/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface Yao, Jiewen
2020-09-15 2:54 ` Zurcher, Christopher J
2020-09-15 2:58 ` Yao, Jiewen
2020-09-15 8:01 ` [edk2-devel] " Laszlo Ersek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox