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