mirror of https://github.com/acidanthera/audk.git
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);
|
|
}
|