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 /** Transport Layer Security (TLS) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SECURE_SOURCE_CODE
24
25 #include "nx_crypto_tls_prf_sha384.h"
26
27 /**************************************************************************/
28 /* */
29 /* FUNCTION RELEASE */
30 /* */
31 /* _nx_crypto_method_prf_sha384_init PORTABLE C */
32 /* 6.3.0 */
33 /* AUTHOR */
34 /* */
35 /* Timothy Stapko, Microsoft Corporation */
36 /* */
37 /* DESCRIPTION */
38 /* */
39 /* This function initializes the PRF crypto module with SHA384. */
40 /* */
41 /* INPUT */
42 /* */
43 /* method Crypto Method Object */
44 /* key Key */
45 /* key_size_in_bits Size of the key, in bits */
46 /* handle Handle, specified by user */
47 /* crypto_metadata Metadata area */
48 /* crypto_metadata_size Size of the metadata area */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* status Completion status */
53 /* */
54 /* CALLS */
55 /* */
56 /* None */
57 /* */
58 /* CALLED BY */
59 /* */
60 /* Application Code */
61 /* */
62 /* RELEASE HISTORY */
63 /* */
64 /* DATE NAME DESCRIPTION */
65 /* */
66 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
67 /* 09-30-2020 Timothy Stapko Modified comment(s), */
68 /* resulting in version 6.1 */
69 /* 10-31-2023 Yanwu Cai Modified comment(s), */
70 /* resulting in version 6.3.0 */
71 /* */
72 /**************************************************************************/
_nx_crypto_method_prf_sha384_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)73 NX_CRYPTO_KEEP UINT _nx_crypto_method_prf_sha384_init(struct NX_CRYPTO_METHOD_STRUCT *method,
74 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
75 VOID **handle,
76 VOID *crypto_metadata,
77 ULONG crypto_metadata_size)
78 {
79 NX_CRYPTO_TLS_PRF_SHA384 *prf;
80 NX_CRYPTO_PHASH *phash;
81
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_TLS_PRF_SHA384))
98 {
99 return(NX_CRYPTO_PTR_ERROR);
100 }
101
102 /* Get our control block. */
103 prf = (NX_CRYPTO_TLS_PRF_SHA384 *)crypto_metadata;
104 phash = &(prf -> nx_secure_tls_prf_phash_info);
105
106 /* Set the secret using the key value. */
107 phash -> nx_crypto_phash_secret = key;
108 /* This is the length of secret in bytes actually */
109 phash -> nx_crypto_phash_secret_length = key_size_in_bits;
110
111 return(NX_CRYPTO_SUCCESS);
112 }
113
114
115 /**************************************************************************/
116 /* */
117 /* FUNCTION RELEASE */
118 /* */
119 /* _nx_crypto_method_prf_sha384_cleanup PORTABLE C */
120 /* 6.1 */
121 /* AUTHOR */
122 /* */
123 /* Timothy Stapko, Microsoft Corporation */
124 /* */
125 /* DESCRIPTION */
126 /* */
127 /* This function cleans up the crypto metadata. */
128 /* */
129 /* INPUT */
130 /* */
131 /* crypto_metadata Crypto metadata */
132 /* */
133 /* OUTPUT */
134 /* */
135 /* status Completion status */
136 /* */
137 /* CALLS */
138 /* */
139 /* NX_CRYPTO_MEMSET Set the memory */
140 /* */
141 /* CALLED BY */
142 /* */
143 /* Application Code */
144 /* */
145 /* RELEASE HISTORY */
146 /* */
147 /* DATE NAME DESCRIPTION */
148 /* */
149 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
150 /* 09-30-2020 Timothy Stapko Modified comment(s), */
151 /* resulting in version 6.1 */
152 /* */
153 /**************************************************************************/
_nx_crypto_method_prf_sha384_cleanup(VOID * crypto_metadata)154 NX_CRYPTO_KEEP UINT _nx_crypto_method_prf_sha384_cleanup(VOID *crypto_metadata)
155 {
156
157 NX_CRYPTO_STATE_CHECK
158
159 #ifdef NX_SECURE_KEY_CLEAR
160 if (!crypto_metadata)
161 return (NX_CRYPTO_SUCCESS);
162
163 /* Clean up the crypto metadata. */
164 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_TLS_PRF_SHA384));
165 #else
166 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
167 #endif/* NX_SECURE_KEY_CLEAR */
168
169 return(NX_CRYPTO_SUCCESS);
170 }
171
172
173 /**************************************************************************/
174 /* */
175 /* FUNCTION RELEASE */
176 /* */
177 /* _nx_crypto_method_prf_sha384_operation PORTABLE C */
178 /* 6.3.0 */
179 /* AUTHOR */
180 /* */
181 /* Timothy Stapko, Microsoft Corporation */
182 /* */
183 /* DESCRIPTION */
184 /* */
185 /* This function encrypts and decrypts a message using */
186 /* the PRF SHA384 algorithm. */
187 /* */
188 /* INPUT */
189 /* */
190 /* op PRF operation */
191 /* handle Crypto handle */
192 /* method Cryption Method Object */
193 /* key Encryption Key */
194 /* key_size_in_bits Key size in bits */
195 /* input Input data */
196 /* input_length_in_byte Input data size */
197 /* iv_ptr Initial vector */
198 /* output Output buffer */
199 /* output_length_in_byte Output buffer size */
200 /* crypto_metadata Metadata area */
201 /* crypto_metadata_size Metadata area size */
202 /* packet_ptr Pointer to packet */
203 /* nx_crypto_hw_process_callback Callback function pointer */
204 /* */
205 /* OUTPUT */
206 /* */
207 /* status Completion status */
208 /* */
209 /* CALLS */
210 /* */
211 /* _nx_crypto_phash_process Implement the PHASH process */
212 /* */
213 /* CALLED BY */
214 /* */
215 /* Application Code */
216 /* */
217 /* RELEASE HISTORY */
218 /* */
219 /* DATE NAME DESCRIPTION */
220 /* */
221 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
222 /* 09-30-2020 Timothy Stapko Modified comment(s), improved */
223 /* buffer length verification, */
224 /* verified memcpy use cases, */
225 /* resulting in version 6.1 */
226 /* 10-31-2023 Yanwu Cai Modified comment(s), */
227 /* resulting in version 6.3.0 */
228 /* */
229 /**************************************************************************/
_nx_crypto_method_prf_sha384_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))230 NX_CRYPTO_KEEP UINT _nx_crypto_method_prf_sha384_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
231 VOID *handle, /* Crypto handler */
232 struct NX_CRYPTO_METHOD_STRUCT *method,
233 UCHAR *key,
234 NX_CRYPTO_KEY_SIZE key_size_in_bits,
235 UCHAR *input,
236 ULONG input_length_in_byte,
237 UCHAR *iv_ptr,
238 UCHAR *output,
239 ULONG output_length_in_byte,
240 VOID *crypto_metadata,
241 ULONG crypto_metadata_size,
242 VOID *packet_ptr,
243 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
244 {
245 UINT status;
246 NX_CRYPTO_TLS_PRF_SHA384 *prf;
247 NX_CRYPTO_PHASH *phash;
248
249 NX_CRYPTO_PARAMETER_NOT_USED(handle);
250 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
251 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
252 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
253
254 NX_CRYPTO_STATE_CHECK
255
256 /* Verify the metadata address is 4-byte aligned. */
257 if((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
258 {
259 return(NX_CRYPTO_PTR_ERROR);
260 }
261
262 if(crypto_metadata_size < sizeof(NX_CRYPTO_TLS_PRF_SHA384))
263 {
264 return(NX_CRYPTO_PTR_ERROR);
265 }
266
267 /* This must be a PRF operation. */
268 if (op != NX_CRYPTO_PRF)
269 {
270 return(NX_CRYPTO_NOT_SUCCESSFUL);
271 }
272
273 /* Get our control block. */
274 prf = (NX_CRYPTO_TLS_PRF_SHA384 *)crypto_metadata;
275 phash = &(prf -> nx_secure_tls_prf_phash_info);
276
277 /* Install the label_seed_buffer to the phash structure as the buffer of phash seed. */
278 phash -> nx_crypto_phash_seed = prf -> nx_secure_tls_prf_label_seed_buffer;
279 if ((key_size_in_bits + input_length_in_byte) > sizeof(prf -> nx_secure_tls_prf_label_seed_buffer))
280 {
281 return(NX_CRYPTO_SIZE_ERROR);
282 }
283
284 /* Concatenate label and seed. */
285 NX_CRYPTO_MEMCPY(phash -> nx_crypto_phash_seed, key, key_size_in_bits); /* Use case of memcpy is verified. */
286 NX_CRYPTO_MEMCPY(&phash -> nx_crypto_phash_seed[key_size_in_bits], input, input_length_in_byte); /* Use case of memcpy is verified. */
287 phash -> nx_crypto_phash_seed_length = key_size_in_bits + input_length_in_byte;
288
289 /* Install the temp_A_buffer to the phash structure. */
290 phash -> nx_crypto_phash_temp_A = prf -> nx_secure_tls_prf_temp_A_buffer;
291 phash -> nx_crypto_phash_temp_A_size = sizeof(prf -> nx_secure_tls_prf_temp_A_buffer);
292
293 /* Install the hmac method to the phash structure. */
294 phash -> nx_crypto_hmac_method = &crypto_method_hmac_sha384;
295
296 /* Install metadata buffer for the hmac method. */
297 phash -> nx_crypto_hmac_metadata = prf -> nx_secure_tls_prf_hmac_metadata_area;
298 phash -> nx_crypto_hmac_metadata_size = sizeof(prf -> nx_secure_tls_prf_hmac_metadata_area);
299
300 /* Install the buffer for hmac output. */
301 phash -> nx_crypto_hmac_output = prf -> nx_secure_tls_prf_temp_hmac_output_buffer;
302 phash -> nx_crypto_hmac_output_size = sizeof(prf -> nx_secure_tls_prf_temp_hmac_output_buffer);
303
304 /* Clear the output buffer for the generic phash routine will show the output by XOR. */
305 NX_CRYPTO_MEMSET(output, 0, output_length_in_byte);
306
307 /* Invoke generic phash routine. */
308 status = _nx_crypto_phash(phash, output, output_length_in_byte);
309
310 return status;
311 }
312