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