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