* [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
@ 2022-02-11 9:05 Li, Zhihao
2022-02-15 6:08 ` Yao, Jiewen
0 siblings, 1 reply; 6+ messages in thread
From: Li, Zhihao @ 2022-02-11 9:05 UTC (permalink / raw)
To: devel; +Cc: Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang, Siyuan Fu
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3596
Parallel hash function ParallelHash256HashAll, as defined in NIST's
Special Publication 800-185, published December 2016. It utilizes
multi-process to calculate the digest.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Signed-off-by: Zhihao Li <zhihao.li@intel.com>
---
CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c | 313 ++++++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c | 275 +++++++++++++++++
CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c | 102 +++++++
CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c | 53 ++++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c | 152 ++++++++++
CryptoPkg/CryptoPkg.dec | 9 +-
CryptoPkg/Include/Library/BaseCryptLib.h | 29 +-
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 12 +-
CryptoPkg/Library/Include/CrtLibSupport.h | 5 +-
CryptoPkg/Library/Include/sha3.h | 32 ++
CryptoPkg/Library/Include/xkcp.h | 23 ++
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3 +-
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf | 7 +
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf | 6 +
14 files changed, 1016 insertions(+), 5 deletions(-)
diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
new file mode 100644
index 0000000000..5efced3f46
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
@@ -0,0 +1,313 @@
+/** @file
+ cSHAKE-256 Digest Wrapper Implementations.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+#include "sha3.h"
+#include "xkcp.h"
+
+#define CSHAKE256_SECURITY_STRENGTH 256
+#define CSHAKE256_RATE_IN_BYTES 136
+
+const CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = {0};
+
+UINTN
+EFIAPI
+LeftEncode (
+ OUT UINT8 *Encbuf,
+ IN UINTN Value
+ )
+{
+ return left_encode (Encbuf, Value);
+}
+
+UINTN
+EFIAPI
+RightEncode (
+ OUT UINT8 *Encbuf,
+ IN UINTN Value
+ )
+{
+ return right_encode (Encbuf, Value);
+}
+
+/**
+ Retrieves the size, in bytes, of the context buffer required for cSHAKE-256 hash operations.
+
+ @return The size, in bytes, of the context buffer required for cSHAKE-256 hash operations.
+
+**/
+UINTN
+EFIAPI
+CShake256GetContextSize (
+ VOID
+ )
+{
+ return (UINTN) (sizeof (KECCAK1600_CTX));
+}
+
+/**
+ Initializes user-supplied memory pointed by CShake256Context as cSHAKE-256 hash context for
+ subsequent use.
+
+ @param[out] CShake256Context Pointer to cSHAKE-256 context being initialized.
+ @param[in] OutputLen The desired number of output length in bytes.
+ @param[in] Name Pointer to the function name string.
+ @param[in] NameLen The length of the function name in bytes.
+ @param[in] Customization Pointer to the customization string.
+ @param[in] CustomizationLen The length of the customization string in bytes.
+
+ @retval TRUE cSHAKE-256 context initialization succeeded.
+ @retval FALSE cSHAKE-256 context initialization failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CShake256Init (
+ OUT VOID *CShake256Context,
+ IN UINTN OutputLen,
+ IN CONST VOID *Name,
+ IN UINTN NameLen,
+ IN CONST VOID *Customization,
+ IN UINTN CustomizationLen
+ )
+{
+ BOOLEAN Status;
+ unsigned char EncBuf[sizeof(size_t)+1];
+ UINTN EncLen;
+ UINTN AbsorbLen;
+ UINTN PadLen;
+
+ //
+ // Check input parameters.
+ //
+ if (CShake256Context == NULL ||
+ OutputLen == 0 ||
+ (NameLen != 0 && Name == NULL) ||
+ (CustomizationLen != 0 && Customization == NULL)) {
+ return FALSE;
+ }
+
+ //
+ // Initialize KECCAK context with pad value and block size.
+ //
+ if (NameLen == 0 && CustomizationLen == 0) {
+ //
+ // When N and S are both empty strings, cSHAKE(X, L, N, S) is equivalent to
+ // SHAKE as defined in FIPS 202.
+ //
+ return (BOOLEAN) init (
+ (KECCAK1600_CTX *) CShake256Context,
+ '\x1f',
+ (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,
+ OutputLen
+ );
+ }
+
+ Status = (BOOLEAN) init (
+ (KECCAK1600_CTX *) CShake256Context,
+ '\x04',
+ (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,
+ OutputLen
+ );
+ if (!Status) {
+ return FALSE;
+ }
+
+ AbsorbLen = 0;
+ //
+ // Absorb Absorb bytepad(.., rate).
+ //
+ EncLen = left_encode (EncBuf, CSHAKE256_RATE_IN_BYTES);
+ Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context, EncBuf, EncLen);
+ if (!Status) {
+ return FALSE;
+ }
+ AbsorbLen += EncLen;
+
+ //
+ // Absorb encode_string(N).
+ //
+ EncLen = left_encode (EncBuf, NameLen * 8);
+ Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context, EncBuf, EncLen);
+ if (!Status) {
+ return FALSE;
+ }
+ AbsorbLen += EncLen;
+ Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context, Name, NameLen);
+ if (!Status) {
+ return FALSE;
+ }
+ AbsorbLen += NameLen;
+
+ //
+ // Absorb encode_string(S).
+ //
+ EncLen = left_encode (EncBuf, CustomizationLen * 8);
+ Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context, EncBuf, EncLen);
+ if (!Status) {
+ return FALSE;
+ }
+ AbsorbLen += EncLen;
+ Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context, Customization, CustomizationLen);
+ if (!Status) {
+ return FALSE;
+ }
+ AbsorbLen += CustomizationLen;
+
+ //
+ // Absorb zero padding up to rate.
+ //
+ PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen % CSHAKE256_RATE_IN_BYTES;
+ Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context, mZeroPadding, PadLen);
+ if (!Status) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Digests the input data and updates cSHAKE-256 context.
+
+ This function performs cSHAKE-256 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.
+ cSHAKE-256 context should be already correctly initialized by CShake256Init(), and should not be finalized
+ by CShake256Final(). Behavior with invalid context is undefined.
+
+ @param[in, out] CShake256Context Pointer to the cSHAKE-256 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 cSHAKE-256 data digest succeeded.
+ @retval FALSE cSHAKE-256 data digest failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CShake256Update (
+ IN OUT VOID *CShake256Context,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (CShake256Context == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Check invalid parameters, in case that only DataLength was checked in OpenSSL.
+ //
+ if (Data == NULL && DataSize != 0) {
+ return FALSE;
+ }
+
+ return (BOOLEAN)(sha3_update ((KECCAK1600_CTX *) CShake256Context, Data, DataSize));
+}
+
+/**
+ Completes computation of the cSHAKE-256 digest value.
+
+ This function completes cSHAKE-256 hash computation and retrieves the digest value into
+ the specified memory. After this function has been called, the cSHAKE-256 context cannot
+ be used again.
+ cSHAKE-256 context should be already correctly initialized by CShake256Init(), and should not be
+ finalized by CShake256Final(). Behavior with invalid cSHAKE-256 context is undefined.
+
+ @param[in, out] CShake256Context Pointer to the cSHAKE-256 context.
+ @param[out] HashValue Pointer to a buffer that receives the cSHAKE-256 digest
+ value.
+
+ @retval TRUE cSHAKE-256 digest computation succeeded.
+ @retval FALSE cSHAKE-256 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CShake256Final (
+ IN OUT VOID *CShake256Context,
+ OUT UINT8 *HashValue
+ )
+{
+ //
+ // Check input parameters.
+ //
+ if (CShake256Context == NULL || HashValue == NULL) {
+ return FALSE;
+ }
+
+ //
+ // cSHAKE-256 Hash Finalization.
+ //
+ return (BOOLEAN) (sha3_final ((KECCAK1600_CTX *) CShake256Context, HashValue));
+}
+
+/**
+ Computes the CSHAKE-256 message digest of a input data buffer.
+
+ This function performs the CSHAKE-256 message digest of a given data buffer, and places
+ the digest value into the specified memory.
+
+ @param[in] Data Pointer to the buffer containing the data to be hashed.
+ @param[in] DataSize Size of Data buffer in bytes.
+ @param[in] OutputLen Size of output in bytes.
+ @param[in] Name Pointer to the function name string.
+ @param[in] NameLen Size of the function name in bytes.
+ @param[in] Customization Pointer to the customization string.
+ @param[in] CustomizationLen Size of the customization string in bytes.
+ @param[out] HashValue Pointer to a buffer that receives the CSHAKE-256 digest
+ value.
+
+ @retval TRUE CSHAKE-256 digest computation succeeded.
+ @retval FALSE CSHAKE-256 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CShake256HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ IN UINTN OutputLen,
+ IN CONST VOID *Name,
+ IN UINTN NameLen,
+ IN CONST VOID *Customization,
+ IN UINTN CustomizationLen,
+ OUT UINT8 *HashValue
+ )
+{
+ BOOLEAN Status;
+ KECCAK1600_CTX Ctx;
+
+ //
+ // Check input parameters.
+ //
+ if (HashValue == NULL) {
+ return FALSE;
+ }
+ if (Data == NULL && DataSize != 0) {
+ return FALSE;
+ }
+
+ Status = CShake256Init (&Ctx, OutputLen, Name, NameLen, Customization, CustomizationLen);
+ if (!Status) {
+ return FALSE;
+ }
+
+ Status = CShake256Update (&Ctx, Data, DataSize);
+ if (!Status) {
+ return FALSE;
+ }
+
+ return CShake256Final (&Ctx, HashValue);
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
new file mode 100644
index 0000000000..3eaa7c2ceb
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
@@ -0,0 +1,275 @@
+/** @file
+ ParallelHash Implementation.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+#include <Library\PcdLib.h>
+#include <Library\SynchronizationLib.h>
+#include <Library\MmServicesTableLib.h>
+
+
+UINT16 mBlockNum;
+UINTN mBlockSize;
+UINTN mLastBlockSize;
+UINT8 *mInput;
+UINTN mBlockResultSize;
+UINT8 *mBlockHashResult;
+BOOLEAN *mBlockIsCompleted;
+SPIN_LOCK *mSpinLockList;
+
+UINTN LeftEncode (OUT UINT8 *Encbuf, IN UINTN Value);
+UINTN RightEncode (OUT UINT8 *Encbuf, IN UINTN Value);
+
+BOOLEAN
+EFIAPI
+CShake256HashAll (
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ IN UINTN OutputLen,
+ IN CONST VOID *Name,
+ IN UINTN NameLen,
+ IN CONST VOID *Customization,
+ IN UINTN CustomizationLen,
+ OUT UINT8 *HashValue
+ );
+
+VOID
+EFIAPI
+ParallelHashApExecute (
+ IN VOID *ProcedureArgument
+ )
+{
+ UINTN Index;
+ BOOLEAN Status;
+
+ for (Index = 0; Index < mBlockNum; Index++) {
+ if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
+ //
+ // Completed, try next one.
+ //
+ if (mBlockIsCompleted[Index])
+ {
+ ReleaseSpinLock (&mSpinLockList[Index]);
+ continue;
+ }
+ //
+ // Calculate CShake256 for this block.
+ //
+ Status = CShake256HashAll (
+ mInput + Index * mBlockSize,
+ (Index == (mBlockNum - 1)) ? mLastBlockSize : mBlockSize,
+ mBlockResultSize,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ mBlockHashResult + Index * mBlockResultSize
+ );
+ if (!EFI_ERROR (Status)){
+ mBlockIsCompleted[Index] = TRUE;
+ }
+ ReleaseSpinLock (&mSpinLockList[Index]);
+ }
+ }
+}
+
+/**
+ Parallel hash function ParallelHash256, as defined in NIST's Special Publication 800-185,
+ published December 2016.
+
+ @param Input[in] Pointer to the input message (X).
+ @param InputByteLen[in] The number(>0) of input bytes provided for the input data.
+ @param Output[out] Pointer to the output buffer.
+ @param OutputByteLen[in] The desired number of output bytes (L).
+ @param Customization[in] Pointer to the customization string (S).
+ @param CustomByteLen[in] The length of the customization string in bytes.
+
+ @retval TRUE ParallelHash256 digest computation succeeded.
+ @retval FALSE ParallelHash256 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+*/
+BOOLEAN
+EFIAPI
+ParallelHash256HashAll (
+ IN CONST VOID *Input,
+ IN UINTN InputByteLen,
+ OUT VOID *Output,
+ IN UINTN OutputByteLen,
+ IN CONST VOID *Customization,
+ IN UINTN CustomByteLen
+ )
+
+{
+ UINT8 EncBufB[sizeof(UINTN)+1];
+ UINTN EncSizeB;
+ UINT8 EncBufN[sizeof(UINTN)+1];
+ UINTN EncSizeN;
+ UINT8 EncBufL[sizeof(UINTN)+1];
+ UINTN EncSizeL;
+ UINTN Index;
+ UINT8 *CombinedInput;
+ UINTN CombinedInputSize;
+ EFI_STATUS Status;
+ UINTN StartedApNum;
+ BOOLEAN AllCompleted;
+ UINTN Offset;
+ BOOLEAN ReturnValue;
+
+ if (InputByteLen == 0 || OutputByteLen == 0) {
+ return FALSE;
+ }
+
+ if (Input == NULL || Output == NULL){
+ return FALSE;
+ }
+
+ if (CustomByteLen != 0 && Customization == NULL){
+ return FALSE;
+ }
+
+ //
+ // Get Block number n.
+ //
+ mBlockNum = PcdGet16 (PcdParallelHashBlockNumber);
+
+ if (mBlockNum < 1 || InputByteLen < mBlockNum - 1){
+ return FALSE;
+ }
+
+ //
+ // Set hash result size of each block in bytes.
+ //
+ mBlockResultSize = OutputByteLen;
+
+ //
+ // calculate the block byte length B.
+ //
+ mBlockSize = InputByteLen % mBlockNum == 0 ? InputByteLen / mBlockNum : InputByteLen / (mBlockNum - 1);
+
+ //
+ // Encode B, n, L to string and record size.
+ //
+ EncSizeB = LeftEncode (EncBufB, mBlockSize);
+ EncSizeN = RightEncode (EncBufN, mBlockNum);
+ EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
+
+ //
+ // Allocate buffer for combined input (newX), Block completed flag and SpinLock.
+ //
+ CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum * mBlockResultSize;
+ CombinedInput = AllocateZeroPool (CombinedInputSize);
+ mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof (BOOLEAN));
+ mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
+ if (CombinedInput == NULL || mBlockIsCompleted == NULL || mSpinLockList == NULL) {
+ ReturnValue = FALSE;
+ goto Exit;
+ }
+
+ //
+ // Fill LeftEncode(B).
+ //
+ CopyMem (CombinedInput, EncBufB, EncSizeB);
+
+ //
+ // Prepare for parallel hash.
+ //
+ mBlockHashResult = CombinedInput + EncSizeB;
+ mInput = Input;
+ mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize : InputByteLen % mBlockSize;
+
+ //
+ // Initialize SpinLock for each result block.
+ //
+ for (Index = 0; Index < mBlockNum; Index++) {
+ InitializeSpinLock (&mSpinLockList[Index]);
+ }
+
+ //
+ // Dispatch blocklist to each AP.
+ //
+ StartedApNum = 0;
+ for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
+ if (Index != gMmst->CurrentlyExecutingCpu) {
+ Status = gMmst->MmStartupThisAp (ParallelHashApExecute, Index, NULL);
+ if (!EFI_ERROR (Status)) {
+ StartedApNum++;
+ }
+ }
+ }
+
+ //
+ // Wait until all block hash completed.
+ //
+ do {
+ AllCompleted = TRUE;
+ for (Index = 0; Index < mBlockNum; Index++) {
+ if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
+ if (!mBlockIsCompleted[Index]) {
+ AllCompleted = FALSE;
+ ReturnValue = CShake256HashAll (
+ mInput + Index * mBlockSize,
+ (Index == (mBlockNum - 1)) ? mLastBlockSize : mBlockSize,
+ mBlockResultSize,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ mBlockHashResult + Index * mBlockResultSize
+ );
+ if (ReturnValue){
+ mBlockIsCompleted[Index] = TRUE;
+ }
+ ReleaseSpinLock (&mSpinLockList[Index]);
+ break;
+ }
+ ReleaseSpinLock (&mSpinLockList[Index]);
+ } else {
+ AllCompleted = FALSE;
+ break;
+ }
+ }
+ } while (!AllCompleted);
+
+ //
+ // Fill LeftEncode(n).
+ //
+ Offset = EncSizeB + mBlockNum * mBlockResultSize;
+ CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
+
+ //
+ // Fill LeftEncode(L).
+ //
+ Offset += EncSizeN;
+ CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
+
+ ReturnValue = CShake256HashAll (
+ CombinedInput,
+ CombinedInputSize,
+ OutputByteLen,
+ PARALLELHASH_CUSTOMIZATION,
+ AsciiStrLen(PARALLELHASH_CUSTOMIZATION),
+ Customization,
+ CustomByteLen,
+ Output
+ );
+
+Exit:
+ ZeroMem (CombinedInput, CombinedInputSize);
+
+ if (CombinedInput != NULL){
+ FreePool (CombinedInput);
+ }
+ if (mSpinLockList != NULL){
+ FreePool (mSpinLockList);
+ }
+ if (mBlockIsCompleted != NULL){
+ FreePool (mBlockIsCompleted);
+ }
+
+ return ReturnValue;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
new file mode 100644
index 0000000000..b170c463de
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
@@ -0,0 +1,102 @@
+/** @file
+ SHA3 realted functions from OpenSSL.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
+Licensed under the OpenSSL license (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+https://www.openssl.org/source/license.html
+
+**/
+
+#include "sha3.h"
+
+size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
+ size_t r);
+void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
+
+int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t md_size)
+{
+ if (bsz <= sizeof(ctx->buf)) {
+ memset(ctx->A, 0, sizeof(ctx->A));
+
+ ctx->num = 0;
+ ctx->block_size = bsz;
+ ctx->md_size = md_size;
+ ctx->pad = pad;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
+{
+ const unsigned char *inp = _inp;
+ size_t bsz = ctx->block_size;
+ size_t num, rem;
+
+ if (len == 0)
+ return 1;
+
+ if ((num = ctx->num) != 0) { /* process intermediate buffer? */
+ rem = bsz - num;
+
+ if (len < rem) {
+ memcpy(ctx->buf + num, inp, len);
+ ctx->num += len;
+ return 1;
+ }
+ /*
+ * We have enough data to fill or overflow the intermediate
+ * buffer. So we append |rem| bytes and process the block,
+ * leaving the rest for later processing...
+ */
+ memcpy(ctx->buf + num, inp, rem);
+ inp += rem, len -= rem;
+ (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
+ ctx->num = 0;
+ /* ctx->buf is processed, ctx->num is guaranteed to be zero */
+ }
+
+ if (len >= bsz)
+ rem = SHA3_absorb(ctx->A, inp, len, bsz);
+ else
+ rem = len;
+
+ if (rem) {
+ memcpy(ctx->buf, inp + len - rem, rem);
+ ctx->num = rem;
+ }
+
+ return 1;
+}
+
+int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md)
+{
+ size_t bsz = ctx->block_size;
+ size_t num = ctx->num;
+
+ if (ctx->md_size == 0)
+ return 1;
+
+ /*
+ * Pad the data with 10*1. Note that |num| can be |bsz - 1|
+ * in which case both byte operations below are performed on
+ * same byte...
+ */
+ memset(ctx->buf + num, 0, bsz - num);
+ ctx->buf[num] = ctx->pad;
+ ctx->buf[bsz - 1] |= 0x80;
+
+ (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
+
+ SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
+
+ return 1;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
new file mode 100644
index 0000000000..b2a40ee044
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
@@ -0,0 +1,53 @@
+/** @file
+ Encode realted functions from Xkcp.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+The eXtended Keccak Code Package (XKCP)
+https://github.com/XKCP/XKCP
+Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche.
+Implementation by the designers, hereby denoted as "the implementer".
+For more information, feedback or questions, please refer to the Keccak Team website:
+https://keccak.team/
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+
+**/
+
+#include "xkcp.h"
+
+unsigned int left_encode(unsigned char * encbuf, size_t value)
+{
+ unsigned int n, i;
+ size_t v;
+
+ for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
+ ; /* empty */
+ if (n == 0)
+ n = 1;
+ for ( i = 1; i <= n; ++i )
+ {
+ encbuf[i] = (unsigned char)(value >> (8 * (n-i)));
+ }
+ encbuf[0] = (unsigned char)n;
+ return n + 1;
+}
+
+unsigned int right_encode(unsigned char * encbuf, size_t value)
+{
+ unsigned int n, i;
+ size_t v;
+
+ for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
+ ; /* empty */
+ if (n == 0)
+ n = 1;
+ for ( i = 1; i <= n; ++i )
+ {
+ encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
+ }
+ encbuf[n] = (unsigned char)n;
+ return n + 1;
+}
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
new file mode 100644
index 0000000000..052ab3a0d6
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
@@ -0,0 +1,152 @@
+/** @file
+ Application for Parallelhash Function Validation.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+//
+// Parallelhash Test Sample common parameters.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN OutputByteLen = 64;
+
+//
+// Parallelhash Test Sample #1 from NIST Special Publication 800-185.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample1[] = {
+ // input data of sample1.
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
+};
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample1ByteLen = 24; // Length of sample1 input data in bytes.
+GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID *CustomizationSample1 = ""; // Customization string (S) of sample1.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN CustomSample1ByteLen = 0; // Customization string length of sample1 in bytes.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample1 = 8; // Block size of sample1.
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 ExpectOutputSample1[] = {
+ // Expected output data of sample1.
+ 0xbc, 0x1e, 0xf1, 0x24, 0xda, 0x34, 0x49, 0x5e, 0x94, 0x8e, 0xad, 0x20, 0x7d, 0xd9, 0x84, 0x22,
+ 0x35, 0xda, 0x43, 0x2d, 0x2b, 0xbc, 0x54, 0xb4, 0xc1, 0x10, 0xe6, 0x4c, 0x45, 0x11, 0x05, 0x53,
+ 0x1b, 0x7f, 0x2a, 0x3e, 0x0c, 0xe0, 0x55, 0xc0, 0x28, 0x05, 0xe7, 0xc2, 0xde, 0x1f, 0xb7, 0x46,
+ 0xaf, 0x97, 0xa1, 0xd0, 0x01, 0xf4, 0x3b, 0x82, 0x4e, 0x31, 0xb8, 0x76, 0x12, 0x41, 0x04, 0x29
+};
+
+//
+// Parallelhash Test Sample #2 from NIST Special Publication 800-185.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 *InputSample2 = InputSample1; // Input of sample2 is same as sample1.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample2ByteLen = 24; // Length of sample2 input data in bytes.
+GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID *CustomizationSample2 = "Parallel Data"; // Customization string (S) of sample2.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN CustomSample2ByteLen = 13; // Customization string length of sample2 in bytes.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample2 = 8; // Block size of sample2.
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 ExpectOutputSample2[] = {
+ // Expected output data of sample2.
+ 0xcd, 0xf1, 0x52, 0x89, 0xb5, 0x4f, 0x62, 0x12, 0xb4, 0xbc, 0x27, 0x05, 0x28, 0xb4, 0x95, 0x26,
+ 0x00, 0x6d, 0xd9, 0xb5, 0x4e, 0x2b, 0x6a, 0xdd, 0x1e, 0xf6, 0x90, 0x0d, 0xda, 0x39, 0x63, 0xbb,
+ 0x33, 0xa7, 0x24, 0x91, 0xf2, 0x36, 0x96, 0x9c, 0xa8, 0xaf, 0xae, 0xa2, 0x9c, 0x68, 0x2d, 0x47,
+ 0xa3, 0x93, 0xc0, 0x65, 0xb3, 0x8e, 0x29, 0xfa, 0xe6, 0x51, 0xa2, 0x09, 0x1c, 0x83, 0x31, 0x10
+};
+
+//
+// Parallelhash Test Sample #3 from NIST Special Publication 800-185.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample3[] = {
+ // input data of sample3.
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
+};
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample3ByteLen = 72; // Length of sample3 input data in bytes.
+GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID *CustomizationSample3 = "Parallel Data"; // Customization string (S) of sample3.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN CustomSample3ByteLen = 13; // Customization string length of sample3 in bytes.
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample3 = 12; // Block size of sample3.
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 ExpectOutputSample3[] = {
+ // Expected output data of sample3.
+ 0x69, 0xd0, 0xfc, 0xb7, 0x64, 0xea, 0x05, 0x5d, 0xd0, 0x93, 0x34, 0xbc, 0x60, 0x21, 0xcb, 0x7e,
+ 0x4b, 0x61, 0x34, 0x8d, 0xff, 0x37, 0x5d, 0xa2, 0x62, 0x67, 0x1c, 0xde, 0xc3, 0xef, 0xfa, 0x8d,
+ 0x1b, 0x45, 0x68, 0xa6, 0xcc, 0xe1, 0x6b, 0x1c, 0xad, 0x94, 0x6d, 0xdd, 0xe2, 0x7f, 0x6c, 0xe2,
+ 0xb8, 0xde, 0xe4, 0xcd, 0x1b, 0x24, 0x85, 0x1e, 0xbf, 0x00, 0xeb, 0x90, 0xd4, 0x38, 0x13, 0xe9
+};
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyParallelHash256HashAll (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ BOOLEAN Status;
+ UINT16 OriginalParallelHashBlockNumber;
+ UINT8 Output[64];
+
+ // Restore original PcdParallelHashBlockNumber.
+ OriginalParallelHashBlockNumber = PcdGet16 (PcdParallelHashBlockNumber);
+
+ //
+ // Test #1 using sample1.
+ //
+ PcdSet16S (PcdParallelHashBlockNumber, InputSample1ByteLen / BlockSizeSample1);
+ Status = ParallelHash256HashAll (
+ InputSample1,
+ InputSample1ByteLen,
+ Output,
+ OutputByteLen,
+ CustomizationSample1,
+ CustomSample1ByteLen
+ );
+ UT_ASSERT_TRUE (Status);
+
+ // Check the output with the expected output.
+ UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample1, OutputByteLen);
+
+ //
+ // Test #2 using sample2.
+ //
+ PcdSet16S (PcdParallelHashBlockNumber, InputSample2ByteLen / BlockSizeSample2);
+ Status = ParallelHash256HashAll (
+ InputSample2,
+ InputSample2ByteLen,
+ Output,
+ OutputByteLen,
+ CustomizationSample2,
+ CustomSample2ByteLen
+ );
+ UT_ASSERT_TRUE (Status);
+
+ // Check the output with the expected output.
+ UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample2, OutputByteLen);
+
+ //
+ // Test #3 using sample3.
+ //
+ PcdSet16S (PcdParallelHashBlockNumber, InputSample3ByteLen / BlockSizeSample3);
+ Status = ParallelHash256HashAll (
+ InputSample3,
+ InputSample3ByteLen,
+ Output,
+ OutputByteLen,
+ CustomizationSample3,
+ CustomSample3ByteLen
+ );
+ UT_ASSERT_TRUE (Status);
+
+ // Check the output with the expected output.
+ UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample3, OutputByteLen);
+
+ // Recover original PcdParallelHashBlockNumber.
+ PcdSet16S (PcdParallelHashBlockNumber, OriginalParallelHashBlockNumber);
+
+ return EFI_SUCCESS;
+}
+
+TEST_DESC mParallelhashTest[] = {
+ //
+ // -----Description------------------------------Class----------------------Function-----------------Pre---Post--Context
+ //
+ { "TestVerifyParallelHash256HashAll()", "CryptoPkg.BaseCryptLib.ParallelHash256HashAll", TestVerifyParallelHash256HashAll, NULL, NULL, NULL },
+};
+
+UINTN mParallelhashTestNum = ARRAY_SIZE (mParallelhashTest);
diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
index 5888941bab..3af55d9c10 100644
--- a/CryptoPkg/CryptoPkg.dec
+++ b/CryptoPkg/CryptoPkg.dec
@@ -4,7 +4,7 @@
# This Package provides cryptographic-related libraries for UEFI security modules.
# It also provides a test application to test libraries.
#
-# Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -81,5 +81,12 @@
# @ValidList 0x80000001 | 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010
gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x00000002|UINT32|0x00000001
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+ ## This PCD indicates the block number of parallel hash
+ # Based on the value set, parallel hash can chose the block
+ # number to calculate specific hash.<BR>
+ # The number can be set by platform team according to the core number.
+ gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber|0x0100|UINT16|0x00000003
+
[UserExtensions.TianoCore."ExtraFiles"]
CryptoPkgExtra.uni
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index f4bc7c0d73..0b274b1257 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -4,7 +4,7 @@
primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security
functionality enabling.
-Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -753,6 +753,33 @@ Sha512HashAll (
OUT UINT8 *HashValue
);
+/**
+ Parallel hash function ParallelHash256, as defined in NIST's Special Publication 800-185,
+ published December 2016.
+
+ @param[in] Input Pointer to the input message (X).
+ @param[in] InputByteLen The number(>0) of input bytes provided for the input data.
+ @param[out] Output Pointer to the output buffer.
+ @param[in] OutputByteLen The desired number of output bytes (L).
+ @param[in] Customization Pointer to the customization string (S).
+ @param[in] CustomByteLen The length of the customization string in bytes.
+
+ @retval TRUE ParallelHash256 digest computation succeeded.
+ @retval FALSE ParallelHash256 digest computation failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ParallelHash256HashAll (
+ IN CONST VOID *Input,
+ IN UINTN InputByteLen,
+ OUT VOID *Output,
+ IN UINTN OutputByteLen,
+ IN CONST VOID *Customization,
+ IN UINTN CustomByteLen
+ );
+
/**
Retrieves the size, in bytes, of the context buffer required for SM3 hash operations.
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index e6470d7a21..70159163d4 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -10,7 +10,7 @@
# RSA external functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and
# authenticode signature verification functions are not supported in this instance.
#
-# Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -38,6 +38,10 @@
Hash/CryptSha256.c
Hash/CryptSm3.c
Hash/CryptSha512.c
+ Hash/CryptSha3.c
+ Hash/CryptXkcp.c
+ Hash/CryptCShake256.c
+ Hash/CryptParallelHash.c
Hmac/CryptHmacSha256.c
Kdf/CryptHkdfNull.c
Cipher/CryptAes.c
@@ -85,6 +89,9 @@
OpensslLib
IntrinsicLib
PrintLib
+ MmServicesTableLib
+ SynchronizationLib
+ PcdLib
#
# Remove these [BuildOptions] after this library is cleaned up
@@ -101,3 +108,6 @@
GCC:*_CLANG35_*_CC_FLAGS = -std=c99
GCC:*_CLANG38_*_CC_FLAGS = -std=c99
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
+
+[Pcd]
+ gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h b/CryptoPkg/Library/Include/CrtLibSupport.h
index d257dca8fa..35d9c62a0b 100644
--- a/CryptoPkg/Library/Include/CrtLibSupport.h
+++ b/CryptoPkg/Library/Include/CrtLibSupport.h
@@ -2,7 +2,7 @@
Root include file of C runtime library to support building the third-party
cryptographic library.
-Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define MAX_STRING_SIZE 0x1000
+#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
+
//
// We already have "no-ui" in out Configure invocation.
// but the code still fails to compile.
@@ -111,6 +113,7 @@ typedef UINT8 u_char;
typedef UINT32 uid_t;
typedef UINT32 gid_t;
typedef CHAR16 wchar_t;
+typedef UINT64 uint64_t;
//
// File operations are not required for EFI building,
diff --git a/CryptoPkg/Library/Include/sha3.h b/CryptoPkg/Library/Include/sha3.h
new file mode 100644
index 0000000000..71b4c75548
--- /dev/null
+++ b/CryptoPkg/Library/Include/sha3.h
@@ -0,0 +1,32 @@
+/** @file
+ SHA3 realted functions from OpenSSL.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
+Licensed under the OpenSSL license (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+https://www.openssl.org/source/license.html
+
+**/
+
+#include <CrtLibSupport.h>
+
+#define KECCAK1600_WIDTH 1600
+
+typedef struct {
+ uint64_t A[5][5];
+ size_t block_size; /* cached ctx->digest->block_size */
+ size_t md_size; /* output length, variable in XOF */
+ size_t num; /* used bytes in below buffer */
+ unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
+ unsigned char pad;
+} KECCAK1600_CTX;
+
+int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t md_size);
+
+int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
+
+int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md);
diff --git a/CryptoPkg/Library/Include/xkcp.h b/CryptoPkg/Library/Include/xkcp.h
new file mode 100644
index 0000000000..b328d672e4
--- /dev/null
+++ b/CryptoPkg/Library/Include/xkcp.h
@@ -0,0 +1,23 @@
+/** @file
+ Encode realted functions from Xkcp.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+The eXtended Keccak Code Package (XKCP)
+https://github.com/XKCP/XKCP
+Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche.
+Implementation by the designers, hereby denoted as "the implementer".
+For more information, feedback or questions, please refer to the Keccak Team website:
+https://keccak.team/
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+
+**/
+
+#include <CrtLibSupport.h>
+
+unsigned int left_encode(unsigned char * encbuf, size_t value);
+
+unsigned int right_encode(unsigned char * encbuf, size_t value);
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index a6b3482742..0bffd687c2 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -1,7 +1,7 @@
/** @file
Application for Cryptographic Primitives Validation.
-Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
// #include <UnitTestTypes.h>
#include <Library/UnitTestLib.h>
// #include <Library/UnitTestAssertLib.h>
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 00c8692650..61a59d6a47 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -2,6 +2,7 @@
# Host-based UnitTest for BaseCryptLib
#
# Copyright (c) Microsoft Corporation.<BR>
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -35,6 +36,7 @@
Pkcs7EkuTests.c
OaepEncryptTests.c
RsaPssTests.c
+ ParallelhashTests.c
[Packages]
MdePkg/MdePkg.dec
@@ -45,3 +47,8 @@
DebugLib
BaseCryptLib
UnitTestLib
+ PcdLib
+
+[Pcd]
+ gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
+
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index ca789aa6ad..682f25a754 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -2,6 +2,7 @@
# BaseCryptLib UnitTest built for execution in UEFI Shell.
#
# Copyright (c) Microsoft Corporation.<BR>
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -36,6 +37,7 @@
Pkcs7EkuTests.c
OaepEncryptTests.c
RsaPssTests.c
+ ParallelhashTests.c
[Packages]
MdePkg/MdePkg.dec
@@ -48,3 +50,7 @@
UnitTestLib
PrintLib
BaseCryptLib
+ PcdLib
+
+[Pcd]
+ gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
--
2.26.2.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
2022-02-11 9:05 [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib Li, Zhihao
@ 2022-02-15 6:08 ` Yao, Jiewen
2022-02-16 7:43 ` Li, Zhihao
0 siblings, 1 reply; 6+ messages in thread
From: Yao, Jiewen @ 2022-02-15 6:08 UTC (permalink / raw)
To: Li, Zhihao, devel@edk2.groups.io
Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin, Fu, Siyuan
Thanks for the update.
Feedback below:
1) How block size is determined for below API?
BOOLEAN
EFIAPI
ParallelHash256HashAll (
IN CONST VOID *Input,
IN UINTN InputByteLen,
OUT VOID *Output,
IN UINTN OutputByteLen,
IN CONST VOID *Customization,
IN UINTN CustomByteLen
);
Is that determined by PcdParallelHashBlockNumber ?
I don’t think it is good idea to let a crypto library determine a platform PCD.
For example, how do you support binary crypto module ?
2) Why we need "sha3.h" and "xkcp.h" ?
These are openssl specific structure. It shall not be put to EDKII file header.
CryptoPkg\Library\Include shall only contain generic dependency header.
Thank you
Yao, Jiewen
> -----Original Message-----
> From: Li, Zhihao <zhihao.li@intel.com>
> Sent: Friday, February 11, 2022 5:05 PM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>;
> Fu, Siyuan <siyuan.fu@intel.com>
> Subject: [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll
> in BaseCryptLib.
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3596
>
> Parallel hash function ParallelHash256HashAll, as defined in NIST's
> Special Publication 800-185, published December 2016. It utilizes
> multi-process to calculate the digest.
>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> Cc: Guomin Jiang <guomin.jiang@intel.com>
> Cc: Siyuan Fu <siyuan.fu@intel.com>
>
> Signed-off-by: Zhihao Li <zhihao.li@intel.com>
> ---
> CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c | 313
> ++++++++++++++++++++
> CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c | 275
> +++++++++++++++++
> CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c | 102 +++++++
> CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c | 53 ++++
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c | 152
> ++++++++++
> CryptoPkg/CryptoPkg.dec | 9 +-
> CryptoPkg/Include/Library/BaseCryptLib.h | 29 +-
> CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 12 +-
> CryptoPkg/Library/Include/CrtLibSupport.h | 5 +-
> CryptoPkg/Library/Include/sha3.h | 32 ++
> CryptoPkg/Library/Include/xkcp.h | 23 ++
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3 +-
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf | 7 +
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf | 6 +
> 14 files changed, 1016 insertions(+), 5 deletions(-)
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> new file mode 100644
> index 0000000000..5efced3f46
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> @@ -0,0 +1,313 @@
> +/** @file
>
> + cSHAKE-256 Digest Wrapper Implementations.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include "InternalCryptLib.h"
>
> +#include "sha3.h"
>
> +#include "xkcp.h"
>
> +
>
> +#define CSHAKE256_SECURITY_STRENGTH 256
>
> +#define CSHAKE256_RATE_IN_BYTES 136
>
> +
>
> +const CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = {0};
>
> +
>
> +UINTN
>
> +EFIAPI
>
> +LeftEncode (
>
> + OUT UINT8 *Encbuf,
>
> + IN UINTN Value
>
> + )
>
> +{
>
> + return left_encode (Encbuf, Value);
>
> +}
>
> +
>
> +UINTN
>
> +EFIAPI
>
> +RightEncode (
>
> + OUT UINT8 *Encbuf,
>
> + IN UINTN Value
>
> + )
>
> +{
>
> + return right_encode (Encbuf, Value);
>
> +}
>
> +
>
> +/**
>
> + Retrieves the size, in bytes, of the context buffer required for cSHAKE-256
> hash operations.
>
> +
>
> + @return The size, in bytes, of the context buffer required for cSHAKE-256
> hash operations.
>
> +
>
> +**/
>
> +UINTN
>
> +EFIAPI
>
> +CShake256GetContextSize (
>
> + VOID
>
> + )
>
> +{
>
> + return (UINTN) (sizeof (KECCAK1600_CTX));
>
> +}
>
> +
>
> +/**
>
> + Initializes user-supplied memory pointed by CShake256Context as cSHAKE-256
> hash context for
>
> + subsequent use.
>
> +
>
> + @param[out] CShake256Context Pointer to cSHAKE-256 context being
> initialized.
>
> + @param[in] OutputLen The desired number of output length in bytes.
>
> + @param[in] Name Pointer to the function name string.
>
> + @param[in] NameLen The length of the function name in bytes.
>
> + @param[in] Customization Pointer to the customization string.
>
> + @param[in] CustomizationLen The length of the customization string in
> bytes.
>
> +
>
> + @retval TRUE cSHAKE-256 context initialization succeeded.
>
> + @retval FALSE cSHAKE-256 context initialization failed.
>
> + @retval FALSE This interface is not supported.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +CShake256Init (
>
> + OUT VOID *CShake256Context,
>
> + IN UINTN OutputLen,
>
> + IN CONST VOID *Name,
>
> + IN UINTN NameLen,
>
> + IN CONST VOID *Customization,
>
> + IN UINTN CustomizationLen
>
> + )
>
> +{
>
> + BOOLEAN Status;
>
> + unsigned char EncBuf[sizeof(size_t)+1];
>
> + UINTN EncLen;
>
> + UINTN AbsorbLen;
>
> + UINTN PadLen;
>
> +
>
> + //
>
> + // Check input parameters.
>
> + //
>
> + if (CShake256Context == NULL ||
>
> + OutputLen == 0 ||
>
> + (NameLen != 0 && Name == NULL) ||
>
> + (CustomizationLen != 0 && Customization == NULL)) {
>
> + return FALSE;
>
> + }
>
> +
>
> + //
>
> + // Initialize KECCAK context with pad value and block size.
>
> + //
>
> + if (NameLen == 0 && CustomizationLen == 0) {
>
> + //
>
> + // When N and S are both empty strings, cSHAKE(X, L, N, S) is equivalent to
>
> + // SHAKE as defined in FIPS 202.
>
> + //
>
> + return (BOOLEAN) init (
>
> + (KECCAK1600_CTX *) CShake256Context,
>
> + '\x1f',
>
> + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,
>
> + OutputLen
>
> + );
>
> + }
>
> +
>
> + Status = (BOOLEAN) init (
>
> + (KECCAK1600_CTX *) CShake256Context,
>
> + '\x04',
>
> + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,
>
> + OutputLen
>
> + );
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> +
>
> + AbsorbLen = 0;
>
> + //
>
> + // Absorb Absorb bytepad(.., rate).
>
> + //
>
> + EncLen = left_encode (EncBuf, CSHAKE256_RATE_IN_BYTES);
>
> + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context,
> EncBuf, EncLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> + AbsorbLen += EncLen;
>
> +
>
> + //
>
> + // Absorb encode_string(N).
>
> + //
>
> + EncLen = left_encode (EncBuf, NameLen * 8);
>
> + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context,
> EncBuf, EncLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> + AbsorbLen += EncLen;
>
> + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context,
> Name, NameLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> + AbsorbLen += NameLen;
>
> +
>
> + //
>
> + // Absorb encode_string(S).
>
> + //
>
> + EncLen = left_encode (EncBuf, CustomizationLen * 8);
>
> + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context,
> EncBuf, EncLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> + AbsorbLen += EncLen;
>
> + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context,
> Customization, CustomizationLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> + AbsorbLen += CustomizationLen;
>
> +
>
> + //
>
> + // Absorb zero padding up to rate.
>
> + //
>
> + PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen %
> CSHAKE256_RATE_IN_BYTES;
>
> + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *) CShake256Context,
> mZeroPadding, PadLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> +
>
> + return TRUE;
>
> +}
>
> +
>
> +/**
>
> + Digests the input data and updates cSHAKE-256 context.
>
> +
>
> + This function performs cSHAKE-256 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.
>
> + cSHAKE-256 context should be already correctly initialized by CShake256Init(),
> and should not be finalized
>
> + by CShake256Final(). Behavior with invalid context is undefined.
>
> +
>
> + @param[in, out] CShake256Context Pointer to the cSHAKE-256 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 cSHAKE-256 data digest succeeded.
>
> + @retval FALSE cSHAKE-256 data digest failed.
>
> + @retval FALSE This interface is not supported.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +CShake256Update (
>
> + IN OUT VOID *CShake256Context,
>
> + IN CONST VOID *Data,
>
> + IN UINTN DataSize
>
> + )
>
> +{
>
> + //
>
> + // Check input parameters.
>
> + //
>
> + if (CShake256Context == NULL) {
>
> + return FALSE;
>
> + }
>
> +
>
> + //
>
> + // Check invalid parameters, in case that only DataLength was checked in
> OpenSSL.
>
> + //
>
> + if (Data == NULL && DataSize != 0) {
>
> + return FALSE;
>
> + }
>
> +
>
> + return (BOOLEAN)(sha3_update ((KECCAK1600_CTX *) CShake256Context,
> Data, DataSize));
>
> +}
>
> +
>
> +/**
>
> + Completes computation of the cSHAKE-256 digest value.
>
> +
>
> + This function completes cSHAKE-256 hash computation and retrieves the
> digest value into
>
> + the specified memory. After this function has been called, the cSHAKE-256
> context cannot
>
> + be used again.
>
> + cSHAKE-256 context should be already correctly initialized by CShake256Init(),
> and should not be
>
> + finalized by CShake256Final(). Behavior with invalid cSHAKE-256 context is
> undefined.
>
> +
>
> + @param[in, out] CShake256Context Pointer to the cSHAKE-256 context.
>
> + @param[out] HashValue Pointer to a buffer that receives the cSHAKE-
> 256 digest
>
> + value.
>
> +
>
> + @retval TRUE cSHAKE-256 digest computation succeeded.
>
> + @retval FALSE cSHAKE-256 digest computation failed.
>
> + @retval FALSE This interface is not supported.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +CShake256Final (
>
> + IN OUT VOID *CShake256Context,
>
> + OUT UINT8 *HashValue
>
> + )
>
> +{
>
> + //
>
> + // Check input parameters.
>
> + //
>
> + if (CShake256Context == NULL || HashValue == NULL) {
>
> + return FALSE;
>
> + }
>
> +
>
> + //
>
> + // cSHAKE-256 Hash Finalization.
>
> + //
>
> + return (BOOLEAN) (sha3_final ((KECCAK1600_CTX *) CShake256Context,
> HashValue));
>
> +}
>
> +
>
> +/**
>
> + Computes the CSHAKE-256 message digest of a input data buffer.
>
> +
>
> + This function performs the CSHAKE-256 message digest of a given data buffer,
> and places
>
> + the digest value into the specified memory.
>
> +
>
> + @param[in] Data Pointer to the buffer containing the data to be
> hashed.
>
> + @param[in] DataSize Size of Data buffer in bytes.
>
> + @param[in] OutputLen Size of output in bytes.
>
> + @param[in] Name Pointer to the function name string.
>
> + @param[in] NameLen Size of the function name in bytes.
>
> + @param[in] Customization Pointer to the customization string.
>
> + @param[in] CustomizationLen Size of the customization string in bytes.
>
> + @param[out] HashValue Pointer to a buffer that receives the CSHAKE-
> 256 digest
>
> + value.
>
> +
>
> + @retval TRUE CSHAKE-256 digest computation succeeded.
>
> + @retval FALSE CSHAKE-256 digest computation failed.
>
> + @retval FALSE This interface is not supported.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +CShake256HashAll (
>
> + IN CONST VOID *Data,
>
> + IN UINTN DataSize,
>
> + IN UINTN OutputLen,
>
> + IN CONST VOID *Name,
>
> + IN UINTN NameLen,
>
> + IN CONST VOID *Customization,
>
> + IN UINTN CustomizationLen,
>
> + OUT UINT8 *HashValue
>
> + )
>
> +{
>
> + BOOLEAN Status;
>
> + KECCAK1600_CTX Ctx;
>
> +
>
> + //
>
> + // Check input parameters.
>
> + //
>
> + if (HashValue == NULL) {
>
> + return FALSE;
>
> + }
>
> + if (Data == NULL && DataSize != 0) {
>
> + return FALSE;
>
> + }
>
> +
>
> + Status = CShake256Init (&Ctx, OutputLen, Name, NameLen, Customization,
> CustomizationLen);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> +
>
> + Status = CShake256Update (&Ctx, Data, DataSize);
>
> + if (!Status) {
>
> + return FALSE;
>
> + }
>
> +
>
> + return CShake256Final (&Ctx, HashValue);
>
> +}
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> new file mode 100644
> index 0000000000..3eaa7c2ceb
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> @@ -0,0 +1,275 @@
> +/** @file
>
> + ParallelHash Implementation.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include "InternalCryptLib.h"
>
> +#include <Library\PcdLib.h>
>
> +#include <Library\SynchronizationLib.h>
>
> +#include <Library\MmServicesTableLib.h>
>
> +
>
> +
>
> +UINT16 mBlockNum;
>
> +UINTN mBlockSize;
>
> +UINTN mLastBlockSize;
>
> +UINT8 *mInput;
>
> +UINTN mBlockResultSize;
>
> +UINT8 *mBlockHashResult;
>
> +BOOLEAN *mBlockIsCompleted;
>
> +SPIN_LOCK *mSpinLockList;
>
> +
>
> +UINTN LeftEncode (OUT UINT8 *Encbuf, IN UINTN Value);
>
> +UINTN RightEncode (OUT UINT8 *Encbuf, IN UINTN Value);
>
> +
>
> +BOOLEAN
>
> +EFIAPI
>
> +CShake256HashAll (
>
> + IN CONST VOID *Data,
>
> + IN UINTN DataSize,
>
> + IN UINTN OutputLen,
>
> + IN CONST VOID *Name,
>
> + IN UINTN NameLen,
>
> + IN CONST VOID *Customization,
>
> + IN UINTN CustomizationLen,
>
> + OUT UINT8 *HashValue
>
> + );
>
> +
>
> +VOID
>
> +EFIAPI
>
> +ParallelHashApExecute (
>
> + IN VOID *ProcedureArgument
>
> + )
>
> +{
>
> + UINTN Index;
>
> + BOOLEAN Status;
>
> +
>
> + for (Index = 0; Index < mBlockNum; Index++) {
>
> + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
>
> + //
>
> + // Completed, try next one.
>
> + //
>
> + if (mBlockIsCompleted[Index])
>
> + {
>
> + ReleaseSpinLock (&mSpinLockList[Index]);
>
> + continue;
>
> + }
>
> + //
>
> + // Calculate CShake256 for this block.
>
> + //
>
> + Status = CShake256HashAll (
>
> + mInput + Index * mBlockSize,
>
> + (Index == (mBlockNum - 1)) ? mLastBlockSize : mBlockSize,
>
> + mBlockResultSize,
>
> + NULL,
>
> + 0,
>
> + NULL,
>
> + 0,
>
> + mBlockHashResult + Index * mBlockResultSize
>
> + );
>
> + if (!EFI_ERROR (Status)){
>
> + mBlockIsCompleted[Index] = TRUE;
>
> + }
>
> + ReleaseSpinLock (&mSpinLockList[Index]);
>
> + }
>
> + }
>
> +}
>
> +
>
> +/**
>
> + Parallel hash function ParallelHash256, as defined in NIST's Special Publication
> 800-185,
>
> + published December 2016.
>
> +
>
> + @param Input[in] Pointer to the input message (X).
>
> + @param InputByteLen[in] The number(>0) of input bytes provided for the
> input data.
>
> + @param Output[out] Pointer to the output buffer.
>
> + @param OutputByteLen[in] The desired number of output bytes (L).
>
> + @param Customization[in] Pointer to the customization string (S).
>
> + @param CustomByteLen[in] The length of the customization string in bytes.
>
> +
>
> + @retval TRUE ParallelHash256 digest computation succeeded.
>
> + @retval FALSE ParallelHash256 digest computation failed.
>
> + @retval FALSE This interface is not supported.
>
> +
>
> +*/
>
> +BOOLEAN
>
> +EFIAPI
>
> +ParallelHash256HashAll (
>
> + IN CONST VOID *Input,
>
> + IN UINTN InputByteLen,
>
> + OUT VOID *Output,
>
> + IN UINTN OutputByteLen,
>
> + IN CONST VOID *Customization,
>
> + IN UINTN CustomByteLen
>
> + )
>
> +
>
> +{
>
> + UINT8 EncBufB[sizeof(UINTN)+1];
>
> + UINTN EncSizeB;
>
> + UINT8 EncBufN[sizeof(UINTN)+1];
>
> + UINTN EncSizeN;
>
> + UINT8 EncBufL[sizeof(UINTN)+1];
>
> + UINTN EncSizeL;
>
> + UINTN Index;
>
> + UINT8 *CombinedInput;
>
> + UINTN CombinedInputSize;
>
> + EFI_STATUS Status;
>
> + UINTN StartedApNum;
>
> + BOOLEAN AllCompleted;
>
> + UINTN Offset;
>
> + BOOLEAN ReturnValue;
>
> +
>
> + if (InputByteLen == 0 || OutputByteLen == 0) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if (Input == NULL || Output == NULL){
>
> + return FALSE;
>
> + }
>
> +
>
> + if (CustomByteLen != 0 && Customization == NULL){
>
> + return FALSE;
>
> + }
>
> +
>
> + //
>
> + // Get Block number n.
>
> + //
>
> + mBlockNum = PcdGet16 (PcdParallelHashBlockNumber);
>
> +
>
> + if (mBlockNum < 1 || InputByteLen < mBlockNum - 1){
>
> + return FALSE;
>
> + }
>
> +
>
> + //
>
> + // Set hash result size of each block in bytes.
>
> + //
>
> + mBlockResultSize = OutputByteLen;
>
> +
>
> + //
>
> + // calculate the block byte length B.
>
> + //
>
> + mBlockSize = InputByteLen % mBlockNum == 0 ? InputByteLen / mBlockNum :
> InputByteLen / (mBlockNum - 1);
>
> +
>
> + //
>
> + // Encode B, n, L to string and record size.
>
> + //
>
> + EncSizeB = LeftEncode (EncBufB, mBlockSize);
>
> + EncSizeN = RightEncode (EncBufN, mBlockNum);
>
> + EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
>
> +
>
> + //
>
> + // Allocate buffer for combined input (newX), Block completed flag and
> SpinLock.
>
> + //
>
> + CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum *
> mBlockResultSize;
>
> + CombinedInput = AllocateZeroPool (CombinedInputSize);
>
> + mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof (BOOLEAN));
>
> + mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
>
> + if (CombinedInput == NULL || mBlockIsCompleted == NULL || mSpinLockList
> == NULL) {
>
> + ReturnValue = FALSE;
>
> + goto Exit;
>
> + }
>
> +
>
> + //
>
> + // Fill LeftEncode(B).
>
> + //
>
> + CopyMem (CombinedInput, EncBufB, EncSizeB);
>
> +
>
> + //
>
> + // Prepare for parallel hash.
>
> + //
>
> + mBlockHashResult = CombinedInput + EncSizeB;
>
> + mInput = Input;
>
> + mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize :
> InputByteLen % mBlockSize;
>
> +
>
> + //
>
> + // Initialize SpinLock for each result block.
>
> + //
>
> + for (Index = 0; Index < mBlockNum; Index++) {
>
> + InitializeSpinLock (&mSpinLockList[Index]);
>
> + }
>
> +
>
> + //
>
> + // Dispatch blocklist to each AP.
>
> + //
>
> + StartedApNum = 0;
>
> + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
>
> + if (Index != gMmst->CurrentlyExecutingCpu) {
>
> + Status = gMmst->MmStartupThisAp (ParallelHashApExecute, Index, NULL);
>
> + if (!EFI_ERROR (Status)) {
>
> + StartedApNum++;
>
> + }
>
> + }
>
> + }
>
> +
>
> + //
>
> + // Wait until all block hash completed.
>
> + //
>
> + do {
>
> + AllCompleted = TRUE;
>
> + for (Index = 0; Index < mBlockNum; Index++) {
>
> + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
>
> + if (!mBlockIsCompleted[Index]) {
>
> + AllCompleted = FALSE;
>
> + ReturnValue = CShake256HashAll (
>
> + mInput + Index * mBlockSize,
>
> + (Index == (mBlockNum - 1)) ? mLastBlockSize : mBlockSize,
>
> + mBlockResultSize,
>
> + NULL,
>
> + 0,
>
> + NULL,
>
> + 0,
>
> + mBlockHashResult + Index * mBlockResultSize
>
> + );
>
> + if (ReturnValue){
>
> + mBlockIsCompleted[Index] = TRUE;
>
> + }
>
> + ReleaseSpinLock (&mSpinLockList[Index]);
>
> + break;
>
> + }
>
> + ReleaseSpinLock (&mSpinLockList[Index]);
>
> + } else {
>
> + AllCompleted = FALSE;
>
> + break;
>
> + }
>
> + }
>
> + } while (!AllCompleted);
>
> +
>
> + //
>
> + // Fill LeftEncode(n).
>
> + //
>
> + Offset = EncSizeB + mBlockNum * mBlockResultSize;
>
> + CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
>
> +
>
> + //
>
> + // Fill LeftEncode(L).
>
> + //
>
> + Offset += EncSizeN;
>
> + CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
>
> +
>
> + ReturnValue = CShake256HashAll (
>
> + CombinedInput,
>
> + CombinedInputSize,
>
> + OutputByteLen,
>
> + PARALLELHASH_CUSTOMIZATION,
>
> + AsciiStrLen(PARALLELHASH_CUSTOMIZATION),
>
> + Customization,
>
> + CustomByteLen,
>
> + Output
>
> + );
>
> +
>
> +Exit:
>
> + ZeroMem (CombinedInput, CombinedInputSize);
>
> +
>
> + if (CombinedInput != NULL){
>
> + FreePool (CombinedInput);
>
> + }
>
> + if (mSpinLockList != NULL){
>
> + FreePool (mSpinLockList);
>
> + }
>
> + if (mBlockIsCompleted != NULL){
>
> + FreePool (mBlockIsCompleted);
>
> + }
>
> +
>
> + return ReturnValue;
>
> +}
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> new file mode 100644
> index 0000000000..b170c463de
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> @@ -0,0 +1,102 @@
> +/** @file
>
> + SHA3 realted functions from OpenSSL.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
>
> +Licensed under the OpenSSL license (the "License"). You may not use
>
> +this file except in compliance with the License. You can obtain a copy
>
> +in the file LICENSE in the source distribution or at
>
> +https://www.openssl.org/source/license.html
>
> +
>
> +**/
>
> +
>
> +#include "sha3.h"
>
> +
>
> +size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
>
> + size_t r);
>
> +void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
>
> +
>
> +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t md_size)
>
> +{
>
> + if (bsz <= sizeof(ctx->buf)) {
>
> + memset(ctx->A, 0, sizeof(ctx->A));
>
> +
>
> + ctx->num = 0;
>
> + ctx->block_size = bsz;
>
> + ctx->md_size = md_size;
>
> + ctx->pad = pad;
>
> +
>
> + return 1;
>
> + }
>
> +
>
> + return 0;
>
> +}
>
> +
>
> +
>
> +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
>
> +{
>
> + const unsigned char *inp = _inp;
>
> + size_t bsz = ctx->block_size;
>
> + size_t num, rem;
>
> +
>
> + if (len == 0)
>
> + return 1;
>
> +
>
> + if ((num = ctx->num) != 0) { /* process intermediate buffer? */
>
> + rem = bsz - num;
>
> +
>
> + if (len < rem) {
>
> + memcpy(ctx->buf + num, inp, len);
>
> + ctx->num += len;
>
> + return 1;
>
> + }
>
> + /*
>
> + * We have enough data to fill or overflow the intermediate
>
> + * buffer. So we append |rem| bytes and process the block,
>
> + * leaving the rest for later processing...
>
> + */
>
> + memcpy(ctx->buf + num, inp, rem);
>
> + inp += rem, len -= rem;
>
> + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
>
> + ctx->num = 0;
>
> + /* ctx->buf is processed, ctx->num is guaranteed to be zero */
>
> + }
>
> +
>
> + if (len >= bsz)
>
> + rem = SHA3_absorb(ctx->A, inp, len, bsz);
>
> + else
>
> + rem = len;
>
> +
>
> + if (rem) {
>
> + memcpy(ctx->buf, inp + len - rem, rem);
>
> + ctx->num = rem;
>
> + }
>
> +
>
> + return 1;
>
> +}
>
> +
>
> +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md)
>
> +{
>
> + size_t bsz = ctx->block_size;
>
> + size_t num = ctx->num;
>
> +
>
> + if (ctx->md_size == 0)
>
> + return 1;
>
> +
>
> + /*
>
> + * Pad the data with 10*1. Note that |num| can be |bsz - 1|
>
> + * in which case both byte operations below are performed on
>
> + * same byte...
>
> + */
>
> + memset(ctx->buf + num, 0, bsz - num);
>
> + ctx->buf[num] = ctx->pad;
>
> + ctx->buf[bsz - 1] |= 0x80;
>
> +
>
> + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
>
> +
>
> + SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
>
> +
>
> + return 1;
>
> +}
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> new file mode 100644
> index 0000000000..b2a40ee044
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> @@ -0,0 +1,53 @@
> +/** @file
>
> + Encode realted functions from Xkcp.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +The eXtended Keccak Code Package (XKCP)
>
> +https://github.com/XKCP/XKCP
>
> +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles
> Van Assche.
>
> +Implementation by the designers, hereby denoted as "the implementer".
>
> +For more information, feedback or questions, please refer to the Keccak Team
> website:
>
> +https://keccak.team/
>
> +To the extent possible under law, the implementer has waived all copyright
>
> +and related or neighboring rights to the source code in this file.
>
> +http://creativecommons.org/publicdomain/zero/1.0/
>
> +
>
> +**/
>
> +
>
> +#include "xkcp.h"
>
> +
>
> +unsigned int left_encode(unsigned char * encbuf, size_t value)
>
> +{
>
> + unsigned int n, i;
>
> + size_t v;
>
> +
>
> + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
>
> + ; /* empty */
>
> + if (n == 0)
>
> + n = 1;
>
> + for ( i = 1; i <= n; ++i )
>
> + {
>
> + encbuf[i] = (unsigned char)(value >> (8 * (n-i)));
>
> + }
>
> + encbuf[0] = (unsigned char)n;
>
> + return n + 1;
>
> +}
>
> +
>
> +unsigned int right_encode(unsigned char * encbuf, size_t value)
>
> +{
>
> + unsigned int n, i;
>
> + size_t v;
>
> +
>
> + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
>
> + ; /* empty */
>
> + if (n == 0)
>
> + n = 1;
>
> + for ( i = 1; i <= n; ++i )
>
> + {
>
> + encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
>
> + }
>
> + encbuf[n] = (unsigned char)n;
>
> + return n + 1;
>
> +}
>
> diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> new file mode 100644
> index 0000000000..052ab3a0d6
> --- /dev/null
> +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> @@ -0,0 +1,152 @@
> +/** @file
>
> + Application for Parallelhash Function Validation.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include "TestBaseCryptLib.h"
>
> +
>
> +//
>
> +// Parallelhash Test Sample common parameters.
>
> +//
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN OutputByteLen = 64;
>
> +
>
> +//
>
> +// Parallelhash Test Sample #1 from NIST Special Publication 800-185.
>
> +//
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample1[] = {
>
> + // input data of sample1.
>
> + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14,
> 0x15, 0x16, 0x17,
>
> + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
>
> +};
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample1ByteLen =
> 24; // Length of sample1 input data in bytes.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID *CustomizationSample1
> = ""; // Customization string (S) of sample1.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN CustomSample1ByteLen =
> 0; // Customization string length of sample1 in bytes.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample1 = 8;
> // Block size of sample1.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 ExpectOutputSample1[]
> = {
>
> + // Expected output data of sample1.
>
> + 0xbc, 0x1e, 0xf1, 0x24, 0xda, 0x34, 0x49, 0x5e, 0x94, 0x8e, 0xad, 0x20, 0x7d,
> 0xd9, 0x84, 0x22,
>
> + 0x35, 0xda, 0x43, 0x2d, 0x2b, 0xbc, 0x54, 0xb4, 0xc1, 0x10, 0xe6, 0x4c, 0x45,
> 0x11, 0x05, 0x53,
>
> + 0x1b, 0x7f, 0x2a, 0x3e, 0x0c, 0xe0, 0x55, 0xc0, 0x28, 0x05, 0xe7, 0xc2, 0xde,
> 0x1f, 0xb7, 0x46,
>
> + 0xaf, 0x97, 0xa1, 0xd0, 0x01, 0xf4, 0x3b, 0x82, 0x4e, 0x31, 0xb8, 0x76, 0x12,
> 0x41, 0x04, 0x29
>
> +};
>
> +
>
> +//
>
> +// Parallelhash Test Sample #2 from NIST Special Publication 800-185.
>
> +//
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 *InputSample2 =
> InputSample1; // Input of sample2 is same as sample1.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample2ByteLen =
> 24; // Length of sample2 input data in bytes.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID *CustomizationSample2
> = "Parallel Data"; // Customization string (S) of sample2.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN CustomSample2ByteLen =
> 13; // Customization string length of sample2 in bytes.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample2 = 8;
> // Block size of sample2.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 ExpectOutputSample2[]
> = {
>
> + // Expected output data of sample2.
>
> + 0xcd, 0xf1, 0x52, 0x89, 0xb5, 0x4f, 0x62, 0x12, 0xb4, 0xbc, 0x27, 0x05, 0x28,
> 0xb4, 0x95, 0x26,
>
> + 0x00, 0x6d, 0xd9, 0xb5, 0x4e, 0x2b, 0x6a, 0xdd, 0x1e, 0xf6, 0x90, 0x0d, 0xda,
> 0x39, 0x63, 0xbb,
>
> + 0x33, 0xa7, 0x24, 0x91, 0xf2, 0x36, 0x96, 0x9c, 0xa8, 0xaf, 0xae, 0xa2, 0x9c,
> 0x68, 0x2d, 0x47,
>
> + 0xa3, 0x93, 0xc0, 0x65, 0xb3, 0x8e, 0x29, 0xfa, 0xe6, 0x51, 0xa2, 0x09, 0x1c,
> 0x83, 0x31, 0x10
>
> +};
>
> +
>
> +//
>
> +// Parallelhash Test Sample #3 from NIST Special Publication 800-185.
>
> +//
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample3[] = {
>
> + // input data of sample3.
>
> + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10,
> 0x11, 0x12, 0x13,
>
> + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22, 0x23, 0x24,
> 0x25, 0x26, 0x27,
>
> + 0x28, 0x29, 0x2a, 0x2b, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
> 0x39, 0x3a, 0x3b,
>
> + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x50,
> 0x51, 0x52, 0x53,
>
> + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
>
> +};
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample3ByteLen =
> 72; // Length of sample3 input data in bytes.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID *CustomizationSample3
> = "Parallel Data"; // Customization string (S) of sample3.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN CustomSample3ByteLen =
> 13; // Customization string length of sample3 in bytes.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample3 = 12;
> // Block size of sample3.
>
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 ExpectOutputSample3[]
> = {
>
> + // Expected output data of sample3.
>
> + 0x69, 0xd0, 0xfc, 0xb7, 0x64, 0xea, 0x05, 0x5d, 0xd0, 0x93, 0x34, 0xbc, 0x60,
> 0x21, 0xcb, 0x7e,
>
> + 0x4b, 0x61, 0x34, 0x8d, 0xff, 0x37, 0x5d, 0xa2, 0x62, 0x67, 0x1c, 0xde, 0xc3,
> 0xef, 0xfa, 0x8d,
>
> + 0x1b, 0x45, 0x68, 0xa6, 0xcc, 0xe1, 0x6b, 0x1c, 0xad, 0x94, 0x6d, 0xdd, 0xe2,
> 0x7f, 0x6c, 0xe2,
>
> + 0xb8, 0xde, 0xe4, 0xcd, 0x1b, 0x24, 0x85, 0x1e, 0xbf, 0x00, 0xeb, 0x90, 0xd4,
> 0x38, 0x13, 0xe9
>
> +};
>
> +
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +TestVerifyParallelHash256HashAll (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + BOOLEAN Status;
>
> + UINT16 OriginalParallelHashBlockNumber;
>
> + UINT8 Output[64];
>
> +
>
> + // Restore original PcdParallelHashBlockNumber.
>
> + OriginalParallelHashBlockNumber = PcdGet16 (PcdParallelHashBlockNumber);
>
> +
>
> + //
>
> + // Test #1 using sample1.
>
> + //
>
> + PcdSet16S (PcdParallelHashBlockNumber, InputSample1ByteLen /
> BlockSizeSample1);
>
> + Status = ParallelHash256HashAll (
>
> + InputSample1,
>
> + InputSample1ByteLen,
>
> + Output,
>
> + OutputByteLen,
>
> + CustomizationSample1,
>
> + CustomSample1ByteLen
>
> + );
>
> + UT_ASSERT_TRUE (Status);
>
> +
>
> + // Check the output with the expected output.
>
> + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample1, OutputByteLen);
>
> +
>
> + //
>
> + // Test #2 using sample2.
>
> + //
>
> + PcdSet16S (PcdParallelHashBlockNumber, InputSample2ByteLen /
> BlockSizeSample2);
>
> + Status = ParallelHash256HashAll (
>
> + InputSample2,
>
> + InputSample2ByteLen,
>
> + Output,
>
> + OutputByteLen,
>
> + CustomizationSample2,
>
> + CustomSample2ByteLen
>
> + );
>
> + UT_ASSERT_TRUE (Status);
>
> +
>
> + // Check the output with the expected output.
>
> + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample2, OutputByteLen);
>
> +
>
> + //
>
> + // Test #3 using sample3.
>
> + //
>
> + PcdSet16S (PcdParallelHashBlockNumber, InputSample3ByteLen /
> BlockSizeSample3);
>
> + Status = ParallelHash256HashAll (
>
> + InputSample3,
>
> + InputSample3ByteLen,
>
> + Output,
>
> + OutputByteLen,
>
> + CustomizationSample3,
>
> + CustomSample3ByteLen
>
> + );
>
> + UT_ASSERT_TRUE (Status);
>
> +
>
> + // Check the output with the expected output.
>
> + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample3, OutputByteLen);
>
> +
>
> + // Recover original PcdParallelHashBlockNumber.
>
> + PcdSet16S (PcdParallelHashBlockNumber, OriginalParallelHashBlockNumber);
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +TEST_DESC mParallelhashTest[] = {
>
> + //
>
> + // -----Description------------------------------Class----------------------Function----
> -------------Pre---Post--Context
>
> + //
>
> + { "TestVerifyParallelHash256HashAll()",
> "CryptoPkg.BaseCryptLib.ParallelHash256HashAll",
> TestVerifyParallelHash256HashAll, NULL, NULL, NULL },
>
> +};
>
> +
>
> +UINTN mParallelhashTestNum = ARRAY_SIZE (mParallelhashTest);
>
> diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
> index 5888941bab..3af55d9c10 100644
> --- a/CryptoPkg/CryptoPkg.dec
> +++ b/CryptoPkg/CryptoPkg.dec
> @@ -4,7 +4,7 @@
> # This Package provides cryptographic-related libraries for UEFI security
> modules.
>
> # It also provides a test application to test libraries.
>
> #
>
> -# Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
>
> +# Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
>
> #
>
> ##
>
> @@ -81,5 +81,12 @@
> # @ValidList 0x80000001 | 0x00000001, 0x00000002, 0x00000004,
> 0x00000008, 0x00000010
>
>
> gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x00000002|UINT32|0x00
> 000001
>
>
>
> +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
>
> + ## This PCD indicates the block number of parallel hash
>
> + # Based on the value set, parallel hash can chose the block
>
> + # number to calculate specific hash.<BR>
>
> + # The number can be set by platform team according to the core number.
>
> +
> gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber|0x0100|UINT16|0
> x00000003
>
> +
>
> [UserExtensions.TianoCore."ExtraFiles"]
>
> CryptoPkgExtra.uni
>
> diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> b/CryptoPkg/Include/Library/BaseCryptLib.h
> index f4bc7c0d73..0b274b1257 100644
> --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> @@ -4,7 +4,7 @@
> primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security
>
> functionality enabling.
>
>
>
> -Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
>
> +Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
>
> **/
>
> @@ -753,6 +753,33 @@ Sha512HashAll (
> OUT UINT8 *HashValue
>
> );
>
>
>
> +/**
>
> + Parallel hash function ParallelHash256, as defined in NIST's Special Publication
> 800-185,
>
> + published December 2016.
>
> +
>
> + @param[in] Input Pointer to the input message (X).
>
> + @param[in] InputByteLen The number(>0) of input bytes provided for the
> input data.
>
> + @param[out] Output Pointer to the output buffer.
>
> + @param[in] OutputByteLen The desired number of output bytes (L).
>
> + @param[in] Customization Pointer to the customization string (S).
>
> + @param[in] CustomByteLen The length of the customization string in bytes.
>
> +
>
> + @retval TRUE ParallelHash256 digest computation succeeded.
>
> + @retval FALSE ParallelHash256 digest computation failed.
>
> + @retval FALSE This interface is not supported.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +ParallelHash256HashAll (
>
> + IN CONST VOID *Input,
>
> + IN UINTN InputByteLen,
>
> + OUT VOID *Output,
>
> + IN UINTN OutputByteLen,
>
> + IN CONST VOID *Customization,
>
> + IN UINTN CustomByteLen
>
> + );
>
> +
>
> /**
>
> Retrieves the size, in bytes, of the context buffer required for SM3 hash
> operations.
>
>
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> index e6470d7a21..70159163d4 100644
> --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> @@ -10,7 +10,7 @@
> # RSA external functions, PKCS#7 SignedData sign functions, Diffie-Hellman
> functions, and
>
> # authenticode signature verification functions are not supported in this
> instance.
>
> #
>
> -# Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
>
> +# Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
>
> #
>
> ##
>
> @@ -38,6 +38,10 @@
> Hash/CryptSha256.c
>
> Hash/CryptSm3.c
>
> Hash/CryptSha512.c
>
> + Hash/CryptSha3.c
>
> + Hash/CryptXkcp.c
>
> + Hash/CryptCShake256.c
>
> + Hash/CryptParallelHash.c
>
> Hmac/CryptHmacSha256.c
>
> Kdf/CryptHkdfNull.c
>
> Cipher/CryptAes.c
>
> @@ -85,6 +89,9 @@
> OpensslLib
>
> IntrinsicLib
>
> PrintLib
>
> + MmServicesTableLib
>
> + SynchronizationLib
>
> + PcdLib
>
>
>
> #
>
> # Remove these [BuildOptions] after this library is cleaned up
>
> @@ -101,3 +108,6 @@
> GCC:*_CLANG35_*_CC_FLAGS = -std=c99
>
> GCC:*_CLANG38_*_CC_FLAGS = -std=c99
>
> GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-
> types
>
> +
>
> +[Pcd]
>
> + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
>
> diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h
> b/CryptoPkg/Library/Include/CrtLibSupport.h
> index d257dca8fa..35d9c62a0b 100644
> --- a/CryptoPkg/Library/Include/CrtLibSupport.h
> +++ b/CryptoPkg/Library/Include/CrtLibSupport.h
> @@ -2,7 +2,7 @@
> Root include file of C runtime library to support building the third-party
>
> cryptographic library.
>
>
>
> -Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
>
> +Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
>
> Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
>
> @@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
> #define MAX_STRING_SIZE 0x1000
>
>
>
> +#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
>
> +
>
> //
>
> // We already have "no-ui" in out Configure invocation.
>
> // but the code still fails to compile.
>
> @@ -111,6 +113,7 @@ typedef UINT8 u_char;
> typedef UINT32 uid_t;
>
> typedef UINT32 gid_t;
>
> typedef CHAR16 wchar_t;
>
> +typedef UINT64 uint64_t;
>
>
>
> //
>
> // File operations are not required for EFI building,
>
> diff --git a/CryptoPkg/Library/Include/sha3.h
> b/CryptoPkg/Library/Include/sha3.h
> new file mode 100644
> index 0000000000..71b4c75548
> --- /dev/null
> +++ b/CryptoPkg/Library/Include/sha3.h
> @@ -0,0 +1,32 @@
> +/** @file
>
> + SHA3 realted functions from OpenSSL.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
>
> +Licensed under the OpenSSL license (the "License"). You may not use
>
> +this file except in compliance with the License. You can obtain a copy
>
> +in the file LICENSE in the source distribution or at
>
> +https://www.openssl.org/source/license.html
>
> +
>
> +**/
>
> +
>
> +#include <CrtLibSupport.h>
>
> +
>
> +#define KECCAK1600_WIDTH 1600
>
> +
>
> +typedef struct {
>
> + uint64_t A[5][5];
>
> + size_t block_size; /* cached ctx->digest->block_size */
>
> + size_t md_size; /* output length, variable in XOF */
>
> + size_t num; /* used bytes in below buffer */
>
> + unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
>
> + unsigned char pad;
>
> +} KECCAK1600_CTX;
>
> +
>
> +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t md_size);
>
> +
>
> +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
>
> +
>
> +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md);
>
> diff --git a/CryptoPkg/Library/Include/xkcp.h
> b/CryptoPkg/Library/Include/xkcp.h
> new file mode 100644
> index 0000000000..b328d672e4
> --- /dev/null
> +++ b/CryptoPkg/Library/Include/xkcp.h
> @@ -0,0 +1,23 @@
> +/** @file
>
> + Encode realted functions from Xkcp.
>
> +
>
> +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +The eXtended Keccak Code Package (XKCP)
>
> +https://github.com/XKCP/XKCP
>
> +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles
> Van Assche.
>
> +Implementation by the designers, hereby denoted as "the implementer".
>
> +For more information, feedback or questions, please refer to the Keccak Team
> website:
>
> +https://keccak.team/
>
> +To the extent possible under law, the implementer has waived all copyright
>
> +and related or neighboring rights to the source code in this file.
>
> +http://creativecommons.org/publicdomain/zero/1.0/
>
> +
>
> +**/
>
> +
>
> +#include <CrtLibSupport.h>
>
> +
>
> +unsigned int left_encode(unsigned char * encbuf, size_t value);
>
> +
>
> +unsigned int right_encode(unsigned char * encbuf, size_t value);
>
> diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> index a6b3482742..0bffd687c2 100644
> --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> @@ -1,7 +1,7 @@
> /** @file
>
> Application for Cryptographic Primitives Validation.
>
>
>
> -Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
>
> +Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
>
> **/
>
> @@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Library/BaseLib.h>
>
> #include <Library/BaseMemoryLib.h>
>
> #include <Library/MemoryAllocationLib.h>
>
> +#include <Library/PcdLib.h>
>
> // #include <UnitTestTypes.h>
>
> #include <Library/UnitTestLib.h>
>
> // #include <Library/UnitTestAssertLib.h>
>
> diff --git
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> index 00c8692650..61a59d6a47 100644
> --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> @@ -2,6 +2,7 @@
> # Host-based UnitTest for BaseCryptLib
>
> #
>
> # Copyright (c) Microsoft Corporation.<BR>
>
> +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
>
> ##
>
>
>
> @@ -35,6 +36,7 @@
> Pkcs7EkuTests.c
>
> OaepEncryptTests.c
>
> RsaPssTests.c
>
> + ParallelhashTests.c
>
>
>
> [Packages]
>
> MdePkg/MdePkg.dec
>
> @@ -45,3 +47,8 @@
> DebugLib
>
> BaseCryptLib
>
> UnitTestLib
>
> + PcdLib
>
> +
>
> +[Pcd]
>
> + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
>
> +
>
> diff --git
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
> index ca789aa6ad..682f25a754 100644
> --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
> +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
> @@ -2,6 +2,7 @@
> # BaseCryptLib UnitTest built for execution in UEFI Shell.
>
> #
>
> # Copyright (c) Microsoft Corporation.<BR>
>
> +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
>
> ##
>
>
>
> @@ -36,6 +37,7 @@
> Pkcs7EkuTests.c
>
> OaepEncryptTests.c
>
> RsaPssTests.c
>
> + ParallelhashTests.c
>
>
>
> [Packages]
>
> MdePkg/MdePkg.dec
>
> @@ -48,3 +50,7 @@
> UnitTestLib
>
> PrintLib
>
> BaseCryptLib
>
> + PcdLib
>
> +
>
> +[Pcd]
>
> + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
>
> --
> 2.26.2.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
2022-02-15 6:08 ` Yao, Jiewen
@ 2022-02-16 7:43 ` Li, Zhihao
2022-02-16 7:51 ` Yao, Jiewen
0 siblings, 1 reply; 6+ messages in thread
From: Li, Zhihao @ 2022-02-16 7:43 UTC (permalink / raw)
To: Yao, Jiewen, devel@edk2.groups.io
Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin, Fu, Siyuan
With your comment, we plan do some modification for parallelhash.
1. Plan to add a parameter (BlockSize) on ParallelHash256HashAll function to replace PcdParallelHashBlockNumber.
2. Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash folder.
> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Tuesday, February 15, 2022 2:09 PM
> To: Li, Zhihao <zhihao.li@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Fu,
> Siyuan <siyuan.fu@intel.com>
> Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> ParallelHash256HashAll in BaseCryptLib.
>
> Thanks for the update.
>
> Feedback below:
>
> 1) How block size is determined for below API?
>
> BOOLEAN
> EFIAPI
> ParallelHash256HashAll (
> IN CONST VOID *Input,
> IN UINTN InputByteLen,
> OUT VOID *Output,
> IN UINTN OutputByteLen,
> IN CONST VOID *Customization,
> IN UINTN CustomByteLen
> );
>
> Is that determined by PcdParallelHashBlockNumber ?
>
> I don’t think it is good idea to let a crypto library determine a platform PCD.
> For example, how do you support binary crypto module ?
Plan to add a parameter (BlockSize) to replace PcdParallelHashBlockNumber.
>
> 2) Why we need "sha3.h" and "xkcp.h" ?
> These are openssl specific structure. It shall not be put to EDKII file header.
>
> CryptoPkg\Library\Include shall only contain generic dependency header.
Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash folder.
>
>
>
>
> Thank you
> Yao, Jiewen
>
> > -----Original Message-----
> > From: Li, Zhihao <zhihao.li@intel.com>
> > Sent: Friday, February 11, 2022 5:05 PM
> > To: devel@edk2.groups.io
> > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > <jian.j.wang@intel.com>; Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang,
> > Guomin <guomin.jiang@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> > Subject: [PATCH v1] CryptoPkg: Add new hash algorithm
> > ParallelHash256HashAll in BaseCryptLib.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3596
> >
> > Parallel hash function ParallelHash256HashAll, as defined in NIST's
> > Special Publication 800-185, published December 2016. It utilizes
> > multi-process to calculate the digest.
> >
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> > Cc: Guomin Jiang <guomin.jiang@intel.com>
> > Cc: Siyuan Fu <siyuan.fu@intel.com>
> >
> > Signed-off-by: Zhihao Li <zhihao.li@intel.com>
> > ---
> > CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c | 313
> > ++++++++++++++++++++
> > CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c | 275
> > +++++++++++++++++
> > CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c | 102
> +++++++
> > CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c | 53 ++++
> > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c |
> 152
> > ++++++++++
> > CryptoPkg/CryptoPkg.dec | 9 +-
> > CryptoPkg/Include/Library/BaseCryptLib.h | 29 +-
> > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 12 +-
> > CryptoPkg/Library/Include/CrtLibSupport.h | 5 +-
> > CryptoPkg/Library/Include/sha3.h | 32 ++
> > CryptoPkg/Library/Include/xkcp.h | 23 ++
> > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3
> +-
> > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> | 7 +
> > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf |
> 6 +
> > 14 files changed, 1016 insertions(+), 5 deletions(-)
> >
> > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > new file mode 100644
> > index 0000000000..5efced3f46
> > --- /dev/null
> > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > @@ -0,0 +1,313 @@
> > +/** @file
> >
> > + cSHAKE-256 Digest Wrapper Implementations.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "InternalCryptLib.h"
> >
> > +#include "sha3.h"
> >
> > +#include "xkcp.h"
> >
> > +
> >
> > +#define CSHAKE256_SECURITY_STRENGTH 256
> >
> > +#define CSHAKE256_RATE_IN_BYTES 136
> >
> > +
> >
> > +const CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = {0};
> >
> > +
> >
> > +UINTN
> >
> > +EFIAPI
> >
> > +LeftEncode (
> >
> > + OUT UINT8 *Encbuf,
> >
> > + IN UINTN Value
> >
> > + )
> >
> > +{
> >
> > + return left_encode (Encbuf, Value);
> >
> > +}
> >
> > +
> >
> > +UINTN
> >
> > +EFIAPI
> >
> > +RightEncode (
> >
> > + OUT UINT8 *Encbuf,
> >
> > + IN UINTN Value
> >
> > + )
> >
> > +{
> >
> > + return right_encode (Encbuf, Value);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > + Retrieves the size, in bytes, of the context buffer required for
> > + cSHAKE-256
> > hash operations.
> >
> > +
> >
> > + @return The size, in bytes, of the context buffer required for
> > + cSHAKE-256
> > hash operations.
> >
> > +
> >
> > +**/
> >
> > +UINTN
> >
> > +EFIAPI
> >
> > +CShake256GetContextSize (
> >
> > + VOID
> >
> > + )
> >
> > +{
> >
> > + return (UINTN) (sizeof (KECCAK1600_CTX));
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > + Initializes user-supplied memory pointed by CShake256Context as
> > + cSHAKE-256
> > hash context for
> >
> > + subsequent use.
> >
> > +
> >
> > + @param[out] CShake256Context Pointer to cSHAKE-256 context being
> > initialized.
> >
> > + @param[in] OutputLen The desired number of output length in
> bytes.
> >
> > + @param[in] Name Pointer to the function name string.
> >
> > + @param[in] NameLen The length of the function name in bytes.
> >
> > + @param[in] Customization Pointer to the customization string.
> >
> > + @param[in] CustomizationLen The length of the customization string in
> > bytes.
> >
> > +
> >
> > + @retval TRUE cSHAKE-256 context initialization succeeded.
> >
> > + @retval FALSE cSHAKE-256 context initialization failed.
> >
> > + @retval FALSE This interface is not supported.
> >
> > +
> >
> > +**/
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +CShake256Init (
> >
> > + OUT VOID *CShake256Context,
> >
> > + IN UINTN OutputLen,
> >
> > + IN CONST VOID *Name,
> >
> > + IN UINTN NameLen,
> >
> > + IN CONST VOID *Customization,
> >
> > + IN UINTN CustomizationLen
> >
> > + )
> >
> > +{
> >
> > + BOOLEAN Status;
> >
> > + unsigned char EncBuf[sizeof(size_t)+1];
> >
> > + UINTN EncLen;
> >
> > + UINTN AbsorbLen;
> >
> > + UINTN PadLen;
> >
> > +
> >
> > + //
> >
> > + // Check input parameters.
> >
> > + //
> >
> > + if (CShake256Context == NULL ||
> >
> > + OutputLen == 0 ||
> >
> > + (NameLen != 0 && Name == NULL) ||
> >
> > + (CustomizationLen != 0 && Customization == NULL)) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Initialize KECCAK context with pad value and block size.
> >
> > + //
> >
> > + if (NameLen == 0 && CustomizationLen == 0) {
> >
> > + //
> >
> > + // When N and S are both empty strings, cSHAKE(X, L, N, S) is
> > + equivalent to
> >
> > + // SHAKE as defined in FIPS 202.
> >
> > + //
> >
> > + return (BOOLEAN) init (
> >
> > + (KECCAK1600_CTX *) CShake256Context,
> >
> > + '\x1f',
> >
> > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > + * 2) / 8,
> >
> > + OutputLen
> >
> > + );
> >
> > + }
> >
> > +
> >
> > + Status = (BOOLEAN) init (
> >
> > + (KECCAK1600_CTX *) CShake256Context,
> >
> > + '\x04',
> >
> > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > + * 2) / 8,
> >
> > + OutputLen
> >
> > + );
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + AbsorbLen = 0;
> >
> > + //
> >
> > + // Absorb Absorb bytepad(.., rate).
> >
> > + //
> >
> > + EncLen = left_encode (EncBuf, CSHAKE256_RATE_IN_BYTES);
> >
> > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > + CShake256Context,
> > EncBuf, EncLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > + AbsorbLen += EncLen;
> >
> > +
> >
> > + //
> >
> > + // Absorb encode_string(N).
> >
> > + //
> >
> > + EncLen = left_encode (EncBuf, NameLen * 8);
> >
> > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > + CShake256Context,
> > EncBuf, EncLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > + AbsorbLen += EncLen;
> >
> > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > + CShake256Context,
> > Name, NameLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > + AbsorbLen += NameLen;
> >
> > +
> >
> > + //
> >
> > + // Absorb encode_string(S).
> >
> > + //
> >
> > + EncLen = left_encode (EncBuf, CustomizationLen * 8);
> >
> > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > + CShake256Context,
> > EncBuf, EncLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > + AbsorbLen += EncLen;
> >
> > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > + CShake256Context,
> > Customization, CustomizationLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > + AbsorbLen += CustomizationLen;
> >
> > +
> >
> > + //
> >
> > + // Absorb zero padding up to rate.
> >
> > + //
> >
> > + PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen %
> > CSHAKE256_RATE_IN_BYTES;
> >
> > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > + CShake256Context,
> > mZeroPadding, PadLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + return TRUE;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > + Digests the input data and updates cSHAKE-256 context.
> >
> > +
> >
> > + This function performs cSHAKE-256 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.
> >
> > + cSHAKE-256 context should be already correctly initialized by
> > + CShake256Init(),
> > and should not be finalized
> >
> > + by CShake256Final(). Behavior with invalid context is undefined.
> >
> > +
> >
> > + @param[in, out] CShake256Context Pointer to the cSHAKE-256 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 cSHAKE-256 data digest succeeded.
> >
> > + @retval FALSE cSHAKE-256 data digest failed.
> >
> > + @retval FALSE This interface is not supported.
> >
> > +
> >
> > +**/
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +CShake256Update (
> >
> > + IN OUT VOID *CShake256Context,
> >
> > + IN CONST VOID *Data,
> >
> > + IN UINTN DataSize
> >
> > + )
> >
> > +{
> >
> > + //
> >
> > + // Check input parameters.
> >
> > + //
> >
> > + if (CShake256Context == NULL) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Check invalid parameters, in case that only DataLength was
> > + checked in
> > OpenSSL.
> >
> > + //
> >
> > + if (Data == NULL && DataSize != 0) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + return (BOOLEAN)(sha3_update ((KECCAK1600_CTX *)
> CShake256Context,
> > Data, DataSize));
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > + Completes computation of the cSHAKE-256 digest value.
> >
> > +
> >
> > + This function completes cSHAKE-256 hash computation and retrieves
> > + the
> > digest value into
> >
> > + the specified memory. After this function has been called, the
> > + cSHAKE-256
> > context cannot
> >
> > + be used again.
> >
> > + cSHAKE-256 context should be already correctly initialized by
> > + CShake256Init(),
> > and should not be
> >
> > + finalized by CShake256Final(). Behavior with invalid cSHAKE-256
> > + context is
> > undefined.
> >
> > +
> >
> > + @param[in, out] CShake256Context Pointer to the cSHAKE-256 context.
> >
> > + @param[out] HashValue Pointer to a buffer that receives the
> cSHAKE-
> > 256 digest
> >
> > + value.
> >
> > +
> >
> > + @retval TRUE cSHAKE-256 digest computation succeeded.
> >
> > + @retval FALSE cSHAKE-256 digest computation failed.
> >
> > + @retval FALSE This interface is not supported.
> >
> > +
> >
> > +**/
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +CShake256Final (
> >
> > + IN OUT VOID *CShake256Context,
> >
> > + OUT UINT8 *HashValue
> >
> > + )
> >
> > +{
> >
> > + //
> >
> > + // Check input parameters.
> >
> > + //
> >
> > + if (CShake256Context == NULL || HashValue == NULL) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // cSHAKE-256 Hash Finalization.
> >
> > + //
> >
> > + return (BOOLEAN) (sha3_final ((KECCAK1600_CTX *) CShake256Context,
> > HashValue));
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > + Computes the CSHAKE-256 message digest of a input data buffer.
> >
> > +
> >
> > + This function performs the CSHAKE-256 message digest of a given
> > + data buffer,
> > and places
> >
> > + the digest value into the specified memory.
> >
> > +
> >
> > + @param[in] Data Pointer to the buffer containing the data to be
> > hashed.
> >
> > + @param[in] DataSize Size of Data buffer in bytes.
> >
> > + @param[in] OutputLen Size of output in bytes.
> >
> > + @param[in] Name Pointer to the function name string.
> >
> > + @param[in] NameLen Size of the function name in bytes.
> >
> > + @param[in] Customization Pointer to the customization string.
> >
> > + @param[in] CustomizationLen Size of the customization string in bytes.
> >
> > + @param[out] HashValue Pointer to a buffer that receives the
> CSHAKE-
> > 256 digest
> >
> > + value.
> >
> > +
> >
> > + @retval TRUE CSHAKE-256 digest computation succeeded.
> >
> > + @retval FALSE CSHAKE-256 digest computation failed.
> >
> > + @retval FALSE This interface is not supported.
> >
> > +
> >
> > +**/
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +CShake256HashAll (
> >
> > + IN CONST VOID *Data,
> >
> > + IN UINTN DataSize,
> >
> > + IN UINTN OutputLen,
> >
> > + IN CONST VOID *Name,
> >
> > + IN UINTN NameLen,
> >
> > + IN CONST VOID *Customization,
> >
> > + IN UINTN CustomizationLen,
> >
> > + OUT UINT8 *HashValue
> >
> > + )
> >
> > +{
> >
> > + BOOLEAN Status;
> >
> > + KECCAK1600_CTX Ctx;
> >
> > +
> >
> > + //
> >
> > + // Check input parameters.
> >
> > + //
> >
> > + if (HashValue == NULL) {
> >
> > + return FALSE;
> >
> > + }
> >
> > + if (Data == NULL && DataSize != 0) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + Status = CShake256Init (&Ctx, OutputLen, Name, NameLen,
> > + Customization,
> > CustomizationLen);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + Status = CShake256Update (&Ctx, Data, DataSize);
> >
> > + if (!Status) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + return CShake256Final (&Ctx, HashValue);
> >
> > +}
> >
> > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > new file mode 100644
> > index 0000000000..3eaa7c2ceb
> > --- /dev/null
> > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > @@ -0,0 +1,275 @@
> > +/** @file
> >
> > + ParallelHash Implementation.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "InternalCryptLib.h"
> >
> > +#include <Library\PcdLib.h>
> >
> > +#include <Library\SynchronizationLib.h>
> >
> > +#include <Library\MmServicesTableLib.h>
> >
> > +
> >
> > +
> >
> > +UINT16 mBlockNum;
> >
> > +UINTN mBlockSize;
> >
> > +UINTN mLastBlockSize;
> >
> > +UINT8 *mInput;
> >
> > +UINTN mBlockResultSize;
> >
> > +UINT8 *mBlockHashResult;
> >
> > +BOOLEAN *mBlockIsCompleted;
> >
> > +SPIN_LOCK *mSpinLockList;
> >
> > +
> >
> > +UINTN LeftEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> >
> > +UINTN RightEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> >
> > +
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +CShake256HashAll (
> >
> > + IN CONST VOID *Data,
> >
> > + IN UINTN DataSize,
> >
> > + IN UINTN OutputLen,
> >
> > + IN CONST VOID *Name,
> >
> > + IN UINTN NameLen,
> >
> > + IN CONST VOID *Customization,
> >
> > + IN UINTN CustomizationLen,
> >
> > + OUT UINT8 *HashValue
> >
> > + );
> >
> > +
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +ParallelHashApExecute (
> >
> > + IN VOID *ProcedureArgument
> >
> > + )
> >
> > +{
> >
> > + UINTN Index;
> >
> > + BOOLEAN Status;
> >
> > +
> >
> > + for (Index = 0; Index < mBlockNum; Index++) {
> >
> > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> >
> > + //
> >
> > + // Completed, try next one.
> >
> > + //
> >
> > + if (mBlockIsCompleted[Index])
> >
> > + {
> >
> > + ReleaseSpinLock (&mSpinLockList[Index]);
> >
> > + continue;
> >
> > + }
> >
> > + //
> >
> > + // Calculate CShake256 for this block.
> >
> > + //
> >
> > + Status = CShake256HashAll (
> >
> > + mInput + Index * mBlockSize,
> >
> > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > + mBlockSize,
> >
> > + mBlockResultSize,
> >
> > + NULL,
> >
> > + 0,
> >
> > + NULL,
> >
> > + 0,
> >
> > + mBlockHashResult + Index * mBlockResultSize
> >
> > + );
> >
> > + if (!EFI_ERROR (Status)){
> >
> > + mBlockIsCompleted[Index] = TRUE;
> >
> > + }
> >
> > + ReleaseSpinLock (&mSpinLockList[Index]);
> >
> > + }
> >
> > + }
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > + Parallel hash function ParallelHash256, as defined in NIST's
> > + Special Publication
> > 800-185,
> >
> > + published December 2016.
> >
> > +
> >
> > + @param Input[in] Pointer to the input message (X).
> >
> > + @param InputByteLen[in] The number(>0) of input bytes provided for
> the
> > input data.
> >
> > + @param Output[out] Pointer to the output buffer.
> >
> > + @param OutputByteLen[in] The desired number of output bytes (L).
> >
> > + @param Customization[in] Pointer to the customization string (S).
> >
> > + @param CustomByteLen[in] The length of the customization string in
> bytes.
> >
> > +
> >
> > + @retval TRUE ParallelHash256 digest computation succeeded.
> >
> > + @retval FALSE ParallelHash256 digest computation failed.
> >
> > + @retval FALSE This interface is not supported.
> >
> > +
> >
> > +*/
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +ParallelHash256HashAll (
> >
> > + IN CONST VOID *Input,
> >
> > + IN UINTN InputByteLen,
> >
> > + OUT VOID *Output,
> >
> > + IN UINTN OutputByteLen,
> >
> > + IN CONST VOID *Customization,
> >
> > + IN UINTN CustomByteLen
> >
> > + )
> >
> > +
> >
> > +{
> >
> > + UINT8 EncBufB[sizeof(UINTN)+1];
> >
> > + UINTN EncSizeB;
> >
> > + UINT8 EncBufN[sizeof(UINTN)+1];
> >
> > + UINTN EncSizeN;
> >
> > + UINT8 EncBufL[sizeof(UINTN)+1];
> >
> > + UINTN EncSizeL;
> >
> > + UINTN Index;
> >
> > + UINT8 *CombinedInput;
> >
> > + UINTN CombinedInputSize;
> >
> > + EFI_STATUS Status;
> >
> > + UINTN StartedApNum;
> >
> > + BOOLEAN AllCompleted;
> >
> > + UINTN Offset;
> >
> > + BOOLEAN ReturnValue;
> >
> > +
> >
> > + if (InputByteLen == 0 || OutputByteLen == 0) {
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + if (Input == NULL || Output == NULL){
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + if (CustomByteLen != 0 && Customization == NULL){
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Get Block number n.
> >
> > + //
> >
> > + mBlockNum = PcdGet16 (PcdParallelHashBlockNumber);
> >
> > +
> >
> > + if (mBlockNum < 1 || InputByteLen < mBlockNum - 1){
> >
> > + return FALSE;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Set hash result size of each block in bytes.
> >
> > + //
> >
> > + mBlockResultSize = OutputByteLen;
> >
> > +
> >
> > + //
> >
> > + // calculate the block byte length B.
> >
> > + //
> >
> > + mBlockSize = InputByteLen % mBlockNum == 0 ? InputByteLen /
> mBlockNum :
> > InputByteLen / (mBlockNum - 1);
> >
> > +
> >
> > + //
> >
> > + // Encode B, n, L to string and record size.
> >
> > + //
> >
> > + EncSizeB = LeftEncode (EncBufB, mBlockSize);
> >
> > + EncSizeN = RightEncode (EncBufN, mBlockNum);
> >
> > + EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
> >
> > +
> >
> > + //
> >
> > + // Allocate buffer for combined input (newX), Block completed flag
> > + and
> > SpinLock.
> >
> > + //
> >
> > + CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum *
> > mBlockResultSize;
> >
> > + CombinedInput = AllocateZeroPool (CombinedInputSize);
> >
> > + mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof
> > + (BOOLEAN));
> >
> > + mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
> >
> > + if (CombinedInput == NULL || mBlockIsCompleted == NULL ||
> > + mSpinLockList
> > == NULL) {
> >
> > + ReturnValue = FALSE;
> >
> > + goto Exit;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Fill LeftEncode(B).
> >
> > + //
> >
> > + CopyMem (CombinedInput, EncBufB, EncSizeB);
> >
> > +
> >
> > + //
> >
> > + // Prepare for parallel hash.
> >
> > + //
> >
> > + mBlockHashResult = CombinedInput + EncSizeB;
> >
> > + mInput = Input;
> >
> > + mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize :
> > InputByteLen % mBlockSize;
> >
> > +
> >
> > + //
> >
> > + // Initialize SpinLock for each result block.
> >
> > + //
> >
> > + for (Index = 0; Index < mBlockNum; Index++) {
> >
> > + InitializeSpinLock (&mSpinLockList[Index]);
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Dispatch blocklist to each AP.
> >
> > + //
> >
> > + StartedApNum = 0;
> >
> > + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
> >
> > + if (Index != gMmst->CurrentlyExecutingCpu) {
> >
> > + Status = gMmst->MmStartupThisAp (ParallelHashApExecute, Index,
> > + NULL);
> >
> > + if (!EFI_ERROR (Status)) {
> >
> > + StartedApNum++;
> >
> > + }
> >
> > + }
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Wait until all block hash completed.
> >
> > + //
> >
> > + do {
> >
> > + AllCompleted = TRUE;
> >
> > + for (Index = 0; Index < mBlockNum; Index++) {
> >
> > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> >
> > + if (!mBlockIsCompleted[Index]) {
> >
> > + AllCompleted = FALSE;
> >
> > + ReturnValue = CShake256HashAll (
> >
> > + mInput + Index * mBlockSize,
> >
> > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > + mBlockSize,
> >
> > + mBlockResultSize,
> >
> > + NULL,
> >
> > + 0,
> >
> > + NULL,
> >
> > + 0,
> >
> > + mBlockHashResult + Index * mBlockResultSize
> >
> > + );
> >
> > + if (ReturnValue){
> >
> > + mBlockIsCompleted[Index] = TRUE;
> >
> > + }
> >
> > + ReleaseSpinLock (&mSpinLockList[Index]);
> >
> > + break;
> >
> > + }
> >
> > + ReleaseSpinLock (&mSpinLockList[Index]);
> >
> > + } else {
> >
> > + AllCompleted = FALSE;
> >
> > + break;
> >
> > + }
> >
> > + }
> >
> > + } while (!AllCompleted);
> >
> > +
> >
> > + //
> >
> > + // Fill LeftEncode(n).
> >
> > + //
> >
> > + Offset = EncSizeB + mBlockNum * mBlockResultSize;
> >
> > + CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
> >
> > +
> >
> > + //
> >
> > + // Fill LeftEncode(L).
> >
> > + //
> >
> > + Offset += EncSizeN;
> >
> > + CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
> >
> > +
> >
> > + ReturnValue = CShake256HashAll (
> >
> > + CombinedInput,
> >
> > + CombinedInputSize,
> >
> > + OutputByteLen,
> >
> > + PARALLELHASH_CUSTOMIZATION,
> >
> > + AsciiStrLen(PARALLELHASH_CUSTOMIZATION),
> >
> > + Customization,
> >
> > + CustomByteLen,
> >
> > + Output
> >
> > + );
> >
> > +
> >
> > +Exit:
> >
> > + ZeroMem (CombinedInput, CombinedInputSize);
> >
> > +
> >
> > + if (CombinedInput != NULL){
> >
> > + FreePool (CombinedInput);
> >
> > + }
> >
> > + if (mSpinLockList != NULL){
> >
> > + FreePool (mSpinLockList);
> >
> > + }
> >
> > + if (mBlockIsCompleted != NULL){
> >
> > + FreePool (mBlockIsCompleted);
> >
> > + }
> >
> > +
> >
> > + return ReturnValue;
> >
> > +}
> >
> > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > new file mode 100644
> > index 0000000000..b170c463de
> > --- /dev/null
> > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > @@ -0,0 +1,102 @@
> > +/** @file
> >
> > + SHA3 realted functions from OpenSSL.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> >
> > +Licensed under the OpenSSL license (the "License"). You may not use
> >
> > +this file except in compliance with the License. You can obtain a
> > +copy
> >
> > +in the file LICENSE in the source distribution or at
> >
> > +https://www.openssl.org/source/license.html
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "sha3.h"
> >
> > +
> >
> > +size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t
> > +len,
> >
> > + size_t r);
> >
> > +void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len,
> > +size_t r);
> >
> > +
> >
> > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > +md_size)
> >
> > +{
> >
> > + if (bsz <= sizeof(ctx->buf)) {
> >
> > + memset(ctx->A, 0, sizeof(ctx->A));
> >
> > +
> >
> > + ctx->num = 0;
> >
> > + ctx->block_size = bsz;
> >
> > + ctx->md_size = md_size;
> >
> > + ctx->pad = pad;
> >
> > +
> >
> > + return 1;
> >
> > + }
> >
> > +
> >
> > + return 0;
> >
> > +}
> >
> > +
> >
> > +
> >
> > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
> >
> > +{
> >
> > + const unsigned char *inp = _inp;
> >
> > + size_t bsz = ctx->block_size;
> >
> > + size_t num, rem;
> >
> > +
> >
> > + if (len == 0)
> >
> > + return 1;
> >
> > +
> >
> > + if ((num = ctx->num) != 0) { /* process intermediate buffer? */
> >
> > + rem = bsz - num;
> >
> > +
> >
> > + if (len < rem) {
> >
> > + memcpy(ctx->buf + num, inp, len);
> >
> > + ctx->num += len;
> >
> > + return 1;
> >
> > + }
> >
> > + /*
> >
> > + * We have enough data to fill or overflow the intermediate
> >
> > + * buffer. So we append |rem| bytes and process the block,
> >
> > + * leaving the rest for later processing...
> >
> > + */
> >
> > + memcpy(ctx->buf + num, inp, rem);
> >
> > + inp += rem, len -= rem;
> >
> > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> >
> > + ctx->num = 0;
> >
> > + /* ctx->buf is processed, ctx->num is guaranteed to be zero
> > + */
> >
> > + }
> >
> > +
> >
> > + if (len >= bsz)
> >
> > + rem = SHA3_absorb(ctx->A, inp, len, bsz);
> >
> > + else
> >
> > + rem = len;
> >
> > +
> >
> > + if (rem) {
> >
> > + memcpy(ctx->buf, inp + len - rem, rem);
> >
> > + ctx->num = rem;
> >
> > + }
> >
> > +
> >
> > + return 1;
> >
> > +}
> >
> > +
> >
> > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md)
> >
> > +{
> >
> > + size_t bsz = ctx->block_size;
> >
> > + size_t num = ctx->num;
> >
> > +
> >
> > + if (ctx->md_size == 0)
> >
> > + return 1;
> >
> > +
> >
> > + /*
> >
> > + * Pad the data with 10*1. Note that |num| can be |bsz - 1|
> >
> > + * in which case both byte operations below are performed on
> >
> > + * same byte...
> >
> > + */
> >
> > + memset(ctx->buf + num, 0, bsz - num);
> >
> > + ctx->buf[num] = ctx->pad;
> >
> > + ctx->buf[bsz - 1] |= 0x80;
> >
> > +
> >
> > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> >
> > +
> >
> > + SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
> >
> > +
> >
> > + return 1;
> >
> > +}
> >
> > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > new file mode 100644
> > index 0000000000..b2a40ee044
> > --- /dev/null
> > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > @@ -0,0 +1,53 @@
> > +/** @file
> >
> > + Encode realted functions from Xkcp.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +The eXtended Keccak Code Package (XKCP)
> >
> > +https://github.com/XKCP/XKCP
> >
> > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and
> > +Gilles
> > Van Assche.
> >
> > +Implementation by the designers, hereby denoted as "the implementer".
> >
> > +For more information, feedback or questions, please refer to the
> > +Keccak Team
> > website:
> >
> > +https://keccak.team/
> >
> > +To the extent possible under law, the implementer has waived all
> > +copyright
> >
> > +and related or neighboring rights to the source code in this file.
> >
> > +http://creativecommons.org/publicdomain/zero/1.0/
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "xkcp.h"
> >
> > +
> >
> > +unsigned int left_encode(unsigned char * encbuf, size_t value)
> >
> > +{
> >
> > + unsigned int n, i;
> >
> > + size_t v;
> >
> > +
> >
> > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> >
> > + ; /* empty */
> >
> > + if (n == 0)
> >
> > + n = 1;
> >
> > + for ( i = 1; i <= n; ++i )
> >
> > + {
> >
> > + encbuf[i] = (unsigned char)(value >> (8 * (n-i)));
> >
> > + }
> >
> > + encbuf[0] = (unsigned char)n;
> >
> > + return n + 1;
> >
> > +}
> >
> > +
> >
> > +unsigned int right_encode(unsigned char * encbuf, size_t value)
> >
> > +{
> >
> > + unsigned int n, i;
> >
> > + size_t v;
> >
> > +
> >
> > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> >
> > + ; /* empty */
> >
> > + if (n == 0)
> >
> > + n = 1;
> >
> > + for ( i = 1; i <= n; ++i )
> >
> > + {
> >
> > + encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
> >
> > + }
> >
> > + encbuf[n] = (unsigned char)n;
> >
> > + return n + 1;
> >
> > +}
> >
> > diff --git
> > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > new file mode 100644
> > index 0000000000..052ab3a0d6
> > --- /dev/null
> > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > @@ -0,0 +1,152 @@
> > +/** @file
> >
> > + Application for Parallelhash Function Validation.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "TestBaseCryptLib.h"
> >
> > +
> >
> > +//
> >
> > +// Parallelhash Test Sample common parameters.
> >
> > +//
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN OutputByteLen =
> 64;
> >
> > +
> >
> > +//
> >
> > +// Parallelhash Test Sample #1 from NIST Special Publication 800-185.
> >
> > +//
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample1[]
> = {
> >
> > + // input data of sample1.
> >
> > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
> > + 0x13, 0x14,
> > 0x15, 0x16, 0x17,
> >
> > + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
> >
> > +};
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample1ByteLen
> =
> > 24; // Length of sample1 input data in bytes.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> *CustomizationSample1
> > = ""; // Customization string (S) of sample1.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> CustomSample1ByteLen =
> > 0; // Customization string length of sample1 in bytes.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample1 =
> 8;
> > // Block size of sample1.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> ExpectOutputSample1[]
> > = {
> >
> > + // Expected output data of sample1.
> >
> > + 0xbc, 0x1e, 0xf1, 0x24, 0xda, 0x34, 0x49, 0x5e, 0x94, 0x8e, 0xad,
> > + 0x20, 0x7d,
> > 0xd9, 0x84, 0x22,
> >
> > + 0x35, 0xda, 0x43, 0x2d, 0x2b, 0xbc, 0x54, 0xb4, 0xc1, 0x10, 0xe6,
> > + 0x4c, 0x45,
> > 0x11, 0x05, 0x53,
> >
> > + 0x1b, 0x7f, 0x2a, 0x3e, 0x0c, 0xe0, 0x55, 0xc0, 0x28, 0x05, 0xe7,
> > + 0xc2, 0xde,
> > 0x1f, 0xb7, 0x46,
> >
> > + 0xaf, 0x97, 0xa1, 0xd0, 0x01, 0xf4, 0x3b, 0x82, 0x4e, 0x31, 0xb8,
> > + 0x76, 0x12,
> > 0x41, 0x04, 0x29
> >
> > +};
> >
> > +
> >
> > +//
> >
> > +// Parallelhash Test Sample #2 from NIST Special Publication 800-185.
> >
> > +//
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 *InputSample2
> =
> > InputSample1; // Input of sample2 is same as sample1.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample2ByteLen
> =
> > 24; // Length of sample2 input data in bytes.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> *CustomizationSample2
> > = "Parallel Data"; // Customization string (S) of sample2.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> CustomSample2ByteLen =
> > 13; // Customization string length of sample2 in bytes.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample2 =
> 8;
> > // Block size of sample2.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> ExpectOutputSample2[]
> > = {
> >
> > + // Expected output data of sample2.
> >
> > + 0xcd, 0xf1, 0x52, 0x89, 0xb5, 0x4f, 0x62, 0x12, 0xb4, 0xbc, 0x27,
> > + 0x05, 0x28,
> > 0xb4, 0x95, 0x26,
> >
> > + 0x00, 0x6d, 0xd9, 0xb5, 0x4e, 0x2b, 0x6a, 0xdd, 0x1e, 0xf6, 0x90,
> > + 0x0d, 0xda,
> > 0x39, 0x63, 0xbb,
> >
> > + 0x33, 0xa7, 0x24, 0x91, 0xf2, 0x36, 0x96, 0x9c, 0xa8, 0xaf, 0xae,
> > + 0xa2, 0x9c,
> > 0x68, 0x2d, 0x47,
> >
> > + 0xa3, 0x93, 0xc0, 0x65, 0xb3, 0x8e, 0x29, 0xfa, 0xe6, 0x51, 0xa2,
> > + 0x09, 0x1c,
> > 0x83, 0x31, 0x10
> >
> > +};
> >
> > +
> >
> > +//
> >
> > +// Parallelhash Test Sample #3 from NIST Special Publication 800-185.
> >
> > +//
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample3[]
> = {
> >
> > + // input data of sample3.
> >
> > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
> > + 0x0b, 0x10,
> > 0x11, 0x12, 0x13,
> >
> > + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22,
> > + 0x23, 0x24,
> > 0x25, 0x26, 0x27,
> >
> > + 0x28, 0x29, 0x2a, 0x2b, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
> > + 0x37, 0x38,
> > 0x39, 0x3a, 0x3b,
> >
> > + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
> > + 0x4b, 0x50,
> > 0x51, 0x52, 0x53,
> >
> > + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
> >
> > +};
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample3ByteLen
> =
> > 72; // Length of sample3 input data in bytes.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> *CustomizationSample3
> > = "Parallel Data"; // Customization string (S) of sample3.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> CustomSample3ByteLen =
> > 13; // Customization string length of sample3 in bytes.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample3 =
> 12;
> > // Block size of sample3.
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> ExpectOutputSample3[]
> > = {
> >
> > + // Expected output data of sample3.
> >
> > + 0x69, 0xd0, 0xfc, 0xb7, 0x64, 0xea, 0x05, 0x5d, 0xd0, 0x93, 0x34,
> > + 0xbc, 0x60,
> > 0x21, 0xcb, 0x7e,
> >
> > + 0x4b, 0x61, 0x34, 0x8d, 0xff, 0x37, 0x5d, 0xa2, 0x62, 0x67, 0x1c,
> > + 0xde, 0xc3,
> > 0xef, 0xfa, 0x8d,
> >
> > + 0x1b, 0x45, 0x68, 0xa6, 0xcc, 0xe1, 0x6b, 0x1c, 0xad, 0x94, 0x6d,
> > + 0xdd, 0xe2,
> > 0x7f, 0x6c, 0xe2,
> >
> > + 0xb8, 0xde, 0xe4, 0xcd, 0x1b, 0x24, 0x85, 0x1e, 0xbf, 0x00, 0xeb,
> > + 0x90, 0xd4,
> > 0x38, 0x13, 0xe9
> >
> > +};
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestVerifyParallelHash256HashAll (
> >
> > + IN UNIT_TEST_CONTEXT Context
> >
> > + )
> >
> > +{
> >
> > + BOOLEAN Status;
> >
> > + UINT16 OriginalParallelHashBlockNumber;
> >
> > + UINT8 Output[64];
> >
> > +
> >
> > + // Restore original PcdParallelHashBlockNumber.
> >
> > + OriginalParallelHashBlockNumber = PcdGet16
> > + (PcdParallelHashBlockNumber);
> >
> > +
> >
> > + //
> >
> > + // Test #1 using sample1.
> >
> > + //
> >
> > + PcdSet16S (PcdParallelHashBlockNumber, InputSample1ByteLen /
> > BlockSizeSample1);
> >
> > + Status = ParallelHash256HashAll (
> >
> > + InputSample1,
> >
> > + InputSample1ByteLen,
> >
> > + Output,
> >
> > + OutputByteLen,
> >
> > + CustomizationSample1,
> >
> > + CustomSample1ByteLen
> >
> > + );
> >
> > + UT_ASSERT_TRUE (Status);
> >
> > +
> >
> > + // Check the output with the expected output.
> >
> > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample1,
> OutputByteLen);
> >
> > +
> >
> > + //
> >
> > + // Test #2 using sample2.
> >
> > + //
> >
> > + PcdSet16S (PcdParallelHashBlockNumber, InputSample2ByteLen /
> > BlockSizeSample2);
> >
> > + Status = ParallelHash256HashAll (
> >
> > + InputSample2,
> >
> > + InputSample2ByteLen,
> >
> > + Output,
> >
> > + OutputByteLen,
> >
> > + CustomizationSample2,
> >
> > + CustomSample2ByteLen
> >
> > + );
> >
> > + UT_ASSERT_TRUE (Status);
> >
> > +
> >
> > + // Check the output with the expected output.
> >
> > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample2,
> OutputByteLen);
> >
> > +
> >
> > + //
> >
> > + // Test #3 using sample3.
> >
> > + //
> >
> > + PcdSet16S (PcdParallelHashBlockNumber, InputSample3ByteLen /
> > BlockSizeSample3);
> >
> > + Status = ParallelHash256HashAll (
> >
> > + InputSample3,
> >
> > + InputSample3ByteLen,
> >
> > + Output,
> >
> > + OutputByteLen,
> >
> > + CustomizationSample3,
> >
> > + CustomSample3ByteLen
> >
> > + );
> >
> > + UT_ASSERT_TRUE (Status);
> >
> > +
> >
> > + // Check the output with the expected output.
> >
> > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample3,
> OutputByteLen);
> >
> > +
> >
> > + // Recover original PcdParallelHashBlockNumber.
> >
> > + PcdSet16S (PcdParallelHashBlockNumber,
> > + OriginalParallelHashBlockNumber);
> >
> > +
> >
> > + return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +TEST_DESC mParallelhashTest[] = {
> >
> > + //
> >
> > + //
> > + -----Description------------------------------Class-----------------
> > + -----Function----
> > -------------Pre---Post--Context
> >
> > + //
> >
> > + { "TestVerifyParallelHash256HashAll()",
> > "CryptoPkg.BaseCryptLib.ParallelHash256HashAll",
> > TestVerifyParallelHash256HashAll, NULL, NULL, NULL },
> >
> > +};
> >
> > +
> >
> > +UINTN mParallelhashTestNum = ARRAY_SIZE (mParallelhashTest);
> >
> > diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec index
> > 5888941bab..3af55d9c10 100644
> > --- a/CryptoPkg/CryptoPkg.dec
> > +++ b/CryptoPkg/CryptoPkg.dec
> > @@ -4,7 +4,7 @@
> > # This Package provides cryptographic-related libraries for UEFI
> > security modules.
> >
> > # It also provides a test application to test libraries.
> >
> > #
> >
> > -# Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > reserved.<BR>
> >
> > +# Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > +reserved.<BR>
> >
> > # SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > #
> >
> > ##
> >
> > @@ -81,5 +81,12 @@
> > # @ValidList 0x80000001 | 0x00000001, 0x00000002, 0x00000004,
> > 0x00000008, 0x00000010
> >
> >
> >
> gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x00000002|UINT32|0x
> 00
> > 000001
> >
> >
> >
> > +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic,
> PcdsDynamicEx]
> >
> > + ## This PCD indicates the block number of parallel hash
> >
> > + # Based on the value set, parallel hash can chose the block
> >
> > + # number to calculate specific hash.<BR>
> >
> > + # The number can be set by platform team according to the core
> number.
> >
> > +
> >
> gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber|0x0100|UINT1
> 6|0
> > x00000003
> >
> > +
> >
> > [UserExtensions.TianoCore."ExtraFiles"]
> >
> > CryptoPkgExtra.uni
> >
> > diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> > b/CryptoPkg/Include/Library/BaseCryptLib.h
> > index f4bc7c0d73..0b274b1257 100644
> > --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> > +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> > @@ -4,7 +4,7 @@
> > primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI
> > security
> >
> > functionality enabling.
> >
> >
> >
> > -Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > reserved.<BR>
> >
> > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > +reserved.<BR>
> >
> > SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> >
> >
> > **/
> >
> > @@ -753,6 +753,33 @@ Sha512HashAll (
> > OUT UINT8 *HashValue
> >
> > );
> >
> >
> >
> > +/**
> >
> > + Parallel hash function ParallelHash256, as defined in NIST's
> > + Special Publication
> > 800-185,
> >
> > + published December 2016.
> >
> > +
> >
> > + @param[in] Input Pointer to the input message (X).
> >
> > + @param[in] InputByteLen The number(>0) of input bytes provided
> for the
> > input data.
> >
> > + @param[out] Output Pointer to the output buffer.
> >
> > + @param[in] OutputByteLen The desired number of output bytes (L).
> >
> > + @param[in] Customization Pointer to the customization string (S).
> >
> > + @param[in] CustomByteLen The length of the customization string in
> bytes.
> >
> > +
> >
> > + @retval TRUE ParallelHash256 digest computation succeeded.
> >
> > + @retval FALSE ParallelHash256 digest computation failed.
> >
> > + @retval FALSE This interface is not supported.
> >
> > +
> >
> > +**/
> >
> > +BOOLEAN
> >
> > +EFIAPI
> >
> > +ParallelHash256HashAll (
> >
> > + IN CONST VOID *Input,
> >
> > + IN UINTN InputByteLen,
> >
> > + OUT VOID *Output,
> >
> > + IN UINTN OutputByteLen,
> >
> > + IN CONST VOID *Customization,
> >
> > + IN UINTN CustomByteLen
> >
> > + );
> >
> > +
> >
> > /**
> >
> > Retrieves the size, in bytes, of the context buffer required for
> > SM3 hash operations.
> >
> >
> >
> > diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > index e6470d7a21..70159163d4 100644
> > --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > @@ -10,7 +10,7 @@
> > # RSA external functions, PKCS#7 SignedData sign functions,
> > Diffie-Hellman functions, and
> >
> > # authenticode signature verification functions are not supported in
> > this instance.
> >
> > #
> >
> > -# Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > reserved.<BR>
> >
> > +# Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > +reserved.<BR>
> >
> > # SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > #
> >
> > ##
> >
> > @@ -38,6 +38,10 @@
> > Hash/CryptSha256.c
> >
> > Hash/CryptSm3.c
> >
> > Hash/CryptSha512.c
> >
> > + Hash/CryptSha3.c
> >
> > + Hash/CryptXkcp.c
> >
> > + Hash/CryptCShake256.c
> >
> > + Hash/CryptParallelHash.c
> >
> > Hmac/CryptHmacSha256.c
> >
> > Kdf/CryptHkdfNull.c
> >
> > Cipher/CryptAes.c
> >
> > @@ -85,6 +89,9 @@
> > OpensslLib
> >
> > IntrinsicLib
> >
> > PrintLib
> >
> > + MmServicesTableLib
> >
> > + SynchronizationLib
> >
> > + PcdLib
> >
> >
> >
> > #
> >
> > # Remove these [BuildOptions] after this library is cleaned up
> >
> > @@ -101,3 +108,6 @@
> > GCC:*_CLANG35_*_CC_FLAGS = -std=c99
> >
> > GCC:*_CLANG38_*_CC_FLAGS = -std=c99
> >
> > GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99
> > -Wno-error=incompatible-pointer- types
> >
> > +
> >
> > +[Pcd]
> >
> > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> >
> > diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h
> > b/CryptoPkg/Library/Include/CrtLibSupport.h
> > index d257dca8fa..35d9c62a0b 100644
> > --- a/CryptoPkg/Library/Include/CrtLibSupport.h
> > +++ b/CryptoPkg/Library/Include/CrtLibSupport.h
> > @@ -2,7 +2,7 @@
> > Root include file of C runtime library to support building the
> > third-party
> >
> > cryptographic library.
> >
> >
> >
> > -Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > reserved.<BR>
> >
> > +Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > +reserved.<BR>
> >
> > Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All
> > rights reserved.<BR>
> >
> > SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> >
> >
> > @@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> >
> > #define MAX_STRING_SIZE 0x1000
> >
> >
> >
> > +#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
> >
> > +
> >
> > //
> >
> > // We already have "no-ui" in out Configure invocation.
> >
> > // but the code still fails to compile.
> >
> > @@ -111,6 +113,7 @@ typedef UINT8 u_char;
> > typedef UINT32 uid_t;
> >
> > typedef UINT32 gid_t;
> >
> > typedef CHAR16 wchar_t;
> >
> > +typedef UINT64 uint64_t;
> >
> >
> >
> > //
> >
> > // File operations are not required for EFI building,
> >
> > diff --git a/CryptoPkg/Library/Include/sha3.h
> > b/CryptoPkg/Library/Include/sha3.h
> > new file mode 100644
> > index 0000000000..71b4c75548
> > --- /dev/null
> > +++ b/CryptoPkg/Library/Include/sha3.h
> > @@ -0,0 +1,32 @@
> > +/** @file
> >
> > + SHA3 realted functions from OpenSSL.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> >
> > +Licensed under the OpenSSL license (the "License"). You may not use
> >
> > +this file except in compliance with the License. You can obtain a
> > +copy
> >
> > +in the file LICENSE in the source distribution or at
> >
> > +https://www.openssl.org/source/license.html
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <CrtLibSupport.h>
> >
> > +
> >
> > +#define KECCAK1600_WIDTH 1600
> >
> > +
> >
> > +typedef struct {
> >
> > + uint64_t A[5][5];
> >
> > + size_t block_size; /* cached ctx->digest->block_size */
> >
> > + size_t md_size; /* output length, variable in XOF */
> >
> > + size_t num; /* used bytes in below buffer */
> >
> > + unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
> >
> > + unsigned char pad;
> >
> > +} KECCAK1600_CTX;
> >
> > +
> >
> > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > +md_size);
> >
> > +
> >
> > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
> >
> > +
> >
> > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md);
> >
> > diff --git a/CryptoPkg/Library/Include/xkcp.h
> > b/CryptoPkg/Library/Include/xkcp.h
> > new file mode 100644
> > index 0000000000..b328d672e4
> > --- /dev/null
> > +++ b/CryptoPkg/Library/Include/xkcp.h
> > @@ -0,0 +1,23 @@
> > +/** @file
> >
> > + Encode realted functions from Xkcp.
> >
> > +
> >
> > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +The eXtended Keccak Code Package (XKCP)
> >
> > +https://github.com/XKCP/XKCP
> >
> > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and
> > +Gilles
> > Van Assche.
> >
> > +Implementation by the designers, hereby denoted as "the implementer".
> >
> > +For more information, feedback or questions, please refer to the
> > +Keccak Team
> > website:
> >
> > +https://keccak.team/
> >
> > +To the extent possible under law, the implementer has waived all
> > +copyright
> >
> > +and related or neighboring rights to the source code in this file.
> >
> > +http://creativecommons.org/publicdomain/zero/1.0/
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <CrtLibSupport.h>
> >
> > +
> >
> > +unsigned int left_encode(unsigned char * encbuf, size_t value);
> >
> > +
> >
> > +unsigned int right_encode(unsigned char * encbuf, size_t value);
> >
> > diff --git
> > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > index a6b3482742..0bffd687c2 100644
> > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > @@ -1,7 +1,7 @@
> > /** @file
> >
> > Application for Cryptographic Primitives Validation.
> >
> >
> >
> > -Copyright (c) 2009 - 2016, Intel Corporation. All rights
> > reserved.<BR>
> >
> > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > +reserved.<BR>
> >
> > SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> >
> >
> > **/
> >
> > @@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > #include <Library/BaseLib.h>
> >
> > #include <Library/BaseMemoryLib.h>
> >
> > #include <Library/MemoryAllocationLib.h>
> >
> > +#include <Library/PcdLib.h>
> >
> > // #include <UnitTestTypes.h>
> >
> > #include <Library/UnitTestLib.h>
> >
> > // #include <Library/UnitTestAssertLib.h>
> >
> > diff --git
> > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > f
> > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > f
> > index 00c8692650..61a59d6a47 100644
> > ---
> > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > f
> > +++
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHos
> > +++ t.inf
> > @@ -2,6 +2,7 @@
> > # Host-based UnitTest for BaseCryptLib
> >
> > #
> >
> > # Copyright (c) Microsoft Corporation.<BR>
> >
> > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > # SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > ##
> >
> >
> >
> > @@ -35,6 +36,7 @@
> > Pkcs7EkuTests.c
> >
> > OaepEncryptTests.c
> >
> > RsaPssTests.c
> >
> > + ParallelhashTests.c
> >
> >
> >
> > [Packages]
> >
> > MdePkg/MdePkg.dec
> >
> > @@ -45,3 +47,8 @@
> > DebugLib
> >
> > BaseCryptLib
> >
> > UnitTestLib
> >
> > + PcdLib
> >
> > +
> >
> > +[Pcd]
> >
> > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> >
> > +
> >
> > diff --git
> > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > nf
> > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > nf
> > index ca789aa6ad..682f25a754 100644
> > ---
> > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > nf
> > +++
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShe
> > +++ ll.inf
> > @@ -2,6 +2,7 @@
> > # BaseCryptLib UnitTest built for execution in UEFI Shell.
> >
> > #
> >
> > # Copyright (c) Microsoft Corporation.<BR>
> >
> > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> >
> > # SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > ##
> >
> >
> >
> > @@ -36,6 +37,7 @@
> > Pkcs7EkuTests.c
> >
> > OaepEncryptTests.c
> >
> > RsaPssTests.c
> >
> > + ParallelhashTests.c
> >
> >
> >
> > [Packages]
> >
> > MdePkg/MdePkg.dec
> >
> > @@ -48,3 +50,7 @@
> > UnitTestLib
> >
> > PrintLib
> >
> > BaseCryptLib
> >
> > + PcdLib
> >
> > +
> >
> > +[Pcd]
> >
> > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> >
> > --
> > 2.26.2.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
2022-02-16 7:43 ` Li, Zhihao
@ 2022-02-16 7:51 ` Yao, Jiewen
2022-02-16 8:23 ` Li, Zhihao
2022-02-17 5:28 ` Li, Zhihao
0 siblings, 2 replies; 6+ messages in thread
From: Yao, Jiewen @ 2022-02-16 7:51 UTC (permalink / raw)
To: Li, Zhihao, devel@edk2.groups.io
Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin, Fu, Siyuan
But I don’t understand why we need sha3.h and xkcp.h at all.
> -----Original Message-----
> From: Li, Zhihao <zhihao.li@intel.com>
> Sent: Wednesday, February 16, 2022 3:43 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>;
> Jiang, Guomin <guomin.jiang@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> ParallelHash256HashAll in BaseCryptLib.
>
> With your comment, we plan do some modification for parallelhash.
> 1. Plan to add a parameter (BlockSize) on ParallelHash256HashAll function to
> replace PcdParallelHashBlockNumber.
> 2. Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash
> folder.
>
>
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: Tuesday, February 15, 2022 2:09 PM
> > To: Li, Zhihao <zhihao.li@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> > <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Fu,
> > Siyuan <siyuan.fu@intel.com>
> > Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> > ParallelHash256HashAll in BaseCryptLib.
> >
> > Thanks for the update.
> >
> > Feedback below:
> >
> > 1) How block size is determined for below API?
> >
> > BOOLEAN
> > EFIAPI
> > ParallelHash256HashAll (
> > IN CONST VOID *Input,
> > IN UINTN InputByteLen,
> > OUT VOID *Output,
> > IN UINTN OutputByteLen,
> > IN CONST VOID *Customization,
> > IN UINTN CustomByteLen
> > );
> >
> > Is that determined by PcdParallelHashBlockNumber ?
> >
> > I don’t think it is good idea to let a crypto library determine a platform PCD.
> > For example, how do you support binary crypto module ?
> Plan to add a parameter (BlockSize) to replace PcdParallelHashBlockNumber.
> >
> > 2) Why we need "sha3.h" and "xkcp.h" ?
> > These are openssl specific structure. It shall not be put to EDKII file header.
> >
> > CryptoPkg\Library\Include shall only contain generic dependency header.
> Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash folder.
> >
> >
> >
> >
> > Thank you
> > Yao, Jiewen
> >
> > > -----Original Message-----
> > > From: Li, Zhihao <zhihao.li@intel.com>
> > > Sent: Friday, February 11, 2022 5:05 PM
> > > To: devel@edk2.groups.io
> > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > <jian.j.wang@intel.com>; Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang,
> > > Guomin <guomin.jiang@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> > > Subject: [PATCH v1] CryptoPkg: Add new hash algorithm
> > > ParallelHash256HashAll in BaseCryptLib.
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3596
> > >
> > > Parallel hash function ParallelHash256HashAll, as defined in NIST's
> > > Special Publication 800-185, published December 2016. It utilizes
> > > multi-process to calculate the digest.
> > >
> > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> > > Cc: Guomin Jiang <guomin.jiang@intel.com>
> > > Cc: Siyuan Fu <siyuan.fu@intel.com>
> > >
> > > Signed-off-by: Zhihao Li <zhihao.li@intel.com>
> > > ---
> > > CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c | 313
> > > ++++++++++++++++++++
> > > CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c | 275
> > > +++++++++++++++++
> > > CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c | 102
> > +++++++
> > > CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c | 53 ++++
> > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c |
> > 152
> > > ++++++++++
> > > CryptoPkg/CryptoPkg.dec | 9 +-
> > > CryptoPkg/Include/Library/BaseCryptLib.h | 29 +-
> > > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 12 +-
> > > CryptoPkg/Library/Include/CrtLibSupport.h | 5 +-
> > > CryptoPkg/Library/Include/sha3.h | 32 ++
> > > CryptoPkg/Library/Include/xkcp.h | 23 ++
> > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3
> > +-
> > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> > | 7 +
> > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf |
> > 6 +
> > > 14 files changed, 1016 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > new file mode 100644
> > > index 0000000000..5efced3f46
> > > --- /dev/null
> > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > @@ -0,0 +1,313 @@
> > > +/** @file
> > >
> > > + cSHAKE-256 Digest Wrapper Implementations.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include "InternalCryptLib.h"
> > >
> > > +#include "sha3.h"
> > >
> > > +#include "xkcp.h"
> > >
> > > +
> > >
> > > +#define CSHAKE256_SECURITY_STRENGTH 256
> > >
> > > +#define CSHAKE256_RATE_IN_BYTES 136
> > >
> > > +
> > >
> > > +const CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = {0};
> > >
> > > +
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +LeftEncode (
> > >
> > > + OUT UINT8 *Encbuf,
> > >
> > > + IN UINTN Value
> > >
> > > + )
> > >
> > > +{
> > >
> > > + return left_encode (Encbuf, Value);
> > >
> > > +}
> > >
> > > +
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +RightEncode (
> > >
> > > + OUT UINT8 *Encbuf,
> > >
> > > + IN UINTN Value
> > >
> > > + )
> > >
> > > +{
> > >
> > > + return right_encode (Encbuf, Value);
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Retrieves the size, in bytes, of the context buffer required for
> > > + cSHAKE-256
> > > hash operations.
> > >
> > > +
> > >
> > > + @return The size, in bytes, of the context buffer required for
> > > + cSHAKE-256
> > > hash operations.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +UINTN
> > >
> > > +EFIAPI
> > >
> > > +CShake256GetContextSize (
> > >
> > > + VOID
> > >
> > > + )
> > >
> > > +{
> > >
> > > + return (UINTN) (sizeof (KECCAK1600_CTX));
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Initializes user-supplied memory pointed by CShake256Context as
> > > + cSHAKE-256
> > > hash context for
> > >
> > > + subsequent use.
> > >
> > > +
> > >
> > > + @param[out] CShake256Context Pointer to cSHAKE-256 context being
> > > initialized.
> > >
> > > + @param[in] OutputLen The desired number of output length in
> > bytes.
> > >
> > > + @param[in] Name Pointer to the function name string.
> > >
> > > + @param[in] NameLen The length of the function name in bytes.
> > >
> > > + @param[in] Customization Pointer to the customization string.
> > >
> > > + @param[in] CustomizationLen The length of the customization string in
> > > bytes.
> > >
> > > +
> > >
> > > + @retval TRUE cSHAKE-256 context initialization succeeded.
> > >
> > > + @retval FALSE cSHAKE-256 context initialization failed.
> > >
> > > + @retval FALSE This interface is not supported.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +CShake256Init (
> > >
> > > + OUT VOID *CShake256Context,
> > >
> > > + IN UINTN OutputLen,
> > >
> > > + IN CONST VOID *Name,
> > >
> > > + IN UINTN NameLen,
> > >
> > > + IN CONST VOID *Customization,
> > >
> > > + IN UINTN CustomizationLen
> > >
> > > + )
> > >
> > > +{
> > >
> > > + BOOLEAN Status;
> > >
> > > + unsigned char EncBuf[sizeof(size_t)+1];
> > >
> > > + UINTN EncLen;
> > >
> > > + UINTN AbsorbLen;
> > >
> > > + UINTN PadLen;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Check input parameters.
> > >
> > > + //
> > >
> > > + if (CShake256Context == NULL ||
> > >
> > > + OutputLen == 0 ||
> > >
> > > + (NameLen != 0 && Name == NULL) ||
> > >
> > > + (CustomizationLen != 0 && Customization == NULL)) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Initialize KECCAK context with pad value and block size.
> > >
> > > + //
> > >
> > > + if (NameLen == 0 && CustomizationLen == 0) {
> > >
> > > + //
> > >
> > > + // When N and S are both empty strings, cSHAKE(X, L, N, S) is
> > > + equivalent to
> > >
> > > + // SHAKE as defined in FIPS 202.
> > >
> > > + //
> > >
> > > + return (BOOLEAN) init (
> > >
> > > + (KECCAK1600_CTX *) CShake256Context,
> > >
> > > + '\x1f',
> > >
> > > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > > + * 2) / 8,
> > >
> > > + OutputLen
> > >
> > > + );
> > >
> > > + }
> > >
> > > +
> > >
> > > + Status = (BOOLEAN) init (
> > >
> > > + (KECCAK1600_CTX *) CShake256Context,
> > >
> > > + '\x04',
> > >
> > > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > > + * 2) / 8,
> > >
> > > + OutputLen
> > >
> > > + );
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + AbsorbLen = 0;
> > >
> > > + //
> > >
> > > + // Absorb Absorb bytepad(.., rate).
> > >
> > > + //
> > >
> > > + EncLen = left_encode (EncBuf, CSHAKE256_RATE_IN_BYTES);
> > >
> > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > + CShake256Context,
> > > EncBuf, EncLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > + AbsorbLen += EncLen;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Absorb encode_string(N).
> > >
> > > + //
> > >
> > > + EncLen = left_encode (EncBuf, NameLen * 8);
> > >
> > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > + CShake256Context,
> > > EncBuf, EncLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > + AbsorbLen += EncLen;
> > >
> > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > + CShake256Context,
> > > Name, NameLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > + AbsorbLen += NameLen;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Absorb encode_string(S).
> > >
> > > + //
> > >
> > > + EncLen = left_encode (EncBuf, CustomizationLen * 8);
> > >
> > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > + CShake256Context,
> > > EncBuf, EncLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > + AbsorbLen += EncLen;
> > >
> > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > + CShake256Context,
> > > Customization, CustomizationLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > + AbsorbLen += CustomizationLen;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Absorb zero padding up to rate.
> > >
> > > + //
> > >
> > > + PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen %
> > > CSHAKE256_RATE_IN_BYTES;
> > >
> > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > + CShake256Context,
> > > mZeroPadding, PadLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + return TRUE;
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Digests the input data and updates cSHAKE-256 context.
> > >
> > > +
> > >
> > > + This function performs cSHAKE-256 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.
> > >
> > > + cSHAKE-256 context should be already correctly initialized by
> > > + CShake256Init(),
> > > and should not be finalized
> > >
> > > + by CShake256Final(). Behavior with invalid context is undefined.
> > >
> > > +
> > >
> > > + @param[in, out] CShake256Context Pointer to the cSHAKE-256 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 cSHAKE-256 data digest succeeded.
> > >
> > > + @retval FALSE cSHAKE-256 data digest failed.
> > >
> > > + @retval FALSE This interface is not supported.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +CShake256Update (
> > >
> > > + IN OUT VOID *CShake256Context,
> > >
> > > + IN CONST VOID *Data,
> > >
> > > + IN UINTN DataSize
> > >
> > > + )
> > >
> > > +{
> > >
> > > + //
> > >
> > > + // Check input parameters.
> > >
> > > + //
> > >
> > > + if (CShake256Context == NULL) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Check invalid parameters, in case that only DataLength was
> > > + checked in
> > > OpenSSL.
> > >
> > > + //
> > >
> > > + if (Data == NULL && DataSize != 0) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + return (BOOLEAN)(sha3_update ((KECCAK1600_CTX *)
> > CShake256Context,
> > > Data, DataSize));
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Completes computation of the cSHAKE-256 digest value.
> > >
> > > +
> > >
> > > + This function completes cSHAKE-256 hash computation and retrieves
> > > + the
> > > digest value into
> > >
> > > + the specified memory. After this function has been called, the
> > > + cSHAKE-256
> > > context cannot
> > >
> > > + be used again.
> > >
> > > + cSHAKE-256 context should be already correctly initialized by
> > > + CShake256Init(),
> > > and should not be
> > >
> > > + finalized by CShake256Final(). Behavior with invalid cSHAKE-256
> > > + context is
> > > undefined.
> > >
> > > +
> > >
> > > + @param[in, out] CShake256Context Pointer to the cSHAKE-256 context.
> > >
> > > + @param[out] HashValue Pointer to a buffer that receives the
> > cSHAKE-
> > > 256 digest
> > >
> > > + value.
> > >
> > > +
> > >
> > > + @retval TRUE cSHAKE-256 digest computation succeeded.
> > >
> > > + @retval FALSE cSHAKE-256 digest computation failed.
> > >
> > > + @retval FALSE This interface is not supported.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +CShake256Final (
> > >
> > > + IN OUT VOID *CShake256Context,
> > >
> > > + OUT UINT8 *HashValue
> > >
> > > + )
> > >
> > > +{
> > >
> > > + //
> > >
> > > + // Check input parameters.
> > >
> > > + //
> > >
> > > + if (CShake256Context == NULL || HashValue == NULL) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // cSHAKE-256 Hash Finalization.
> > >
> > > + //
> > >
> > > + return (BOOLEAN) (sha3_final ((KECCAK1600_CTX *) CShake256Context,
> > > HashValue));
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Computes the CSHAKE-256 message digest of a input data buffer.
> > >
> > > +
> > >
> > > + This function performs the CSHAKE-256 message digest of a given
> > > + data buffer,
> > > and places
> > >
> > > + the digest value into the specified memory.
> > >
> > > +
> > >
> > > + @param[in] Data Pointer to the buffer containing the data to be
> > > hashed.
> > >
> > > + @param[in] DataSize Size of Data buffer in bytes.
> > >
> > > + @param[in] OutputLen Size of output in bytes.
> > >
> > > + @param[in] Name Pointer to the function name string.
> > >
> > > + @param[in] NameLen Size of the function name in bytes.
> > >
> > > + @param[in] Customization Pointer to the customization string.
> > >
> > > + @param[in] CustomizationLen Size of the customization string in bytes.
> > >
> > > + @param[out] HashValue Pointer to a buffer that receives the
> > CSHAKE-
> > > 256 digest
> > >
> > > + value.
> > >
> > > +
> > >
> > > + @retval TRUE CSHAKE-256 digest computation succeeded.
> > >
> > > + @retval FALSE CSHAKE-256 digest computation failed.
> > >
> > > + @retval FALSE This interface is not supported.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +CShake256HashAll (
> > >
> > > + IN CONST VOID *Data,
> > >
> > > + IN UINTN DataSize,
> > >
> > > + IN UINTN OutputLen,
> > >
> > > + IN CONST VOID *Name,
> > >
> > > + IN UINTN NameLen,
> > >
> > > + IN CONST VOID *Customization,
> > >
> > > + IN UINTN CustomizationLen,
> > >
> > > + OUT UINT8 *HashValue
> > >
> > > + )
> > >
> > > +{
> > >
> > > + BOOLEAN Status;
> > >
> > > + KECCAK1600_CTX Ctx;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Check input parameters.
> > >
> > > + //
> > >
> > > + if (HashValue == NULL) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > + if (Data == NULL && DataSize != 0) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + Status = CShake256Init (&Ctx, OutputLen, Name, NameLen,
> > > + Customization,
> > > CustomizationLen);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + Status = CShake256Update (&Ctx, Data, DataSize);
> > >
> > > + if (!Status) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + return CShake256Final (&Ctx, HashValue);
> > >
> > > +}
> > >
> > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > new file mode 100644
> > > index 0000000000..3eaa7c2ceb
> > > --- /dev/null
> > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > @@ -0,0 +1,275 @@
> > > +/** @file
> > >
> > > + ParallelHash Implementation.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include "InternalCryptLib.h"
> > >
> > > +#include <Library\PcdLib.h>
> > >
> > > +#include <Library\SynchronizationLib.h>
> > >
> > > +#include <Library\MmServicesTableLib.h>
> > >
> > > +
> > >
> > > +
> > >
> > > +UINT16 mBlockNum;
> > >
> > > +UINTN mBlockSize;
> > >
> > > +UINTN mLastBlockSize;
> > >
> > > +UINT8 *mInput;
> > >
> > > +UINTN mBlockResultSize;
> > >
> > > +UINT8 *mBlockHashResult;
> > >
> > > +BOOLEAN *mBlockIsCompleted;
> > >
> > > +SPIN_LOCK *mSpinLockList;
> > >
> > > +
> > >
> > > +UINTN LeftEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> > >
> > > +UINTN RightEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> > >
> > > +
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +CShake256HashAll (
> > >
> > > + IN CONST VOID *Data,
> > >
> > > + IN UINTN DataSize,
> > >
> > > + IN UINTN OutputLen,
> > >
> > > + IN CONST VOID *Name,
> > >
> > > + IN UINTN NameLen,
> > >
> > > + IN CONST VOID *Customization,
> > >
> > > + IN UINTN CustomizationLen,
> > >
> > > + OUT UINT8 *HashValue
> > >
> > > + );
> > >
> > > +
> > >
> > > +VOID
> > >
> > > +EFIAPI
> > >
> > > +ParallelHashApExecute (
> > >
> > > + IN VOID *ProcedureArgument
> > >
> > > + )
> > >
> > > +{
> > >
> > > + UINTN Index;
> > >
> > > + BOOLEAN Status;
> > >
> > > +
> > >
> > > + for (Index = 0; Index < mBlockNum; Index++) {
> > >
> > > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> > >
> > > + //
> > >
> > > + // Completed, try next one.
> > >
> > > + //
> > >
> > > + if (mBlockIsCompleted[Index])
> > >
> > > + {
> > >
> > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > >
> > > + continue;
> > >
> > > + }
> > >
> > > + //
> > >
> > > + // Calculate CShake256 for this block.
> > >
> > > + //
> > >
> > > + Status = CShake256HashAll (
> > >
> > > + mInput + Index * mBlockSize,
> > >
> > > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > > + mBlockSize,
> > >
> > > + mBlockResultSize,
> > >
> > > + NULL,
> > >
> > > + 0,
> > >
> > > + NULL,
> > >
> > > + 0,
> > >
> > > + mBlockHashResult + Index * mBlockResultSize
> > >
> > > + );
> > >
> > > + if (!EFI_ERROR (Status)){
> > >
> > > + mBlockIsCompleted[Index] = TRUE;
> > >
> > > + }
> > >
> > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > >
> > > + }
> > >
> > > + }
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > + Parallel hash function ParallelHash256, as defined in NIST's
> > > + Special Publication
> > > 800-185,
> > >
> > > + published December 2016.
> > >
> > > +
> > >
> > > + @param Input[in] Pointer to the input message (X).
> > >
> > > + @param InputByteLen[in] The number(>0) of input bytes provided for
> > the
> > > input data.
> > >
> > > + @param Output[out] Pointer to the output buffer.
> > >
> > > + @param OutputByteLen[in] The desired number of output bytes (L).
> > >
> > > + @param Customization[in] Pointer to the customization string (S).
> > >
> > > + @param CustomByteLen[in] The length of the customization string in
> > bytes.
> > >
> > > +
> > >
> > > + @retval TRUE ParallelHash256 digest computation succeeded.
> > >
> > > + @retval FALSE ParallelHash256 digest computation failed.
> > >
> > > + @retval FALSE This interface is not supported.
> > >
> > > +
> > >
> > > +*/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +ParallelHash256HashAll (
> > >
> > > + IN CONST VOID *Input,
> > >
> > > + IN UINTN InputByteLen,
> > >
> > > + OUT VOID *Output,
> > >
> > > + IN UINTN OutputByteLen,
> > >
> > > + IN CONST VOID *Customization,
> > >
> > > + IN UINTN CustomByteLen
> > >
> > > + )
> > >
> > > +
> > >
> > > +{
> > >
> > > + UINT8 EncBufB[sizeof(UINTN)+1];
> > >
> > > + UINTN EncSizeB;
> > >
> > > + UINT8 EncBufN[sizeof(UINTN)+1];
> > >
> > > + UINTN EncSizeN;
> > >
> > > + UINT8 EncBufL[sizeof(UINTN)+1];
> > >
> > > + UINTN EncSizeL;
> > >
> > > + UINTN Index;
> > >
> > > + UINT8 *CombinedInput;
> > >
> > > + UINTN CombinedInputSize;
> > >
> > > + EFI_STATUS Status;
> > >
> > > + UINTN StartedApNum;
> > >
> > > + BOOLEAN AllCompleted;
> > >
> > > + UINTN Offset;
> > >
> > > + BOOLEAN ReturnValue;
> > >
> > > +
> > >
> > > + if (InputByteLen == 0 || OutputByteLen == 0) {
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (Input == NULL || Output == NULL){
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (CustomByteLen != 0 && Customization == NULL){
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Get Block number n.
> > >
> > > + //
> > >
> > > + mBlockNum = PcdGet16 (PcdParallelHashBlockNumber);
> > >
> > > +
> > >
> > > + if (mBlockNum < 1 || InputByteLen < mBlockNum - 1){
> > >
> > > + return FALSE;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Set hash result size of each block in bytes.
> > >
> > > + //
> > >
> > > + mBlockResultSize = OutputByteLen;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // calculate the block byte length B.
> > >
> > > + //
> > >
> > > + mBlockSize = InputByteLen % mBlockNum == 0 ? InputByteLen /
> > mBlockNum :
> > > InputByteLen / (mBlockNum - 1);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Encode B, n, L to string and record size.
> > >
> > > + //
> > >
> > > + EncSizeB = LeftEncode (EncBufB, mBlockSize);
> > >
> > > + EncSizeN = RightEncode (EncBufN, mBlockNum);
> > >
> > > + EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Allocate buffer for combined input (newX), Block completed flag
> > > + and
> > > SpinLock.
> > >
> > > + //
> > >
> > > + CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum *
> > > mBlockResultSize;
> > >
> > > + CombinedInput = AllocateZeroPool (CombinedInputSize);
> > >
> > > + mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof
> > > + (BOOLEAN));
> > >
> > > + mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
> > >
> > > + if (CombinedInput == NULL || mBlockIsCompleted == NULL ||
> > > + mSpinLockList
> > > == NULL) {
> > >
> > > + ReturnValue = FALSE;
> > >
> > > + goto Exit;
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Fill LeftEncode(B).
> > >
> > > + //
> > >
> > > + CopyMem (CombinedInput, EncBufB, EncSizeB);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Prepare for parallel hash.
> > >
> > > + //
> > >
> > > + mBlockHashResult = CombinedInput + EncSizeB;
> > >
> > > + mInput = Input;
> > >
> > > + mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize :
> > > InputByteLen % mBlockSize;
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Initialize SpinLock for each result block.
> > >
> > > + //
> > >
> > > + for (Index = 0; Index < mBlockNum; Index++) {
> > >
> > > + InitializeSpinLock (&mSpinLockList[Index]);
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Dispatch blocklist to each AP.
> > >
> > > + //
> > >
> > > + StartedApNum = 0;
> > >
> > > + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
> > >
> > > + if (Index != gMmst->CurrentlyExecutingCpu) {
> > >
> > > + Status = gMmst->MmStartupThisAp (ParallelHashApExecute, Index,
> > > + NULL);
> > >
> > > + if (!EFI_ERROR (Status)) {
> > >
> > > + StartedApNum++;
> > >
> > > + }
> > >
> > > + }
> > >
> > > + }
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Wait until all block hash completed.
> > >
> > > + //
> > >
> > > + do {
> > >
> > > + AllCompleted = TRUE;
> > >
> > > + for (Index = 0; Index < mBlockNum; Index++) {
> > >
> > > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> > >
> > > + if (!mBlockIsCompleted[Index]) {
> > >
> > > + AllCompleted = FALSE;
> > >
> > > + ReturnValue = CShake256HashAll (
> > >
> > > + mInput + Index * mBlockSize,
> > >
> > > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > > + mBlockSize,
> > >
> > > + mBlockResultSize,
> > >
> > > + NULL,
> > >
> > > + 0,
> > >
> > > + NULL,
> > >
> > > + 0,
> > >
> > > + mBlockHashResult + Index * mBlockResultSize
> > >
> > > + );
> > >
> > > + if (ReturnValue){
> > >
> > > + mBlockIsCompleted[Index] = TRUE;
> > >
> > > + }
> > >
> > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > >
> > > + break;
> > >
> > > + }
> > >
> > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > >
> > > + } else {
> > >
> > > + AllCompleted = FALSE;
> > >
> > > + break;
> > >
> > > + }
> > >
> > > + }
> > >
> > > + } while (!AllCompleted);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Fill LeftEncode(n).
> > >
> > > + //
> > >
> > > + Offset = EncSizeB + mBlockNum * mBlockResultSize;
> > >
> > > + CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Fill LeftEncode(L).
> > >
> > > + //
> > >
> > > + Offset += EncSizeN;
> > >
> > > + CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
> > >
> > > +
> > >
> > > + ReturnValue = CShake256HashAll (
> > >
> > > + CombinedInput,
> > >
> > > + CombinedInputSize,
> > >
> > > + OutputByteLen,
> > >
> > > + PARALLELHASH_CUSTOMIZATION,
> > >
> > > + AsciiStrLen(PARALLELHASH_CUSTOMIZATION),
> > >
> > > + Customization,
> > >
> > > + CustomByteLen,
> > >
> > > + Output
> > >
> > > + );
> > >
> > > +
> > >
> > > +Exit:
> > >
> > > + ZeroMem (CombinedInput, CombinedInputSize);
> > >
> > > +
> > >
> > > + if (CombinedInput != NULL){
> > >
> > > + FreePool (CombinedInput);
> > >
> > > + }
> > >
> > > + if (mSpinLockList != NULL){
> > >
> > > + FreePool (mSpinLockList);
> > >
> > > + }
> > >
> > > + if (mBlockIsCompleted != NULL){
> > >
> > > + FreePool (mBlockIsCompleted);
> > >
> > > + }
> > >
> > > +
> > >
> > > + return ReturnValue;
> > >
> > > +}
> > >
> > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > new file mode 100644
> > > index 0000000000..b170c463de
> > > --- /dev/null
> > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > @@ -0,0 +1,102 @@
> > > +/** @file
> > >
> > > + SHA3 realted functions from OpenSSL.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> > >
> > > +Licensed under the OpenSSL license (the "License"). You may not use
> > >
> > > +this file except in compliance with the License. You can obtain a
> > > +copy
> > >
> > > +in the file LICENSE in the source distribution or at
> > >
> > > +https://www.openssl.org/source/license.html
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include "sha3.h"
> > >
> > > +
> > >
> > > +size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t
> > > +len,
> > >
> > > + size_t r);
> > >
> > > +void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len,
> > > +size_t r);
> > >
> > > +
> > >
> > > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > > +md_size)
> > >
> > > +{
> > >
> > > + if (bsz <= sizeof(ctx->buf)) {
> > >
> > > + memset(ctx->A, 0, sizeof(ctx->A));
> > >
> > > +
> > >
> > > + ctx->num = 0;
> > >
> > > + ctx->block_size = bsz;
> > >
> > > + ctx->md_size = md_size;
> > >
> > > + ctx->pad = pad;
> > >
> > > +
> > >
> > > + return 1;
> > >
> > > + }
> > >
> > > +
> > >
> > > + return 0;
> > >
> > > +}
> > >
> > > +
> > >
> > > +
> > >
> > > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
> > >
> > > +{
> > >
> > > + const unsigned char *inp = _inp;
> > >
> > > + size_t bsz = ctx->block_size;
> > >
> > > + size_t num, rem;
> > >
> > > +
> > >
> > > + if (len == 0)
> > >
> > > + return 1;
> > >
> > > +
> > >
> > > + if ((num = ctx->num) != 0) { /* process intermediate buffer? */
> > >
> > > + rem = bsz - num;
> > >
> > > +
> > >
> > > + if (len < rem) {
> > >
> > > + memcpy(ctx->buf + num, inp, len);
> > >
> > > + ctx->num += len;
> > >
> > > + return 1;
> > >
> > > + }
> > >
> > > + /*
> > >
> > > + * We have enough data to fill or overflow the intermediate
> > >
> > > + * buffer. So we append |rem| bytes and process the block,
> > >
> > > + * leaving the rest for later processing...
> > >
> > > + */
> > >
> > > + memcpy(ctx->buf + num, inp, rem);
> > >
> > > + inp += rem, len -= rem;
> > >
> > > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> > >
> > > + ctx->num = 0;
> > >
> > > + /* ctx->buf is processed, ctx->num is guaranteed to be zero
> > > + */
> > >
> > > + }
> > >
> > > +
> > >
> > > + if (len >= bsz)
> > >
> > > + rem = SHA3_absorb(ctx->A, inp, len, bsz);
> > >
> > > + else
> > >
> > > + rem = len;
> > >
> > > +
> > >
> > > + if (rem) {
> > >
> > > + memcpy(ctx->buf, inp + len - rem, rem);
> > >
> > > + ctx->num = rem;
> > >
> > > + }
> > >
> > > +
> > >
> > > + return 1;
> > >
> > > +}
> > >
> > > +
> > >
> > > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md)
> > >
> > > +{
> > >
> > > + size_t bsz = ctx->block_size;
> > >
> > > + size_t num = ctx->num;
> > >
> > > +
> > >
> > > + if (ctx->md_size == 0)
> > >
> > > + return 1;
> > >
> > > +
> > >
> > > + /*
> > >
> > > + * Pad the data with 10*1. Note that |num| can be |bsz - 1|
> > >
> > > + * in which case both byte operations below are performed on
> > >
> > > + * same byte...
> > >
> > > + */
> > >
> > > + memset(ctx->buf + num, 0, bsz - num);
> > >
> > > + ctx->buf[num] = ctx->pad;
> > >
> > > + ctx->buf[bsz - 1] |= 0x80;
> > >
> > > +
> > >
> > > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> > >
> > > +
> > >
> > > + SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
> > >
> > > +
> > >
> > > + return 1;
> > >
> > > +}
> > >
> > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > new file mode 100644
> > > index 0000000000..b2a40ee044
> > > --- /dev/null
> > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > @@ -0,0 +1,53 @@
> > > +/** @file
> > >
> > > + Encode realted functions from Xkcp.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +The eXtended Keccak Code Package (XKCP)
> > >
> > > +https://github.com/XKCP/XKCP
> > >
> > > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and
> > > +Gilles
> > > Van Assche.
> > >
> > > +Implementation by the designers, hereby denoted as "the implementer".
> > >
> > > +For more information, feedback or questions, please refer to the
> > > +Keccak Team
> > > website:
> > >
> > > +https://keccak.team/
> > >
> > > +To the extent possible under law, the implementer has waived all
> > > +copyright
> > >
> > > +and related or neighboring rights to the source code in this file.
> > >
> > > +http://creativecommons.org/publicdomain/zero/1.0/
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include "xkcp.h"
> > >
> > > +
> > >
> > > +unsigned int left_encode(unsigned char * encbuf, size_t value)
> > >
> > > +{
> > >
> > > + unsigned int n, i;
> > >
> > > + size_t v;
> > >
> > > +
> > >
> > > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> > >
> > > + ; /* empty */
> > >
> > > + if (n == 0)
> > >
> > > + n = 1;
> > >
> > > + for ( i = 1; i <= n; ++i )
> > >
> > > + {
> > >
> > > + encbuf[i] = (unsigned char)(value >> (8 * (n-i)));
> > >
> > > + }
> > >
> > > + encbuf[0] = (unsigned char)n;
> > >
> > > + return n + 1;
> > >
> > > +}
> > >
> > > +
> > >
> > > +unsigned int right_encode(unsigned char * encbuf, size_t value)
> > >
> > > +{
> > >
> > > + unsigned int n, i;
> > >
> > > + size_t v;
> > >
> > > +
> > >
> > > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> > >
> > > + ; /* empty */
> > >
> > > + if (n == 0)
> > >
> > > + n = 1;
> > >
> > > + for ( i = 1; i <= n; ++i )
> > >
> > > + {
> > >
> > > + encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
> > >
> > > + }
> > >
> > > + encbuf[n] = (unsigned char)n;
> > >
> > > + return n + 1;
> > >
> > > +}
> > >
> > > diff --git
> > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > new file mode 100644
> > > index 0000000000..052ab3a0d6
> > > --- /dev/null
> > > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > @@ -0,0 +1,152 @@
> > > +/** @file
> > >
> > > + Application for Parallelhash Function Validation.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include "TestBaseCryptLib.h"
> > >
> > > +
> > >
> > > +//
> > >
> > > +// Parallelhash Test Sample common parameters.
> > >
> > > +//
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN OutputByteLen =
> > 64;
> > >
> > > +
> > >
> > > +//
> > >
> > > +// Parallelhash Test Sample #1 from NIST Special Publication 800-185.
> > >
> > > +//
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample1[]
> > = {
> > >
> > > + // input data of sample1.
> > >
> > > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
> > > + 0x13, 0x14,
> > > 0x15, 0x16, 0x17,
> > >
> > > + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
> > >
> > > +};
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample1ByteLen
> > =
> > > 24; // Length of sample1 input data in bytes.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > *CustomizationSample1
> > > = ""; // Customization string (S) of sample1.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > CustomSample1ByteLen =
> > > 0; // Customization string length of sample1 in bytes.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample1 =
> > 8;
> > > // Block size of sample1.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > ExpectOutputSample1[]
> > > = {
> > >
> > > + // Expected output data of sample1.
> > >
> > > + 0xbc, 0x1e, 0xf1, 0x24, 0xda, 0x34, 0x49, 0x5e, 0x94, 0x8e, 0xad,
> > > + 0x20, 0x7d,
> > > 0xd9, 0x84, 0x22,
> > >
> > > + 0x35, 0xda, 0x43, 0x2d, 0x2b, 0xbc, 0x54, 0xb4, 0xc1, 0x10, 0xe6,
> > > + 0x4c, 0x45,
> > > 0x11, 0x05, 0x53,
> > >
> > > + 0x1b, 0x7f, 0x2a, 0x3e, 0x0c, 0xe0, 0x55, 0xc0, 0x28, 0x05, 0xe7,
> > > + 0xc2, 0xde,
> > > 0x1f, 0xb7, 0x46,
> > >
> > > + 0xaf, 0x97, 0xa1, 0xd0, 0x01, 0xf4, 0x3b, 0x82, 0x4e, 0x31, 0xb8,
> > > + 0x76, 0x12,
> > > 0x41, 0x04, 0x29
> > >
> > > +};
> > >
> > > +
> > >
> > > +//
> > >
> > > +// Parallelhash Test Sample #2 from NIST Special Publication 800-185.
> > >
> > > +//
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 *InputSample2
> > =
> > > InputSample1; // Input of sample2 is same as sample1.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample2ByteLen
> > =
> > > 24; // Length of sample2 input data in bytes.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > *CustomizationSample2
> > > = "Parallel Data"; // Customization string (S) of sample2.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > CustomSample2ByteLen =
> > > 13; // Customization string length of sample2 in bytes.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample2 =
> > 8;
> > > // Block size of sample2.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > ExpectOutputSample2[]
> > > = {
> > >
> > > + // Expected output data of sample2.
> > >
> > > + 0xcd, 0xf1, 0x52, 0x89, 0xb5, 0x4f, 0x62, 0x12, 0xb4, 0xbc, 0x27,
> > > + 0x05, 0x28,
> > > 0xb4, 0x95, 0x26,
> > >
> > > + 0x00, 0x6d, 0xd9, 0xb5, 0x4e, 0x2b, 0x6a, 0xdd, 0x1e, 0xf6, 0x90,
> > > + 0x0d, 0xda,
> > > 0x39, 0x63, 0xbb,
> > >
> > > + 0x33, 0xa7, 0x24, 0x91, 0xf2, 0x36, 0x96, 0x9c, 0xa8, 0xaf, 0xae,
> > > + 0xa2, 0x9c,
> > > 0x68, 0x2d, 0x47,
> > >
> > > + 0xa3, 0x93, 0xc0, 0x65, 0xb3, 0x8e, 0x29, 0xfa, 0xe6, 0x51, 0xa2,
> > > + 0x09, 0x1c,
> > > 0x83, 0x31, 0x10
> > >
> > > +};
> > >
> > > +
> > >
> > > +//
> > >
> > > +// Parallelhash Test Sample #3 from NIST Special Publication 800-185.
> > >
> > > +//
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample3[]
> > = {
> > >
> > > + // input data of sample3.
> > >
> > > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
> > > + 0x0b, 0x10,
> > > 0x11, 0x12, 0x13,
> > >
> > > + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22,
> > > + 0x23, 0x24,
> > > 0x25, 0x26, 0x27,
> > >
> > > + 0x28, 0x29, 0x2a, 0x2b, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
> > > + 0x37, 0x38,
> > > 0x39, 0x3a, 0x3b,
> > >
> > > + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
> > > + 0x4b, 0x50,
> > > 0x51, 0x52, 0x53,
> > >
> > > + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
> > >
> > > +};
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN InputSample3ByteLen
> > =
> > > 72; // Length of sample3 input data in bytes.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > *CustomizationSample3
> > > = "Parallel Data"; // Customization string (S) of sample3.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > CustomSample3ByteLen =
> > > 13; // Customization string length of sample3 in bytes.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample3 =
> > 12;
> > > // Block size of sample3.
> > >
> > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > ExpectOutputSample3[]
> > > = {
> > >
> > > + // Expected output data of sample3.
> > >
> > > + 0x69, 0xd0, 0xfc, 0xb7, 0x64, 0xea, 0x05, 0x5d, 0xd0, 0x93, 0x34,
> > > + 0xbc, 0x60,
> > > 0x21, 0xcb, 0x7e,
> > >
> > > + 0x4b, 0x61, 0x34, 0x8d, 0xff, 0x37, 0x5d, 0xa2, 0x62, 0x67, 0x1c,
> > > + 0xde, 0xc3,
> > > 0xef, 0xfa, 0x8d,
> > >
> > > + 0x1b, 0x45, 0x68, 0xa6, 0xcc, 0xe1, 0x6b, 0x1c, 0xad, 0x94, 0x6d,
> > > + 0xdd, 0xe2,
> > > 0x7f, 0x6c, 0xe2,
> > >
> > > + 0xb8, 0xde, 0xe4, 0xcd, 0x1b, 0x24, 0x85, 0x1e, 0xbf, 0x00, 0xeb,
> > > + 0x90, 0xd4,
> > > 0x38, 0x13, 0xe9
> > >
> > > +};
> > >
> > > +
> > >
> > > +UNIT_TEST_STATUS
> > >
> > > +EFIAPI
> > >
> > > +TestVerifyParallelHash256HashAll (
> > >
> > > + IN UNIT_TEST_CONTEXT Context
> > >
> > > + )
> > >
> > > +{
> > >
> > > + BOOLEAN Status;
> > >
> > > + UINT16 OriginalParallelHashBlockNumber;
> > >
> > > + UINT8 Output[64];
> > >
> > > +
> > >
> > > + // Restore original PcdParallelHashBlockNumber.
> > >
> > > + OriginalParallelHashBlockNumber = PcdGet16
> > > + (PcdParallelHashBlockNumber);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Test #1 using sample1.
> > >
> > > + //
> > >
> > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample1ByteLen /
> > > BlockSizeSample1);
> > >
> > > + Status = ParallelHash256HashAll (
> > >
> > > + InputSample1,
> > >
> > > + InputSample1ByteLen,
> > >
> > > + Output,
> > >
> > > + OutputByteLen,
> > >
> > > + CustomizationSample1,
> > >
> > > + CustomSample1ByteLen
> > >
> > > + );
> > >
> > > + UT_ASSERT_TRUE (Status);
> > >
> > > +
> > >
> > > + // Check the output with the expected output.
> > >
> > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample1,
> > OutputByteLen);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Test #2 using sample2.
> > >
> > > + //
> > >
> > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample2ByteLen /
> > > BlockSizeSample2);
> > >
> > > + Status = ParallelHash256HashAll (
> > >
> > > + InputSample2,
> > >
> > > + InputSample2ByteLen,
> > >
> > > + Output,
> > >
> > > + OutputByteLen,
> > >
> > > + CustomizationSample2,
> > >
> > > + CustomSample2ByteLen
> > >
> > > + );
> > >
> > > + UT_ASSERT_TRUE (Status);
> > >
> > > +
> > >
> > > + // Check the output with the expected output.
> > >
> > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample2,
> > OutputByteLen);
> > >
> > > +
> > >
> > > + //
> > >
> > > + // Test #3 using sample3.
> > >
> > > + //
> > >
> > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample3ByteLen /
> > > BlockSizeSample3);
> > >
> > > + Status = ParallelHash256HashAll (
> > >
> > > + InputSample3,
> > >
> > > + InputSample3ByteLen,
> > >
> > > + Output,
> > >
> > > + OutputByteLen,
> > >
> > > + CustomizationSample3,
> > >
> > > + CustomSample3ByteLen
> > >
> > > + );
> > >
> > > + UT_ASSERT_TRUE (Status);
> > >
> > > +
> > >
> > > + // Check the output with the expected output.
> > >
> > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample3,
> > OutputByteLen);
> > >
> > > +
> > >
> > > + // Recover original PcdParallelHashBlockNumber.
> > >
> > > + PcdSet16S (PcdParallelHashBlockNumber,
> > > + OriginalParallelHashBlockNumber);
> > >
> > > +
> > >
> > > + return EFI_SUCCESS;
> > >
> > > +}
> > >
> > > +
> > >
> > > +TEST_DESC mParallelhashTest[] = {
> > >
> > > + //
> > >
> > > + //
> > > + -----Description------------------------------Class-----------------
> > > + -----Function----
> > > -------------Pre---Post--Context
> > >
> > > + //
> > >
> > > + { "TestVerifyParallelHash256HashAll()",
> > > "CryptoPkg.BaseCryptLib.ParallelHash256HashAll",
> > > TestVerifyParallelHash256HashAll, NULL, NULL, NULL },
> > >
> > > +};
> > >
> > > +
> > >
> > > +UINTN mParallelhashTestNum = ARRAY_SIZE (mParallelhashTest);
> > >
> > > diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec index
> > > 5888941bab..3af55d9c10 100644
> > > --- a/CryptoPkg/CryptoPkg.dec
> > > +++ b/CryptoPkg/CryptoPkg.dec
> > > @@ -4,7 +4,7 @@
> > > # This Package provides cryptographic-related libraries for UEFI
> > > security modules.
> > >
> > > # It also provides a test application to test libraries.
> > >
> > > #
> > >
> > > -# Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > > reserved.<BR>
> > >
> > > +# Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > +reserved.<BR>
> > >
> > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > #
> > >
> > > ##
> > >
> > > @@ -81,5 +81,12 @@
> > > # @ValidList 0x80000001 | 0x00000001, 0x00000002, 0x00000004,
> > > 0x00000008, 0x00000010
> > >
> > >
> > >
> > gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x00000002|UINT32|0x
> > 00
> > > 000001
> > >
> > >
> > >
> > > +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic,
> > PcdsDynamicEx]
> > >
> > > + ## This PCD indicates the block number of parallel hash
> > >
> > > + # Based on the value set, parallel hash can chose the block
> > >
> > > + # number to calculate specific hash.<BR>
> > >
> > > + # The number can be set by platform team according to the core
> > number.
> > >
> > > +
> > >
> > gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber|0x0100|UINT1
> > 6|0
> > > x00000003
> > >
> > > +
> > >
> > > [UserExtensions.TianoCore."ExtraFiles"]
> > >
> > > CryptoPkgExtra.uni
> > >
> > > diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> > > b/CryptoPkg/Include/Library/BaseCryptLib.h
> > > index f4bc7c0d73..0b274b1257 100644
> > > --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> > > +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> > > @@ -4,7 +4,7 @@
> > > primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI
> > > security
> > >
> > > functionality enabling.
> > >
> > >
> > >
> > > -Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > > reserved.<BR>
> > >
> > > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > +reserved.<BR>
> > >
> > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > >
> > >
> > > **/
> > >
> > > @@ -753,6 +753,33 @@ Sha512HashAll (
> > > OUT UINT8 *HashValue
> > >
> > > );
> > >
> > >
> > >
> > > +/**
> > >
> > > + Parallel hash function ParallelHash256, as defined in NIST's
> > > + Special Publication
> > > 800-185,
> > >
> > > + published December 2016.
> > >
> > > +
> > >
> > > + @param[in] Input Pointer to the input message (X).
> > >
> > > + @param[in] InputByteLen The number(>0) of input bytes provided
> > for the
> > > input data.
> > >
> > > + @param[out] Output Pointer to the output buffer.
> > >
> > > + @param[in] OutputByteLen The desired number of output bytes (L).
> > >
> > > + @param[in] Customization Pointer to the customization string (S).
> > >
> > > + @param[in] CustomByteLen The length of the customization string in
> > bytes.
> > >
> > > +
> > >
> > > + @retval TRUE ParallelHash256 digest computation succeeded.
> > >
> > > + @retval FALSE ParallelHash256 digest computation failed.
> > >
> > > + @retval FALSE This interface is not supported.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +BOOLEAN
> > >
> > > +EFIAPI
> > >
> > > +ParallelHash256HashAll (
> > >
> > > + IN CONST VOID *Input,
> > >
> > > + IN UINTN InputByteLen,
> > >
> > > + OUT VOID *Output,
> > >
> > > + IN UINTN OutputByteLen,
> > >
> > > + IN CONST VOID *Customization,
> > >
> > > + IN UINTN CustomByteLen
> > >
> > > + );
> > >
> > > +
> > >
> > > /**
> > >
> > > Retrieves the size, in bytes, of the context buffer required for
> > > SM3 hash operations.
> > >
> > >
> > >
> > > diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > index e6470d7a21..70159163d4 100644
> > > --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > @@ -10,7 +10,7 @@
> > > # RSA external functions, PKCS#7 SignedData sign functions,
> > > Diffie-Hellman functions, and
> > >
> > > # authenticode signature verification functions are not supported in
> > > this instance.
> > >
> > > #
> > >
> > > -# Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > > reserved.<BR>
> > >
> > > +# Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > > +reserved.<BR>
> > >
> > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > #
> > >
> > > ##
> > >
> > > @@ -38,6 +38,10 @@
> > > Hash/CryptSha256.c
> > >
> > > Hash/CryptSm3.c
> > >
> > > Hash/CryptSha512.c
> > >
> > > + Hash/CryptSha3.c
> > >
> > > + Hash/CryptXkcp.c
> > >
> > > + Hash/CryptCShake256.c
> > >
> > > + Hash/CryptParallelHash.c
> > >
> > > Hmac/CryptHmacSha256.c
> > >
> > > Kdf/CryptHkdfNull.c
> > >
> > > Cipher/CryptAes.c
> > >
> > > @@ -85,6 +89,9 @@
> > > OpensslLib
> > >
> > > IntrinsicLib
> > >
> > > PrintLib
> > >
> > > + MmServicesTableLib
> > >
> > > + SynchronizationLib
> > >
> > > + PcdLib
> > >
> > >
> > >
> > > #
> > >
> > > # Remove these [BuildOptions] after this library is cleaned up
> > >
> > > @@ -101,3 +108,6 @@
> > > GCC:*_CLANG35_*_CC_FLAGS = -std=c99
> > >
> > > GCC:*_CLANG38_*_CC_FLAGS = -std=c99
> > >
> > > GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99
> > > -Wno-error=incompatible-pointer- types
> > >
> > > +
> > >
> > > +[Pcd]
> > >
> > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > >
> > > diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h
> > > b/CryptoPkg/Library/Include/CrtLibSupport.h
> > > index d257dca8fa..35d9c62a0b 100644
> > > --- a/CryptoPkg/Library/Include/CrtLibSupport.h
> > > +++ b/CryptoPkg/Library/Include/CrtLibSupport.h
> > > @@ -2,7 +2,7 @@
> > > Root include file of C runtime library to support building the
> > > third-party
> > >
> > > cryptographic library.
> > >
> > >
> > >
> > > -Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > > reserved.<BR>
> > >
> > > +Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > > +reserved.<BR>
> > >
> > > Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All
> > > rights reserved.<BR>
> > >
> > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > >
> > >
> > > @@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > >
> > > #define MAX_STRING_SIZE 0x1000
> > >
> > >
> > >
> > > +#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
> > >
> > > +
> > >
> > > //
> > >
> > > // We already have "no-ui" in out Configure invocation.
> > >
> > > // but the code still fails to compile.
> > >
> > > @@ -111,6 +113,7 @@ typedef UINT8 u_char;
> > > typedef UINT32 uid_t;
> > >
> > > typedef UINT32 gid_t;
> > >
> > > typedef CHAR16 wchar_t;
> > >
> > > +typedef UINT64 uint64_t;
> > >
> > >
> > >
> > > //
> > >
> > > // File operations are not required for EFI building,
> > >
> > > diff --git a/CryptoPkg/Library/Include/sha3.h
> > > b/CryptoPkg/Library/Include/sha3.h
> > > new file mode 100644
> > > index 0000000000..71b4c75548
> > > --- /dev/null
> > > +++ b/CryptoPkg/Library/Include/sha3.h
> > > @@ -0,0 +1,32 @@
> > > +/** @file
> > >
> > > + SHA3 realted functions from OpenSSL.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> > >
> > > +Licensed under the OpenSSL license (the "License"). You may not use
> > >
> > > +this file except in compliance with the License. You can obtain a
> > > +copy
> > >
> > > +in the file LICENSE in the source distribution or at
> > >
> > > +https://www.openssl.org/source/license.html
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include <CrtLibSupport.h>
> > >
> > > +
> > >
> > > +#define KECCAK1600_WIDTH 1600
> > >
> > > +
> > >
> > > +typedef struct {
> > >
> > > + uint64_t A[5][5];
> > >
> > > + size_t block_size; /* cached ctx->digest->block_size */
> > >
> > > + size_t md_size; /* output length, variable in XOF */
> > >
> > > + size_t num; /* used bytes in below buffer */
> > >
> > > + unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
> > >
> > > + unsigned char pad;
> > >
> > > +} KECCAK1600_CTX;
> > >
> > > +
> > >
> > > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > > +md_size);
> > >
> > > +
> > >
> > > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
> > >
> > > +
> > >
> > > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md);
> > >
> > > diff --git a/CryptoPkg/Library/Include/xkcp.h
> > > b/CryptoPkg/Library/Include/xkcp.h
> > > new file mode 100644
> > > index 0000000000..b328d672e4
> > > --- /dev/null
> > > +++ b/CryptoPkg/Library/Include/xkcp.h
> > > @@ -0,0 +1,23 @@
> > > +/** @file
> > >
> > > + Encode realted functions from Xkcp.
> > >
> > > +
> > >
> > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > +
> > >
> > > +The eXtended Keccak Code Package (XKCP)
> > >
> > > +https://github.com/XKCP/XKCP
> > >
> > > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and
> > > +Gilles
> > > Van Assche.
> > >
> > > +Implementation by the designers, hereby denoted as "the implementer".
> > >
> > > +For more information, feedback or questions, please refer to the
> > > +Keccak Team
> > > website:
> > >
> > > +https://keccak.team/
> > >
> > > +To the extent possible under law, the implementer has waived all
> > > +copyright
> > >
> > > +and related or neighboring rights to the source code in this file.
> > >
> > > +http://creativecommons.org/publicdomain/zero/1.0/
> > >
> > > +
> > >
> > > +**/
> > >
> > > +
> > >
> > > +#include <CrtLibSupport.h>
> > >
> > > +
> > >
> > > +unsigned int left_encode(unsigned char * encbuf, size_t value);
> > >
> > > +
> > >
> > > +unsigned int right_encode(unsigned char * encbuf, size_t value);
> > >
> > > diff --git
> > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > index a6b3482742..0bffd687c2 100644
> > > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > @@ -1,7 +1,7 @@
> > > /** @file
> > >
> > > Application for Cryptographic Primitives Validation.
> > >
> > >
> > >
> > > -Copyright (c) 2009 - 2016, Intel Corporation. All rights
> > > reserved.<BR>
> > >
> > > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > +reserved.<BR>
> > >
> > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > >
> > >
> > > **/
> > >
> > > @@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > #include <Library/BaseLib.h>
> > >
> > > #include <Library/BaseMemoryLib.h>
> > >
> > > #include <Library/MemoryAllocationLib.h>
> > >
> > > +#include <Library/PcdLib.h>
> > >
> > > // #include <UnitTestTypes.h>
> > >
> > > #include <Library/UnitTestLib.h>
> > >
> > > // #include <Library/UnitTestAssertLib.h>
> > >
> > > diff --git
> > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > f
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > f
> > > index 00c8692650..61a59d6a47 100644
> > > ---
> > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > f
> > > +++
> > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHos
> > > +++ t.inf
> > > @@ -2,6 +2,7 @@
> > > # Host-based UnitTest for BaseCryptLib
> > >
> > > #
> > >
> > > # Copyright (c) Microsoft Corporation.<BR>
> > >
> > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > ##
> > >
> > >
> > >
> > > @@ -35,6 +36,7 @@
> > > Pkcs7EkuTests.c
> > >
> > > OaepEncryptTests.c
> > >
> > > RsaPssTests.c
> > >
> > > + ParallelhashTests.c
> > >
> > >
> > >
> > > [Packages]
> > >
> > > MdePkg/MdePkg.dec
> > >
> > > @@ -45,3 +47,8 @@
> > > DebugLib
> > >
> > > BaseCryptLib
> > >
> > > UnitTestLib
> > >
> > > + PcdLib
> > >
> > > +
> > >
> > > +[Pcd]
> > >
> > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > >
> > > +
> > >
> > > diff --git
> > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > nf
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > nf
> > > index ca789aa6ad..682f25a754 100644
> > > ---
> > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > nf
> > > +++
> > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShe
> > > +++ ll.inf
> > > @@ -2,6 +2,7 @@
> > > # BaseCryptLib UnitTest built for execution in UEFI Shell.
> > >
> > > #
> > >
> > > # Copyright (c) Microsoft Corporation.<BR>
> > >
> > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > >
> > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > >
> > > ##
> > >
> > >
> > >
> > > @@ -36,6 +37,7 @@
> > > Pkcs7EkuTests.c
> > >
> > > OaepEncryptTests.c
> > >
> > > RsaPssTests.c
> > >
> > > + ParallelhashTests.c
> > >
> > >
> > >
> > > [Packages]
> > >
> > > MdePkg/MdePkg.dec
> > >
> > > @@ -48,3 +50,7 @@
> > > UnitTestLib
> > >
> > > PrintLib
> > >
> > > BaseCryptLib
> > >
> > > + PcdLib
> > >
> > > +
> > >
> > > +[Pcd]
> > >
> > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > >
> > > --
> > > 2.26.2.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
2022-02-16 7:51 ` Yao, Jiewen
@ 2022-02-16 8:23 ` Li, Zhihao
2022-02-17 5:28 ` Li, Zhihao
1 sibling, 0 replies; 6+ messages in thread
From: Li, Zhihao @ 2022-02-16 8:23 UTC (permalink / raw)
To: Yao, Jiewen, devel@edk2.groups.io
Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin, Fu, Siyuan
In CT 46 review result, it require that the code in openssl_sha3 and in xkcp need to be made proper attribution.
We separated their implementation into CryptSha3.c and CryptXkcp.c, separated their header files into sha3.h and xkcp.h.
Now we plan to delete these header files and put the declaration and structure define into CryptCshake256.c if head file not within the scope of CT46 suggestion.
> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Wednesday, February 16, 2022 3:52 PM
> To: Li, Zhihao <zhihao.li@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Fu,
> Siyuan <siyuan.fu@intel.com>
> Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> ParallelHash256HashAll in BaseCryptLib.
>
> But I don’t understand why we need sha3.h and xkcp.h at all.
>
>
> > -----Original Message-----
> > From: Li, Zhihao <zhihao.li@intel.com>
> > Sent: Wednesday, February 16, 2022 3:43 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>;
> > Jiang, Guomin <guomin.jiang@intel.com>; Fu, Siyuan
> <siyuan.fu@intel.com>
> > Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> > ParallelHash256HashAll in BaseCryptLib.
> >
> > With your comment, we plan do some modification for parallelhash.
> > 1. Plan to add a parameter (BlockSize) on ParallelHash256HashAll function
> to
> > replace PcdParallelHashBlockNumber.
> > 2. Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash
> > folder.
> >
> >
> > > -----Original Message-----
> > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > Sent: Tuesday, February 15, 2022 2:09 PM
> > > To: Li, Zhihao <zhihao.li@intel.com>; devel@edk2.groups.io
> > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> > > <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Fu,
> > > Siyuan <siyuan.fu@intel.com>
> > > Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> > > ParallelHash256HashAll in BaseCryptLib.
> > >
> > > Thanks for the update.
> > >
> > > Feedback below:
> > >
> > > 1) How block size is determined for below API?
> > >
> > > BOOLEAN
> > > EFIAPI
> > > ParallelHash256HashAll (
> > > IN CONST VOID *Input,
> > > IN UINTN InputByteLen,
> > > OUT VOID *Output,
> > > IN UINTN OutputByteLen,
> > > IN CONST VOID *Customization,
> > > IN UINTN CustomByteLen
> > > );
> > >
> > > Is that determined by PcdParallelHashBlockNumber ?
> > >
> > > I don’t think it is good idea to let a crypto library determine a platform
> PCD.
> > > For example, how do you support binary crypto module ?
> > Plan to add a parameter (BlockSize) to replace
> PcdParallelHashBlockNumber.
> > >
> > > 2) Why we need "sha3.h" and "xkcp.h" ?
> > > These are openssl specific structure. It shall not be put to EDKII file
> header.
> > >
> > > CryptoPkg\Library\Include shall only contain generic dependency header.
> > Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash
> folder.
> > >
> > >
> > >
> > >
> > > Thank you
> > > Yao, Jiewen
> > >
> > > > -----Original Message-----
> > > > From: Li, Zhihao <zhihao.li@intel.com>
> > > > Sent: Friday, February 11, 2022 5:05 PM
> > > > To: devel@edk2.groups.io
> > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > > <jian.j.wang@intel.com>; Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang,
> > > > Guomin <guomin.jiang@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> > > > Subject: [PATCH v1] CryptoPkg: Add new hash algorithm
> > > > ParallelHash256HashAll in BaseCryptLib.
> > > >
> > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3596
> > > >
> > > > Parallel hash function ParallelHash256HashAll, as defined in NIST's
> > > > Special Publication 800-185, published December 2016. It utilizes
> > > > multi-process to calculate the digest.
> > > >
> > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > > Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> > > > Cc: Guomin Jiang <guomin.jiang@intel.com>
> > > > Cc: Siyuan Fu <siyuan.fu@intel.com>
> > > >
> > > > Signed-off-by: Zhihao Li <zhihao.li@intel.com>
> > > > ---
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c | 313
> > > > ++++++++++++++++++++
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c | 275
> > > > +++++++++++++++++
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c | 102
> > > +++++++
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c | 53
> ++++
> > > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c |
> > > 152
> > > > ++++++++++
> > > > CryptoPkg/CryptoPkg.dec | 9 +-
> > > > CryptoPkg/Include/Library/BaseCryptLib.h | 29 +-
> > > > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 12 +-
> > > > CryptoPkg/Library/Include/CrtLibSupport.h | 5 +-
> > > > CryptoPkg/Library/Include/sha3.h | 32 ++
> > > > CryptoPkg/Library/Include/xkcp.h | 23 ++
> > > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> | 3
> > > +-
> > > >
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> > > | 7 +
> > > >
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf |
> > > 6 +
> > > > 14 files changed, 1016 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > > new file mode 100644
> > > > index 0000000000..5efced3f46
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > > @@ -0,0 +1,313 @@
> > > > +/** @file
> > > >
> > > > + cSHAKE-256 Digest Wrapper Implementations.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "InternalCryptLib.h"
> > > >
> > > > +#include "sha3.h"
> > > >
> > > > +#include "xkcp.h"
> > > >
> > > > +
> > > >
> > > > +#define CSHAKE256_SECURITY_STRENGTH 256
> > > >
> > > > +#define CSHAKE256_RATE_IN_BYTES 136
> > > >
> > > > +
> > > >
> > > > +const CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = {0};
> > > >
> > > > +
> > > >
> > > > +UINTN
> > > >
> > > > +EFIAPI
> > > >
> > > > +LeftEncode (
> > > >
> > > > + OUT UINT8 *Encbuf,
> > > >
> > > > + IN UINTN Value
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + return left_encode (Encbuf, Value);
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +UINTN
> > > >
> > > > +EFIAPI
> > > >
> > > > +RightEncode (
> > > >
> > > > + OUT UINT8 *Encbuf,
> > > >
> > > > + IN UINTN Value
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + return right_encode (Encbuf, Value);
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Retrieves the size, in bytes, of the context buffer required for
> > > > + cSHAKE-256
> > > > hash operations.
> > > >
> > > > +
> > > >
> > > > + @return The size, in bytes, of the context buffer required for
> > > > + cSHAKE-256
> > > > hash operations.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +UINTN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256GetContextSize (
> > > >
> > > > + VOID
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + return (UINTN) (sizeof (KECCAK1600_CTX));
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Initializes user-supplied memory pointed by CShake256Context as
> > > > + cSHAKE-256
> > > > hash context for
> > > >
> > > > + subsequent use.
> > > >
> > > > +
> > > >
> > > > + @param[out] CShake256Context Pointer to cSHAKE-256 context
> being
> > > > initialized.
> > > >
> > > > + @param[in] OutputLen The desired number of output length in
> > > bytes.
> > > >
> > > > + @param[in] Name Pointer to the function name string.
> > > >
> > > > + @param[in] NameLen The length of the function name in bytes.
> > > >
> > > > + @param[in] Customization Pointer to the customization string.
> > > >
> > > > + @param[in] CustomizationLen The length of the customization
> string in
> > > > bytes.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE cSHAKE-256 context initialization succeeded.
> > > >
> > > > + @retval FALSE cSHAKE-256 context initialization failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256Init (
> > > >
> > > > + OUT VOID *CShake256Context,
> > > >
> > > > + IN UINTN OutputLen,
> > > >
> > > > + IN CONST VOID *Name,
> > > >
> > > > + IN UINTN NameLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomizationLen
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > + unsigned char EncBuf[sizeof(size_t)+1];
> > > >
> > > > + UINTN EncLen;
> > > >
> > > > + UINTN AbsorbLen;
> > > >
> > > > + UINTN PadLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (CShake256Context == NULL ||
> > > >
> > > > + OutputLen == 0 ||
> > > >
> > > > + (NameLen != 0 && Name == NULL) ||
> > > >
> > > > + (CustomizationLen != 0 && Customization == NULL)) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Initialize KECCAK context with pad value and block size.
> > > >
> > > > + //
> > > >
> > > > + if (NameLen == 0 && CustomizationLen == 0) {
> > > >
> > > > + //
> > > >
> > > > + // When N and S are both empty strings, cSHAKE(X, L, N, S) is
> > > > + equivalent to
> > > >
> > > > + // SHAKE as defined in FIPS 202.
> > > >
> > > > + //
> > > >
> > > > + return (BOOLEAN) init (
> > > >
> > > > + (KECCAK1600_CTX *) CShake256Context,
> > > >
> > > > + '\x1f',
> > > >
> > > > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > > > + * 2) / 8,
> > > >
> > > > + OutputLen
> > > >
> > > > + );
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + Status = (BOOLEAN) init (
> > > >
> > > > + (KECCAK1600_CTX *) CShake256Context,
> > > >
> > > > + '\x04',
> > > >
> > > > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > > > + * 2) / 8,
> > > >
> > > > + OutputLen
> > > >
> > > > + );
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + AbsorbLen = 0;
> > > >
> > > > + //
> > > >
> > > > + // Absorb Absorb bytepad(.., rate).
> > > >
> > > > + //
> > > >
> > > > + EncLen = left_encode (EncBuf, CSHAKE256_RATE_IN_BYTES);
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > EncBuf, EncLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += EncLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Absorb encode_string(N).
> > > >
> > > > + //
> > > >
> > > > + EncLen = left_encode (EncBuf, NameLen * 8);
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > EncBuf, EncLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += EncLen;
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > Name, NameLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += NameLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Absorb encode_string(S).
> > > >
> > > > + //
> > > >
> > > > + EncLen = left_encode (EncBuf, CustomizationLen * 8);
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > EncBuf, EncLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += EncLen;
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > Customization, CustomizationLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += CustomizationLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Absorb zero padding up to rate.
> > > >
> > > > + //
> > > >
> > > > + PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen %
> > > > CSHAKE256_RATE_IN_BYTES;
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > mZeroPadding, PadLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return TRUE;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Digests the input data and updates cSHAKE-256 context.
> > > >
> > > > +
> > > >
> > > > + This function performs cSHAKE-256 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.
> > > >
> > > > + cSHAKE-256 context should be already correctly initialized by
> > > > + CShake256Init(),
> > > > and should not be finalized
> > > >
> > > > + by CShake256Final(). Behavior with invalid context is undefined.
> > > >
> > > > +
> > > >
> > > > + @param[in, out] CShake256Context Pointer to the cSHAKE-256
> 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 cSHAKE-256 data digest succeeded.
> > > >
> > > > + @retval FALSE cSHAKE-256 data digest failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256Update (
> > > >
> > > > + IN OUT VOID *CShake256Context,
> > > >
> > > > + IN CONST VOID *Data,
> > > >
> > > > + IN UINTN DataSize
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (CShake256Context == NULL) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Check invalid parameters, in case that only DataLength was
> > > > + checked in
> > > > OpenSSL.
> > > >
> > > > + //
> > > >
> > > > + if (Data == NULL && DataSize != 0) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return (BOOLEAN)(sha3_update ((KECCAK1600_CTX *)
> > > CShake256Context,
> > > > Data, DataSize));
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Completes computation of the cSHAKE-256 digest value.
> > > >
> > > > +
> > > >
> > > > + This function completes cSHAKE-256 hash computation and retrieves
> > > > + the
> > > > digest value into
> > > >
> > > > + the specified memory. After this function has been called, the
> > > > + cSHAKE-256
> > > > context cannot
> > > >
> > > > + be used again.
> > > >
> > > > + cSHAKE-256 context should be already correctly initialized by
> > > > + CShake256Init(),
> > > > and should not be
> > > >
> > > > + finalized by CShake256Final(). Behavior with invalid cSHAKE-256
> > > > + context is
> > > > undefined.
> > > >
> > > > +
> > > >
> > > > + @param[in, out] CShake256Context Pointer to the cSHAKE-256
> context.
> > > >
> > > > + @param[out] HashValue Pointer to a buffer that receives the
> > > cSHAKE-
> > > > 256 digest
> > > >
> > > > + value.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE cSHAKE-256 digest computation succeeded.
> > > >
> > > > + @retval FALSE cSHAKE-256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256Final (
> > > >
> > > > + IN OUT VOID *CShake256Context,
> > > >
> > > > + OUT UINT8 *HashValue
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (CShake256Context == NULL || HashValue == NULL) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // cSHAKE-256 Hash Finalization.
> > > >
> > > > + //
> > > >
> > > > + return (BOOLEAN) (sha3_final ((KECCAK1600_CTX *)
> CShake256Context,
> > > > HashValue));
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Computes the CSHAKE-256 message digest of a input data buffer.
> > > >
> > > > +
> > > >
> > > > + This function performs the CSHAKE-256 message digest of a given
> > > > + data buffer,
> > > > and places
> > > >
> > > > + the digest value into the specified memory.
> > > >
> > > > +
> > > >
> > > > + @param[in] Data Pointer to the buffer containing the data to
> be
> > > > hashed.
> > > >
> > > > + @param[in] DataSize Size of Data buffer in bytes.
> > > >
> > > > + @param[in] OutputLen Size of output in bytes.
> > > >
> > > > + @param[in] Name Pointer to the function name string.
> > > >
> > > > + @param[in] NameLen Size of the function name in bytes.
> > > >
> > > > + @param[in] Customization Pointer to the customization string.
> > > >
> > > > + @param[in] CustomizationLen Size of the customization string in
> bytes.
> > > >
> > > > + @param[out] HashValue Pointer to a buffer that receives the
> > > CSHAKE-
> > > > 256 digest
> > > >
> > > > + value.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE CSHAKE-256 digest computation succeeded.
> > > >
> > > > + @retval FALSE CSHAKE-256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256HashAll (
> > > >
> > > > + IN CONST VOID *Data,
> > > >
> > > > + IN UINTN DataSize,
> > > >
> > > > + IN UINTN OutputLen,
> > > >
> > > > + IN CONST VOID *Name,
> > > >
> > > > + IN UINTN NameLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomizationLen,
> > > >
> > > > + OUT UINT8 *HashValue
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > + KECCAK1600_CTX Ctx;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (HashValue == NULL) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + if (Data == NULL && DataSize != 0) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + Status = CShake256Init (&Ctx, OutputLen, Name, NameLen,
> > > > + Customization,
> > > > CustomizationLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + Status = CShake256Update (&Ctx, Data, DataSize);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return CShake256Final (&Ctx, HashValue);
> > > >
> > > > +}
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > > new file mode 100644
> > > > index 0000000000..3eaa7c2ceb
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > > @@ -0,0 +1,275 @@
> > > > +/** @file
> > > >
> > > > + ParallelHash Implementation.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "InternalCryptLib.h"
> > > >
> > > > +#include <Library\PcdLib.h>
> > > >
> > > > +#include <Library\SynchronizationLib.h>
> > > >
> > > > +#include <Library\MmServicesTableLib.h>
> > > >
> > > > +
> > > >
> > > > +
> > > >
> > > > +UINT16 mBlockNum;
> > > >
> > > > +UINTN mBlockSize;
> > > >
> > > > +UINTN mLastBlockSize;
> > > >
> > > > +UINT8 *mInput;
> > > >
> > > > +UINTN mBlockResultSize;
> > > >
> > > > +UINT8 *mBlockHashResult;
> > > >
> > > > +BOOLEAN *mBlockIsCompleted;
> > > >
> > > > +SPIN_LOCK *mSpinLockList;
> > > >
> > > > +
> > > >
> > > > +UINTN LeftEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> > > >
> > > > +UINTN RightEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> > > >
> > > > +
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256HashAll (
> > > >
> > > > + IN CONST VOID *Data,
> > > >
> > > > + IN UINTN DataSize,
> > > >
> > > > + IN UINTN OutputLen,
> > > >
> > > > + IN CONST VOID *Name,
> > > >
> > > > + IN UINTN NameLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomizationLen,
> > > >
> > > > + OUT UINT8 *HashValue
> > > >
> > > > + );
> > > >
> > > > +
> > > >
> > > > +VOID
> > > >
> > > > +EFIAPI
> > > >
> > > > +ParallelHashApExecute (
> > > >
> > > > + IN VOID *ProcedureArgument
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + UINTN Index;
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > +
> > > >
> > > > + for (Index = 0; Index < mBlockNum; Index++) {
> > > >
> > > > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> > > >
> > > > + //
> > > >
> > > > + // Completed, try next one.
> > > >
> > > > + //
> > > >
> > > > + if (mBlockIsCompleted[Index])
> > > >
> > > > + {
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + continue;
> > > >
> > > > + }
> > > >
> > > > + //
> > > >
> > > > + // Calculate CShake256 for this block.
> > > >
> > > > + //
> > > >
> > > > + Status = CShake256HashAll (
> > > >
> > > > + mInput + Index * mBlockSize,
> > > >
> > > > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > > > + mBlockSize,
> > > >
> > > > + mBlockResultSize,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + mBlockHashResult + Index * mBlockResultSize
> > > >
> > > > + );
> > > >
> > > > + if (!EFI_ERROR (Status)){
> > > >
> > > > + mBlockIsCompleted[Index] = TRUE;
> > > >
> > > > + }
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Parallel hash function ParallelHash256, as defined in NIST's
> > > > + Special Publication
> > > > 800-185,
> > > >
> > > > + published December 2016.
> > > >
> > > > +
> > > >
> > > > + @param Input[in] Pointer to the input message (X).
> > > >
> > > > + @param InputByteLen[in] The number(>0) of input bytes provided
> for
> > > the
> > > > input data.
> > > >
> > > > + @param Output[out] Pointer to the output buffer.
> > > >
> > > > + @param OutputByteLen[in] The desired number of output bytes
> (L).
> > > >
> > > > + @param Customization[in] Pointer to the customization string (S).
> > > >
> > > > + @param CustomByteLen[in] The length of the customization string
> in
> > > bytes.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE ParallelHash256 digest computation succeeded.
> > > >
> > > > + @retval FALSE ParallelHash256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +*/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +ParallelHash256HashAll (
> > > >
> > > > + IN CONST VOID *Input,
> > > >
> > > > + IN UINTN InputByteLen,
> > > >
> > > > + OUT VOID *Output,
> > > >
> > > > + IN UINTN OutputByteLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomByteLen
> > > >
> > > > + )
> > > >
> > > > +
> > > >
> > > > +{
> > > >
> > > > + UINT8 EncBufB[sizeof(UINTN)+1];
> > > >
> > > > + UINTN EncSizeB;
> > > >
> > > > + UINT8 EncBufN[sizeof(UINTN)+1];
> > > >
> > > > + UINTN EncSizeN;
> > > >
> > > > + UINT8 EncBufL[sizeof(UINTN)+1];
> > > >
> > > > + UINTN EncSizeL;
> > > >
> > > > + UINTN Index;
> > > >
> > > > + UINT8 *CombinedInput;
> > > >
> > > > + UINTN CombinedInputSize;
> > > >
> > > > + EFI_STATUS Status;
> > > >
> > > > + UINTN StartedApNum;
> > > >
> > > > + BOOLEAN AllCompleted;
> > > >
> > > > + UINTN Offset;
> > > >
> > > > + BOOLEAN ReturnValue;
> > > >
> > > > +
> > > >
> > > > + if (InputByteLen == 0 || OutputByteLen == 0) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + if (Input == NULL || Output == NULL){
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + if (CustomByteLen != 0 && Customization == NULL){
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Get Block number n.
> > > >
> > > > + //
> > > >
> > > > + mBlockNum = PcdGet16 (PcdParallelHashBlockNumber);
> > > >
> > > > +
> > > >
> > > > + if (mBlockNum < 1 || InputByteLen < mBlockNum - 1){
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Set hash result size of each block in bytes.
> > > >
> > > > + //
> > > >
> > > > + mBlockResultSize = OutputByteLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // calculate the block byte length B.
> > > >
> > > > + //
> > > >
> > > > + mBlockSize = InputByteLen % mBlockNum == 0 ? InputByteLen /
> > > mBlockNum :
> > > > InputByteLen / (mBlockNum - 1);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Encode B, n, L to string and record size.
> > > >
> > > > + //
> > > >
> > > > + EncSizeB = LeftEncode (EncBufB, mBlockSize);
> > > >
> > > > + EncSizeN = RightEncode (EncBufN, mBlockNum);
> > > >
> > > > + EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Allocate buffer for combined input (newX), Block completed flag
> > > > + and
> > > > SpinLock.
> > > >
> > > > + //
> > > >
> > > > + CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum *
> > > > mBlockResultSize;
> > > >
> > > > + CombinedInput = AllocateZeroPool (CombinedInputSize);
> > > >
> > > > + mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof
> > > > + (BOOLEAN));
> > > >
> > > > + mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
> > > >
> > > > + if (CombinedInput == NULL || mBlockIsCompleted == NULL ||
> > > > + mSpinLockList
> > > > == NULL) {
> > > >
> > > > + ReturnValue = FALSE;
> > > >
> > > > + goto Exit;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Fill LeftEncode(B).
> > > >
> > > > + //
> > > >
> > > > + CopyMem (CombinedInput, EncBufB, EncSizeB);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Prepare for parallel hash.
> > > >
> > > > + //
> > > >
> > > > + mBlockHashResult = CombinedInput + EncSizeB;
> > > >
> > > > + mInput = Input;
> > > >
> > > > + mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize :
> > > > InputByteLen % mBlockSize;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Initialize SpinLock for each result block.
> > > >
> > > > + //
> > > >
> > > > + for (Index = 0; Index < mBlockNum; Index++) {
> > > >
> > > > + InitializeSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Dispatch blocklist to each AP.
> > > >
> > > > + //
> > > >
> > > > + StartedApNum = 0;
> > > >
> > > > + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
> > > >
> > > > + if (Index != gMmst->CurrentlyExecutingCpu) {
> > > >
> > > > + Status = gMmst->MmStartupThisAp (ParallelHashApExecute, Index,
> > > > + NULL);
> > > >
> > > > + if (!EFI_ERROR (Status)) {
> > > >
> > > > + StartedApNum++;
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Wait until all block hash completed.
> > > >
> > > > + //
> > > >
> > > > + do {
> > > >
> > > > + AllCompleted = TRUE;
> > > >
> > > > + for (Index = 0; Index < mBlockNum; Index++) {
> > > >
> > > > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> > > >
> > > > + if (!mBlockIsCompleted[Index]) {
> > > >
> > > > + AllCompleted = FALSE;
> > > >
> > > > + ReturnValue = CShake256HashAll (
> > > >
> > > > + mInput + Index * mBlockSize,
> > > >
> > > > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > > > + mBlockSize,
> > > >
> > > > + mBlockResultSize,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + mBlockHashResult + Index * mBlockResultSize
> > > >
> > > > + );
> > > >
> > > > + if (ReturnValue){
> > > >
> > > > + mBlockIsCompleted[Index] = TRUE;
> > > >
> > > > + }
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + break;
> > > >
> > > > + }
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + } else {
> > > >
> > > > + AllCompleted = FALSE;
> > > >
> > > > + break;
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > + } while (!AllCompleted);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Fill LeftEncode(n).
> > > >
> > > > + //
> > > >
> > > > + Offset = EncSizeB + mBlockNum * mBlockResultSize;
> > > >
> > > > + CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Fill LeftEncode(L).
> > > >
> > > > + //
> > > >
> > > > + Offset += EncSizeN;
> > > >
> > > > + CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
> > > >
> > > > +
> > > >
> > > > + ReturnValue = CShake256HashAll (
> > > >
> > > > + CombinedInput,
> > > >
> > > > + CombinedInputSize,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + PARALLELHASH_CUSTOMIZATION,
> > > >
> > > > + AsciiStrLen(PARALLELHASH_CUSTOMIZATION),
> > > >
> > > > + Customization,
> > > >
> > > > + CustomByteLen,
> > > >
> > > > + Output
> > > >
> > > > + );
> > > >
> > > > +
> > > >
> > > > +Exit:
> > > >
> > > > + ZeroMem (CombinedInput, CombinedInputSize);
> > > >
> > > > +
> > > >
> > > > + if (CombinedInput != NULL){
> > > >
> > > > + FreePool (CombinedInput);
> > > >
> > > > + }
> > > >
> > > > + if (mSpinLockList != NULL){
> > > >
> > > > + FreePool (mSpinLockList);
> > > >
> > > > + }
> > > >
> > > > + if (mBlockIsCompleted != NULL){
> > > >
> > > > + FreePool (mBlockIsCompleted);
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return ReturnValue;
> > > >
> > > > +}
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > > new file mode 100644
> > > > index 0000000000..b170c463de
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > > @@ -0,0 +1,102 @@
> > > > +/** @file
> > > >
> > > > + SHA3 realted functions from OpenSSL.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> > > >
> > > > +Licensed under the OpenSSL license (the "License"). You may not use
> > > >
> > > > +this file except in compliance with the License. You can obtain a
> > > > +copy
> > > >
> > > > +in the file LICENSE in the source distribution or at
> > > >
> > > > +https://www.openssl.org/source/license.html
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "sha3.h"
> > > >
> > > > +
> > > >
> > > > +size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t
> > > > +len,
> > > >
> > > > + size_t r);
> > > >
> > > > +void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len,
> > > > +size_t r);
> > > >
> > > > +
> > > >
> > > > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > > > +md_size)
> > > >
> > > > +{
> > > >
> > > > + if (bsz <= sizeof(ctx->buf)) {
> > > >
> > > > + memset(ctx->A, 0, sizeof(ctx->A));
> > > >
> > > > +
> > > >
> > > > + ctx->num = 0;
> > > >
> > > > + ctx->block_size = bsz;
> > > >
> > > > + ctx->md_size = md_size;
> > > >
> > > > + ctx->pad = pad;
> > > >
> > > > +
> > > >
> > > > + return 1;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return 0;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +
> > > >
> > > > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
> > > >
> > > > +{
> > > >
> > > > + const unsigned char *inp = _inp;
> > > >
> > > > + size_t bsz = ctx->block_size;
> > > >
> > > > + size_t num, rem;
> > > >
> > > > +
> > > >
> > > > + if (len == 0)
> > > >
> > > > + return 1;
> > > >
> > > > +
> > > >
> > > > + if ((num = ctx->num) != 0) { /* process intermediate buffer? */
> > > >
> > > > + rem = bsz - num;
> > > >
> > > > +
> > > >
> > > > + if (len < rem) {
> > > >
> > > > + memcpy(ctx->buf + num, inp, len);
> > > >
> > > > + ctx->num += len;
> > > >
> > > > + return 1;
> > > >
> > > > + }
> > > >
> > > > + /*
> > > >
> > > > + * We have enough data to fill or overflow the intermediate
> > > >
> > > > + * buffer. So we append |rem| bytes and process the block,
> > > >
> > > > + * leaving the rest for later processing...
> > > >
> > > > + */
> > > >
> > > > + memcpy(ctx->buf + num, inp, rem);
> > > >
> > > > + inp += rem, len -= rem;
> > > >
> > > > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> > > >
> > > > + ctx->num = 0;
> > > >
> > > > + /* ctx->buf is processed, ctx->num is guaranteed to be zero
> > > > + */
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + if (len >= bsz)
> > > >
> > > > + rem = SHA3_absorb(ctx->A, inp, len, bsz);
> > > >
> > > > + else
> > > >
> > > > + rem = len;
> > > >
> > > > +
> > > >
> > > > + if (rem) {
> > > >
> > > > + memcpy(ctx->buf, inp + len - rem, rem);
> > > >
> > > > + ctx->num = rem;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return 1;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md)
> > > >
> > > > +{
> > > >
> > > > + size_t bsz = ctx->block_size;
> > > >
> > > > + size_t num = ctx->num;
> > > >
> > > > +
> > > >
> > > > + if (ctx->md_size == 0)
> > > >
> > > > + return 1;
> > > >
> > > > +
> > > >
> > > > + /*
> > > >
> > > > + * Pad the data with 10*1. Note that |num| can be |bsz - 1|
> > > >
> > > > + * in which case both byte operations below are performed on
> > > >
> > > > + * same byte...
> > > >
> > > > + */
> > > >
> > > > + memset(ctx->buf + num, 0, bsz - num);
> > > >
> > > > + ctx->buf[num] = ctx->pad;
> > > >
> > > > + ctx->buf[bsz - 1] |= 0x80;
> > > >
> > > > +
> > > >
> > > > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> > > >
> > > > +
> > > >
> > > > + SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
> > > >
> > > > +
> > > >
> > > > + return 1;
> > > >
> > > > +}
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > > new file mode 100644
> > > > index 0000000000..b2a40ee044
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > > @@ -0,0 +1,53 @@
> > > > +/** @file
> > > >
> > > > + Encode realted functions from Xkcp.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +The eXtended Keccak Code Package (XKCP)
> > > >
> > > > +https://github.com/XKCP/XKCP
> > > >
> > > > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters
> and
> > > > +Gilles
> > > > Van Assche.
> > > >
> > > > +Implementation by the designers, hereby denoted as "the
> implementer".
> > > >
> > > > +For more information, feedback or questions, please refer to the
> > > > +Keccak Team
> > > > website:
> > > >
> > > > +https://keccak.team/
> > > >
> > > > +To the extent possible under law, the implementer has waived all
> > > > +copyright
> > > >
> > > > +and related or neighboring rights to the source code in this file.
> > > >
> > > > +http://creativecommons.org/publicdomain/zero/1.0/
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "xkcp.h"
> > > >
> > > > +
> > > >
> > > > +unsigned int left_encode(unsigned char * encbuf, size_t value)
> > > >
> > > > +{
> > > >
> > > > + unsigned int n, i;
> > > >
> > > > + size_t v;
> > > >
> > > > +
> > > >
> > > > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> > > >
> > > > + ; /* empty */
> > > >
> > > > + if (n == 0)
> > > >
> > > > + n = 1;
> > > >
> > > > + for ( i = 1; i <= n; ++i )
> > > >
> > > > + {
> > > >
> > > > + encbuf[i] = (unsigned char)(value >> (8 * (n-i)));
> > > >
> > > > + }
> > > >
> > > > + encbuf[0] = (unsigned char)n;
> > > >
> > > > + return n + 1;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +unsigned int right_encode(unsigned char * encbuf, size_t value)
> > > >
> > > > +{
> > > >
> > > > + unsigned int n, i;
> > > >
> > > > + size_t v;
> > > >
> > > > +
> > > >
> > > > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> > > >
> > > > + ; /* empty */
> > > >
> > > > + if (n == 0)
> > > >
> > > > + n = 1;
> > > >
> > > > + for ( i = 1; i <= n; ++i )
> > > >
> > > > + {
> > > >
> > > > + encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
> > > >
> > > > + }
> > > >
> > > > + encbuf[n] = (unsigned char)n;
> > > >
> > > > + return n + 1;
> > > >
> > > > +}
> > > >
> > > > diff --git
> > > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > > new file mode 100644
> > > > index 0000000000..052ab3a0d6
> > > > --- /dev/null
> > > > +++
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > > @@ -0,0 +1,152 @@
> > > > +/** @file
> > > >
> > > > + Application for Parallelhash Function Validation.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "TestBaseCryptLib.h"
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample common parameters.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN OutputByteLen
> =
> > > 64;
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample #1 from NIST Special Publication 800-185.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample1[]
> > > = {
> > > >
> > > > + // input data of sample1.
> > > >
> > > > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
> > > > + 0x13, 0x14,
> > > > 0x15, 0x16, 0x17,
> > > >
> > > > + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
> > > >
> > > > +};
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> InputSample1ByteLen
> > > =
> > > > 24; // Length of sample1 input data in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > > *CustomizationSample1
> > > > = ""; // Customization string (S) of sample1.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > > CustomSample1ByteLen =
> > > > 0; // Customization string length of sample1 in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample1
> =
> > > 8;
> > > > // Block size of sample1.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > > ExpectOutputSample1[]
> > > > = {
> > > >
> > > > + // Expected output data of sample1.
> > > >
> > > > + 0xbc, 0x1e, 0xf1, 0x24, 0xda, 0x34, 0x49, 0x5e, 0x94, 0x8e, 0xad,
> > > > + 0x20, 0x7d,
> > > > 0xd9, 0x84, 0x22,
> > > >
> > > > + 0x35, 0xda, 0x43, 0x2d, 0x2b, 0xbc, 0x54, 0xb4, 0xc1, 0x10, 0xe6,
> > > > + 0x4c, 0x45,
> > > > 0x11, 0x05, 0x53,
> > > >
> > > > + 0x1b, 0x7f, 0x2a, 0x3e, 0x0c, 0xe0, 0x55, 0xc0, 0x28, 0x05, 0xe7,
> > > > + 0xc2, 0xde,
> > > > 0x1f, 0xb7, 0x46,
> > > >
> > > > + 0xaf, 0x97, 0xa1, 0xd0, 0x01, 0xf4, 0x3b, 0x82, 0x4e, 0x31, 0xb8,
> > > > + 0x76, 0x12,
> > > > 0x41, 0x04, 0x29
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample #2 from NIST Special Publication 800-185.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 *InputSample2
> > > =
> > > > InputSample1; // Input of sample2 is same as sample1.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> InputSample2ByteLen
> > > =
> > > > 24; // Length of sample2 input data in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > > *CustomizationSample2
> > > > = "Parallel Data"; // Customization string (S) of sample2.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > > CustomSample2ByteLen =
> > > > 13; // Customization string length of sample2 in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample2
> =
> > > 8;
> > > > // Block size of sample2.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > > ExpectOutputSample2[]
> > > > = {
> > > >
> > > > + // Expected output data of sample2.
> > > >
> > > > + 0xcd, 0xf1, 0x52, 0x89, 0xb5, 0x4f, 0x62, 0x12, 0xb4, 0xbc, 0x27,
> > > > + 0x05, 0x28,
> > > > 0xb4, 0x95, 0x26,
> > > >
> > > > + 0x00, 0x6d, 0xd9, 0xb5, 0x4e, 0x2b, 0x6a, 0xdd, 0x1e, 0xf6, 0x90,
> > > > + 0x0d, 0xda,
> > > > 0x39, 0x63, 0xbb,
> > > >
> > > > + 0x33, 0xa7, 0x24, 0x91, 0xf2, 0x36, 0x96, 0x9c, 0xa8, 0xaf, 0xae,
> > > > + 0xa2, 0x9c,
> > > > 0x68, 0x2d, 0x47,
> > > >
> > > > + 0xa3, 0x93, 0xc0, 0x65, 0xb3, 0x8e, 0x29, 0xfa, 0xe6, 0x51, 0xa2,
> > > > + 0x09, 0x1c,
> > > > 0x83, 0x31, 0x10
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample #3 from NIST Special Publication 800-185.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample3[]
> > > = {
> > > >
> > > > + // input data of sample3.
> > > >
> > > > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
> > > > + 0x0b, 0x10,
> > > > 0x11, 0x12, 0x13,
> > > >
> > > > + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22,
> > > > + 0x23, 0x24,
> > > > 0x25, 0x26, 0x27,
> > > >
> > > > + 0x28, 0x29, 0x2a, 0x2b, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
> > > > + 0x37, 0x38,
> > > > 0x39, 0x3a, 0x3b,
> > > >
> > > > + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
> > > > + 0x4b, 0x50,
> > > > 0x51, 0x52, 0x53,
> > > >
> > > > + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
> > > >
> > > > +};
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> InputSample3ByteLen
> > > =
> > > > 72; // Length of sample3 input data in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > > *CustomizationSample3
> > > > = "Parallel Data"; // Customization string (S) of sample3.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > > CustomSample3ByteLen =
> > > > 13; // Customization string length of sample3 in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample3
> =
> > > 12;
> > > > // Block size of sample3.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > > ExpectOutputSample3[]
> > > > = {
> > > >
> > > > + // Expected output data of sample3.
> > > >
> > > > + 0x69, 0xd0, 0xfc, 0xb7, 0x64, 0xea, 0x05, 0x5d, 0xd0, 0x93, 0x34,
> > > > + 0xbc, 0x60,
> > > > 0x21, 0xcb, 0x7e,
> > > >
> > > > + 0x4b, 0x61, 0x34, 0x8d, 0xff, 0x37, 0x5d, 0xa2, 0x62, 0x67, 0x1c,
> > > > + 0xde, 0xc3,
> > > > 0xef, 0xfa, 0x8d,
> > > >
> > > > + 0x1b, 0x45, 0x68, 0xa6, 0xcc, 0xe1, 0x6b, 0x1c, 0xad, 0x94, 0x6d,
> > > > + 0xdd, 0xe2,
> > > > 0x7f, 0x6c, 0xe2,
> > > >
> > > > + 0xb8, 0xde, 0xe4, 0xcd, 0x1b, 0x24, 0x85, 0x1e, 0xbf, 0x00, 0xeb,
> > > > + 0x90, 0xd4,
> > > > 0x38, 0x13, 0xe9
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +UNIT_TEST_STATUS
> > > >
> > > > +EFIAPI
> > > >
> > > > +TestVerifyParallelHash256HashAll (
> > > >
> > > > + IN UNIT_TEST_CONTEXT Context
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > + UINT16 OriginalParallelHashBlockNumber;
> > > >
> > > > + UINT8 Output[64];
> > > >
> > > > +
> > > >
> > > > + // Restore original PcdParallelHashBlockNumber.
> > > >
> > > > + OriginalParallelHashBlockNumber = PcdGet16
> > > > + (PcdParallelHashBlockNumber);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Test #1 using sample1.
> > > >
> > > > + //
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample1ByteLen /
> > > > BlockSizeSample1);
> > > >
> > > > + Status = ParallelHash256HashAll (
> > > >
> > > > + InputSample1,
> > > >
> > > > + InputSample1ByteLen,
> > > >
> > > > + Output,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + CustomizationSample1,
> > > >
> > > > + CustomSample1ByteLen
> > > >
> > > > + );
> > > >
> > > > + UT_ASSERT_TRUE (Status);
> > > >
> > > > +
> > > >
> > > > + // Check the output with the expected output.
> > > >
> > > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample1,
> > > OutputByteLen);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Test #2 using sample2.
> > > >
> > > > + //
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample2ByteLen /
> > > > BlockSizeSample2);
> > > >
> > > > + Status = ParallelHash256HashAll (
> > > >
> > > > + InputSample2,
> > > >
> > > > + InputSample2ByteLen,
> > > >
> > > > + Output,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + CustomizationSample2,
> > > >
> > > > + CustomSample2ByteLen
> > > >
> > > > + );
> > > >
> > > > + UT_ASSERT_TRUE (Status);
> > > >
> > > > +
> > > >
> > > > + // Check the output with the expected output.
> > > >
> > > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample2,
> > > OutputByteLen);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Test #3 using sample3.
> > > >
> > > > + //
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample3ByteLen /
> > > > BlockSizeSample3);
> > > >
> > > > + Status = ParallelHash256HashAll (
> > > >
> > > > + InputSample3,
> > > >
> > > > + InputSample3ByteLen,
> > > >
> > > > + Output,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + CustomizationSample3,
> > > >
> > > > + CustomSample3ByteLen
> > > >
> > > > + );
> > > >
> > > > + UT_ASSERT_TRUE (Status);
> > > >
> > > > +
> > > >
> > > > + // Check the output with the expected output.
> > > >
> > > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample3,
> > > OutputByteLen);
> > > >
> > > > +
> > > >
> > > > + // Recover original PcdParallelHashBlockNumber.
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber,
> > > > + OriginalParallelHashBlockNumber);
> > > >
> > > > +
> > > >
> > > > + return EFI_SUCCESS;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +TEST_DESC mParallelhashTest[] = {
> > > >
> > > > + //
> > > >
> > > > + //
> > > > + -----Description------------------------------Class-----------------
> > > > + -----Function----
> > > > -------------Pre---Post--Context
> > > >
> > > > + //
> > > >
> > > > + { "TestVerifyParallelHash256HashAll()",
> > > > "CryptoPkg.BaseCryptLib.ParallelHash256HashAll",
> > > > TestVerifyParallelHash256HashAll, NULL, NULL, NULL },
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +UINTN mParallelhashTestNum = ARRAY_SIZE (mParallelhashTest);
> > > >
> > > > diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec index
> > > > 5888941bab..3af55d9c10 100644
> > > > --- a/CryptoPkg/CryptoPkg.dec
> > > > +++ b/CryptoPkg/CryptoPkg.dec
> > > > @@ -4,7 +4,7 @@
> > > > # This Package provides cryptographic-related libraries for UEFI
> > > > security modules.
> > > >
> > > > # It also provides a test application to test libraries.
> > > >
> > > > #
> > > >
> > > > -# Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +# Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > #
> > > >
> > > > ##
> > > >
> > > > @@ -81,5 +81,12 @@
> > > > # @ValidList 0x80000001 | 0x00000001, 0x00000002, 0x00000004,
> > > > 0x00000008, 0x00000010
> > > >
> > > >
> > > >
> > >
> gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x00000002|UINT32|0x
> > > 00
> > > > 000001
> > > >
> > > >
> > > >
> > > > +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic,
> > > PcdsDynamicEx]
> > > >
> > > > + ## This PCD indicates the block number of parallel hash
> > > >
> > > > + # Based on the value set, parallel hash can chose the block
> > > >
> > > > + # number to calculate specific hash.<BR>
> > > >
> > > > + # The number can be set by platform team according to the core
> > > number.
> > > >
> > > > +
> > > >
> > >
> gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber|0x0100|UINT1
> > > 6|0
> > > > x00000003
> > > >
> > > > +
> > > >
> > > > [UserExtensions.TianoCore."ExtraFiles"]
> > > >
> > > > CryptoPkgExtra.uni
> > > >
> > > > diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > b/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > index f4bc7c0d73..0b274b1257 100644
> > > > --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > @@ -4,7 +4,7 @@
> > > > primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI
> > > > security
> > > >
> > > > functionality enabling.
> > > >
> > > >
> > > >
> > > > -Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > >
> > > > **/
> > > >
> > > > @@ -753,6 +753,33 @@ Sha512HashAll (
> > > > OUT UINT8 *HashValue
> > > >
> > > > );
> > > >
> > > >
> > > >
> > > > +/**
> > > >
> > > > + Parallel hash function ParallelHash256, as defined in NIST's
> > > > + Special Publication
> > > > 800-185,
> > > >
> > > > + published December 2016.
> > > >
> > > > +
> > > >
> > > > + @param[in] Input Pointer to the input message (X).
> > > >
> > > > + @param[in] InputByteLen The number(>0) of input bytes
> provided
> > > for the
> > > > input data.
> > > >
> > > > + @param[out] Output Pointer to the output buffer.
> > > >
> > > > + @param[in] OutputByteLen The desired number of output bytes
> (L).
> > > >
> > > > + @param[in] Customization Pointer to the customization string (S).
> > > >
> > > > + @param[in] CustomByteLen The length of the customization string
> in
> > > bytes.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE ParallelHash256 digest computation succeeded.
> > > >
> > > > + @retval FALSE ParallelHash256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +ParallelHash256HashAll (
> > > >
> > > > + IN CONST VOID *Input,
> > > >
> > > > + IN UINTN InputByteLen,
> > > >
> > > > + OUT VOID *Output,
> > > >
> > > > + IN UINTN OutputByteLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomByteLen
> > > >
> > > > + );
> > > >
> > > > +
> > > >
> > > > /**
> > > >
> > > > Retrieves the size, in bytes, of the context buffer required for
> > > > SM3 hash operations.
> > > >
> > > >
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > index e6470d7a21..70159163d4 100644
> > > > --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > @@ -10,7 +10,7 @@
> > > > # RSA external functions, PKCS#7 SignedData sign functions,
> > > > Diffie-Hellman functions, and
> > > >
> > > > # authenticode signature verification functions are not supported in
> > > > this instance.
> > > >
> > > > #
> > > >
> > > > -# Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +# Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > #
> > > >
> > > > ##
> > > >
> > > > @@ -38,6 +38,10 @@
> > > > Hash/CryptSha256.c
> > > >
> > > > Hash/CryptSm3.c
> > > >
> > > > Hash/CryptSha512.c
> > > >
> > > > + Hash/CryptSha3.c
> > > >
> > > > + Hash/CryptXkcp.c
> > > >
> > > > + Hash/CryptCShake256.c
> > > >
> > > > + Hash/CryptParallelHash.c
> > > >
> > > > Hmac/CryptHmacSha256.c
> > > >
> > > > Kdf/CryptHkdfNull.c
> > > >
> > > > Cipher/CryptAes.c
> > > >
> > > > @@ -85,6 +89,9 @@
> > > > OpensslLib
> > > >
> > > > IntrinsicLib
> > > >
> > > > PrintLib
> > > >
> > > > + MmServicesTableLib
> > > >
> > > > + SynchronizationLib
> > > >
> > > > + PcdLib
> > > >
> > > >
> > > >
> > > > #
> > > >
> > > > # Remove these [BuildOptions] after this library is cleaned up
> > > >
> > > > @@ -101,3 +108,6 @@
> > > > GCC:*_CLANG35_*_CC_FLAGS = -std=c99
> > > >
> > > > GCC:*_CLANG38_*_CC_FLAGS = -std=c99
> > > >
> > > > GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99
> > > > -Wno-error=incompatible-pointer- types
> > > >
> > > > +
> > > >
> > > > +[Pcd]
> > > >
> > > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > > >
> > > > diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > b/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > index d257dca8fa..35d9c62a0b 100644
> > > > --- a/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > +++ b/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > @@ -2,7 +2,7 @@
> > > > Root include file of C runtime library to support building the
> > > > third-party
> > > >
> > > > cryptographic library.
> > > >
> > > >
> > > >
> > > > -Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All
> > > > rights reserved.<BR>
> > > >
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > >
> > > > @@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > > #define MAX_STRING_SIZE 0x1000
> > > >
> > > >
> > > >
> > > > +#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
> > > >
> > > > +
> > > >
> > > > //
> > > >
> > > > // We already have "no-ui" in out Configure invocation.
> > > >
> > > > // but the code still fails to compile.
> > > >
> > > > @@ -111,6 +113,7 @@ typedef UINT8 u_char;
> > > > typedef UINT32 uid_t;
> > > >
> > > > typedef UINT32 gid_t;
> > > >
> > > > typedef CHAR16 wchar_t;
> > > >
> > > > +typedef UINT64 uint64_t;
> > > >
> > > >
> > > >
> > > > //
> > > >
> > > > // File operations are not required for EFI building,
> > > >
> > > > diff --git a/CryptoPkg/Library/Include/sha3.h
> > > > b/CryptoPkg/Library/Include/sha3.h
> > > > new file mode 100644
> > > > index 0000000000..71b4c75548
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/Include/sha3.h
> > > > @@ -0,0 +1,32 @@
> > > > +/** @file
> > > >
> > > > + SHA3 realted functions from OpenSSL.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> > > >
> > > > +Licensed under the OpenSSL license (the "License"). You may not use
> > > >
> > > > +this file except in compliance with the License. You can obtain a
> > > > +copy
> > > >
> > > > +in the file LICENSE in the source distribution or at
> > > >
> > > > +https://www.openssl.org/source/license.html
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include <CrtLibSupport.h>
> > > >
> > > > +
> > > >
> > > > +#define KECCAK1600_WIDTH 1600
> > > >
> > > > +
> > > >
> > > > +typedef struct {
> > > >
> > > > + uint64_t A[5][5];
> > > >
> > > > + size_t block_size; /* cached ctx->digest->block_size */
> > > >
> > > > + size_t md_size; /* output length, variable in XOF */
> > > >
> > > > + size_t num; /* used bytes in below buffer */
> > > >
> > > > + unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
> > > >
> > > > + unsigned char pad;
> > > >
> > > > +} KECCAK1600_CTX;
> > > >
> > > > +
> > > >
> > > > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > > > +md_size);
> > > >
> > > > +
> > > >
> > > > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
> > > >
> > > > +
> > > >
> > > > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md);
> > > >
> > > > diff --git a/CryptoPkg/Library/Include/xkcp.h
> > > > b/CryptoPkg/Library/Include/xkcp.h
> > > > new file mode 100644
> > > > index 0000000000..b328d672e4
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/Include/xkcp.h
> > > > @@ -0,0 +1,23 @@
> > > > +/** @file
> > > >
> > > > + Encode realted functions from Xkcp.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +The eXtended Keccak Code Package (XKCP)
> > > >
> > > > +https://github.com/XKCP/XKCP
> > > >
> > > > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters
> and
> > > > +Gilles
> > > > Van Assche.
> > > >
> > > > +Implementation by the designers, hereby denoted as "the
> implementer".
> > > >
> > > > +For more information, feedback or questions, please refer to the
> > > > +Keccak Team
> > > > website:
> > > >
> > > > +https://keccak.team/
> > > >
> > > > +To the extent possible under law, the implementer has waived all
> > > > +copyright
> > > >
> > > > +and related or neighboring rights to the source code in this file.
> > > >
> > > > +http://creativecommons.org/publicdomain/zero/1.0/
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include <CrtLibSupport.h>
> > > >
> > > > +
> > > >
> > > > +unsigned int left_encode(unsigned char * encbuf, size_t value);
> > > >
> > > > +
> > > >
> > > > +unsigned int right_encode(unsigned char * encbuf, size_t value);
> > > >
> > > > diff --git
> > > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > index a6b3482742..0bffd687c2 100644
> > > > ---
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > +++
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > @@ -1,7 +1,7 @@
> > > > /** @file
> > > >
> > > > Application for Cryptographic Primitives Validation.
> > > >
> > > >
> > > >
> > > > -Copyright (c) 2009 - 2016, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > >
> > > > **/
> > > >
> > > > @@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > #include <Library/BaseLib.h>
> > > >
> > > > #include <Library/BaseMemoryLib.h>
> > > >
> > > > #include <Library/MemoryAllocationLib.h>
> > > >
> > > > +#include <Library/PcdLib.h>
> > > >
> > > > // #include <UnitTestTypes.h>
> > > >
> > > > #include <Library/UnitTestLib.h>
> > > >
> > > > // #include <Library/UnitTestAssertLib.h>
> > > >
> > > > diff --git
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > > f
> > > >
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > > f
> > > > index 00c8692650..61a59d6a47 100644
> > > > ---
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > > f
> > > > +++
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHos
> > > > +++ t.inf
> > > > @@ -2,6 +2,7 @@
> > > > # Host-based UnitTest for BaseCryptLib
> > > >
> > > > #
> > > >
> > > > # Copyright (c) Microsoft Corporation.<BR>
> > > >
> > > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > ##
> > > >
> > > >
> > > >
> > > > @@ -35,6 +36,7 @@
> > > > Pkcs7EkuTests.c
> > > >
> > > > OaepEncryptTests.c
> > > >
> > > > RsaPssTests.c
> > > >
> > > > + ParallelhashTests.c
> > > >
> > > >
> > > >
> > > > [Packages]
> > > >
> > > > MdePkg/MdePkg.dec
> > > >
> > > > @@ -45,3 +47,8 @@
> > > > DebugLib
> > > >
> > > > BaseCryptLib
> > > >
> > > > UnitTestLib
> > > >
> > > > + PcdLib
> > > >
> > > > +
> > > >
> > > > +[Pcd]
> > > >
> > > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > > >
> > > > +
> > > >
> > > > diff --git
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > > nf
> > > >
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > > nf
> > > > index ca789aa6ad..682f25a754 100644
> > > > ---
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > > nf
> > > > +++
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShe
> > > > +++ ll.inf
> > > > @@ -2,6 +2,7 @@
> > > > # BaseCryptLib UnitTest built for execution in UEFI Shell.
> > > >
> > > > #
> > > >
> > > > # Copyright (c) Microsoft Corporation.<BR>
> > > >
> > > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > ##
> > > >
> > > >
> > > >
> > > > @@ -36,6 +37,7 @@
> > > > Pkcs7EkuTests.c
> > > >
> > > > OaepEncryptTests.c
> > > >
> > > > RsaPssTests.c
> > > >
> > > > + ParallelhashTests.c
> > > >
> > > >
> > > >
> > > > [Packages]
> > > >
> > > > MdePkg/MdePkg.dec
> > > >
> > > > @@ -48,3 +50,7 @@
> > > > UnitTestLib
> > > >
> > > > PrintLib
> > > >
> > > > BaseCryptLib
> > > >
> > > > + PcdLib
> > > >
> > > > +
> > > >
> > > > +[Pcd]
> > > >
> > > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > > >
> > > > --
> > > > 2.26.2.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
2022-02-16 7:51 ` Yao, Jiewen
2022-02-16 8:23 ` Li, Zhihao
@ 2022-02-17 5:28 ` Li, Zhihao
1 sibling, 0 replies; 6+ messages in thread
From: Li, Zhihao @ 2022-02-17 5:28 UTC (permalink / raw)
To: Yao, Jiewen, devel@edk2.groups.io
Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin, Fu, Siyuan
We try to make proper attribution for the code in openssl_sha3 and in xkcp.
We separated their implementation into CryptSha3.c and CryptXkcp.c,
Separated their declaration into sha3.h and xkcp.h.
With the comment, we plan to delete these header files and put the declaration and
Structure define into CryptCshake256.c.
> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: Wednesday, February 16, 2022 3:52 PM
> To: Li, Zhihao <zhihao.li@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Fu,
> Siyuan <siyuan.fu@intel.com>
> Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> ParallelHash256HashAll in BaseCryptLib.
>
> But I don’t understand why we need sha3.h and xkcp.h at all.
>
>
> > -----Original Message-----
> > From: Li, Zhihao <zhihao.li@intel.com>
> > Sent: Wednesday, February 16, 2022 3:43 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>;
> > Jiang, Guomin <guomin.jiang@intel.com>; Fu, Siyuan
> <siyuan.fu@intel.com>
> > Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> > ParallelHash256HashAll in BaseCryptLib.
> >
> > With your comment, we plan do some modification for parallelhash.
> > 1. Plan to add a parameter (BlockSize) on ParallelHash256HashAll function
> to
> > replace PcdParallelHashBlockNumber.
> > 2. Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash
> > folder.
> >
> >
> > > -----Original Message-----
> > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > Sent: Tuesday, February 15, 2022 2:09 PM
> > > To: Li, Zhihao <zhihao.li@intel.com>; devel@edk2.groups.io
> > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> > > <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Fu,
> > > Siyuan <siyuan.fu@intel.com>
> > > Subject: RE: [PATCH v1] CryptoPkg: Add new hash algorithm
> > > ParallelHash256HashAll in BaseCryptLib.
> > >
> > > Thanks for the update.
> > >
> > > Feedback below:
> > >
> > > 1) How block size is determined for below API?
> > >
> > > BOOLEAN
> > > EFIAPI
> > > ParallelHash256HashAll (
> > > IN CONST VOID *Input,
> > > IN UINTN InputByteLen,
> > > OUT VOID *Output,
> > > IN UINTN OutputByteLen,
> > > IN CONST VOID *Customization,
> > > IN UINTN CustomByteLen
> > > );
> > >
> > > Is that determined by PcdParallelHashBlockNumber ?
> > >
> > > I don’t think it is good idea to let a crypto library determine a platform
> PCD.
> > > For example, how do you support binary crypto module ?
> > Plan to add a parameter (BlockSize) to replace
> PcdParallelHashBlockNumber.
> > >
> > > 2) Why we need "sha3.h" and "xkcp.h" ?
> > > These are openssl specific structure. It shall not be put to EDKII file
> header.
> > >
> > > CryptoPkg\Library\Include shall only contain generic dependency header.
> > Plan to move sha3.h and xkcp.h to CryptoPkg\Library\BaseCryptLib\Hash
> folder.
> > >
> > >
> > >
> > >
> > > Thank you
> > > Yao, Jiewen
> > >
> > > > -----Original Message-----
> > > > From: Li, Zhihao <zhihao.li@intel.com>
> > > > Sent: Friday, February 11, 2022 5:05 PM
> > > > To: devel@edk2.groups.io
> > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > > <jian.j.wang@intel.com>; Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang,
> > > > Guomin <guomin.jiang@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> > > > Subject: [PATCH v1] CryptoPkg: Add new hash algorithm
> > > > ParallelHash256HashAll in BaseCryptLib.
> > > >
> > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3596
> > > >
> > > > Parallel hash function ParallelHash256HashAll, as defined in NIST's
> > > > Special Publication 800-185, published December 2016. It utilizes
> > > > multi-process to calculate the digest.
> > > >
> > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > > Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> > > > Cc: Guomin Jiang <guomin.jiang@intel.com>
> > > > Cc: Siyuan Fu <siyuan.fu@intel.com>
> > > >
> > > > Signed-off-by: Zhihao Li <zhihao.li@intel.com>
> > > > ---
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c | 313
> > > > ++++++++++++++++++++
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c | 275
> > > > +++++++++++++++++
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c | 102
> > > +++++++
> > > > CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c | 53
> ++++
> > > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c |
> > > 152
> > > > ++++++++++
> > > > CryptoPkg/CryptoPkg.dec | 9 +-
> > > > CryptoPkg/Include/Library/BaseCryptLib.h | 29 +-
> > > > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 12 +-
> > > > CryptoPkg/Library/Include/CrtLibSupport.h | 5 +-
> > > > CryptoPkg/Library/Include/sha3.h | 32 ++
> > > > CryptoPkg/Library/Include/xkcp.h | 23 ++
> > > > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> | 3
> > > +-
> > > >
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
> > > | 7 +
> > > >
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf |
> > > 6 +
> > > > 14 files changed, 1016 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > > new file mode 100644
> > > > index 0000000000..5efced3f46
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
> > > > @@ -0,0 +1,313 @@
> > > > +/** @file
> > > >
> > > > + cSHAKE-256 Digest Wrapper Implementations.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "InternalCryptLib.h"
> > > >
> > > > +#include "sha3.h"
> > > >
> > > > +#include "xkcp.h"
> > > >
> > > > +
> > > >
> > > > +#define CSHAKE256_SECURITY_STRENGTH 256
> > > >
> > > > +#define CSHAKE256_RATE_IN_BYTES 136
> > > >
> > > > +
> > > >
> > > > +const CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = {0};
> > > >
> > > > +
> > > >
> > > > +UINTN
> > > >
> > > > +EFIAPI
> > > >
> > > > +LeftEncode (
> > > >
> > > > + OUT UINT8 *Encbuf,
> > > >
> > > > + IN UINTN Value
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + return left_encode (Encbuf, Value);
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +UINTN
> > > >
> > > > +EFIAPI
> > > >
> > > > +RightEncode (
> > > >
> > > > + OUT UINT8 *Encbuf,
> > > >
> > > > + IN UINTN Value
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + return right_encode (Encbuf, Value);
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Retrieves the size, in bytes, of the context buffer required for
> > > > + cSHAKE-256
> > > > hash operations.
> > > >
> > > > +
> > > >
> > > > + @return The size, in bytes, of the context buffer required for
> > > > + cSHAKE-256
> > > > hash operations.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +UINTN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256GetContextSize (
> > > >
> > > > + VOID
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + return (UINTN) (sizeof (KECCAK1600_CTX));
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Initializes user-supplied memory pointed by CShake256Context as
> > > > + cSHAKE-256
> > > > hash context for
> > > >
> > > > + subsequent use.
> > > >
> > > > +
> > > >
> > > > + @param[out] CShake256Context Pointer to cSHAKE-256 context
> being
> > > > initialized.
> > > >
> > > > + @param[in] OutputLen The desired number of output length in
> > > bytes.
> > > >
> > > > + @param[in] Name Pointer to the function name string.
> > > >
> > > > + @param[in] NameLen The length of the function name in bytes.
> > > >
> > > > + @param[in] Customization Pointer to the customization string.
> > > >
> > > > + @param[in] CustomizationLen The length of the customization
> string in
> > > > bytes.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE cSHAKE-256 context initialization succeeded.
> > > >
> > > > + @retval FALSE cSHAKE-256 context initialization failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256Init (
> > > >
> > > > + OUT VOID *CShake256Context,
> > > >
> > > > + IN UINTN OutputLen,
> > > >
> > > > + IN CONST VOID *Name,
> > > >
> > > > + IN UINTN NameLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomizationLen
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > + unsigned char EncBuf[sizeof(size_t)+1];
> > > >
> > > > + UINTN EncLen;
> > > >
> > > > + UINTN AbsorbLen;
> > > >
> > > > + UINTN PadLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (CShake256Context == NULL ||
> > > >
> > > > + OutputLen == 0 ||
> > > >
> > > > + (NameLen != 0 && Name == NULL) ||
> > > >
> > > > + (CustomizationLen != 0 && Customization == NULL)) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Initialize KECCAK context with pad value and block size.
> > > >
> > > > + //
> > > >
> > > > + if (NameLen == 0 && CustomizationLen == 0) {
> > > >
> > > > + //
> > > >
> > > > + // When N and S are both empty strings, cSHAKE(X, L, N, S) is
> > > > + equivalent to
> > > >
> > > > + // SHAKE as defined in FIPS 202.
> > > >
> > > > + //
> > > >
> > > > + return (BOOLEAN) init (
> > > >
> > > > + (KECCAK1600_CTX *) CShake256Context,
> > > >
> > > > + '\x1f',
> > > >
> > > > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > > > + * 2) / 8,
> > > >
> > > > + OutputLen
> > > >
> > > > + );
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + Status = (BOOLEAN) init (
> > > >
> > > > + (KECCAK1600_CTX *) CShake256Context,
> > > >
> > > > + '\x04',
> > > >
> > > > + (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH
> > > > + * 2) / 8,
> > > >
> > > > + OutputLen
> > > >
> > > > + );
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + AbsorbLen = 0;
> > > >
> > > > + //
> > > >
> > > > + // Absorb Absorb bytepad(.., rate).
> > > >
> > > > + //
> > > >
> > > > + EncLen = left_encode (EncBuf, CSHAKE256_RATE_IN_BYTES);
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > EncBuf, EncLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += EncLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Absorb encode_string(N).
> > > >
> > > > + //
> > > >
> > > > + EncLen = left_encode (EncBuf, NameLen * 8);
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > EncBuf, EncLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += EncLen;
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > Name, NameLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += NameLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Absorb encode_string(S).
> > > >
> > > > + //
> > > >
> > > > + EncLen = left_encode (EncBuf, CustomizationLen * 8);
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > EncBuf, EncLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += EncLen;
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > Customization, CustomizationLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + AbsorbLen += CustomizationLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Absorb zero padding up to rate.
> > > >
> > > > + //
> > > >
> > > > + PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen %
> > > > CSHAKE256_RATE_IN_BYTES;
> > > >
> > > > + Status = (BOOLEAN) sha3_update ((KECCAK1600_CTX *)
> > > > + CShake256Context,
> > > > mZeroPadding, PadLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return TRUE;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Digests the input data and updates cSHAKE-256 context.
> > > >
> > > > +
> > > >
> > > > + This function performs cSHAKE-256 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.
> > > >
> > > > + cSHAKE-256 context should be already correctly initialized by
> > > > + CShake256Init(),
> > > > and should not be finalized
> > > >
> > > > + by CShake256Final(). Behavior with invalid context is undefined.
> > > >
> > > > +
> > > >
> > > > + @param[in, out] CShake256Context Pointer to the cSHAKE-256
> 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 cSHAKE-256 data digest succeeded.
> > > >
> > > > + @retval FALSE cSHAKE-256 data digest failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256Update (
> > > >
> > > > + IN OUT VOID *CShake256Context,
> > > >
> > > > + IN CONST VOID *Data,
> > > >
> > > > + IN UINTN DataSize
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (CShake256Context == NULL) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Check invalid parameters, in case that only DataLength was
> > > > + checked in
> > > > OpenSSL.
> > > >
> > > > + //
> > > >
> > > > + if (Data == NULL && DataSize != 0) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return (BOOLEAN)(sha3_update ((KECCAK1600_CTX *)
> > > CShake256Context,
> > > > Data, DataSize));
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Completes computation of the cSHAKE-256 digest value.
> > > >
> > > > +
> > > >
> > > > + This function completes cSHAKE-256 hash computation and retrieves
> > > > + the
> > > > digest value into
> > > >
> > > > + the specified memory. After this function has been called, the
> > > > + cSHAKE-256
> > > > context cannot
> > > >
> > > > + be used again.
> > > >
> > > > + cSHAKE-256 context should be already correctly initialized by
> > > > + CShake256Init(),
> > > > and should not be
> > > >
> > > > + finalized by CShake256Final(). Behavior with invalid cSHAKE-256
> > > > + context is
> > > > undefined.
> > > >
> > > > +
> > > >
> > > > + @param[in, out] CShake256Context Pointer to the cSHAKE-256
> context.
> > > >
> > > > + @param[out] HashValue Pointer to a buffer that receives the
> > > cSHAKE-
> > > > 256 digest
> > > >
> > > > + value.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE cSHAKE-256 digest computation succeeded.
> > > >
> > > > + @retval FALSE cSHAKE-256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256Final (
> > > >
> > > > + IN OUT VOID *CShake256Context,
> > > >
> > > > + OUT UINT8 *HashValue
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (CShake256Context == NULL || HashValue == NULL) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // cSHAKE-256 Hash Finalization.
> > > >
> > > > + //
> > > >
> > > > + return (BOOLEAN) (sha3_final ((KECCAK1600_CTX *)
> CShake256Context,
> > > > HashValue));
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Computes the CSHAKE-256 message digest of a input data buffer.
> > > >
> > > > +
> > > >
> > > > + This function performs the CSHAKE-256 message digest of a given
> > > > + data buffer,
> > > > and places
> > > >
> > > > + the digest value into the specified memory.
> > > >
> > > > +
> > > >
> > > > + @param[in] Data Pointer to the buffer containing the data to
> be
> > > > hashed.
> > > >
> > > > + @param[in] DataSize Size of Data buffer in bytes.
> > > >
> > > > + @param[in] OutputLen Size of output in bytes.
> > > >
> > > > + @param[in] Name Pointer to the function name string.
> > > >
> > > > + @param[in] NameLen Size of the function name in bytes.
> > > >
> > > > + @param[in] Customization Pointer to the customization string.
> > > >
> > > > + @param[in] CustomizationLen Size of the customization string in
> bytes.
> > > >
> > > > + @param[out] HashValue Pointer to a buffer that receives the
> > > CSHAKE-
> > > > 256 digest
> > > >
> > > > + value.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE CSHAKE-256 digest computation succeeded.
> > > >
> > > > + @retval FALSE CSHAKE-256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256HashAll (
> > > >
> > > > + IN CONST VOID *Data,
> > > >
> > > > + IN UINTN DataSize,
> > > >
> > > > + IN UINTN OutputLen,
> > > >
> > > > + IN CONST VOID *Name,
> > > >
> > > > + IN UINTN NameLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomizationLen,
> > > >
> > > > + OUT UINT8 *HashValue
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > + KECCAK1600_CTX Ctx;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Check input parameters.
> > > >
> > > > + //
> > > >
> > > > + if (HashValue == NULL) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > + if (Data == NULL && DataSize != 0) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + Status = CShake256Init (&Ctx, OutputLen, Name, NameLen,
> > > > + Customization,
> > > > CustomizationLen);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + Status = CShake256Update (&Ctx, Data, DataSize);
> > > >
> > > > + if (!Status) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return CShake256Final (&Ctx, HashValue);
> > > >
> > > > +}
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > > new file mode 100644
> > > > index 0000000000..3eaa7c2ceb
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptParallelHash.c
> > > > @@ -0,0 +1,275 @@
> > > > +/** @file
> > > >
> > > > + ParallelHash Implementation.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "InternalCryptLib.h"
> > > >
> > > > +#include <Library\PcdLib.h>
> > > >
> > > > +#include <Library\SynchronizationLib.h>
> > > >
> > > > +#include <Library\MmServicesTableLib.h>
> > > >
> > > > +
> > > >
> > > > +
> > > >
> > > > +UINT16 mBlockNum;
> > > >
> > > > +UINTN mBlockSize;
> > > >
> > > > +UINTN mLastBlockSize;
> > > >
> > > > +UINT8 *mInput;
> > > >
> > > > +UINTN mBlockResultSize;
> > > >
> > > > +UINT8 *mBlockHashResult;
> > > >
> > > > +BOOLEAN *mBlockIsCompleted;
> > > >
> > > > +SPIN_LOCK *mSpinLockList;
> > > >
> > > > +
> > > >
> > > > +UINTN LeftEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> > > >
> > > > +UINTN RightEncode (OUT UINT8 *Encbuf, IN UINTN Value);
> > > >
> > > > +
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +CShake256HashAll (
> > > >
> > > > + IN CONST VOID *Data,
> > > >
> > > > + IN UINTN DataSize,
> > > >
> > > > + IN UINTN OutputLen,
> > > >
> > > > + IN CONST VOID *Name,
> > > >
> > > > + IN UINTN NameLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomizationLen,
> > > >
> > > > + OUT UINT8 *HashValue
> > > >
> > > > + );
> > > >
> > > > +
> > > >
> > > > +VOID
> > > >
> > > > +EFIAPI
> > > >
> > > > +ParallelHashApExecute (
> > > >
> > > > + IN VOID *ProcedureArgument
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + UINTN Index;
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > +
> > > >
> > > > + for (Index = 0; Index < mBlockNum; Index++) {
> > > >
> > > > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> > > >
> > > > + //
> > > >
> > > > + // Completed, try next one.
> > > >
> > > > + //
> > > >
> > > > + if (mBlockIsCompleted[Index])
> > > >
> > > > + {
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + continue;
> > > >
> > > > + }
> > > >
> > > > + //
> > > >
> > > > + // Calculate CShake256 for this block.
> > > >
> > > > + //
> > > >
> > > > + Status = CShake256HashAll (
> > > >
> > > > + mInput + Index * mBlockSize,
> > > >
> > > > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > > > + mBlockSize,
> > > >
> > > > + mBlockResultSize,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + mBlockHashResult + Index * mBlockResultSize
> > > >
> > > > + );
> > > >
> > > > + if (!EFI_ERROR (Status)){
> > > >
> > > > + mBlockIsCompleted[Index] = TRUE;
> > > >
> > > > + }
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > + Parallel hash function ParallelHash256, as defined in NIST's
> > > > + Special Publication
> > > > 800-185,
> > > >
> > > > + published December 2016.
> > > >
> > > > +
> > > >
> > > > + @param Input[in] Pointer to the input message (X).
> > > >
> > > > + @param InputByteLen[in] The number(>0) of input bytes provided
> for
> > > the
> > > > input data.
> > > >
> > > > + @param Output[out] Pointer to the output buffer.
> > > >
> > > > + @param OutputByteLen[in] The desired number of output bytes
> (L).
> > > >
> > > > + @param Customization[in] Pointer to the customization string (S).
> > > >
> > > > + @param CustomByteLen[in] The length of the customization string
> in
> > > bytes.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE ParallelHash256 digest computation succeeded.
> > > >
> > > > + @retval FALSE ParallelHash256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +*/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +ParallelHash256HashAll (
> > > >
> > > > + IN CONST VOID *Input,
> > > >
> > > > + IN UINTN InputByteLen,
> > > >
> > > > + OUT VOID *Output,
> > > >
> > > > + IN UINTN OutputByteLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomByteLen
> > > >
> > > > + )
> > > >
> > > > +
> > > >
> > > > +{
> > > >
> > > > + UINT8 EncBufB[sizeof(UINTN)+1];
> > > >
> > > > + UINTN EncSizeB;
> > > >
> > > > + UINT8 EncBufN[sizeof(UINTN)+1];
> > > >
> > > > + UINTN EncSizeN;
> > > >
> > > > + UINT8 EncBufL[sizeof(UINTN)+1];
> > > >
> > > > + UINTN EncSizeL;
> > > >
> > > > + UINTN Index;
> > > >
> > > > + UINT8 *CombinedInput;
> > > >
> > > > + UINTN CombinedInputSize;
> > > >
> > > > + EFI_STATUS Status;
> > > >
> > > > + UINTN StartedApNum;
> > > >
> > > > + BOOLEAN AllCompleted;
> > > >
> > > > + UINTN Offset;
> > > >
> > > > + BOOLEAN ReturnValue;
> > > >
> > > > +
> > > >
> > > > + if (InputByteLen == 0 || OutputByteLen == 0) {
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + if (Input == NULL || Output == NULL){
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + if (CustomByteLen != 0 && Customization == NULL){
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Get Block number n.
> > > >
> > > > + //
> > > >
> > > > + mBlockNum = PcdGet16 (PcdParallelHashBlockNumber);
> > > >
> > > > +
> > > >
> > > > + if (mBlockNum < 1 || InputByteLen < mBlockNum - 1){
> > > >
> > > > + return FALSE;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Set hash result size of each block in bytes.
> > > >
> > > > + //
> > > >
> > > > + mBlockResultSize = OutputByteLen;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // calculate the block byte length B.
> > > >
> > > > + //
> > > >
> > > > + mBlockSize = InputByteLen % mBlockNum == 0 ? InputByteLen /
> > > mBlockNum :
> > > > InputByteLen / (mBlockNum - 1);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Encode B, n, L to string and record size.
> > > >
> > > > + //
> > > >
> > > > + EncSizeB = LeftEncode (EncBufB, mBlockSize);
> > > >
> > > > + EncSizeN = RightEncode (EncBufN, mBlockNum);
> > > >
> > > > + EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Allocate buffer for combined input (newX), Block completed flag
> > > > + and
> > > > SpinLock.
> > > >
> > > > + //
> > > >
> > > > + CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum *
> > > > mBlockResultSize;
> > > >
> > > > + CombinedInput = AllocateZeroPool (CombinedInputSize);
> > > >
> > > > + mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof
> > > > + (BOOLEAN));
> > > >
> > > > + mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
> > > >
> > > > + if (CombinedInput == NULL || mBlockIsCompleted == NULL ||
> > > > + mSpinLockList
> > > > == NULL) {
> > > >
> > > > + ReturnValue = FALSE;
> > > >
> > > > + goto Exit;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Fill LeftEncode(B).
> > > >
> > > > + //
> > > >
> > > > + CopyMem (CombinedInput, EncBufB, EncSizeB);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Prepare for parallel hash.
> > > >
> > > > + //
> > > >
> > > > + mBlockHashResult = CombinedInput + EncSizeB;
> > > >
> > > > + mInput = Input;
> > > >
> > > > + mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize :
> > > > InputByteLen % mBlockSize;
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Initialize SpinLock for each result block.
> > > >
> > > > + //
> > > >
> > > > + for (Index = 0; Index < mBlockNum; Index++) {
> > > >
> > > > + InitializeSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Dispatch blocklist to each AP.
> > > >
> > > > + //
> > > >
> > > > + StartedApNum = 0;
> > > >
> > > > + for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
> > > >
> > > > + if (Index != gMmst->CurrentlyExecutingCpu) {
> > > >
> > > > + Status = gMmst->MmStartupThisAp (ParallelHashApExecute, Index,
> > > > + NULL);
> > > >
> > > > + if (!EFI_ERROR (Status)) {
> > > >
> > > > + StartedApNum++;
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Wait until all block hash completed.
> > > >
> > > > + //
> > > >
> > > > + do {
> > > >
> > > > + AllCompleted = TRUE;
> > > >
> > > > + for (Index = 0; Index < mBlockNum; Index++) {
> > > >
> > > > + if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
> > > >
> > > > + if (!mBlockIsCompleted[Index]) {
> > > >
> > > > + AllCompleted = FALSE;
> > > >
> > > > + ReturnValue = CShake256HashAll (
> > > >
> > > > + mInput + Index * mBlockSize,
> > > >
> > > > + (Index == (mBlockNum - 1)) ? mLastBlockSize :
> > > > + mBlockSize,
> > > >
> > > > + mBlockResultSize,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + NULL,
> > > >
> > > > + 0,
> > > >
> > > > + mBlockHashResult + Index * mBlockResultSize
> > > >
> > > > + );
> > > >
> > > > + if (ReturnValue){
> > > >
> > > > + mBlockIsCompleted[Index] = TRUE;
> > > >
> > > > + }
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + break;
> > > >
> > > > + }
> > > >
> > > > + ReleaseSpinLock (&mSpinLockList[Index]);
> > > >
> > > > + } else {
> > > >
> > > > + AllCompleted = FALSE;
> > > >
> > > > + break;
> > > >
> > > > + }
> > > >
> > > > + }
> > > >
> > > > + } while (!AllCompleted);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Fill LeftEncode(n).
> > > >
> > > > + //
> > > >
> > > > + Offset = EncSizeB + mBlockNum * mBlockResultSize;
> > > >
> > > > + CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Fill LeftEncode(L).
> > > >
> > > > + //
> > > >
> > > > + Offset += EncSizeN;
> > > >
> > > > + CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
> > > >
> > > > +
> > > >
> > > > + ReturnValue = CShake256HashAll (
> > > >
> > > > + CombinedInput,
> > > >
> > > > + CombinedInputSize,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + PARALLELHASH_CUSTOMIZATION,
> > > >
> > > > + AsciiStrLen(PARALLELHASH_CUSTOMIZATION),
> > > >
> > > > + Customization,
> > > >
> > > > + CustomByteLen,
> > > >
> > > > + Output
> > > >
> > > > + );
> > > >
> > > > +
> > > >
> > > > +Exit:
> > > >
> > > > + ZeroMem (CombinedInput, CombinedInputSize);
> > > >
> > > > +
> > > >
> > > > + if (CombinedInput != NULL){
> > > >
> > > > + FreePool (CombinedInput);
> > > >
> > > > + }
> > > >
> > > > + if (mSpinLockList != NULL){
> > > >
> > > > + FreePool (mSpinLockList);
> > > >
> > > > + }
> > > >
> > > > + if (mBlockIsCompleted != NULL){
> > > >
> > > > + FreePool (mBlockIsCompleted);
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return ReturnValue;
> > > >
> > > > +}
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > > new file mode 100644
> > > > index 0000000000..b170c463de
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
> > > > @@ -0,0 +1,102 @@
> > > > +/** @file
> > > >
> > > > + SHA3 realted functions from OpenSSL.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> > > >
> > > > +Licensed under the OpenSSL license (the "License"). You may not use
> > > >
> > > > +this file except in compliance with the License. You can obtain a
> > > > +copy
> > > >
> > > > +in the file LICENSE in the source distribution or at
> > > >
> > > > +https://www.openssl.org/source/license.html
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "sha3.h"
> > > >
> > > > +
> > > >
> > > > +size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t
> > > > +len,
> > > >
> > > > + size_t r);
> > > >
> > > > +void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len,
> > > > +size_t r);
> > > >
> > > > +
> > > >
> > > > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > > > +md_size)
> > > >
> > > > +{
> > > >
> > > > + if (bsz <= sizeof(ctx->buf)) {
> > > >
> > > > + memset(ctx->A, 0, sizeof(ctx->A));
> > > >
> > > > +
> > > >
> > > > + ctx->num = 0;
> > > >
> > > > + ctx->block_size = bsz;
> > > >
> > > > + ctx->md_size = md_size;
> > > >
> > > > + ctx->pad = pad;
> > > >
> > > > +
> > > >
> > > > + return 1;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return 0;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +
> > > >
> > > > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
> > > >
> > > > +{
> > > >
> > > > + const unsigned char *inp = _inp;
> > > >
> > > > + size_t bsz = ctx->block_size;
> > > >
> > > > + size_t num, rem;
> > > >
> > > > +
> > > >
> > > > + if (len == 0)
> > > >
> > > > + return 1;
> > > >
> > > > +
> > > >
> > > > + if ((num = ctx->num) != 0) { /* process intermediate buffer? */
> > > >
> > > > + rem = bsz - num;
> > > >
> > > > +
> > > >
> > > > + if (len < rem) {
> > > >
> > > > + memcpy(ctx->buf + num, inp, len);
> > > >
> > > > + ctx->num += len;
> > > >
> > > > + return 1;
> > > >
> > > > + }
> > > >
> > > > + /*
> > > >
> > > > + * We have enough data to fill or overflow the intermediate
> > > >
> > > > + * buffer. So we append |rem| bytes and process the block,
> > > >
> > > > + * leaving the rest for later processing...
> > > >
> > > > + */
> > > >
> > > > + memcpy(ctx->buf + num, inp, rem);
> > > >
> > > > + inp += rem, len -= rem;
> > > >
> > > > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> > > >
> > > > + ctx->num = 0;
> > > >
> > > > + /* ctx->buf is processed, ctx->num is guaranteed to be zero
> > > > + */
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + if (len >= bsz)
> > > >
> > > > + rem = SHA3_absorb(ctx->A, inp, len, bsz);
> > > >
> > > > + else
> > > >
> > > > + rem = len;
> > > >
> > > > +
> > > >
> > > > + if (rem) {
> > > >
> > > > + memcpy(ctx->buf, inp + len - rem, rem);
> > > >
> > > > + ctx->num = rem;
> > > >
> > > > + }
> > > >
> > > > +
> > > >
> > > > + return 1;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md)
> > > >
> > > > +{
> > > >
> > > > + size_t bsz = ctx->block_size;
> > > >
> > > > + size_t num = ctx->num;
> > > >
> > > > +
> > > >
> > > > + if (ctx->md_size == 0)
> > > >
> > > > + return 1;
> > > >
> > > > +
> > > >
> > > > + /*
> > > >
> > > > + * Pad the data with 10*1. Note that |num| can be |bsz - 1|
> > > >
> > > > + * in which case both byte operations below are performed on
> > > >
> > > > + * same byte...
> > > >
> > > > + */
> > > >
> > > > + memset(ctx->buf + num, 0, bsz - num);
> > > >
> > > > + ctx->buf[num] = ctx->pad;
> > > >
> > > > + ctx->buf[bsz - 1] |= 0x80;
> > > >
> > > > +
> > > >
> > > > + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
> > > >
> > > > +
> > > >
> > > > + SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
> > > >
> > > > +
> > > >
> > > > + return 1;
> > > >
> > > > +}
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > > b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > > new file mode 100644
> > > > index 0000000000..b2a40ee044
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptXkcp.c
> > > > @@ -0,0 +1,53 @@
> > > > +/** @file
> > > >
> > > > + Encode realted functions from Xkcp.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +The eXtended Keccak Code Package (XKCP)
> > > >
> > > > +https://github.com/XKCP/XKCP
> > > >
> > > > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters
> and
> > > > +Gilles
> > > > Van Assche.
> > > >
> > > > +Implementation by the designers, hereby denoted as "the
> implementer".
> > > >
> > > > +For more information, feedback or questions, please refer to the
> > > > +Keccak Team
> > > > website:
> > > >
> > > > +https://keccak.team/
> > > >
> > > > +To the extent possible under law, the implementer has waived all
> > > > +copyright
> > > >
> > > > +and related or neighboring rights to the source code in this file.
> > > >
> > > > +http://creativecommons.org/publicdomain/zero/1.0/
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "xkcp.h"
> > > >
> > > > +
> > > >
> > > > +unsigned int left_encode(unsigned char * encbuf, size_t value)
> > > >
> > > > +{
> > > >
> > > > + unsigned int n, i;
> > > >
> > > > + size_t v;
> > > >
> > > > +
> > > >
> > > > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> > > >
> > > > + ; /* empty */
> > > >
> > > > + if (n == 0)
> > > >
> > > > + n = 1;
> > > >
> > > > + for ( i = 1; i <= n; ++i )
> > > >
> > > > + {
> > > >
> > > > + encbuf[i] = (unsigned char)(value >> (8 * (n-i)));
> > > >
> > > > + }
> > > >
> > > > + encbuf[0] = (unsigned char)n;
> > > >
> > > > + return n + 1;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +unsigned int right_encode(unsigned char * encbuf, size_t value)
> > > >
> > > > +{
> > > >
> > > > + unsigned int n, i;
> > > >
> > > > + size_t v;
> > > >
> > > > +
> > > >
> > > > + for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
> > > >
> > > > + ; /* empty */
> > > >
> > > > + if (n == 0)
> > > >
> > > > + n = 1;
> > > >
> > > > + for ( i = 1; i <= n; ++i )
> > > >
> > > > + {
> > > >
> > > > + encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
> > > >
> > > > + }
> > > >
> > > > + encbuf[n] = (unsigned char)n;
> > > >
> > > > + return n + 1;
> > > >
> > > > +}
> > > >
> > > > diff --git
> > > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > > new file mode 100644
> > > > index 0000000000..052ab3a0d6
> > > > --- /dev/null
> > > > +++
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/ParallelhashTests.c
> > > > @@ -0,0 +1,152 @@
> > > > +/** @file
> > > >
> > > > + Application for Parallelhash Function Validation.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include "TestBaseCryptLib.h"
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample common parameters.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN OutputByteLen
> =
> > > 64;
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample #1 from NIST Special Publication 800-185.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample1[]
> > > = {
> > > >
> > > > + // input data of sample1.
> > > >
> > > > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
> > > > + 0x13, 0x14,
> > > > 0x15, 0x16, 0x17,
> > > >
> > > > + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
> > > >
> > > > +};
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> InputSample1ByteLen
> > > =
> > > > 24; // Length of sample1 input data in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > > *CustomizationSample1
> > > > = ""; // Customization string (S) of sample1.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > > CustomSample1ByteLen =
> > > > 0; // Customization string length of sample1 in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample1
> =
> > > 8;
> > > > // Block size of sample1.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > > ExpectOutputSample1[]
> > > > = {
> > > >
> > > > + // Expected output data of sample1.
> > > >
> > > > + 0xbc, 0x1e, 0xf1, 0x24, 0xda, 0x34, 0x49, 0x5e, 0x94, 0x8e, 0xad,
> > > > + 0x20, 0x7d,
> > > > 0xd9, 0x84, 0x22,
> > > >
> > > > + 0x35, 0xda, 0x43, 0x2d, 0x2b, 0xbc, 0x54, 0xb4, 0xc1, 0x10, 0xe6,
> > > > + 0x4c, 0x45,
> > > > 0x11, 0x05, 0x53,
> > > >
> > > > + 0x1b, 0x7f, 0x2a, 0x3e, 0x0c, 0xe0, 0x55, 0xc0, 0x28, 0x05, 0xe7,
> > > > + 0xc2, 0xde,
> > > > 0x1f, 0xb7, 0x46,
> > > >
> > > > + 0xaf, 0x97, 0xa1, 0xd0, 0x01, 0xf4, 0x3b, 0x82, 0x4e, 0x31, 0xb8,
> > > > + 0x76, 0x12,
> > > > 0x41, 0x04, 0x29
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample #2 from NIST Special Publication 800-185.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 *InputSample2
> > > =
> > > > InputSample1; // Input of sample2 is same as sample1.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> InputSample2ByteLen
> > > =
> > > > 24; // Length of sample2 input data in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > > *CustomizationSample2
> > > > = "Parallel Data"; // Customization string (S) of sample2.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > > CustomSample2ByteLen =
> > > > 13; // Customization string length of sample2 in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample2
> =
> > > 8;
> > > > // Block size of sample2.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > > ExpectOutputSample2[]
> > > > = {
> > > >
> > > > + // Expected output data of sample2.
> > > >
> > > > + 0xcd, 0xf1, 0x52, 0x89, 0xb5, 0x4f, 0x62, 0x12, 0xb4, 0xbc, 0x27,
> > > > + 0x05, 0x28,
> > > > 0xb4, 0x95, 0x26,
> > > >
> > > > + 0x00, 0x6d, 0xd9, 0xb5, 0x4e, 0x2b, 0x6a, 0xdd, 0x1e, 0xf6, 0x90,
> > > > + 0x0d, 0xda,
> > > > 0x39, 0x63, 0xbb,
> > > >
> > > > + 0x33, 0xa7, 0x24, 0x91, 0xf2, 0x36, 0x96, 0x9c, 0xa8, 0xaf, 0xae,
> > > > + 0xa2, 0x9c,
> > > > 0x68, 0x2d, 0x47,
> > > >
> > > > + 0xa3, 0x93, 0xc0, 0x65, 0xb3, 0x8e, 0x29, 0xfa, 0xe6, 0x51, 0xa2,
> > > > + 0x09, 0x1c,
> > > > 0x83, 0x31, 0x10
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +//
> > > >
> > > > +// Parallelhash Test Sample #3 from NIST Special Publication 800-185.
> > > >
> > > > +//
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 InputSample3[]
> > > = {
> > > >
> > > > + // input data of sample3.
> > > >
> > > > + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
> > > > + 0x0b, 0x10,
> > > > 0x11, 0x12, 0x13,
> > > >
> > > > + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x20, 0x21, 0x22,
> > > > + 0x23, 0x24,
> > > > 0x25, 0x26, 0x27,
> > > >
> > > > + 0x28, 0x29, 0x2a, 0x2b, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
> > > > + 0x37, 0x38,
> > > > 0x39, 0x3a, 0x3b,
> > > >
> > > > + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
> > > > + 0x4b, 0x50,
> > > > 0x51, 0x52, 0x53,
> > > >
> > > > + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
> > > >
> > > > +};
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> InputSample3ByteLen
> > > =
> > > > 72; // Length of sample3 input data in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST VOID
> > > *CustomizationSample3
> > > > = "Parallel Data"; // Customization string (S) of sample3.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> > > CustomSample3ByteLen =
> > > > 13; // Customization string length of sample3 in bytes.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED UINTN BlockSizeSample3
> =
> > > 12;
> > > > // Block size of sample3.
> > > >
> > > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8
> > > ExpectOutputSample3[]
> > > > = {
> > > >
> > > > + // Expected output data of sample3.
> > > >
> > > > + 0x69, 0xd0, 0xfc, 0xb7, 0x64, 0xea, 0x05, 0x5d, 0xd0, 0x93, 0x34,
> > > > + 0xbc, 0x60,
> > > > 0x21, 0xcb, 0x7e,
> > > >
> > > > + 0x4b, 0x61, 0x34, 0x8d, 0xff, 0x37, 0x5d, 0xa2, 0x62, 0x67, 0x1c,
> > > > + 0xde, 0xc3,
> > > > 0xef, 0xfa, 0x8d,
> > > >
> > > > + 0x1b, 0x45, 0x68, 0xa6, 0xcc, 0xe1, 0x6b, 0x1c, 0xad, 0x94, 0x6d,
> > > > + 0xdd, 0xe2,
> > > > 0x7f, 0x6c, 0xe2,
> > > >
> > > > + 0xb8, 0xde, 0xe4, 0xcd, 0x1b, 0x24, 0x85, 0x1e, 0xbf, 0x00, 0xeb,
> > > > + 0x90, 0xd4,
> > > > 0x38, 0x13, 0xe9
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +UNIT_TEST_STATUS
> > > >
> > > > +EFIAPI
> > > >
> > > > +TestVerifyParallelHash256HashAll (
> > > >
> > > > + IN UNIT_TEST_CONTEXT Context
> > > >
> > > > + )
> > > >
> > > > +{
> > > >
> > > > + BOOLEAN Status;
> > > >
> > > > + UINT16 OriginalParallelHashBlockNumber;
> > > >
> > > > + UINT8 Output[64];
> > > >
> > > > +
> > > >
> > > > + // Restore original PcdParallelHashBlockNumber.
> > > >
> > > > + OriginalParallelHashBlockNumber = PcdGet16
> > > > + (PcdParallelHashBlockNumber);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Test #1 using sample1.
> > > >
> > > > + //
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample1ByteLen /
> > > > BlockSizeSample1);
> > > >
> > > > + Status = ParallelHash256HashAll (
> > > >
> > > > + InputSample1,
> > > >
> > > > + InputSample1ByteLen,
> > > >
> > > > + Output,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + CustomizationSample1,
> > > >
> > > > + CustomSample1ByteLen
> > > >
> > > > + );
> > > >
> > > > + UT_ASSERT_TRUE (Status);
> > > >
> > > > +
> > > >
> > > > + // Check the output with the expected output.
> > > >
> > > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample1,
> > > OutputByteLen);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Test #2 using sample2.
> > > >
> > > > + //
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample2ByteLen /
> > > > BlockSizeSample2);
> > > >
> > > > + Status = ParallelHash256HashAll (
> > > >
> > > > + InputSample2,
> > > >
> > > > + InputSample2ByteLen,
> > > >
> > > > + Output,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + CustomizationSample2,
> > > >
> > > > + CustomSample2ByteLen
> > > >
> > > > + );
> > > >
> > > > + UT_ASSERT_TRUE (Status);
> > > >
> > > > +
> > > >
> > > > + // Check the output with the expected output.
> > > >
> > > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample2,
> > > OutputByteLen);
> > > >
> > > > +
> > > >
> > > > + //
> > > >
> > > > + // Test #3 using sample3.
> > > >
> > > > + //
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber, InputSample3ByteLen /
> > > > BlockSizeSample3);
> > > >
> > > > + Status = ParallelHash256HashAll (
> > > >
> > > > + InputSample3,
> > > >
> > > > + InputSample3ByteLen,
> > > >
> > > > + Output,
> > > >
> > > > + OutputByteLen,
> > > >
> > > > + CustomizationSample3,
> > > >
> > > > + CustomSample3ByteLen
> > > >
> > > > + );
> > > >
> > > > + UT_ASSERT_TRUE (Status);
> > > >
> > > > +
> > > >
> > > > + // Check the output with the expected output.
> > > >
> > > > + UT_ASSERT_MEM_EQUAL (Output, ExpectOutputSample3,
> > > OutputByteLen);
> > > >
> > > > +
> > > >
> > > > + // Recover original PcdParallelHashBlockNumber.
> > > >
> > > > + PcdSet16S (PcdParallelHashBlockNumber,
> > > > + OriginalParallelHashBlockNumber);
> > > >
> > > > +
> > > >
> > > > + return EFI_SUCCESS;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +TEST_DESC mParallelhashTest[] = {
> > > >
> > > > + //
> > > >
> > > > + //
> > > > + -----Description------------------------------Class-----------------
> > > > + -----Function----
> > > > -------------Pre---Post--Context
> > > >
> > > > + //
> > > >
> > > > + { "TestVerifyParallelHash256HashAll()",
> > > > "CryptoPkg.BaseCryptLib.ParallelHash256HashAll",
> > > > TestVerifyParallelHash256HashAll, NULL, NULL, NULL },
> > > >
> > > > +};
> > > >
> > > > +
> > > >
> > > > +UINTN mParallelhashTestNum = ARRAY_SIZE (mParallelhashTest);
> > > >
> > > > diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec index
> > > > 5888941bab..3af55d9c10 100644
> > > > --- a/CryptoPkg/CryptoPkg.dec
> > > > +++ b/CryptoPkg/CryptoPkg.dec
> > > > @@ -4,7 +4,7 @@
> > > > # This Package provides cryptographic-related libraries for UEFI
> > > > security modules.
> > > >
> > > > # It also provides a test application to test libraries.
> > > >
> > > > #
> > > >
> > > > -# Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +# Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > #
> > > >
> > > > ##
> > > >
> > > > @@ -81,5 +81,12 @@
> > > > # @ValidList 0x80000001 | 0x00000001, 0x00000002, 0x00000004,
> > > > 0x00000008, 0x00000010
> > > >
> > > >
> > > >
> > >
> gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x00000002|UINT32|0x
> > > 00
> > > > 000001
> > > >
> > > >
> > > >
> > > > +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic,
> > > PcdsDynamicEx]
> > > >
> > > > + ## This PCD indicates the block number of parallel hash
> > > >
> > > > + # Based on the value set, parallel hash can chose the block
> > > >
> > > > + # number to calculate specific hash.<BR>
> > > >
> > > > + # The number can be set by platform team according to the core
> > > number.
> > > >
> > > > +
> > > >
> > >
> gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber|0x0100|UINT1
> > > 6|0
> > > > x00000003
> > > >
> > > > +
> > > >
> > > > [UserExtensions.TianoCore."ExtraFiles"]
> > > >
> > > > CryptoPkgExtra.uni
> > > >
> > > > diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > b/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > index f4bc7c0d73..0b274b1257 100644
> > > > --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> > > > @@ -4,7 +4,7 @@
> > > > primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI
> > > > security
> > > >
> > > > functionality enabling.
> > > >
> > > >
> > > >
> > > > -Copyright (c) 2009 - 2020, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > >
> > > > **/
> > > >
> > > > @@ -753,6 +753,33 @@ Sha512HashAll (
> > > > OUT UINT8 *HashValue
> > > >
> > > > );
> > > >
> > > >
> > > >
> > > > +/**
> > > >
> > > > + Parallel hash function ParallelHash256, as defined in NIST's
> > > > + Special Publication
> > > > 800-185,
> > > >
> > > > + published December 2016.
> > > >
> > > > +
> > > >
> > > > + @param[in] Input Pointer to the input message (X).
> > > >
> > > > + @param[in] InputByteLen The number(>0) of input bytes
> provided
> > > for the
> > > > input data.
> > > >
> > > > + @param[out] Output Pointer to the output buffer.
> > > >
> > > > + @param[in] OutputByteLen The desired number of output bytes
> (L).
> > > >
> > > > + @param[in] Customization Pointer to the customization string (S).
> > > >
> > > > + @param[in] CustomByteLen The length of the customization string
> in
> > > bytes.
> > > >
> > > > +
> > > >
> > > > + @retval TRUE ParallelHash256 digest computation succeeded.
> > > >
> > > > + @retval FALSE ParallelHash256 digest computation failed.
> > > >
> > > > + @retval FALSE This interface is not supported.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +BOOLEAN
> > > >
> > > > +EFIAPI
> > > >
> > > > +ParallelHash256HashAll (
> > > >
> > > > + IN CONST VOID *Input,
> > > >
> > > > + IN UINTN InputByteLen,
> > > >
> > > > + OUT VOID *Output,
> > > >
> > > > + IN UINTN OutputByteLen,
> > > >
> > > > + IN CONST VOID *Customization,
> > > >
> > > > + IN UINTN CustomByteLen
> > > >
> > > > + );
> > > >
> > > > +
> > > >
> > > > /**
> > > >
> > > > Retrieves the size, in bytes, of the context buffer required for
> > > > SM3 hash operations.
> > > >
> > > >
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > index e6470d7a21..70159163d4 100644
> > > > --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> > > > @@ -10,7 +10,7 @@
> > > > # RSA external functions, PKCS#7 SignedData sign functions,
> > > > Diffie-Hellman functions, and
> > > >
> > > > # authenticode signature verification functions are not supported in
> > > > this instance.
> > > >
> > > > #
> > > >
> > > > -# Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +# Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > #
> > > >
> > > > ##
> > > >
> > > > @@ -38,6 +38,10 @@
> > > > Hash/CryptSha256.c
> > > >
> > > > Hash/CryptSm3.c
> > > >
> > > > Hash/CryptSha512.c
> > > >
> > > > + Hash/CryptSha3.c
> > > >
> > > > + Hash/CryptXkcp.c
> > > >
> > > > + Hash/CryptCShake256.c
> > > >
> > > > + Hash/CryptParallelHash.c
> > > >
> > > > Hmac/CryptHmacSha256.c
> > > >
> > > > Kdf/CryptHkdfNull.c
> > > >
> > > > Cipher/CryptAes.c
> > > >
> > > > @@ -85,6 +89,9 @@
> > > > OpensslLib
> > > >
> > > > IntrinsicLib
> > > >
> > > > PrintLib
> > > >
> > > > + MmServicesTableLib
> > > >
> > > > + SynchronizationLib
> > > >
> > > > + PcdLib
> > > >
> > > >
> > > >
> > > > #
> > > >
> > > > # Remove these [BuildOptions] after this library is cleaned up
> > > >
> > > > @@ -101,3 +108,6 @@
> > > > GCC:*_CLANG35_*_CC_FLAGS = -std=c99
> > > >
> > > > GCC:*_CLANG38_*_CC_FLAGS = -std=c99
> > > >
> > > > GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99
> > > > -Wno-error=incompatible-pointer- types
> > > >
> > > > +
> > > >
> > > > +[Pcd]
> > > >
> > > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > > >
> > > > diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > b/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > index d257dca8fa..35d9c62a0b 100644
> > > > --- a/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > +++ b/CryptoPkg/Library/Include/CrtLibSupport.h
> > > > @@ -2,7 +2,7 @@
> > > > Root include file of C runtime library to support building the
> > > > third-party
> > > >
> > > > cryptographic library.
> > > >
> > > >
> > > >
> > > > -Copyright (c) 2010 - 2021, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +Copyright (c) 2010 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All
> > > > rights reserved.<BR>
> > > >
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > >
> > > > @@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > > #define MAX_STRING_SIZE 0x1000
> > > >
> > > >
> > > >
> > > > +#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
> > > >
> > > > +
> > > >
> > > > //
> > > >
> > > > // We already have "no-ui" in out Configure invocation.
> > > >
> > > > // but the code still fails to compile.
> > > >
> > > > @@ -111,6 +113,7 @@ typedef UINT8 u_char;
> > > > typedef UINT32 uid_t;
> > > >
> > > > typedef UINT32 gid_t;
> > > >
> > > > typedef CHAR16 wchar_t;
> > > >
> > > > +typedef UINT64 uint64_t;
> > > >
> > > >
> > > >
> > > > //
> > > >
> > > > // File operations are not required for EFI building,
> > > >
> > > > diff --git a/CryptoPkg/Library/Include/sha3.h
> > > > b/CryptoPkg/Library/Include/sha3.h
> > > > new file mode 100644
> > > > index 0000000000..71b4c75548
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/Include/sha3.h
> > > > @@ -0,0 +1,32 @@
> > > > +/** @file
> > > >
> > > > + SHA3 realted functions from OpenSSL.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
> > > >
> > > > +Licensed under the OpenSSL license (the "License"). You may not use
> > > >
> > > > +this file except in compliance with the License. You can obtain a
> > > > +copy
> > > >
> > > > +in the file LICENSE in the source distribution or at
> > > >
> > > > +https://www.openssl.org/source/license.html
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include <CrtLibSupport.h>
> > > >
> > > > +
> > > >
> > > > +#define KECCAK1600_WIDTH 1600
> > > >
> > > > +
> > > >
> > > > +typedef struct {
> > > >
> > > > + uint64_t A[5][5];
> > > >
> > > > + size_t block_size; /* cached ctx->digest->block_size */
> > > >
> > > > + size_t md_size; /* output length, variable in XOF */
> > > >
> > > > + size_t num; /* used bytes in below buffer */
> > > >
> > > > + unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
> > > >
> > > > + unsigned char pad;
> > > >
> > > > +} KECCAK1600_CTX;
> > > >
> > > > +
> > > >
> > > > +int init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bsz, size_t
> > > > +md_size);
> > > >
> > > > +
> > > >
> > > > +int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
> > > >
> > > > +
> > > >
> > > > +int sha3_final(KECCAK1600_CTX *ctx, unsigned char *md);
> > > >
> > > > diff --git a/CryptoPkg/Library/Include/xkcp.h
> > > > b/CryptoPkg/Library/Include/xkcp.h
> > > > new file mode 100644
> > > > index 0000000000..b328d672e4
> > > > --- /dev/null
> > > > +++ b/CryptoPkg/Library/Include/xkcp.h
> > > > @@ -0,0 +1,23 @@
> > > > +/** @file
> > > >
> > > > + Encode realted functions from Xkcp.
> > > >
> > > > +
> > > >
> > > > +Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > +
> > > >
> > > > +The eXtended Keccak Code Package (XKCP)
> > > >
> > > > +https://github.com/XKCP/XKCP
> > > >
> > > > +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters
> and
> > > > +Gilles
> > > > Van Assche.
> > > >
> > > > +Implementation by the designers, hereby denoted as "the
> implementer".
> > > >
> > > > +For more information, feedback or questions, please refer to the
> > > > +Keccak Team
> > > > website:
> > > >
> > > > +https://keccak.team/
> > > >
> > > > +To the extent possible under law, the implementer has waived all
> > > > +copyright
> > > >
> > > > +and related or neighboring rights to the source code in this file.
> > > >
> > > > +http://creativecommons.org/publicdomain/zero/1.0/
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +
> > > >
> > > > +#include <CrtLibSupport.h>
> > > >
> > > > +
> > > >
> > > > +unsigned int left_encode(unsigned char * encbuf, size_t value);
> > > >
> > > > +
> > > >
> > > > +unsigned int right_encode(unsigned char * encbuf, size_t value);
> > > >
> > > > diff --git
> > > > a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > index a6b3482742..0bffd687c2 100644
> > > > ---
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > +++
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
> > > > @@ -1,7 +1,7 @@
> > > > /** @file
> > > >
> > > > Application for Cryptographic Primitives Validation.
> > > >
> > > >
> > > >
> > > > -Copyright (c) 2009 - 2016, Intel Corporation. All rights
> > > > reserved.<BR>
> > > >
> > > > +Copyright (c) 2009 - 2022, Intel Corporation. All rights
> > > > +reserved.<BR>
> > > >
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > >
> > > >
> > > > **/
> > > >
> > > > @@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > #include <Library/BaseLib.h>
> > > >
> > > > #include <Library/BaseMemoryLib.h>
> > > >
> > > > #include <Library/MemoryAllocationLib.h>
> > > >
> > > > +#include <Library/PcdLib.h>
> > > >
> > > > // #include <UnitTestTypes.h>
> > > >
> > > > #include <Library/UnitTestLib.h>
> > > >
> > > > // #include <Library/UnitTestAssertLib.h>
> > > >
> > > > diff --git
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > > f
> > > >
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > > f
> > > > index 00c8692650..61a59d6a47 100644
> > > > ---
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.in
> > > > f
> > > > +++
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHos
> > > > +++ t.inf
> > > > @@ -2,6 +2,7 @@
> > > > # Host-based UnitTest for BaseCryptLib
> > > >
> > > > #
> > > >
> > > > # Copyright (c) Microsoft Corporation.<BR>
> > > >
> > > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > ##
> > > >
> > > >
> > > >
> > > > @@ -35,6 +36,7 @@
> > > > Pkcs7EkuTests.c
> > > >
> > > > OaepEncryptTests.c
> > > >
> > > > RsaPssTests.c
> > > >
> > > > + ParallelhashTests.c
> > > >
> > > >
> > > >
> > > > [Packages]
> > > >
> > > > MdePkg/MdePkg.dec
> > > >
> > > > @@ -45,3 +47,8 @@
> > > > DebugLib
> > > >
> > > > BaseCryptLib
> > > >
> > > > UnitTestLib
> > > >
> > > > + PcdLib
> > > >
> > > > +
> > > >
> > > > +[Pcd]
> > > >
> > > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > > >
> > > > +
> > > >
> > > > diff --git
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > > nf
> > > >
> b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > > nf
> > > > index ca789aa6ad..682f25a754 100644
> > > > ---
> > > >
> a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.i
> > > > nf
> > > > +++
> > > b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShe
> > > > +++ ll.inf
> > > > @@ -2,6 +2,7 @@
> > > > # BaseCryptLib UnitTest built for execution in UEFI Shell.
> > > >
> > > > #
> > > >
> > > > # Copyright (c) Microsoft Corporation.<BR>
> > > >
> > > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > > >
> > > > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >
> > > > ##
> > > >
> > > >
> > > >
> > > > @@ -36,6 +37,7 @@
> > > > Pkcs7EkuTests.c
> > > >
> > > > OaepEncryptTests.c
> > > >
> > > > RsaPssTests.c
> > > >
> > > > + ParallelhashTests.c
> > > >
> > > >
> > > >
> > > > [Packages]
> > > >
> > > > MdePkg/MdePkg.dec
> > > >
> > > > @@ -48,3 +50,7 @@
> > > > UnitTestLib
> > > >
> > > > PrintLib
> > > >
> > > > BaseCryptLib
> > > >
> > > > + PcdLib
> > > >
> > > > +
> > > >
> > > > +[Pcd]
> > > >
> > > > + gEfiCryptoPkgTokenSpaceGuid.PcdParallelHashBlockNumber
> > > >
> > > > --
> > > > 2.26.2.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-02-17 5:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-11 9:05 [PATCH v1] CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib Li, Zhihao
2022-02-15 6:08 ` Yao, Jiewen
2022-02-16 7:43 ` Li, Zhihao
2022-02-16 7:51 ` Yao, Jiewen
2022-02-16 8:23 ` Li, Zhihao
2022-02-17 5:28 ` Li, Zhihao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox