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