public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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