]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Hash/CryptCShake256.c
CryptoPkg: Add new hash algorithm ParallelHash256HashAll in BaseCryptLib.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Hash / CryptCShake256.c
CommitLineData
c1e66210
ZL
1/** @file\r
2 cSHAKE-256 Digest Wrapper Implementations.\r
3\r
4Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "CryptParallelHash.h"\r
10\r
11#define CSHAKE256_SECURITY_STRENGTH 256\r
12#define CSHAKE256_RATE_IN_BYTES 136\r
13\r
14CONST CHAR8 mZeroPadding[CSHAKE256_RATE_IN_BYTES] = { 0 };\r
15\r
16/**\r
17 CShake256 initial function.\r
18\r
19 Initializes user-supplied memory pointed by CShake256Context as cSHAKE-256 hash context for\r
20 subsequent use.\r
21\r
22 @param[out] CShake256Context Pointer to cSHAKE-256 context being initialized.\r
23 @param[in] OutputLen The desired number of output length in bytes.\r
24 @param[in] Name Pointer to the function name string.\r
25 @param[in] NameLen The length of the function name in bytes.\r
26 @param[in] Customization Pointer to the customization string.\r
27 @param[in] CustomizationLen The length of the customization string in bytes.\r
28\r
29 @retval TRUE cSHAKE-256 context initialization succeeded.\r
30 @retval FALSE cSHAKE-256 context initialization failed.\r
31 @retval FALSE This interface is not supported.\r
32**/\r
33BOOLEAN\r
34EFIAPI\r
35CShake256Init (\r
36 OUT VOID *CShake256Context,\r
37 IN UINTN OutputLen,\r
38 IN CONST VOID *Name,\r
39 IN UINTN NameLen,\r
40 IN CONST VOID *Customization,\r
41 IN UINTN CustomizationLen\r
42 )\r
43{\r
44 BOOLEAN Status;\r
45 UINT8 EncBuf[sizeof (UINTN) + 1];\r
46 UINTN EncLen;\r
47 UINTN AbsorbLen;\r
48 UINTN PadLen;\r
49\r
50 //\r
51 // Check input parameters.\r
52 //\r
53 if ((CShake256Context == NULL) || (OutputLen == 0) || ((NameLen != 0) && (Name == NULL)) || ((CustomizationLen != 0) && (Customization == NULL))) {\r
54 return FALSE;\r
55 }\r
56\r
57 //\r
58 // Initialize KECCAK context with pad value and block size.\r
59 //\r
60 if ((NameLen == 0) && (CustomizationLen == 0)) {\r
61 //\r
62 // When N and S are both empty strings, cSHAKE(X, L, N, S) is equivalent to\r
63 // SHAKE as defined in FIPS 202.\r
64 //\r
65 Status = (BOOLEAN)KeccakInit (\r
66 (Keccak1600_Ctx *)CShake256Context,\r
67 '\x1f',\r
68 (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,\r
69 OutputLen\r
70 );\r
71\r
72 return Status;\r
73 } else {\r
74 Status = (BOOLEAN)KeccakInit (\r
75 (Keccak1600_Ctx *)CShake256Context,\r
76 '\x04',\r
77 (KECCAK1600_WIDTH - CSHAKE256_SECURITY_STRENGTH * 2) / 8,\r
78 OutputLen\r
79 );\r
80 if (!Status) {\r
81 return FALSE;\r
82 }\r
83\r
84 AbsorbLen = 0;\r
85 //\r
86 // Absorb Absorb bytepad(.., rate).\r
87 //\r
88 EncLen = LeftEncode (EncBuf, CSHAKE256_RATE_IN_BYTES);\r
89 Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, EncBuf, EncLen);\r
90 if (!Status) {\r
91 return FALSE;\r
92 }\r
93\r
94 AbsorbLen += EncLen;\r
95\r
96 //\r
97 // Absorb encode_string(N).\r
98 //\r
99 EncLen = LeftEncode (EncBuf, NameLen * 8);\r
100 Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, EncBuf, EncLen);\r
101 if (!Status) {\r
102 return FALSE;\r
103 }\r
104\r
105 AbsorbLen += EncLen;\r
106 Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, Name, NameLen);\r
107 if (!Status) {\r
108 return FALSE;\r
109 }\r
110\r
111 AbsorbLen += NameLen;\r
112\r
113 //\r
114 // Absorb encode_string(S).\r
115 //\r
116 EncLen = LeftEncode (EncBuf, CustomizationLen * 8);\r
117 Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, EncBuf, EncLen);\r
118 if (!Status) {\r
119 return FALSE;\r
120 }\r
121\r
122 AbsorbLen += EncLen;\r
123 Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, Customization, CustomizationLen);\r
124 if (!Status) {\r
125 return FALSE;\r
126 }\r
127\r
128 AbsorbLen += CustomizationLen;\r
129\r
130 //\r
131 // Absorb zero padding up to rate.\r
132 //\r
133 PadLen = CSHAKE256_RATE_IN_BYTES - AbsorbLen % CSHAKE256_RATE_IN_BYTES;\r
134 Status = (BOOLEAN)Sha3Update ((Keccak1600_Ctx *)CShake256Context, mZeroPadding, PadLen);\r
135 if (!Status) {\r
136 return FALSE;\r
137 }\r
138\r
139 return TRUE;\r
140 }\r
141}\r
142\r
143/**\r
144 Digests the input data and updates cSHAKE-256 context.\r
145\r
146 This function performs cSHAKE-256 digest on a data buffer of the specified size.\r
147 It can be called multiple times to compute the digest of long or discontinuous data streams.\r
148 cSHAKE-256 context should be already correctly initialized by CShake256Init(), and should not be finalized\r
149 by CShake256Final(). Behavior with invalid context is undefined.\r
150\r
151 @param[in, out] CShake256Context Pointer to the cSHAKE-256 context.\r
152 @param[in] Data Pointer to the buffer containing the data to be hashed.\r
153 @param[in] DataSize Size of Data buffer in bytes.\r
154\r
155 @retval TRUE cSHAKE-256 data digest succeeded.\r
156 @retval FALSE cSHAKE-256 data digest failed.\r
157 @retval FALSE This interface is not supported.\r
158\r
159**/\r
160BOOLEAN\r
161EFIAPI\r
162CShake256Update (\r
163 IN OUT VOID *CShake256Context,\r
164 IN CONST VOID *Data,\r
165 IN UINTN DataSize\r
166 )\r
167{\r
168 //\r
169 // Check input parameters.\r
170 //\r
171 if (CShake256Context == NULL) {\r
172 return FALSE;\r
173 }\r
174\r
175 //\r
176 // Check invalid parameters, in case that only DataLength was checked in OpenSSL.\r
177 //\r
178 if ((Data == NULL) && (DataSize != 0)) {\r
179 return FALSE;\r
180 }\r
181\r
182 return (BOOLEAN)(Sha3Update ((Keccak1600_Ctx *)CShake256Context, Data, DataSize));\r
183}\r
184\r
185/**\r
186 Completes computation of the cSHAKE-256 digest value.\r
187\r
188 This function completes cSHAKE-256 hash computation and retrieves the digest value into\r
189 the specified memory. After this function has been called, the cSHAKE-256 context cannot\r
190 be used again.\r
191 cSHAKE-256 context should be already correctly initialized by CShake256Init(), and should not be\r
192 finalized by CShake256Final(). Behavior with invalid cSHAKE-256 context is undefined.\r
193\r
194 @param[in, out] CShake256Context Pointer to the cSHAKE-256 context.\r
195 @param[out] HashValue Pointer to a buffer that receives the cSHAKE-256 digest\r
196 value.\r
197\r
198 @retval TRUE cSHAKE-256 digest computation succeeded.\r
199 @retval FALSE cSHAKE-256 digest computation failed.\r
200 @retval FALSE This interface is not supported.\r
201\r
202**/\r
203BOOLEAN\r
204EFIAPI\r
205CShake256Final (\r
206 IN OUT VOID *CShake256Context,\r
207 OUT UINT8 *HashValue\r
208 )\r
209{\r
210 //\r
211 // Check input parameters.\r
212 //\r
213 if ((CShake256Context == NULL) || (HashValue == NULL)) {\r
214 return FALSE;\r
215 }\r
216\r
217 //\r
218 // cSHAKE-256 Hash Finalization.\r
219 //\r
220 return (BOOLEAN)(Sha3Final ((Keccak1600_Ctx *)CShake256Context, HashValue));\r
221}\r
222\r
223/**\r
224 Computes the CSHAKE-256 message digest of a input data buffer.\r
225\r
226 This function performs the CSHAKE-256 message digest of a given data buffer, and places\r
227 the digest value into the specified memory.\r
228\r
229 @param[in] Data Pointer to the buffer containing the data to be hashed.\r
230 @param[in] DataSize Size of Data buffer in bytes.\r
231 @param[in] OutputLen Size of output in bytes.\r
232 @param[in] Name Pointer to the function name string.\r
233 @param[in] NameLen Size of the function name in bytes.\r
234 @param[in] Customization Pointer to the customization string.\r
235 @param[in] CustomizationLen Size of the customization string in bytes.\r
236 @param[out] HashValue Pointer to a buffer that receives the CSHAKE-256 digest\r
237 value.\r
238\r
239 @retval TRUE CSHAKE-256 digest computation succeeded.\r
240 @retval FALSE CSHAKE-256 digest computation failed.\r
241 @retval FALSE This interface is not supported.\r
242\r
243**/\r
244BOOLEAN\r
245EFIAPI\r
246CShake256HashAll (\r
247 IN CONST VOID *Data,\r
248 IN UINTN DataSize,\r
249 IN UINTN OutputLen,\r
250 IN CONST VOID *Name,\r
251 IN UINTN NameLen,\r
252 IN CONST VOID *Customization,\r
253 IN UINTN CustomizationLen,\r
254 OUT UINT8 *HashValue\r
255 )\r
256{\r
257 BOOLEAN Status;\r
258 Keccak1600_Ctx Ctx;\r
259\r
260 //\r
261 // Check input parameters.\r
262 //\r
263 if (HashValue == NULL) {\r
264 return FALSE;\r
265 }\r
266\r
267 if ((Data == NULL) && (DataSize != 0)) {\r
268 return FALSE;\r
269 }\r
270\r
271 Status = CShake256Init (&Ctx, OutputLen, Name, NameLen, Customization, CustomizationLen);\r
272 if (!Status) {\r
273 return FALSE;\r
274 }\r
275\r
276 Status = CShake256Update (&Ctx, Data, DataSize);\r
277 if (!Status) {\r
278 return FALSE;\r
279 }\r
280\r
281 return CShake256Final (&Ctx, HashValue);\r
282}\r