From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 244A494148F for ; Thu, 28 Sep 2023 15:34:40 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=wQAIyAjf6wp3vL1sm16RYLAhGcpJD1EEpfaKmjOuy1s=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1695915279; v=1; b=eNXrc0xQmNGkykIKaHBTL9mzOkUgXI0dFm7/R1rlJwv523mU5I1YHoF9FccY22fh8BQbuZGz acfuFDLuDYXLYgKDC5WjddPnCN7YtUxF8JMn3CTcS0OaKv7Aw6ZVd8KB+mW1x6NW1aTajvPp20H 4tOX4mBZRL2uQNbgKIiNmuaw= X-Received: by 127.0.0.2 with SMTP id 6j5dYY7687511xcFVYXgNld0; Thu, 28 Sep 2023 08:34:39 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) by mx.groups.io with SMTP id smtpd.web10.16607.1695915264250602914 for ; Thu, 28 Sep 2023 08:34:39 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10847"; a="704022" X-IronPort-AV: E=Sophos;i="6.03,184,1694761200"; d="scan'208";a="704022" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Sep 2023 08:34:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10847"; a="778943270" X-IronPort-AV: E=Sophos;i="6.03,184,1694761200"; d="scan'208";a="778943270" X-Received: from shwdejointd777.ccr.corp.intel.com ([10.239.58.116]) by orsmga008.jf.intel.com with ESMTP; 28 Sep 2023 08:34:37 -0700 From: "Wenxing Hou" To: devel@edk2.groups.io Cc: Jiewen Yao , Yi Li , Xiaoyu Lu , Guomin Jiang Subject: [edk2-devel] [PATCH v3 08/11] CryptoPkg: Add MD5/SHA1/SHA2 functions based on Mbedtls Date: Thu, 28 Sep 2023 23:34:13 +0800 Message-Id: <20230928153416.537-9-wenxing.hou@intel.com> In-Reply-To: <20230928153416.537-1-wenxing.hou@intel.com> References: <20230928153416.537-1-wenxing.hou@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wenxing.hou@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: GYBAwtwyzRoiYYHuWXkDzY5wx7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=eNXrc0xQ; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Add MD5/SHA1/SHA256/SHA384/SHA512 APIs. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4177 Cc: Jiewen Yao Cc: Yi Li Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Wenxing Hou --- .../BaseCryptLibMbedTls/Hash/CryptMd5.c | 226 +++++++++ .../BaseCryptLibMbedTls/Hash/CryptSha1.c | 226 +++++++++ .../BaseCryptLibMbedTls/Hash/CryptSha256.c | 219 +++++++++ .../BaseCryptLibMbedTls/Hash/CryptSha512.c | 431 ++++++++++++++++++ .../UnitTest/Library/BaseCryptLib/HashTests.c | 33 +- 5 files changed, 1130 insertions(+), 5 deletions(-) create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c b/Crypto= Pkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c new file mode 100644 index 0000000000..35978291ca --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptMd5.c @@ -0,0 +1,226 @@ +/** @file=0D + MD5 Digest Wrapper Implementation over MbedTLS.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "InternalCryptLib.h"=0D +#include =0D +#include =0D +=0D +#ifdef ENABLE_MD5_DEPRECATED_INTERFACES=0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for MD5 has= h operations.=0D +=0D + @return The size, in bytes, of the context buffer required for MD5 hash= operations.=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +Md5GetContextSize (=0D + VOID=0D + )=0D +{=0D + //=0D + // Retrieves the MD5 Context Size=0D + //=0D + return (UINTN)(sizeof (mbedtls_md5_context));=0D +}=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Md5Context as MD5 hash conte= xt for=0D + subsequent use.=0D +=0D + If Md5Context is NULL, then return FALSE.=0D +=0D + @param[out] Md5Context Pointer to MD5 context being initialized.=0D +=0D + @retval TRUE MD5 context initialization succeeded.=0D + @retval FALSE MD5 context initialization failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Md5Init (=0D + OUT VOID *Md5Context=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Md5Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_md5_init (Md5Context);=0D +=0D + Ret =3D mbedtls_md5_starts_ret (Md5Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Makes a copy of an existing MD5 context.=0D +=0D + If Md5Context is NULL, then return FALSE.=0D + If NewMd5Context is NULL, then return FALSE.=0D +=0D + @param[in] Md5Context Pointer to MD5 context being copied.=0D + @param[out] NewMd5Context Pointer to new MD5 context.=0D +=0D + @retval TRUE MD5 context copy succeeded.=0D + @retval FALSE MD5 context copy failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Md5Duplicate (=0D + IN CONST VOID *Md5Context,=0D + OUT VOID *NewMd5Context=0D + )=0D +{=0D + if ((Md5Context =3D=3D NULL) || (NewMd5Context =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_md5_clone (NewMd5Context, Md5Context);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Digests the input data and updates MD5 context.=0D +=0D + This function performs MD5 digest on a data buffer of the specified size= .=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + MD5 context should be already correctly initialized by Md5Init(), and sh= ould not be finalized=0D + by Md5Final(). Behavior with invalid context is undefined.=0D +=0D + If Md5Context is NULL, then return FALSE.=0D +=0D + @param[in, out] Md5Context Pointer to the MD5 context.=0D + @param[in] Data Pointer to the buffer containing the data t= o be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE MD5 data digest succeeded.=0D + @retval FALSE MD5 data digest failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Md5Update (=0D + IN OUT VOID *Md5Context,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Md5Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_md5_update_ret (Md5Context, Data, DataSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Completes computation of the MD5 digest value.=0D +=0D + This function completes MD5 hash computation and retrieves the digest va= lue into=0D + the specified memory. After this function has been called, the MD5 conte= xt cannot=0D + be used again.=0D + MD5 context should be already correctly initialized by Md5Init(), and sh= ould not be=0D + finalized by Md5Final(). Behavior with invalid MD5 context is undefined.= =0D +=0D + If Md5Context is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D +=0D + @param[in, out] Md5Context Pointer to the MD5 context.=0D + @param[out] HashValue Pointer to a buffer that receives the MD5 d= igest=0D + value (16 bytes).=0D +=0D + @retval TRUE MD5 digest computation succeeded.=0D + @retval FALSE MD5 digest computation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Md5Final (=0D + IN OUT VOID *Md5Context,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if ((Md5Context =3D=3D NULL) || (HashValue =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_md5_finish_ret (Md5Context, HashValue);=0D + mbedtls_md5_free (Md5Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Computes the MD5 message digest of a input data buffer.=0D +=0D + This function performs the MD5 message digest of a given data buffer, an= d places=0D + the digest value into the specified memory.=0D +=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Data Pointer to the buffer containing the data to be= hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D + @param[out] HashValue Pointer to a buffer that receives the MD5 diges= t=0D + value (16 bytes).=0D +=0D + @retval TRUE MD5 digest computation succeeded.=0D + @retval FALSE MD5 digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Md5HashAll (=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (HashValue =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_md5_ret (Data, DataSize, HashValue);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +#endif=0D diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c b/Crypt= oPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c new file mode 100644 index 0000000000..68b107bd7b --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha1.c @@ -0,0 +1,226 @@ +/** @file=0D + SHA-1 Digest Wrapper Implementation over MbedTLS.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "InternalCryptLib.h"=0D +#include =0D +#include =0D +=0D +#ifndef DISABLE_SHA1_DEPRECATED_INTERFACES=0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for SHA-1 h= ash operations.=0D +=0D + @return The size, in bytes, of the context buffer required for SHA-1 ha= sh operations.=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +Sha1GetContextSize (=0D + VOID=0D + )=0D +{=0D + //=0D + // Retrieves MbedTLS SHA Context Size=0D + //=0D + return (UINTN)(sizeof (mbedtls_sha1_context));=0D +}=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash co= ntext for=0D + subsequent use.=0D +=0D + If Sha1Context is NULL, then return FALSE.=0D +=0D + @param[out] Sha1Context Pointer to SHA-1 context being initialized.=0D +=0D + @retval TRUE SHA-1 context initialization succeeded.=0D + @retval FALSE SHA-1 context initialization failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha1Init (=0D + OUT VOID *Sha1Context=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha1Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha1_init (Sha1Context);=0D +=0D + Ret =3D mbedtls_sha1_starts_ret (Sha1Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Makes a copy of an existing SHA-1 context.=0D +=0D + If Sha1Context is NULL, then return FALSE.=0D + If NewSha1Context is NULL, then return FALSE.=0D +=0D + @param[in] Sha1Context Pointer to SHA-1 context being copied.=0D + @param[out] NewSha1Context Pointer to new SHA-1 context.=0D +=0D + @retval TRUE SHA-1 context copy succeeded.=0D + @retval FALSE SHA-1 context copy failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha1Duplicate (=0D + IN CONST VOID *Sha1Context,=0D + OUT VOID *NewSha1Context=0D + )=0D +{=0D + if ((Sha1Context =3D=3D NULL) || (NewSha1Context =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha1_clone (NewSha1Context, Sha1Context);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Digests the input data and updates SHA-1 context.=0D +=0D + This function performs SHA-1 digest on a data buffer of the specified si= ze.=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + SHA-1 context should be already correctly initialized by Sha1Init(), and= should not be finalized=0D + by Sha1Final(). Behavior with invalid context is undefined.=0D +=0D + If Sha1Context is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha1Context Pointer to the SHA-1 context.=0D + @param[in] Data Pointer to the buffer containing the data = to be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE SHA-1 data digest succeeded.=0D + @retval FALSE SHA-1 data digest failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha1Update (=0D + IN OUT VOID *Sha1Context,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha1Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha1_update_ret (Sha1Context, Data, DataSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Completes computation of the SHA-1 digest value.=0D +=0D + This function completes SHA-1 hash computation and retrieves the digest = value into=0D + the specified memory. After this function has been called, the SHA-1 con= text cannot=0D + be used again.=0D + SHA-1 context should be already correctly initialized by Sha1Init(), and= should not be=0D + finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefin= ed.=0D +=0D + If Sha1Context is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha1Context Pointer to the SHA-1 context.=0D + @param[out] HashValue Pointer to a buffer that receives the SHA-= 1 digest=0D + value (20 bytes).=0D +=0D + @retval TRUE SHA-1 digest computation succeeded.=0D + @retval FALSE SHA-1 digest computation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha1Final (=0D + IN OUT VOID *Sha1Context,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if ((Sha1Context =3D=3D NULL) || (HashValue =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha1_finish_ret (Sha1Context, HashValue);=0D + mbedtls_sha1_free (Sha1Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Computes the SHA-1 message digest of a input data buffer.=0D +=0D + This function performs the SHA-1 message digest of a given data buffer, = and places=0D + the digest value into the specified memory.=0D +=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Data Pointer to the buffer containing the data to be= hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D + @param[out] HashValue Pointer to a buffer that receives the SHA-1 dig= est=0D + value (20 bytes).=0D +=0D + @retval TRUE SHA-1 digest computation succeeded.=0D + @retval FALSE SHA-1 digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha1HashAll (=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (HashValue =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha1_ret (Data, DataSize, HashValue);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +#endif=0D diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c b/Cry= ptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c new file mode 100644 index 0000000000..007f5c12aa --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha256.c @@ -0,0 +1,219 @@ +/** @file=0D + SHA-256 Digest Wrapper Implementation over MbedTLS.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "InternalCryptLib.h"=0D +#include =0D +#include =0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for SHA-256= hash operations.=0D +=0D + @return The size, in bytes, of the context buffer required for SHA-256 = hash operations.=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +Sha256GetContextSize (=0D + VOID=0D + )=0D +{=0D + return (UINTN)(sizeof (mbedtls_sha256_context));=0D +}=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Sha256Context as SHA-256 has= h context for=0D + subsequent use.=0D +=0D + If Sha256Context is NULL, then return FALSE.=0D +=0D + @param[out] Sha256Context Pointer to SHA-256 context being initialized= .=0D +=0D + @retval TRUE SHA-256 context initialization succeeded.=0D + @retval FALSE SHA-256 context initialization failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha256Init (=0D + OUT VOID *Sha256Context=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha256Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha256_init (Sha256Context);=0D +=0D + Ret =3D mbedtls_sha256_starts_ret (Sha256Context, FALSE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Makes a copy of an existing SHA-256 context.=0D +=0D + If Sha256Context is NULL, then return FALSE.=0D + If NewSha256Context is NULL, then return FALSE.=0D +=0D + @param[in] Sha256Context Pointer to SHA-256 context being copied.=0D + @param[out] NewSha256Context Pointer to new SHA-256 context.=0D +=0D + @retval TRUE SHA-256 context copy succeeded.=0D + @retval FALSE SHA-256 context copy failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha256Duplicate (=0D + IN CONST VOID *Sha256Context,=0D + OUT VOID *NewSha256Context=0D + )=0D +{=0D + if ((Sha256Context =3D=3D NULL) || (NewSha256Context =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha256_clone (NewSha256Context, Sha256Context);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Digests the input data and updates SHA-256 context.=0D +=0D + This function performs SHA-256 digest on a data buffer of the specified = size.=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + SHA-256 context should be already correctly initialized by Sha256Init(),= and should not be finalized=0D + by Sha256Final(). Behavior with invalid context is undefined.=0D +=0D + If Sha256Context is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha256Context Pointer to the SHA-256 context.=0D + @param[in] Data Pointer to the buffer containing the dat= a to be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE SHA-256 data digest succeeded.=0D + @retval FALSE SHA-256 data digest failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha256Update (=0D + IN OUT VOID *Sha256Context,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha256Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha256_update_ret (Sha256Context, Data, DataSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Completes computation of the SHA-256 digest value.=0D +=0D + This function completes SHA-256 hash computation and retrieves the diges= t value into=0D + the specified memory. After this function has been called, the SHA-256 c= ontext cannot=0D + be used again.=0D + SHA-256 context should be already correctly initialized by Sha256Init(),= and should not be=0D + finalized by Sha256Final(). Behavior with invalid SHA-256 context is und= efined.=0D +=0D + If Sha256Context is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha256Context Pointer to the SHA-256 context.=0D + @param[out] HashValue Pointer to a buffer that receives the SH= A-256 digest=0D + value (32 bytes).=0D +=0D + @retval TRUE SHA-256 digest computation succeeded.=0D + @retval FALSE SHA-256 digest computation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha256Final (=0D + IN OUT VOID *Sha256Context,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if ((Sha256Context =3D=3D NULL) || (HashValue =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha256_finish_ret (Sha256Context, HashValue);=0D + mbedtls_sha256_free (Sha256Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Computes the SHA-256 message digest of a input data buffer.=0D +=0D + This function performs the SHA-256 message digest of a given data buffer= , and places=0D + the digest value into the specified memory.=0D +=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Data Pointer to the buffer containing the data to be= hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D + @param[out] HashValue Pointer to a buffer that receives the SHA-256 d= igest=0D + value (32 bytes).=0D +=0D + @retval TRUE SHA-256 digest computation succeeded.=0D + @retval FALSE SHA-256 digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha256HashAll (=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (HashValue =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha256_ret (Data, DataSize, HashValue, FALSE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c b/Cry= ptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c new file mode 100644 index 0000000000..3c6fc951d3 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Hash/CryptSha512.c @@ -0,0 +1,431 @@ +/** @file=0D + SHA-384 and SHA-512 Digest Wrapper Implementations over MbedTLS.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "InternalCryptLib.h"=0D +#include =0D +#include =0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for SHA-384= hash operations.=0D +=0D + @return The size, in bytes, of the context buffer required for SHA-384 = hash operations.=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +Sha384GetContextSize (=0D + VOID=0D + )=0D +{=0D + return (UINTN)(sizeof (mbedtls_sha512_context));=0D +}=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Sha384Context as SHA-384 has= h context for=0D + subsequent use.=0D +=0D + If Sha384Context is NULL, then return FALSE.=0D +=0D + @param[out] Sha384Context Pointer to SHA-384 context being initialized= .=0D +=0D + @retval TRUE SHA-384 context initialization succeeded.=0D + @retval FALSE SHA-384 context initialization failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha384Init (=0D + OUT VOID *Sha384Context=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha384Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha512_init (Sha384Context);=0D +=0D + Ret =3D mbedtls_sha512_starts_ret (Sha384Context, TRUE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Makes a copy of an existing SHA-384 context.=0D +=0D + If Sha384Context is NULL, then return FALSE.=0D + If NewSha384Context is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Sha384Context Pointer to SHA-384 context being copied.=0D + @param[out] NewSha384Context Pointer to new SHA-384 context.=0D +=0D + @retval TRUE SHA-384 context copy succeeded.=0D + @retval FALSE SHA-384 context copy failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha384Duplicate (=0D + IN CONST VOID *Sha384Context,=0D + OUT VOID *NewSha384Context=0D + )=0D +{=0D + if ((Sha384Context =3D=3D NULL) || (NewSha384Context =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha512_clone (NewSha384Context, Sha384Context);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Digests the input data and updates SHA-384 context.=0D +=0D + This function performs SHA-384 digest on a data buffer of the specified = size.=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + SHA-384 context should be already correctly initialized by Sha384Init(),= and should not be finalized=0D + by Sha384Final(). Behavior with invalid context is undefined.=0D +=0D + If Sha384Context is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha384Context Pointer to the SHA-384 context.=0D + @param[in] Data Pointer to the buffer containing the dat= a to be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE SHA-384 data digest succeeded.=0D + @retval FALSE SHA-384 data digest failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha384Update (=0D + IN OUT VOID *Sha384Context,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha384Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha512_update_ret (Sha384Context, Data, DataSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Completes computation of the SHA-384 digest value.=0D +=0D + This function completes SHA-384 hash computation and retrieves the diges= t value into=0D + the specified memory. After this function has been called, the SHA-384 c= ontext cannot=0D + be used again.=0D + SHA-384 context should be already correctly initialized by Sha384Init(),= and should not be=0D + finalized by Sha384Final(). Behavior with invalid SHA-384 context is und= efined.=0D +=0D + If Sha384Context is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha384Context Pointer to the SHA-384 context.=0D + @param[out] HashValue Pointer to a buffer that receives the SH= A-384 digest=0D + value (48 bytes).=0D +=0D + @retval TRUE SHA-384 digest computation succeeded.=0D + @retval FALSE SHA-384 digest computation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha384Final (=0D + IN OUT VOID *Sha384Context,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if ((Sha384Context =3D=3D NULL) || (HashValue =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha512_finish_ret (Sha384Context, HashValue);=0D + mbedtls_sha512_free (Sha384Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Computes the SHA-384 message digest of a input data buffer.=0D +=0D + This function performs the SHA-384 message digest of a given data buffer= , and places=0D + the digest value into the specified memory.=0D +=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Data Pointer to the buffer containing the data to be= hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D + @param[out] HashValue Pointer to a buffer that receives the SHA-384 d= igest=0D + value (48 bytes).=0D +=0D + @retval TRUE SHA-384 digest computation succeeded.=0D + @retval FALSE SHA-384 digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha384HashAll (=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (HashValue =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha512_ret (Data, DataSize, HashValue, TRUE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for SHA-512= hash operations.=0D +=0D + @return The size, in bytes, of the context buffer required for SHA-512 = hash operations.=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +Sha512GetContextSize (=0D + VOID=0D + )=0D +{=0D + return (UINTN)(sizeof (mbedtls_sha512_context));=0D +}=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Sha512Context as SHA-512 has= h context for=0D + subsequent use.=0D +=0D + If Sha512Context is NULL, then return FALSE.=0D +=0D + @param[out] Sha512Context Pointer to SHA-512 context being initialized= .=0D +=0D + @retval TRUE SHA-512 context initialization succeeded.=0D + @retval FALSE SHA-512 context initialization failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha512Init (=0D + OUT VOID *Sha512Context=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha512Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha512_init (Sha512Context);=0D +=0D + Ret =3D mbedtls_sha512_starts_ret (Sha512Context, FALSE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Makes a copy of an existing SHA-512 context.=0D +=0D + If Sha512Context is NULL, then return FALSE.=0D + If NewSha512Context is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Sha512Context Pointer to SHA-512 context being copied.=0D + @param[out] NewSha512Context Pointer to new SHA-512 context.=0D +=0D + @retval TRUE SHA-512 context copy succeeded.=0D + @retval FALSE SHA-512 context copy failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha512Duplicate (=0D + IN CONST VOID *Sha512Context,=0D + OUT VOID *NewSha512Context=0D + )=0D +{=0D + if ((Sha512Context =3D=3D NULL) || (NewSha512Context =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_sha512_clone (NewSha512Context, Sha512Context);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Digests the input data and updates SHA-512 context.=0D +=0D + This function performs SHA-512 digest on a data buffer of the specified = size.=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + SHA-512 context should be already correctly initialized by Sha512Init(),= and should not be finalized=0D + by Sha512Final(). Behavior with invalid context is undefined.=0D +=0D + If Sha512Context is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha512Context Pointer to the SHA-512 context.=0D + @param[in] Data Pointer to the buffer containing the dat= a to be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE SHA-512 data digest succeeded.=0D + @retval FALSE SHA-512 data digest failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha512Update (=0D + IN OUT VOID *Sha512Context,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (Sha512Context =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha512_update_ret (Sha512Context, Data, DataSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Completes computation of the SHA-512 digest value.=0D +=0D + This function completes SHA-512 hash computation and retrieves the diges= t value into=0D + the specified memory. After this function has been called, the SHA-512 c= ontext cannot=0D + be used again.=0D + SHA-512 context should be already correctly initialized by Sha512Init(),= and should not be=0D + finalized by Sha512Final(). Behavior with invalid SHA-512 context is und= efined.=0D +=0D + If Sha512Context is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D +=0D + @param[in, out] Sha512Context Pointer to the SHA-512 context.=0D + @param[out] HashValue Pointer to a buffer that receives the SH= A-512 digest=0D + value (64 bytes).=0D +=0D + @retval TRUE SHA-512 digest computation succeeded.=0D + @retval FALSE SHA-512 digest computation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha512Final (=0D + IN OUT VOID *Sha512Context,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if ((Sha512Context =3D=3D NULL) || (HashValue =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha512_finish_ret (Sha512Context, HashValue);=0D + mbedtls_sha512_free (Sha512Context);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Computes the SHA-512 message digest of a input data buffer.=0D +=0D + This function performs the SHA-512 message digest of a given data buffer= , and places=0D + the digest value into the specified memory.=0D +=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Data Pointer to the buffer containing the data to be= hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D + @param[out] HashValue Pointer to a buffer that receives the SHA-512 d= igest=0D + value (64 bytes).=0D +=0D + @retval TRUE SHA-512 digest computation succeeded.=0D + @retval FALSE SHA-512 digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Sha512HashAll (=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize,=0D + OUT UINT8 *HashValue=0D + )=0D +{=0D + INT32 Ret;=0D +=0D + if (HashValue =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + if ((Data =3D=3D NULL) && (DataSize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_sha512_ret (Data, DataSize, HashValue, FALSE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c b/Cry= ptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c index e7e67b645b..dc5820227a 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c @@ -82,6 +82,13 @@ BOOLEAN IN UINTN DataSize=0D );=0D =0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_DUP)(=0D + IN CONST VOID *HashContext,=0D + OUT VOID *NewHashContext=0D + );=0D +=0D typedef=0D BOOLEAN=0D (EFIAPI *EFI_HASH_FINAL)(=0D @@ -102,6 +109,7 @@ typedef struct { EFI_HASH_GET_CONTEXT_SIZE GetContextSize;=0D EFI_HASH_INIT HashInit;=0D EFI_HASH_UPDATE HashUpdate;=0D + EFI_HASH_DUP HashDup;=0D EFI_HASH_FINAL HashFinal;=0D EFI_HASH_ALL HashAll;=0D CONST UINT8 *Digest;=0D @@ -109,12 +117,12 @@ typedef struct { } HASH_TEST_CONTEXT;=0D =0D #ifdef ENABLE_MD5_DEPRECATED_INTERFACES=0D -HASH_TEST_CONTEXT mMd5TestCtx =3D { MD5_DIGEST_SIZE, Md5GetContextSize, M= d5Init, Md5Update, Md5Final, Md5HashAll, Md5Digest };=0D +HASH_TEST_CONTEXT mMd5TestCtx =3D { MD5_DIGEST_SIZE, Md5GetContextSize, M= d5Init, Md5Update, Md5Duplicate, Md5Final, Md5HashAll, Md5Digest };=0D #endif=0D -HASH_TEST_CONTEXT mSha1TestCtx =3D { SHA1_DIGEST_SIZE, Sha1GetContextSi= ze, Sha1Init, Sha1Update, Sha1Final, Sha1HashAll, Sha1Digest };=0D -HASH_TEST_CONTEXT mSha256TestCtx =3D { SHA256_DIGEST_SIZE, Sha256GetConte= xtSize, Sha256Init, Sha256Update, Sha256Final, Sha256HashAll, Sha256Digest = };=0D -HASH_TEST_CONTEXT mSha384TestCtx =3D { SHA384_DIGEST_SIZE, Sha384GetConte= xtSize, Sha384Init, Sha384Update, Sha384Final, Sha384HashAll, Sha384Digest = };=0D -HASH_TEST_CONTEXT mSha512TestCtx =3D { SHA512_DIGEST_SIZE, Sha512GetConte= xtSize, Sha512Init, Sha512Update, Sha512Final, Sha512HashAll, Sha512Digest = };=0D +HASH_TEST_CONTEXT mSha1TestCtx =3D { SHA1_DIGEST_SIZE, Sha1GetContextSi= ze, Sha1Init, Sha1Update, Sha1Duplicate, Sha1Final, Sha1HashAll, Sha1Digest= };=0D +HASH_TEST_CONTEXT mSha256TestCtx =3D { SHA256_DIGEST_SIZE, Sha256GetConte= xtSize, Sha256Init, Sha256Update, Sha256Duplicate, Sha256Final, Sha256HashA= ll, Sha256Digest };=0D +HASH_TEST_CONTEXT mSha384TestCtx =3D { SHA384_DIGEST_SIZE, Sha384GetConte= xtSize, Sha384Init, Sha384Update, Sha384Duplicate, Sha384Final, Sha384HashA= ll, Sha384Digest };=0D +HASH_TEST_CONTEXT mSha512TestCtx =3D { SHA512_DIGEST_SIZE, Sha512GetConte= xtSize, Sha512Init, Sha512Update, Sha512Duplicate, Sha512Final, Sha512HashA= ll, Sha512Digest };=0D =0D UNIT_TEST_STATUS=0D EFIAPI=0D @@ -157,25 +165,40 @@ TestVerifyHash ( {=0D UINTN DataSize;=0D UINT8 Digest[MAX_DIGEST_SIZE];=0D + UINT8 DigestCopy[MAX_DIGEST_SIZE];=0D BOOLEAN Status;=0D HASH_TEST_CONTEXT *HashTestContext;=0D + VOID *HashCopyContext;=0D =0D HashTestContext =3D Context;=0D =0D DataSize =3D AsciiStrLen (HashData);=0D =0D ZeroMem (Digest, MAX_DIGEST_SIZE);=0D + ZeroMem (DigestCopy, MAX_DIGEST_SIZE);=0D +=0D + HashCopyContext =3D AllocatePool (HashTestContext->GetContextSize ());=0D =0D Status =3D HashTestContext->HashInit (HashTestContext->HashCtx);=0D UT_ASSERT_TRUE (Status);=0D =0D + Status =3D HashTestContext->HashInit (HashCopyContext);=0D + UT_ASSERT_TRUE (Status);=0D +=0D Status =3D HashTestContext->HashUpdate (HashTestContext->HashCtx, HashDa= ta, DataSize);=0D UT_ASSERT_TRUE (Status);=0D =0D + Status =3D HashTestContext->HashDup (HashTestContext->HashCtx, HashCopyC= ontext);=0D + UT_ASSERT_TRUE (Status);=0D +=0D Status =3D HashTestContext->HashFinal (HashTestContext->HashCtx, Digest)= ;=0D UT_ASSERT_TRUE (Status);=0D =0D + Status =3D HashTestContext->HashFinal (HashCopyContext, DigestCopy);=0D + UT_ASSERT_TRUE (Status);=0D +=0D UT_ASSERT_MEM_EQUAL (Digest, HashTestContext->Digest, HashTestContext->D= igestSize);=0D + UT_ASSERT_MEM_EQUAL (Digest, DigestCopy, HashTestContext->DigestSize);=0D =0D ZeroMem (Digest, MAX_DIGEST_SIZE);=0D Status =3D HashTestContext->HashAll (HashData, DataSize, Digest);=0D --=20 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#109160): https://edk2.groups.io/g/devel/message/109160 Mute This Topic: https://groups.io/mt/101639983/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-