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