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