]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Hash/CryptSha3.c
CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Hash / CryptSha3.c
CommitLineData
c1e66210
ZL
1/** @file\r
2 SHA3 realted functions from OpenSSL.\r
3\r
4Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.\r
8Licensed under the OpenSSL license (the "License"). You may not use\r
9this file except in compliance with the License. You can obtain a copy\r
10in the file LICENSE in the source distribution or at\r
11https://www.openssl.org/source/license.html\r
12**/\r
13\r
14#include "CryptParallelHash.h"\r
15\r
16/**\r
17 Keccak initial fuction.\r
18\r
19 Set up state with specified capacity.\r
20\r
21 @param[out] Context Pointer to the context being initialized.\r
22 @param[in] Pad Delimited Suffix.\r
23 @param[in] BlockSize Size of context block.\r
24 @param[in] MessageDigestLen Size of message digest in bytes.\r
25\r
26 @retval 1 Initialize successfully.\r
27 @retval 0 Fail to initialize.\r
28**/\r
29UINT8\r
30EFIAPI\r
31KeccakInit (\r
32 OUT Keccak1600_Ctx *Context,\r
33 IN UINT8 Pad,\r
34 IN UINTN BlockSize,\r
35 IN UINTN MessageDigestLen\r
36 )\r
37{\r
38 if (BlockSize <= sizeof (Context->buf)) {\r
39 memset (Context->A, 0, sizeof (Context->A));\r
40\r
41 Context->num = 0;\r
42 Context->block_size = BlockSize;\r
43 Context->md_size = MessageDigestLen;\r
44 Context->pad = Pad;\r
45\r
46 return 1;\r
47 }\r
48\r
49 return 0;\r
50}\r
51\r
52/**\r
53 Sha3 update fuction.\r
54\r
55 This function performs Sha3 digest on a data buffer of the specified size.\r
56 It can be called multiple times to compute the digest of long or discontinuous data streams.\r
57\r
58 @param[in,out] Context Pointer to the Keccak context.\r
59 @param[in] Data Pointer to the buffer containing the data to be hashed.\r
60 @param[in] DataSize Size of Data buffer in bytes.\r
61\r
62 @retval 1 Update successfully.\r
63**/\r
64UINT8\r
65EFIAPI\r
66Sha3Update (\r
67 IN OUT Keccak1600_Ctx *Context,\r
68 IN const VOID *Data,\r
69 IN UINTN DataSize\r
70 )\r
71{\r
72 const UINT8 *DataCopy;\r
73 UINTN BlockSize;\r
74 UINTN Num;\r
75 UINTN Rem;\r
76\r
77 DataCopy = Data;\r
78 BlockSize = (UINT8)(Context->block_size);\r
79\r
80 if (DataSize == 0) {\r
81 return 1;\r
82 }\r
83\r
84 if ((Num = Context->num) != 0) {\r
85 //\r
86 // process intermediate buffer\r
87 //\r
88 Rem = BlockSize - Num;\r
89\r
90 if (DataSize < Rem) {\r
91 memcpy (Context->buf + Num, DataCopy, DataSize);\r
92 Context->num += DataSize;\r
93 return 1;\r
94 }\r
95\r
96 //\r
97 // We have enough data to fill or overflow the intermediate\r
98 // buffer. So we append |Rem| bytes and process the block,\r
99 // leaving the rest for later processing.\r
100 //\r
101 memcpy (Context->buf + Num, DataCopy, Rem);\r
102 DataCopy += Rem;\r
103 DataSize -= Rem;\r
104 (void)SHA3_absorb (Context->A, Context->buf, BlockSize, BlockSize);\r
105 Context->num = 0;\r
106 // Context->buf is processed, Context->num is guaranteed to be zero.\r
107 }\r
108\r
109 if (DataSize >= BlockSize) {\r
110 Rem = SHA3_absorb (Context->A, DataCopy, DataSize, BlockSize);\r
111 } else {\r
112 Rem = DataSize;\r
113 }\r
114\r
115 if (Rem > 0) {\r
116 memcpy (Context->buf, DataCopy + DataSize - Rem, Rem);\r
117 Context->num = Rem;\r
118 }\r
119\r
120 return 1;\r
121}\r
122\r
123/**\r
124 Completes computation of Sha3 message digest.\r
125\r
126 This function completes sha3 hash computation and retrieves the digest value into\r
127 the specified memory. After this function has been called, the keccak context cannot\r
128 be used again.\r
129\r
130 @param[in, out] Context Pointer to the keccak context.\r
131 @param[out] MessageDigest Pointer to a buffer that receives the message digest.\r
132\r
133 @retval 1 Meaasge digest computation succeeded.\r
134**/\r
135UINT8\r
136EFIAPI\r
137Sha3Final (\r
138 IN OUT Keccak1600_Ctx *Context,\r
139 OUT UINT8 *MessageDigest\r
140 )\r
141{\r
142 UINTN BlockSize;\r
143 UINTN Num;\r
144\r
145 BlockSize = Context->block_size;\r
146 Num = Context->num;\r
147\r
148 if (Context->md_size == 0) {\r
149 return 1;\r
150 }\r
151\r
152 //\r
153 // Pad the data with 10*1. Note that |Num| can be |BlockSize - 1|\r
154 // in which case both byte operations below are performed on\r
155 // same byte.\r
156 //\r
157 memset (Context->buf + Num, 0, BlockSize - Num);\r
158 Context->buf[Num] = Context->pad;\r
159 Context->buf[BlockSize - 1] |= 0x80;\r
160\r
161 (void)SHA3_absorb (Context->A, Context->buf, BlockSize, BlockSize);\r
162\r
163 SHA3_squeeze (Context->A, MessageDigest, Context->md_size, BlockSize);\r
164\r
165 return 1;\r
166}\r