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. Passed CI test. Onprotocol version code passed test. 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> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
		
			
				
	
	
		
			283 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  cSHAKE-256 Digest Wrapper Implementations.
 | 
						|
 | 
						|
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "CryptParallelHash.h"
 | 
						|
 | 
						|
#define  CSHAKE256_SECURITY_STRENGTH  256
 | 
						|
#define  CSHAKE256_RATE_IN_BYTES      136
 | 
						|
 | 
						|
CONST CHAR8  mZeroPadding[CSHAKE256_RATE_IN_BYTES] = { 0 };
 | 
						|
 | 
						|
/**
 | 
						|
  CShake256 initial function.
 | 
						|
 | 
						|
  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;
 | 
						|
  UINT8    EncBuf[sizeof (UINTN) + 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.
 | 
						|
    //
 | 
						|
    Status = (BOOLEAN)KeccakInit (
 | 
						|
                        (Keccak1600_Ctx *)CShake256Context,
 | 
						|
                        '\x1f',
 | 
						|
                        (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,
 | 
						|
                        OutputLen
 | 
						|
                        );
 | 
						|
 | 
						|
    return Status;
 | 
						|
  } else {
 | 
						|
    Status = (BOOLEAN)KeccakInit (
 | 
						|
                        (Keccak1600_Ctx *)CShake256Context,
 | 
						|
                        '\x04',
 | 
						|
                        (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,
 | 
						|
                        OutputLen
 | 
						|
                        );
 | 
						|
    if (!Status) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    AbsorbLen = 0;
 | 
						|
    //
 | 
						|
    // Absorb Absorb bytepad(.., rate).
 | 
						|
    //
 | 
						|
    EncLen = LeftEncode (EncBuf, CSHAKE256_RATE_IN_BYTES);
 | 
						|
    Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, EncBuf, EncLen);
 | 
						|
    if (!Status) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    AbsorbLen += EncLen;
 | 
						|
 | 
						|
    //
 | 
						|
    // Absorb encode_string(N).
 | 
						|
    //
 | 
						|
    EncLen = LeftEncode (EncBuf, NameLen * 8);
 | 
						|
    Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, EncBuf, EncLen);
 | 
						|
    if (!Status) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    AbsorbLen += EncLen;
 | 
						|
    Status     = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, Name, NameLen);
 | 
						|
    if (!Status) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    AbsorbLen += NameLen;
 | 
						|
 | 
						|
    //
 | 
						|
    // Absorb encode_string(S).
 | 
						|
    //
 | 
						|
    EncLen = LeftEncode (EncBuf, CustomizationLen * 8);
 | 
						|
    Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, EncBuf, EncLen);
 | 
						|
    if (!Status) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    AbsorbLen += EncLen;
 | 
						|
    Status     = (BOOLEAN)Sha3Update ((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)Sha3Update ((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)(Sha3Update ((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)(Sha3Final ((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);
 | 
						|
}
 |