1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Crypto Component */
16 /** */
17 /** HMAC SHA5 Digest Algorithm (SHA5) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #include "nx_crypto_sha5.h"
23 #include "nx_crypto_hmac_sha5.h"
24 #include "nx_crypto_hmac.h"
25
26
27 /**************************************************************************/
28 /* */
29 /* FUNCTION RELEASE */
30 /* */
31 /* _nx_crypto_method_hmac_sha512_init PORTABLE C */
32 /* 6.3.0 */
33 /* AUTHOR */
34 /* */
35 /* Timothy Stapko, Microsoft Corporation */
36 /* */
37 /* DESCRIPTION */
38 /* */
39 /* This function is the common crypto method init callback for */
40 /* Microsoft supported HMAC SHA512 cryptographic algorithm. */
41 /* */
42 /* INPUT */
43 /* */
44 /* method Pointer to crypto method */
45 /* key Pointer to key */
46 /* key_size_in_bits Length of key size in bits */
47 /* handler Returned crypto handler */
48 /* crypto_metadata Metadata area */
49 /* crypto_metadata_size Size of the metadata area */
50 /* */
51 /* OUTPUT */
52 /* */
53 /* status Completion status */
54 /* */
55 /* CALLS */
56 /* */
57 /* None */
58 /* */
59 /* CALLED BY */
60 /* */
61 /* Application Code */
62 /* */
63 /* RELEASE HISTORY */
64 /* */
65 /* DATE NAME DESCRIPTION */
66 /* */
67 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
68 /* 09-30-2020 Timothy Stapko Modified comment(s), */
69 /* resulting in version 6.1 */
70 /* 10-31-2023 Yanwu Cai Modified comment(s), */
71 /* resulting in version 6.3.0 */
72 /* */
73 /**************************************************************************/
_nx_crypto_method_hmac_sha512_init(struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,VOID ** handle,VOID * crypto_metadata,ULONG crypto_metadata_size)74 NX_CRYPTO_KEEP UINT _nx_crypto_method_hmac_sha512_init(struct NX_CRYPTO_METHOD_STRUCT *method,
75 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
76 VOID **handle,
77 VOID *crypto_metadata,
78 ULONG crypto_metadata_size)
79 {
80
81 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
82 NX_CRYPTO_PARAMETER_NOT_USED(handle);
83
84 NX_CRYPTO_STATE_CHECK
85
86 if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
87 {
88 return(NX_CRYPTO_PTR_ERROR);
89 }
90
91 /* Verify the metadata address is 4-byte aligned. */
92 if((((ULONG)crypto_metadata) & 0x3) != 0)
93 {
94 return(NX_CRYPTO_PTR_ERROR);
95 }
96
97 if(crypto_metadata_size < sizeof(NX_CRYPTO_SHA512_HMAC))
98 {
99 return(NX_CRYPTO_PTR_ERROR);
100 }
101
102 return(NX_CRYPTO_SUCCESS);
103 }
104
105
106 /**************************************************************************/
107 /* */
108 /* FUNCTION RELEASE */
109 /* */
110 /* _nx_crypto_method_hmac_sha512_cleanup PORTABLE C */
111 /* 6.1 */
112 /* AUTHOR */
113 /* */
114 /* Timothy Stapko, Microsoft Corporation */
115 /* */
116 /* DESCRIPTION */
117 /* */
118 /* This function cleans up the crypto metadata. */
119 /* */
120 /* INPUT */
121 /* */
122 /* crypto_metadata Crypto metadata */
123 /* */
124 /* OUTPUT */
125 /* */
126 /* status Completion status */
127 /* */
128 /* CALLS */
129 /* */
130 /* NX_CRYPTO_MEMSET Set the memory */
131 /* */
132 /* CALLED BY */
133 /* */
134 /* Application Code */
135 /* */
136 /* RELEASE HISTORY */
137 /* */
138 /* DATE NAME DESCRIPTION */
139 /* */
140 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
141 /* 09-30-2020 Timothy Stapko Modified comment(s), */
142 /* resulting in version 6.1 */
143 /* */
144 /**************************************************************************/
_nx_crypto_method_hmac_sha512_cleanup(VOID * crypto_metadata)145 NX_CRYPTO_KEEP UINT _nx_crypto_method_hmac_sha512_cleanup(VOID *crypto_metadata)
146 {
147
148 NX_CRYPTO_STATE_CHECK
149
150 #ifdef NX_SECURE_KEY_CLEAR
151 if (!crypto_metadata)
152 return (NX_CRYPTO_SUCCESS);
153
154 /* Clean up the crypto metadata. */
155 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_SHA512_HMAC));
156 #else
157 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
158 #endif/* NX_SECURE_KEY_CLEAR */
159
160 return(NX_CRYPTO_SUCCESS);
161 }
162
163
164 /**************************************************************************/
165 /* */
166 /* FUNCTION RELEASE */
167 /* */
168 /* _nx_crypto_method_hmac_sha512_operation PORTABLE C */
169 /* 6.3.0 */
170 /* AUTHOR */
171 /* */
172 /* Timothy Stapko, Microsoft Corporation */
173 /* */
174 /* DESCRIPTION */
175 /* */
176 /* This function handles HMAC SHA512 Authentication operation. */
177 /* */
178 /* INPUT */
179 /* */
180 /* op Operation Type */
181 /* Encrypt, Decrypt, Authenticate*/
182 /* handler Pointer to crypto context */
183 /* key Pointer to key */
184 /* key_size_in_bits Length of key size in bits */
185 /* input Input Stream */
186 /* input_length_in_byte Input Stream Length */
187 /* iv_ptr Initialized Vector */
188 /* output Output Stream */
189 /* output_length_in_byte Output Stream Length */
190 /* crypto_metadata Metadata area */
191 /* crypto_metadata_size Size of the metadata area */
192 /* packet_ptr Pointer to packet */
193 /* nx_crypto_hw_process_callback Callback function pointer */
194 /* */
195 /* OUTPUT */
196 /* */
197 /* status Completion status */
198 /* */
199 /* CALLS */
200 /* */
201 /* _nx_crypto_hmac Calculate the HMAC */
202 /* _nx_crypto_hmac_metadata_set Set HMAC metadata */
203 /* _nx_crypto_hmac_initialize Perform HMAC initialization */
204 /* _nx_crypto_hmac_update Perform HMAC update */
205 /* _nx_crypto_hmac_digest_calculate Calculate HMAC digest */
206 /* */
207 /* CALLED BY */
208 /* */
209 /* Application Code */
210 /* */
211 /* RELEASE HISTORY */
212 /* */
213 /* DATE NAME DESCRIPTION */
214 /* */
215 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
216 /* 09-30-2020 Timothy Stapko Modified comment(s), */
217 /* resulting in version 6.1 */
218 /* 10-31-2023 Yanwu Cai Modified comment(s), */
219 /* resulting in version 6.3.0 */
220 /* */
221 /**************************************************************************/
_nx_crypto_method_hmac_sha512_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))222 NX_CRYPTO_KEEP UINT _nx_crypto_method_hmac_sha512_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
223 VOID *handle, /* Crypto handler */
224 struct NX_CRYPTO_METHOD_STRUCT *method,
225 UCHAR *key,
226 NX_CRYPTO_KEY_SIZE key_size_in_bits,
227 UCHAR *input,
228 ULONG input_length_in_byte,
229 UCHAR *iv_ptr,
230 UCHAR *output,
231 ULONG output_length_in_byte,
232 VOID *crypto_metadata,
233 ULONG crypto_metadata_size,
234 VOID *packet_ptr,
235 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
236 {
237 UINT status = NX_CRYPTO_NOT_SUCCESSFUL;
238 NX_CRYPTO_SHA512_HMAC *ctx;
239 NX_CRYPTO_HMAC *hmac_metadata;
240 UINT icv_full_length;
241
242 NX_CRYPTO_PARAMETER_NOT_USED(handle);
243 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
244 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
245 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
246 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
247
248 NX_CRYPTO_STATE_CHECK
249
250 /* Verify the metadata address is 4-byte aligned. */
251 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
252 {
253 return(NX_CRYPTO_PTR_ERROR);
254 }
255
256 if(crypto_metadata_size < sizeof(NX_CRYPTO_SHA512_HMAC))
257 {
258 return(NX_CRYPTO_PTR_ERROR);
259 }
260
261 if (op != NX_CRYPTO_AUTHENTICATE && op != NX_CRYPTO_VERIFY && op != NX_CRYPTO_HASH_INITIALIZE &&
262 op != NX_CRYPTO_HASH_UPDATE && op != NX_CRYPTO_HASH_CALCULATE)
263 {
264 /* Incorrect Operation. */
265 return status;
266 }
267
268 if (method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512)
269 {
270 icv_full_length = NX_CRYPTO_HMAC_SHA512_ICV_FULL_LEN_IN_BITS;
271 }
272 else if (method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_384)
273 {
274 icv_full_length = NX_CRYPTO_HMAC_SHA384_ICV_FULL_LEN_IN_BITS;
275 }
276 else if (method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512_224)
277 {
278 icv_full_length = NX_CRYPTO_HMAC_SHA512_224_ICV_FULL_LEN_IN_BITS;
279 }
280 else if (method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_512_256)
281 {
282 icv_full_length = NX_CRYPTO_HMAC_SHA512_256_ICV_FULL_LEN_IN_BITS;
283 }
284 else
285 {
286 return(NX_CRYPTO_NOT_SUCCESSFUL);
287 }
288
289 ctx = (NX_CRYPTO_SHA512_HMAC *)crypto_metadata;
290 hmac_metadata = &ctx->nx_sha512_hmac_metadata;
291
292 _nx_crypto_hmac_metadata_set(hmac_metadata,
293 &(ctx -> nx_sha512_hmac_context),
294 method -> nx_crypto_algorithm,
295 NX_CRYPTO_SHA512_BLOCK_SIZE_IN_BYTES,
296 icv_full_length >> 3,
297 (UINT (*)(VOID *, UINT))_nx_crypto_sha512_initialize,
298 (UINT (*)(VOID *, UCHAR *, UINT))_nx_crypto_sha512_update,
299 (UINT (*)(VOID *, UCHAR *, UINT))_nx_crypto_sha512_digest_calculate);
300
301
302 switch (op)
303 {
304 case NX_CRYPTO_HASH_INITIALIZE:
305 if(key == NX_CRYPTO_NULL)
306 {
307 return(NX_CRYPTO_PTR_ERROR);
308 }
309
310 _nx_crypto_hmac_initialize(hmac_metadata, key, key_size_in_bits >> 3);
311 break;
312
313 case NX_CRYPTO_HASH_UPDATE:
314 _nx_crypto_hmac_update(hmac_metadata, input, input_length_in_byte);
315 break;
316
317 case NX_CRYPTO_HASH_CALCULATE:
318 _nx_crypto_hmac_digest_calculate(hmac_metadata, output,
319 (output_length_in_byte > (ULONG)((method -> nx_crypto_ICV_size_in_bits) >> 3) ?
320 ((method -> nx_crypto_ICV_size_in_bits) >> 3) : output_length_in_byte));
321 break;
322
323 default:
324 if(key == NX_CRYPTO_NULL)
325 {
326 return(NX_CRYPTO_PTR_ERROR);
327 }
328
329 _nx_crypto_hmac(hmac_metadata, input, input_length_in_byte, key, (key_size_in_bits >> 3), output,
330 (output_length_in_byte > (ULONG)((method -> nx_crypto_ICV_size_in_bits) >> 3) ?
331 ((method -> nx_crypto_ICV_size_in_bits) >> 3) : output_length_in_byte));
332 break;
333 }
334
335 return NX_CRYPTO_SUCCESS;
336 }
337
338