mirror of https://github.com/acidanthera/audk.git
167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
/** @file
|
|
SHA3 realted functions from OpenSSL.
|
|
|
|
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
Copyright 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 "CryptParallelHash.h"
|
|
|
|
/**
|
|
Keccak initial fuction.
|
|
|
|
Set up state with specified capacity.
|
|
|
|
@param[out] Context Pointer to the context being initialized.
|
|
@param[in] Pad Delimited Suffix.
|
|
@param[in] BlockSize Size of context block.
|
|
@param[in] MessageDigestLen Size of message digest in bytes.
|
|
|
|
@retval 1 Initialize successfully.
|
|
@retval 0 Fail to initialize.
|
|
**/
|
|
UINT8
|
|
EFIAPI
|
|
KeccakInit (
|
|
OUT Keccak1600_Ctx *Context,
|
|
IN UINT8 Pad,
|
|
IN UINTN BlockSize,
|
|
IN UINTN MessageDigestLen
|
|
)
|
|
{
|
|
if (BlockSize <= sizeof (Context->buf)) {
|
|
memset (Context->A, 0, sizeof (Context->A));
|
|
|
|
Context->num = 0;
|
|
Context->block_size = BlockSize;
|
|
Context->md_size = MessageDigestLen;
|
|
Context->pad = Pad;
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
Sha3 update fuction.
|
|
|
|
This function performs Sha3 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.
|
|
|
|
@param[in,out] Context Pointer to the Keccak context.
|
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
|
@param[in] DataSize Size of Data buffer in bytes.
|
|
|
|
@retval 1 Update successfully.
|
|
**/
|
|
UINT8
|
|
EFIAPI
|
|
Sha3Update (
|
|
IN OUT Keccak1600_Ctx *Context,
|
|
IN const VOID *Data,
|
|
IN UINTN DataSize
|
|
)
|
|
{
|
|
const UINT8 *DataCopy;
|
|
UINTN BlockSize;
|
|
UINTN Num;
|
|
UINTN Rem;
|
|
|
|
DataCopy = Data;
|
|
BlockSize = (UINT8)(Context->block_size);
|
|
|
|
if (DataSize == 0) {
|
|
return 1;
|
|
}
|
|
|
|
if ((Num = Context->num) != 0) {
|
|
//
|
|
// process intermediate buffer
|
|
//
|
|
Rem = BlockSize - Num;
|
|
|
|
if (DataSize < Rem) {
|
|
memcpy (Context->buf + Num, DataCopy, DataSize);
|
|
Context->num += DataSize;
|
|
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 (Context->buf + Num, DataCopy, Rem);
|
|
DataCopy += Rem;
|
|
DataSize -= Rem;
|
|
(void)SHA3_absorb (Context->A, Context->buf, BlockSize, BlockSize);
|
|
Context->num = 0;
|
|
// Context->buf is processed, Context->num is guaranteed to be zero.
|
|
}
|
|
|
|
if (DataSize >= BlockSize) {
|
|
Rem = SHA3_absorb (Context->A, DataCopy, DataSize, BlockSize);
|
|
} else {
|
|
Rem = DataSize;
|
|
}
|
|
|
|
if (Rem > 0) {
|
|
memcpy (Context->buf, DataCopy + DataSize - Rem, Rem);
|
|
Context->num = Rem;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
Completes computation of Sha3 message digest.
|
|
|
|
This function completes sha3 hash computation and retrieves the digest value into
|
|
the specified memory. After this function has been called, the keccak context cannot
|
|
be used again.
|
|
|
|
@param[in, out] Context Pointer to the keccak context.
|
|
@param[out] MessageDigest Pointer to a buffer that receives the message digest.
|
|
|
|
@retval 1 Meaasge digest computation succeeded.
|
|
**/
|
|
UINT8
|
|
EFIAPI
|
|
Sha3Final (
|
|
IN OUT Keccak1600_Ctx *Context,
|
|
OUT UINT8 *MessageDigest
|
|
)
|
|
{
|
|
UINTN BlockSize;
|
|
UINTN Num;
|
|
|
|
BlockSize = Context->block_size;
|
|
Num = Context->num;
|
|
|
|
if (Context->md_size == 0) {
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Pad the data with 10*1. Note that |Num| can be |BlockSize - 1|
|
|
// in which case both byte operations below are performed on
|
|
// same byte.
|
|
//
|
|
memset (Context->buf + Num, 0, BlockSize - Num);
|
|
Context->buf[Num] = Context->pad;
|
|
Context->buf[BlockSize - 1] |= 0x80;
|
|
|
|
(void)SHA3_absorb (Context->A, Context->buf, BlockSize, BlockSize);
|
|
|
|
SHA3_squeeze (Context->A, MessageDigest, Context->md_size, BlockSize);
|
|
|
|
return 1;
|
|
}
|