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 /**   Crypto Self-test                                                    */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_CRYPTO_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 #include "nx_crypto_method_self_test.h"
28 
29 #ifdef NX_CRYPTO_SELF_TEST
30 
31 /* 7fc1c44f7f432927f404922107eae9d10b26ed35527d66d9858c58be388c98a1
32    981a1b7c098a26747a723b171cae16670de0c320a82b1cfcbe77d2f807a217b5 */
33 static UCHAR test_public_key[] = {
34 0x04,
35 0x7f, 0xc1, 0xc4, 0x4f, 0x7f, 0x43, 0x29, 0x27, 0xf4, 0x04, 0x92, 0x21, 0x07, 0xea, 0xe9, 0xd1,
36 0x0b, 0x26, 0xed, 0x35, 0x52, 0x7d, 0x66, 0xd9, 0x85, 0x8c, 0x58, 0xbe, 0x38, 0x8c, 0x98, 0xa1,
37 0x98, 0x1a, 0x1b, 0x7c, 0x09, 0x8a, 0x26, 0x74, 0x7a, 0x72, 0x3b, 0x17, 0x1c, 0xae, 0x16, 0x67,
38 0x0d, 0xe0, 0xc3, 0x20, 0xa8, 0x2b, 0x1c, 0xfc, 0xbe, 0x77, 0xd2, 0xf8, 0x07, 0xa2, 0x17, 0xb5,
39 };
40 static UCHAR test_public_key_len =sizeof(test_public_key);
41 
42 /* 16439d147442b843cf849727211ba081e9f6275c0407d741652ffd9ec285ee2e */
43 static UCHAR test_private_key[] = {
44 0x16, 0x43, 0x9d, 0x14, 0x74, 0x42, 0xb8, 0x43, 0xcf, 0x84, 0x97, 0x27, 0x21, 0x1b, 0xa0, 0x81,
45 0xe9, 0xf6, 0x27, 0x5c, 0x04, 0x07, 0xd7, 0x41, 0x65, 0x2f, 0xfd, 0x9e, 0xc2, 0x85, 0xee, 0x2e,
46 };
47 static UCHAR test_private_key_len =sizeof(test_private_key);
48 
49 static UCHAR local_public_key[128];
50 static UINT local_public_key_len;
51 
52 static UCHAR shared_secret[128];
53 static UINT shared_secret_len;
54 
55 static UCHAR output[128];
56 
57 extern NX_CRYPTO_METHOD crypto_method_ec_secp256;
58 
59 /**************************************************************************/
60 /*                                                                        */
61 /*  FUNCTION                                               RELEASE        */
62 /*                                                                        */
63 /*    nx_crypto_method_self_test_ecdh                     PORTABLE C      */
64 /*                                                           6.1.7        */
65 /*  AUTHOR                                                                */
66 /*                                                                        */
67 /*    Timothy Stapko, Microsoft Corporation                               */
68 /*                                                                        */
69 /*  DESCRIPTION                                                           */
70 /*                                                                        */
71 /*    This function performs the Known Answer Test for ECDH crypto method.*/
72 /*                                                                        */
73 /*  INPUT                                                                 */
74 /*                                                                        */
75 /*    method_ptr                            Pointer to the crypto method  */
76 /*                                            to be tested.               */
77 /*                                                                        */
78 /*  OUTPUT                                                                */
79 /*                                                                        */
80 /*    status                                Completion status             */
81 /*                                                                        */
82 /*  CALLS                                                                 */
83 /*                                                                        */
84 /*    None                                                                */
85 /*                                                                        */
86 /*  CALLED BY                                                             */
87 /*                                                                        */
88 /*    Application Code                                                    */
89 /*                                                                        */
90 /*  RELEASE HISTORY                                                       */
91 /*                                                                        */
92 /*    DATE              NAME                      DESCRIPTION             */
93 /*                                                                        */
94 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
95 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
96 /*                                            resulting in version 6.1    */
97 /*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
98 /*                                            renamed FIPS symbol to      */
99 /*                                            self-test,                  */
100 /*                                            resulting in version 6.1.7  */
101 /*                                                                        */
102 /**************************************************************************/
_nx_crypto_method_self_test_ecdh(NX_CRYPTO_METHOD * crypto_method_ecdh,VOID * metadata,UINT metadata_size)103 NX_CRYPTO_KEEP UINT _nx_crypto_method_self_test_ecdh(NX_CRYPTO_METHOD *crypto_method_ecdh,
104                                                       VOID *metadata, UINT metadata_size)
105 {
106 NX_CRYPTO_METHOD *curve_method;
107 UINT   status;
108 NX_CRYPTO_EXTENDED_OUTPUT extended_output;
109 
110 
111     /* Validate the crypto method */
112     if(crypto_method_ecdh == NX_CRYPTO_NULL)
113         return(NX_CRYPTO_PTR_ERROR);
114 
115     /* Set the test data.  */
116     curve_method = &crypto_method_ec_secp256;
117 
118     /* Clear the output buffer.  */
119     NX_CRYPTO_MEMSET(output, 0, sizeof(output));
120 
121     /* Call the crypto initialization function.  */
122     if (crypto_method_ecdh -> nx_crypto_init)
123     {
124         status = crypto_method_ecdh -> nx_crypto_init(crypto_method_ecdh,
125                                                       NX_CRYPTO_NULL,
126                                                       0,
127                                                       NX_CRYPTO_NULL,
128                                                       metadata,
129                                                       metadata_size);
130 
131         if (status != NX_CRYPTO_SUCCESS)
132         {
133             return(status);
134         }
135     }
136 
137     if (crypto_method_ecdh -> nx_crypto_operation == NX_CRYPTO_NULL)
138     {
139         return(NX_CRYPTO_PTR_ERROR);
140     }
141 
142     /* Set EC curve.  */
143     status = crypto_method_ecdh -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET,
144                                                        NX_CRYPTO_NULL,
145                                                        crypto_method_ecdh,
146                                                        NX_CRYPTO_NULL,
147                                                        0,
148                                                        (UCHAR *)curve_method,
149                                                        sizeof(NX_CRYPTO_METHOD *),
150                                                        NX_CRYPTO_NULL,
151                                                        NX_CRYPTO_NULL,
152                                                        0,
153                                                        metadata,
154                                                        metadata_size,
155                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
156     if (status != NX_CRYPTO_SUCCESS)
157     {
158         return(status);
159     }
160 
161     /* Generate local public key.  */
162     extended_output.nx_crypto_extended_output_data = local_public_key;
163     extended_output.nx_crypto_extended_output_length_in_byte = sizeof(local_public_key);
164     status = crypto_method_ecdh -> nx_crypto_operation(NX_CRYPTO_DH_SETUP,
165                                                        NX_CRYPTO_NULL,
166                                                        crypto_method_ecdh,
167                                                        NX_CRYPTO_NULL,
168                                                        0,
169                                                        NX_CRYPTO_NULL,
170                                                        0,
171                                                        NX_CRYPTO_NULL,
172                                                        (UCHAR *)&extended_output,
173                                                        sizeof(extended_output),
174                                                        metadata,
175                                                        metadata_size,
176                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
177     if (status != NX_CRYPTO_SUCCESS)
178     {
179         return(status);
180     }
181     local_public_key_len = extended_output.nx_crypto_extended_output_actual_size;
182 
183     /* Calculate shared secret using the test public key.  */
184     extended_output.nx_crypto_extended_output_data = shared_secret;
185     extended_output.nx_crypto_extended_output_length_in_byte = sizeof(shared_secret);
186     status = crypto_method_ecdh -> nx_crypto_operation(NX_CRYPTO_DH_CALCULATE,
187                                                        NX_CRYPTO_NULL,
188                                                        crypto_method_ecdh,
189                                                        NX_CRYPTO_NULL,
190                                                        0,
191                                                        test_public_key,
192                                                        test_public_key_len,
193                                                        NX_CRYPTO_NULL,
194                                                        (UCHAR *)&extended_output,
195                                                        sizeof(extended_output),
196                                                        metadata,
197                                                        metadata_size,
198                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
199     /* Check the status.  */
200     if(status != NX_CRYPTO_SUCCESS)
201     {
202         return(status);
203     }
204     shared_secret_len = extended_output.nx_crypto_extended_output_actual_size;
205 
206     if (crypto_method_ecdh -> nx_crypto_cleanup)
207     {
208         status = crypto_method_ecdh -> nx_crypto_cleanup(metadata);
209 
210         if (status != NX_CRYPTO_SUCCESS)
211         {
212             return(status);
213         }
214     }
215 
216     /* Verify.  */
217     /* Call the crypto initialization function.  */
218     if (crypto_method_ecdh -> nx_crypto_init)
219     {
220         status = crypto_method_ecdh -> nx_crypto_init(crypto_method_ecdh,
221                                                       NX_CRYPTO_NULL,
222                                                       0,
223                                                       NX_CRYPTO_NULL,
224                                                       metadata,
225                                                       metadata_size);
226 
227         if (status != NX_CRYPTO_SUCCESS)
228         {
229             return(status);
230         }
231     }
232 
233     /* Set EC curve.  */
234     status = crypto_method_ecdh -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET,
235                                                        NX_CRYPTO_NULL,
236                                                        crypto_method_ecdh,
237                                                        NX_CRYPTO_NULL,
238                                                        0,
239                                                        (UCHAR *)curve_method,
240                                                        sizeof(NX_CRYPTO_METHOD *),
241                                                        NX_CRYPTO_NULL,
242                                                        NX_CRYPTO_NULL,
243                                                        0,
244                                                        metadata,
245                                                        metadata_size,
246                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
247     if (status != NX_CRYPTO_SUCCESS)
248     {
249         return(status);
250     }
251 
252     /* Import the test private key.  */
253     status = crypto_method_ecdh -> nx_crypto_operation(NX_CRYPTO_DH_KEY_PAIR_IMPORT,
254                                                        NX_CRYPTO_NULL,
255                                                        crypto_method_ecdh,
256                                                        test_private_key,
257                                                        (NX_CRYPTO_KEY_SIZE)(test_private_key_len << 3),
258                                                        test_public_key,
259                                                        test_public_key_len,
260                                                        NX_CRYPTO_NULL,
261                                                        NX_CRYPTO_NULL,
262                                                        0,
263                                                        metadata,
264                                                        metadata_size,
265                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
266     if (status != NX_CRYPTO_SUCCESS)
267     {
268         return(status);
269     }
270 
271     /* Calculate the shared secret using the local public key.  */
272     extended_output.nx_crypto_extended_output_data = output;
273     extended_output.nx_crypto_extended_output_length_in_byte = sizeof(output);
274     status = crypto_method_ecdh -> nx_crypto_operation(NX_CRYPTO_DH_CALCULATE,
275                                                        NX_CRYPTO_NULL,
276                                                        crypto_method_ecdh,
277                                                        NX_CRYPTO_NULL,
278                                                        0,
279                                                        local_public_key,
280                                                        local_public_key_len,
281                                                        NX_CRYPTO_NULL,
282                                                        (UCHAR *)&extended_output,
283                                                        sizeof(extended_output),
284                                                        metadata,
285                                                        metadata_size,
286                                                        NX_CRYPTO_NULL, NX_CRYPTO_NULL);
287     if (status != NX_CRYPTO_SUCCESS)
288     {
289         return(status);
290     }
291 
292     /* Validate the output.  */
293     if (extended_output.nx_crypto_extended_output_actual_size != shared_secret_len)
294     {
295         return(NX_CRYPTO_NOT_SUCCESSFUL);
296     }
297 
298     if(NX_CRYPTO_MEMCMP(output, shared_secret, extended_output.nx_crypto_extended_output_actual_size) != 0)
299     {
300         return(NX_CRYPTO_NOT_SUCCESSFUL);
301     }
302 
303     if (crypto_method_ecdh -> nx_crypto_cleanup)
304     {
305         status = crypto_method_ecdh -> nx_crypto_cleanup(metadata);
306     }
307 
308     return(status);
309 }
310 #endif
311