Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2022 Eriptic Technologies.
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0 or MIT
5 : : */
6 : :
7 : : #include <zephyr/kernel.h>
8 : : #include <zephyr/ztest.h>
9 : : #include <zephyr/debug/thread_analyzer.h>
10 : :
11 : : #include <edhoc.h>
12 : :
13 : : #include "edhoc_test_vectors_p256_v15.h"
14 : : #include "latency.h"
15 : :
16 : : uint8_t I_prk_exporter_buf[32];
17 : : struct byte_array I_prk_exporter = { .ptr = I_prk_exporter_buf,
18 : : .len = sizeof(I_prk_exporter_buf) };
19 : :
20 : : uint8_t I_master_secret_buf[16];
21 : : struct byte_array I_master_secret = { .ptr = I_master_secret_buf,
22 : : .len = sizeof(I_master_secret_buf) };
23 : :
24 : : uint8_t I_master_salt_buf[8];
25 : : struct byte_array I_master_salt = { .ptr = I_master_salt_buf,
26 : : .len = sizeof(I_master_salt_buf) };
27 : :
28 : : uint8_t I_PRK_out_buf[32];
29 : : struct byte_array I_PRK_out = { .ptr = I_PRK_out_buf,
30 : : .len = sizeof(I_PRK_out_buf) };
31 : :
32 : : uint8_t I_err_msg_buf[0];
33 : : struct byte_array I_err_msg = { .ptr = I_err_msg_buf,
34 : : .len = sizeof(I_err_msg_buf) };
35 : : /******************************************************************************/
36 : :
37 : : uint8_t R_prk_exporter_buf[32];
38 : : struct byte_array R_prk_exporter = { .ptr = R_prk_exporter_buf,
39 : : .len = sizeof(R_prk_exporter_buf) };
40 : :
41 : : uint8_t R_master_secret_buf[16];
42 : : struct byte_array R_master_secret = { .ptr = R_master_secret_buf,
43 : : .len = sizeof(R_master_secret_buf) };
44 : :
45 : : uint8_t R_master_salt_buf[8];
46 : : struct byte_array R_master_salt = { .ptr = R_master_salt_buf,
47 : : .len = sizeof(R_master_salt_buf) };
48 : :
49 : : uint8_t R_PRK_out_buf[32];
50 : : struct byte_array R_PRK_out = { .ptr = R_PRK_out_buf,
51 : : .len = sizeof(R_PRK_out_buf) };
52 : :
53 : : uint8_t R_err_msg_buf[0];
54 : : struct byte_array R_err_msg = { .ptr = R_err_msg_buf,
55 : : .len = sizeof(R_err_msg_buf) };
56 : :
57 : : /* size of stack area used by each thread */
58 : : #define STACKSIZE 7500
59 : : /* scheduling priority used by each thread */
60 : : #define PRIORITY 7
61 : : K_THREAD_STACK_DEFINE(thread_initiator_stack_area, STACKSIZE);
62 : : static struct k_thread thread_initiator_data;
63 : : K_THREAD_STACK_DEFINE(thread_responder_stack_area, STACKSIZE);
64 : : static struct k_thread thread_responder_data;
65 : :
66 : : /*semaphores*/
67 : : K_SEM_DEFINE(tx_initiator_completed, 0, 1);
68 : : K_SEM_DEFINE(tx_responder_completed, 0, 1);
69 : :
70 : : /*message exchange buffer*/
71 : : uint8_t msg_exchange_buf[1024];
72 : : uint32_t msg_exchange_buf_len = sizeof(msg_exchange_buf);
73 : :
74 : 6 : void semaphore_give(struct k_sem *sem)
75 : : {
76 : 6 : k_sem_give(sem);
77 : 6 : }
78 : :
79 : 6 : enum err semaphore_take(struct k_sem *sem, uint8_t *data, uint32_t *data_len)
80 : : {
81 [ - + ]: 6 : if (k_sem_take(sem, K_FOREVER) != 0) {
82 : 0 : PRINT_MSG("Cannot receive a message!\n");
83 : : } else {
84 [ - + ]: 6 : if (msg_exchange_buf_len > *data_len) {
85 : 0 : return buffer_to_small;
86 : : } else {
87 : 6 : memcpy(data, msg_exchange_buf, *data_len);
88 : 6 : *data_len = msg_exchange_buf_len;
89 : : }
90 : : }
91 : 6 : return ok;
92 : : }
93 : :
94 : 6 : enum err copy_message(uint8_t *data, uint32_t data_len)
95 : : {
96 [ - + ]: 6 : if (data_len > sizeof(msg_exchange_buf)) {
97 : 0 : PRINT_MSG("msg_exchange_buf to small\n");
98 : 0 : return buffer_to_small;
99 : : } else {
100 : 6 : memcpy(msg_exchange_buf, data, data_len);
101 : 6 : msg_exchange_buf_len = data_len;
102 : : }
103 : 6 : return ok;
104 : : }
105 : :
106 : 4 : enum err tx_initiator(void *sock, struct byte_array *data)
107 : : {
108 : 4 : enum err r = copy_message(data->ptr, data->len);
109 [ + - ]: 4 : if (r != ok) {
110 : : return r;
111 : : }
112 : 4 : semaphore_give(&tx_initiator_completed);
113 : 4 : return ok;
114 : : }
115 : :
116 : 2 : enum err tx_responder(void *sock, struct byte_array *data)
117 : : {
118 : : //PRINTF("tx_responder data len: %d\n", data->len);
119 : 2 : enum err r = copy_message(data->ptr, data->len);
120 [ + - ]: 2 : if (r != ok) {
121 : : return r;
122 : : }
123 : : //PRINTF("msg_exchange_buf_len: %d\n",msg_exchange_buf_len);
124 : 2 : semaphore_give(&tx_responder_completed);
125 : 2 : return ok;
126 : : }
127 : :
128 : 2 : enum err rx_initiator(void *sock, struct byte_array *data)
129 : : {
130 : 2 : PRINTF("msg_exchange_buf_len: %d\n", msg_exchange_buf_len);
131 : 2 : return semaphore_take(&tx_responder_completed, data->ptr, &data->len);
132 : : }
133 : 4 : enum err rx_responder(void *sock, struct byte_array *data)
134 : : {
135 : 4 : return semaphore_take(&tx_initiator_completed, data->ptr, &data->len);
136 : : }
137 : 6 : enum err ead_process(void *params, struct byte_array *ead13)
138 : : {
139 : 6 : return ok;
140 : : }
141 : :
142 : : /**
143 : : * @brief A thread in which an Initiator instance is executed
144 : : *
145 : : * @param vec_num Test vector number
146 : : * @param dummy2 unused
147 : : * @param dummy3 unused
148 : : */
149 : 2 : void thread_initiator(void *vec_num, void *dummy2, void *dummy3)
150 : : {
151 : 2 : ARG_UNUSED(dummy2);
152 : 2 : ARG_UNUSED(dummy3);
153 : :
154 : 2 : PRINT_MSG("Initiator thread started!\n");
155 : 2 : int vec_num_i = *((int *)vec_num) - 1;
156 : :
157 : 2 : enum err r;
158 : :
159 : 2 : struct other_party_cred cred_r;
160 : 2 : struct edhoc_initiator_context c_i;
161 : :
162 : 2 : c_i.sock = NULL;
163 : 2 : c_i.c_i.len = test_vectors[vec_num_i].c_i_len;
164 : 2 : c_i.c_i.ptr = (uint8_t *)test_vectors[vec_num_i].c_i;
165 : 2 : c_i.method = (enum method_type) * test_vectors[vec_num_i].method;
166 : 2 : c_i.suites_i.len = test_vectors[vec_num_i].SUITES_I_len;
167 : 2 : c_i.suites_i.ptr = (uint8_t *)test_vectors[vec_num_i].SUITES_I;
168 : 2 : c_i.ead_1.len = test_vectors[vec_num_i].ead_1_len;
169 : 2 : c_i.ead_1.ptr = (uint8_t *)test_vectors[vec_num_i].ead_1;
170 : 2 : c_i.ead_3.len = test_vectors[vec_num_i].ead_3_len;
171 : 2 : c_i.ead_3.ptr = (uint8_t *)test_vectors[vec_num_i].ead_3;
172 : 2 : c_i.id_cred_i.len = test_vectors[vec_num_i].id_cred_i_len;
173 : 2 : c_i.id_cred_i.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_i;
174 : 2 : c_i.cred_i.len = test_vectors[vec_num_i].cred_i_len;
175 : 2 : c_i.cred_i.ptr = (uint8_t *)test_vectors[vec_num_i].cred_i;
176 : 2 : c_i.g_x.len = test_vectors[vec_num_i].g_x_raw_len;
177 : 2 : c_i.g_x.ptr = (uint8_t *)test_vectors[vec_num_i].g_x_raw;
178 : 2 : c_i.x.len = test_vectors[vec_num_i].x_raw_len;
179 : 2 : c_i.x.ptr = (uint8_t *)test_vectors[vec_num_i].x_raw;
180 : 2 : c_i.g_i.len = test_vectors[vec_num_i].g_i_raw_len;
181 : 2 : c_i.g_i.ptr = (uint8_t *)test_vectors[vec_num_i].g_i_raw;
182 : 2 : c_i.i.len = test_vectors[vec_num_i].i_raw_len;
183 : 2 : c_i.i.ptr = (uint8_t *)test_vectors[vec_num_i].i_raw;
184 : 2 : c_i.sk_i.len = test_vectors[vec_num_i].sk_i_raw_len;
185 : 2 : c_i.sk_i.ptr = (uint8_t *)test_vectors[vec_num_i].sk_i_raw;
186 : 2 : c_i.pk_i.len = test_vectors[vec_num_i].pk_i_raw_len;
187 : 2 : c_i.pk_i.ptr = (uint8_t *)test_vectors[vec_num_i].pk_i_raw;
188 : :
189 : 2 : cred_r.id_cred.len = test_vectors[vec_num_i].id_cred_r_len;
190 : 2 : cred_r.id_cred.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_r;
191 : 2 : cred_r.cred.len = test_vectors[vec_num_i].cred_r_len;
192 : 2 : cred_r.cred.ptr = (uint8_t *)test_vectors[vec_num_i].cred_r;
193 : 2 : cred_r.g.len = test_vectors[vec_num_i].g_r_raw_len;
194 : 2 : cred_r.g.ptr = (uint8_t *)test_vectors[vec_num_i].g_r_raw;
195 : 2 : cred_r.pk.len = test_vectors[vec_num_i].pk_r_raw_len;
196 : 2 : cred_r.pk.ptr = (uint8_t *)test_vectors[vec_num_i].pk_r_raw;
197 : 2 : cred_r.ca.len = test_vectors[vec_num_i].ca_r_len;
198 : 2 : cred_r.ca.ptr = (uint8_t *)test_vectors[vec_num_i].ca_r;
199 : 2 : cred_r.ca_pk.len = test_vectors[vec_num_i].ca_r_pk_len;
200 : 2 : cred_r.ca_pk.ptr = (uint8_t *)test_vectors[vec_num_i].ca_r_pk;
201 : :
202 : 2 : struct cred_array cred_r_array = { .len = 1, .ptr = &cred_r };
203 : :
204 : 2 : r = edhoc_initiator_run(&c_i, &cred_r_array, &I_err_msg, &I_PRK_out,
205 : : tx_initiator, rx_initiator, ead_process);
206 [ - + ]: 2 : if (r != ok) {
207 : 0 : goto end;
208 : : }
209 : :
210 : 2 : PRINT_ARRAY("I_PRK_out", I_PRK_out.ptr, I_PRK_out.len);
211 : :
212 : 2 : r = prk_out2exporter(SHA_256, &I_PRK_out, &I_prk_exporter);
213 [ - + ]: 2 : if (r != ok) {
214 : 0 : goto end;
215 : : }
216 : 2 : PRINT_ARRAY("I_prk_exporter", I_prk_exporter.ptr, I_prk_exporter.len);
217 : :
218 : 2 : r = edhoc_exporter(SHA_256, OSCORE_MASTER_SECRET, &I_prk_exporter,
219 : : &I_master_secret);
220 [ - + ]: 2 : if (r != ok) {
221 : 0 : goto end;
222 : : }
223 : 2 : PRINT_ARRAY("OSCORE Master Secret", I_master_secret.ptr,
224 : 2 : I_master_secret.len);
225 : :
226 : 2 : r = edhoc_exporter(SHA_256, OSCORE_MASTER_SALT, &I_prk_exporter,
227 : : &I_master_salt);
228 [ - + ]: 2 : if (r != ok) {
229 : 0 : goto end;
230 : : }
231 : 2 : PRINT_ARRAY("OSCORE Master Salt", I_master_salt.ptr, I_master_salt.len);
232 : :
233 : : #ifdef REPORT_STACK_USAGE
234 : : thread_analyzer_print();
235 : : #endif
236 : :
237 : 2 : return;
238 : 0 : end:
239 : 0 : PRINTF("An error has occurred. Error code: %d\n", r);
240 : : }
241 : :
242 : : /**
243 : : * @brief A thread in which a Responder instance is executed
244 : : *
245 : : * @param vec_num Test vector number
246 : : * @param dummy2 unused
247 : : * @param dummy3 unused
248 : : */
249 : 2 : void thread_responder(void *vec_num, void *dummy2, void *dummy3)
250 : : {
251 : 2 : ARG_UNUSED(dummy2);
252 : 2 : ARG_UNUSED(dummy3);
253 : :
254 : 2 : PRINT_MSG("Responder thread started!\n");
255 : 2 : enum err r;
256 : 2 : int vec_num_i = *((int *)vec_num) - 1;
257 : :
258 : : /* test vector inputs */
259 : 2 : struct other_party_cred cred_i;
260 : 2 : struct edhoc_responder_context c_r;
261 : :
262 : 2 : c_r.sock = NULL;
263 : 2 : c_r.c_r.ptr = (uint8_t *)test_vectors[vec_num_i].c_r;
264 : 2 : c_r.c_r.len = test_vectors[vec_num_i].c_r_len;
265 : 2 : c_r.suites_r.len = test_vectors[vec_num_i].SUITES_R_len;
266 : 2 : c_r.suites_r.ptr = (uint8_t *)test_vectors[vec_num_i].SUITES_R;
267 : 2 : c_r.ead_2.len = test_vectors[vec_num_i].ead_2_len;
268 : 2 : c_r.ead_2.ptr = (uint8_t *)test_vectors[vec_num_i].ead_2;
269 : 2 : c_r.ead_4.len = test_vectors[vec_num_i].ead_4_len;
270 : 2 : c_r.ead_4.ptr = (uint8_t *)test_vectors[vec_num_i].ead_4;
271 : 2 : c_r.id_cred_r.len = test_vectors[vec_num_i].id_cred_r_len;
272 : 2 : c_r.id_cred_r.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_r;
273 : 2 : c_r.cred_r.len = test_vectors[vec_num_i].cred_r_len;
274 : 2 : c_r.cred_r.ptr = (uint8_t *)test_vectors[vec_num_i].cred_r;
275 : 2 : c_r.g_y.len = test_vectors[vec_num_i].g_y_raw_len;
276 : 2 : c_r.g_y.ptr = (uint8_t *)test_vectors[vec_num_i].g_y_raw;
277 : 2 : c_r.y.len = test_vectors[vec_num_i].y_raw_len;
278 : 2 : c_r.y.ptr = (uint8_t *)test_vectors[vec_num_i].y_raw;
279 : 2 : c_r.g_r.len = test_vectors[vec_num_i].g_r_raw_len;
280 : 2 : c_r.g_r.ptr = (uint8_t *)test_vectors[vec_num_i].g_r_raw;
281 : 2 : c_r.r.len = test_vectors[vec_num_i].r_raw_len;
282 : 2 : c_r.r.ptr = (uint8_t *)test_vectors[vec_num_i].r_raw;
283 : 2 : c_r.sk_r.len = test_vectors[vec_num_i].sk_r_raw_len;
284 : 2 : c_r.sk_r.ptr = (uint8_t *)test_vectors[vec_num_i].sk_r_raw;
285 : 2 : c_r.pk_r.len = test_vectors[vec_num_i].pk_r_raw_len;
286 : 2 : c_r.pk_r.ptr = (uint8_t *)test_vectors[vec_num_i].pk_r_raw;
287 : :
288 : 2 : cred_i.id_cred.len = test_vectors[vec_num_i].id_cred_i_len;
289 : 2 : cred_i.id_cred.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_i;
290 : 2 : cred_i.cred.len = test_vectors[vec_num_i].cred_i_len;
291 : 2 : cred_i.cred.ptr = (uint8_t *)test_vectors[vec_num_i].cred_i;
292 : 2 : cred_i.g.len = test_vectors[vec_num_i].g_i_raw_len;
293 : 2 : cred_i.g.ptr = (uint8_t *)test_vectors[vec_num_i].g_i_raw;
294 : 2 : cred_i.pk.len = test_vectors[vec_num_i].pk_i_raw_len;
295 : 2 : cred_i.pk.ptr = (uint8_t *)test_vectors[vec_num_i].pk_i_raw;
296 : 2 : cred_i.ca.len = test_vectors[vec_num_i].ca_i_len;
297 : 2 : cred_i.ca.ptr = (uint8_t *)test_vectors[vec_num_i].ca_i;
298 : 2 : cred_i.ca_pk.len = test_vectors[vec_num_i].ca_i_pk_len;
299 : 2 : cred_i.ca_pk.ptr = (uint8_t *)test_vectors[vec_num_i].ca_i_pk;
300 : :
301 : 2 : struct cred_array cred_i_array = { .len = 1, .ptr = &cred_i };
302 : 2 : r = edhoc_responder_run(&c_r, &cred_i_array, &R_err_msg, &R_PRK_out,
303 : : tx_responder, rx_responder, ead_process);
304 [ - + ]: 2 : if (r != ok) {
305 : 0 : goto end;
306 : : }
307 : :
308 : 2 : PRINT_ARRAY("R_PRK_out", R_PRK_out.ptr, R_PRK_out.len);
309 : :
310 : 2 : r = prk_out2exporter(SHA_256, &R_PRK_out, &R_prk_exporter);
311 [ - + ]: 2 : if (r != ok) {
312 : 0 : goto end;
313 : : }
314 : 2 : PRINT_ARRAY("R_prk_exporter", R_prk_exporter.ptr, R_prk_exporter.len);
315 : :
316 : 2 : r = edhoc_exporter(SHA_256, OSCORE_MASTER_SECRET, &R_prk_exporter,
317 : : &R_master_secret);
318 [ - + ]: 2 : if (r != ok) {
319 : 0 : goto end;
320 : : }
321 : 2 : PRINT_ARRAY("OSCORE Master Secret", R_master_secret.ptr,
322 : 2 : R_master_secret.len);
323 : :
324 : 2 : r = edhoc_exporter(SHA_256, OSCORE_MASTER_SALT, &R_prk_exporter,
325 : : &R_master_salt);
326 [ - + ]: 2 : if (r != ok) {
327 : 0 : goto end;
328 : : }
329 : 2 : PRINT_ARRAY("OSCORE Master Salt", R_master_salt.ptr, R_master_salt.len);
330 : :
331 : : #ifdef REPORT_STACK_USAGE
332 : : thread_analyzer_print();
333 : : #endif
334 : :
335 : 2 : return;
336 : 0 : end:
337 : 0 : PRINTF("An error has occurred. Error code: %d\n", r);
338 : : }
339 : :
340 : 2 : int test_initiator_responder_interaction(int vec_num)
341 : : {
342 : 2 : PRINT_MSG("start initiator_responder_interaction\n");
343 : :
344 : : /*initiator thread*/
345 : 4 : k_tid_t initiator_tid = k_thread_create(
346 : : &thread_initiator_data, thread_initiator_stack_area,
347 : : K_THREAD_STACK_SIZEOF(thread_initiator_stack_area),
348 : : thread_initiator, (void *)&vec_num, NULL, NULL, PRIORITY, 0,
349 : 2 : K_NO_WAIT);
350 : :
351 : : /*responder thread*/
352 : 4 : k_tid_t responder_tid = k_thread_create(
353 : : &thread_responder_data, thread_responder_stack_area,
354 : : K_THREAD_STACK_SIZEOF(thread_responder_stack_area),
355 : : thread_responder, (void *)&vec_num, NULL, NULL, PRIORITY, 0,
356 : 2 : K_NO_WAIT);
357 : :
358 : 2 : k_thread_start(&thread_initiator_data);
359 : 2 : k_thread_start(&thread_responder_data);
360 : :
361 [ - + ]: 2 : if (0 != k_thread_join(&thread_initiator_data, K_FOREVER)) {
362 : 0 : PRINT_MSG("initiator thread stalled! Aborting.");
363 : 0 : k_thread_abort(initiator_tid);
364 : : }
365 [ - + ]: 2 : if (0 != k_thread_join(&thread_responder_data, K_FOREVER)) {
366 : 0 : PRINT_MSG("responder thread stalled! Aborting.");
367 : 0 : k_thread_abort(responder_tid);
368 : : }
369 : :
370 : 2 : PRINT_MSG("threads completed\n");
371 : :
372 : : /* check if Initiator and Responder computed the same values */
373 : :
374 : 2 : zassert_mem_equal__(I_PRK_out.ptr, R_PRK_out.ptr, R_PRK_out.len,
375 : : "wrong prk_out");
376 : :
377 : 2 : zassert_mem_equal__(I_prk_exporter.ptr, R_prk_exporter.ptr,
378 : : R_prk_exporter.len, "wrong prk_exporter");
379 : :
380 : 2 : zassert_mem_equal__(I_master_secret.ptr, R_master_secret.ptr,
381 : : R_master_secret.len, "wrong master_secret");
382 : :
383 : 2 : zassert_mem_equal__(I_master_salt.ptr, R_master_salt.ptr,
384 : : R_master_salt.len, "wrong master_salt");
385 : 2 : return 0;
386 : : }
387 : :
388 : 1 : void t_initiator_responder_interaction1()
389 : : {
390 [ - + ]: 1 : MEASURE_LATENCY(test_initiator_responder_interaction(1));
391 : 1 : }
392 : :
393 : 1 : void t_initiator_responder_interaction2()
394 : : {
395 [ - + ]: 1 : MEASURE_LATENCY(test_initiator_responder_interaction(2));
396 : 1 : }
|