X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=CryptoPkg%2FLibrary%2FBaseCryptLib%2FHash%2FCryptSha3.c;fp=CryptoPkg%2FLibrary%2FBaseCryptLib%2FHash%2FCryptSha3.c;h=6abafc3c00e60dde0c6953ac2ba211eac4d4d49a;hp=0000000000000000000000000000000000000000;hb=c1e662101addbfd983026f06d119da2d470865a1;hpb=28eeb08d8664df813637e12cb00c60cb30330be8 diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c new file mode 100644 index 0000000000..6abafc3c00 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c @@ -0,0 +1,166 @@ +/** @file + SHA3 realted functions from OpenSSL. + +Copyright (c) 2022, Intel Corporation. All rights reserved.
+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; +}