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 <stdio.h>
8 : : #include <zephyr/kernel.h>
9 : : #include <zephyr/ztest.h>
10 : : #include "oscore.h"
11 : :
12 : : #include "oscore_test_vectors.h"
13 : :
14 : : #include "oscore/oscore_coap.h"
15 : : #include "oscore/option.h"
16 : :
17 : : #include "common/print_util.h"
18 : :
19 : : enum reverse_t { NORMAL, REVERSED };
20 : :
21 : : enum freshness_t { FRESH, RESTORED };
22 : :
23 : 5 : static struct oscore_init_params get_default_params(enum reverse_t is_reversed,
24 : : enum freshness_t is_fresh)
25 : : {
26 : 5 : struct byte_array sender = { .ptr = (uint8_t *)T1__SENDER_ID,
27 : : .len = T1__SENDER_ID_LEN };
28 : 5 : struct byte_array recipient = { .ptr = (uint8_t *)T1__RECIPIENT_ID,
29 : : .len = T1__RECIPIENT_ID_LEN };
30 : :
31 [ + + + + ]: 5 : struct oscore_init_params params = {
32 : : .master_secret.ptr = (uint8_t *)T1__MASTER_SECRET,
33 : : .master_secret.len = T1__MASTER_SECRET_LEN,
34 : : .sender_id = (is_reversed == NORMAL) ? sender : recipient,
35 : : .recipient_id = (is_reversed == NORMAL) ? recipient : sender,
36 : : .master_salt.ptr = (uint8_t *)T1__MASTER_SALT,
37 : : .master_salt.len = T1__MASTER_SALT_LEN,
38 : : .id_context.ptr = (uint8_t *)T1__ID_CONTEXT,
39 : : .id_context.len = T1__ID_CONTEXT_LEN,
40 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
41 : : .hkdf = OSCORE_SHA_256,
42 : 5 : .fresh_master_secret_salt = (is_fresh == FRESH),
43 : : };
44 : 5 : return params;
45 : : }
46 : :
47 : : /**
48 : : * Test 1:
49 : : * - Client Key derivation with master salt see RFC8613 Appendix C.1.1
50 : : * - Generating OSCORE request with key form C.1.1 see RFC8613 Appendix C.4
51 : : */
52 : 1 : void t1_oscore_client_request_response(void)
53 : : {
54 : 1 : enum err r;
55 : 1 : struct context c_client;
56 : 1 : struct oscore_init_params params = get_default_params(NORMAL, RESTORED);
57 : :
58 : 1 : r = oscore_context_init(¶ms, &c_client);
59 : :
60 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
61 : :
62 : : /*
63 : : required only for the test vector.
64 : : during normal operation the sender sequence number is
65 : : increased automatically after every sending
66 : : */
67 : : //c_client.sc.ssn = 20;
68 : :
69 : 1 : uint8_t buf_oscore[256];
70 : 1 : uint32_t buf_oscore_len = sizeof(buf_oscore);
71 : 1 : uint8_t buf_coap[256];
72 : 1 : uint32_t buf_coap_len = sizeof(buf_coap);
73 : :
74 : : /*test converting the request*/
75 : 1 : r = coap2oscore((uint8_t *)T1__COAP_REQ, T1__COAP_REQ_LEN,
76 : : (uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
77 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
78 : :
79 : 1 : zassert_mem_equal__(c_client.sc.sender_key.ptr, T1__SENDER_KEY,
80 : : c_client.sc.sender_key.len,
81 : : "T1 sender key derivation failed");
82 : :
83 : 1 : zassert_mem_equal__(c_client.rc.recipient_key.ptr, T1__RECIPIENT_KEY,
84 : : c_client.rc.recipient_key.len,
85 : : "T1 recipient key derivation failed");
86 : :
87 : 1 : zassert_mem_equal__(c_client.cc.common_iv.ptr, T1__COMMON_IV,
88 : : c_client.cc.common_iv.len,
89 : : "T1 common IV derivation failed");
90 : :
91 : 1 : zassert_mem_equal__(&buf_oscore, T1__OSCORE_REQ, T1__OSCORE_REQ_LEN,
92 : : "coap2oscore failed");
93 : :
94 : : /*test converting the response*/
95 : 1 : r = oscore2coap((uint8_t *)T1__OSCORE_RESP, T1__OSCORE_RESP_LEN,
96 : : (uint8_t *)&buf_coap, &buf_coap_len, &c_client);
97 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
98 : 1 : zassert_mem_equal__(&buf_coap, T1__COAP_RESPONSE, T1__COAP_RESPONSE_LEN,
99 : : "oscore2coap failed");
100 : 1 : }
101 : :
102 : : /**
103 : : * Test 3:
104 : : * - Client Key derivation without master salt see RFC8613 Appendix C.2.1
105 : : * - Generating OSCORE request with key form C.2.1 see RFC8613 Appendix C.5
106 : : */
107 : 1 : void t3_oscore_client_request(void)
108 : : {
109 : 1 : enum err r;
110 : 1 : struct context c_client;
111 : 1 : struct oscore_init_params params = {
112 : : .master_secret.ptr = (uint8_t *)T3__MASTER_SECRET,
113 : : .master_secret.len = T3__MASTER_SECRET_LEN,
114 : : .sender_id.ptr = (uint8_t *)T3__SENDER_ID,
115 : : .sender_id.len = T3__SENDER_ID_LEN,
116 : : .recipient_id.ptr = (uint8_t *)T3__RECIPIENT_ID,
117 : : .recipient_id.len = T3__RECIPIENT_ID_LEN,
118 : : .master_salt.ptr = (uint8_t *)T3__MASTER_SALT,
119 : : .master_salt.len = T3__MASTER_SALT_LEN,
120 : : .id_context.ptr = (uint8_t *)T3__ID_CONTEXT,
121 : : .id_context.len = T3__ID_CONTEXT_LEN,
122 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
123 : : .hkdf = OSCORE_SHA_256,
124 : : .fresh_master_secret_salt = true,
125 : : };
126 : :
127 : 1 : r = oscore_context_init(¶ms, &c_client);
128 : :
129 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
130 : :
131 : : /*
132 : : required only for the test vector.
133 : : during normal operation the sender sequence number is
134 : : increased automatically after every sending
135 : : */
136 : 1 : c_client.sc.ssn = 20;
137 : :
138 : 1 : uint8_t buf_oscore[256];
139 : 1 : uint32_t buf_oscore_len = sizeof(buf_oscore);
140 : :
141 : 1 : r = coap2oscore((uint8_t *)T3__COAP_REQ, T3__COAP_REQ_LEN,
142 : : (uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
143 : :
144 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
145 : :
146 : 1 : zassert_mem_equal__(&buf_oscore, T3__OSCORE_REQ, T3__OSCORE_REQ_LEN,
147 : : "coap2oscore failed");
148 : 1 : }
149 : :
150 : : /**
151 : : * Test 5 :
152 : : * - Client Key derivation with ID Context see Appendix 3.1
153 : : * - OSCORE request generation see Appendix C6
154 : : */
155 : 1 : void t5_oscore_client_request(void)
156 : : {
157 : 1 : enum err r;
158 : 1 : struct context c_client;
159 : 1 : struct oscore_init_params params = {
160 : : .master_secret.ptr = (uint8_t *)T5__MASTER_SECRET,
161 : : .master_secret.len = T5__MASTER_SECRET_LEN,
162 : : .sender_id.ptr = (uint8_t *)T5__SENDER_ID,
163 : : .sender_id.len = T5__SENDER_ID_LEN,
164 : : .recipient_id.ptr = (uint8_t *)T5__RECIPIENT_ID,
165 : : .recipient_id.len = T5__RECIPIENT_ID_LEN,
166 : : .master_salt.ptr = (uint8_t *)T5__MASTER_SALT,
167 : : .master_salt.len = T5__MASTER_SALT_LEN,
168 : : .id_context.ptr = (uint8_t *)T5__ID_CONTEXT,
169 : : .id_context.len = T5__ID_CONTEXT_LEN,
170 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
171 : : .hkdf = OSCORE_SHA_256,
172 : : .fresh_master_secret_salt = true,
173 : : };
174 : :
175 : 1 : r = oscore_context_init(¶ms, &c_client);
176 : :
177 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
178 : :
179 : : /*
180 : : required only for the test vector.
181 : : during normal operation the sender sequence number is
182 : : increased automatically after every sending
183 : : */
184 : 1 : c_client.sc.ssn = 20;
185 : :
186 : 1 : uint8_t buf_oscore[256];
187 : 1 : uint32_t buf_oscore_len = sizeof(buf_oscore);
188 : :
189 : 1 : r = coap2oscore((uint8_t *)T5__COAP_REQ, T5__COAP_REQ_LEN,
190 : : (uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
191 : :
192 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
193 : :
194 : 1 : zassert_mem_equal__(&buf_oscore, T5__OSCORE_REQ, buf_oscore_len,
195 : : "coap2oscore failed");
196 : 1 : }
197 : :
198 : : /**
199 : : * Test 2:
200 : : * - Server Key derivation with master salt see RFC8613 Appendix C.1.2
201 : : * - Generating OSCORE response with key form C.1.2 see RFC8613 Appendix C.7
202 : : */
203 : 1 : void t2_oscore_server_request_response(void)
204 : : {
205 : 1 : enum err r;
206 : 1 : struct context c_server;
207 : 1 : struct oscore_init_params params_server = {
208 : : .master_secret.ptr = (uint8_t *)T2__MASTER_SECRET,
209 : : .master_secret.len = T2__MASTER_SECRET_LEN,
210 : : .sender_id.ptr = (uint8_t *)T2__SENDER_ID,
211 : : .sender_id.len = T2__SENDER_ID_LEN,
212 : : .recipient_id.ptr = (uint8_t *)T2__RECIPIENT_ID,
213 : : .recipient_id.len = T2__RECIPIENT_ID_LEN,
214 : : .master_salt.ptr = (uint8_t *)T2__MASTER_SALT,
215 : : .master_salt.len = T2__MASTER_SALT_LEN,
216 : : .id_context.ptr = (uint8_t *)T2__ID_CONTEXT,
217 : : .id_context.len = T2__ID_CONTEXT_LEN,
218 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
219 : : .hkdf = OSCORE_SHA_256,
220 : : .fresh_master_secret_salt = true,
221 : : };
222 : :
223 : 1 : r = oscore_context_init(¶ms_server, &c_server);
224 : :
225 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
226 : :
227 : : /*Test decrypting of an incoming request*/
228 : 1 : uint8_t buf_coap[256];
229 : 1 : uint32_t buf_coap_len = sizeof(buf_coap);
230 : :
231 : 1 : r = oscore2coap((uint8_t *)T2__OSCORE_REQ, T2__OSCORE_REQ_LEN, buf_coap,
232 : : &buf_coap_len, &c_server);
233 : :
234 : 1 : zassert_equal(r, ok, "Error in oscore2coap! Error code: %d", r);
235 : 1 : zassert_mem_equal__(&buf_coap, T2__COAP_REQ, buf_coap_len,
236 : : "oscore2coap failed");
237 : :
238 : : /*test response not matching the recipient ID*/
239 : 1 : uint8_t wrong_recipient_id[] = { 0x02 };
240 : 1 : c_server.rc.recipient_id.ptr = wrong_recipient_id;
241 : 1 : c_server.rc.recipient_id.len = sizeof(wrong_recipient_id);
242 : :
243 : 1 : r = oscore2coap((uint8_t *)T2__OSCORE_REQ, T2__OSCORE_REQ_LEN,
244 : : (uint8_t *)&buf_coap, &buf_coap_len, &c_server);
245 : 1 : zassert_equal(r, oscore_kid_recipient_id_mismatch,
246 : : "Error in coap2oscore!");
247 : :
248 : : /*Test generating an encrypted response, see Appendix C7*/
249 : 1 : uint8_t buf_oscore[256];
250 : 1 : uint32_t buf_oscore_len = sizeof(buf_oscore);
251 : :
252 : 1 : r = coap2oscore((uint8_t *)T2__COAP_RESPONSE, T2__COAP_RESPONSE_LEN,
253 : : (uint8_t *)&buf_oscore, &buf_oscore_len, &c_server);
254 : :
255 : 1 : zassert_equal(r, ok, "Error in coap2oscore");
256 : :
257 : 1 : zassert_mem_equal__(&buf_oscore, T2__OSCORE_RESP, buf_oscore_len,
258 : : "coap2oscore failed");
259 : 1 : }
260 : :
261 : 1 : void t4_oscore_server_key_derivation(void)
262 : : {
263 : 1 : enum err r;
264 : 1 : struct context c_server;
265 : 1 : struct oscore_init_params params_server = {
266 : : .master_secret.ptr = (uint8_t *)T4__MASTER_SECRET,
267 : : .master_secret.len = T4__MASTER_SECRET_LEN,
268 : : .sender_id.ptr = (uint8_t *)T4__SENDER_ID,
269 : : .sender_id.len = T4__SENDER_ID_LEN,
270 : : .recipient_id.ptr = (uint8_t *)T4__RECIPIENT_ID,
271 : : .recipient_id.len = T4__RECIPIENT_ID_LEN,
272 : : .master_salt.ptr = (uint8_t *)T4__MASTER_SALT,
273 : : .master_salt.len = T4__MASTER_SALT_LEN,
274 : : .id_context.ptr = (uint8_t *)T4__ID_CONTEXT,
275 : : .id_context.len = T4__ID_CONTEXT_LEN,
276 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
277 : : .hkdf = OSCORE_SHA_256,
278 : : .fresh_master_secret_salt = true,
279 : : };
280 : :
281 : 1 : r = oscore_context_init(¶ms_server, &c_server);
282 : :
283 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
284 : :
285 : 1 : zassert_mem_equal__(c_server.sc.sender_key.ptr, T4__SENDER_KEY,
286 : : c_server.sc.sender_key.len,
287 : : "T4 sender key derivation failed");
288 : :
289 : 1 : zassert_mem_equal__(c_server.rc.recipient_key.ptr, T4__RECIPIENT_KEY,
290 : : c_server.rc.recipient_key.len,
291 : : "T4 recipient key derivation failed");
292 : :
293 : 1 : zassert_mem_equal__(c_server.cc.common_iv.ptr, T4__COMMON_IV,
294 : : c_server.cc.common_iv.len,
295 : : "T4 common IV derivation failed");
296 : 1 : }
297 : :
298 : : /**
299 : : * Test 6:
300 : : * - Server Key derivation with ID context see RFC8613 Appendix C.3.2
301 : : */
302 : 1 : void t6_oscore_server_key_derivation(void)
303 : : {
304 : 1 : enum err r;
305 : 1 : struct context c_server;
306 : 1 : struct oscore_init_params params_server = {
307 : : .master_secret.ptr = (uint8_t *)T6__MASTER_SECRET,
308 : : .master_secret.len = T6__MASTER_SECRET_LEN,
309 : : .sender_id.ptr = (uint8_t *)T6__SENDER_ID,
310 : : .sender_id.len = T6__SENDER_ID_LEN,
311 : : .recipient_id.ptr = (uint8_t *)T6__RECIPIENT_ID,
312 : : .recipient_id.len = T6__RECIPIENT_ID_LEN,
313 : : .master_salt.ptr = (uint8_t *)T6__MASTER_SALT,
314 : : .master_salt.len = T6__MASTER_SALT_LEN,
315 : : .id_context.ptr = (uint8_t *)T6__ID_CONTEXT,
316 : : .id_context.len = T6__ID_CONTEXT_LEN,
317 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
318 : : .hkdf = OSCORE_SHA_256,
319 : : .fresh_master_secret_salt = true,
320 : : };
321 : :
322 : 1 : r = oscore_context_init(¶ms_server, &c_server);
323 : :
324 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
325 : :
326 : 1 : zassert_mem_equal__(c_server.sc.sender_key.ptr, T6__SENDER_KEY,
327 : : c_server.sc.sender_key.len,
328 : : "T6 sender key derivation failed");
329 : :
330 : 1 : zassert_mem_equal__(c_server.rc.recipient_key.ptr, T6__RECIPIENT_KEY,
331 : : c_server.rc.recipient_key.len,
332 : : "T6 recipient key derivation failed");
333 : :
334 : 1 : zassert_mem_equal__(c_server.cc.common_iv.ptr, T6__COMMON_IV,
335 : : c_server.cc.common_iv.len,
336 : : "T6 common IV derivation failed");
337 : 1 : }
338 : :
339 : : /**
340 : : * Test 8:
341 : : * - Simple ACK packet should not be encrypted and result should be the same as input buffer (see RFC8613 Section 4.2)
342 : : */
343 : 1 : void t8_oscore_server_response_simple_ack(void)
344 : : {
345 : 1 : enum err r;
346 : 1 : struct context context;
347 : 1 : struct oscore_init_params params = {
348 : : .master_secret.ptr = (uint8_t *)T7__MASTER_SECRET,
349 : : .master_secret.len = T7__MASTER_SECRET_LEN,
350 : : .sender_id.ptr = (uint8_t *)T7__SENDER_ID,
351 : : .sender_id.len = T7__SENDER_ID_LEN,
352 : : .recipient_id.ptr = (uint8_t *)T7__RECIPIENT_ID,
353 : : .recipient_id.len = T7__RECIPIENT_ID_LEN,
354 : : .master_salt.ptr = (uint8_t *)T7__MASTER_SALT,
355 : : .master_salt.len = T7__MASTER_SALT_LEN,
356 : : .id_context.ptr = (uint8_t *)T7__ID_CONTEXT,
357 : : .id_context.len = T7__ID_CONTEXT_LEN,
358 : : .aead_alg = OSCORE_AES_CCM_16_64_128,
359 : : .hkdf = OSCORE_SHA_256,
360 : : .fresh_master_secret_salt = true,
361 : : };
362 : :
363 : 1 : r = oscore_context_init(¶ms, &context);
364 : :
365 : 1 : zassert_equal(r, ok, "Error in oscore_context_init");
366 : :
367 : : /*Test if encrypting simple ACK message results in valid unencrypted message, see Section 4.2*/
368 : 1 : uint8_t buf_oscore[256];
369 : 1 : uint32_t buf_oscore_len = sizeof(buf_oscore);
370 : :
371 : 1 : r = coap2oscore((uint8_t *)T8__COAP_ACK, T8__COAP_ACK_LEN,
372 : : (uint8_t *)&buf_oscore, &buf_oscore_len, &context);
373 : :
374 : 1 : zassert_equal(r, ok, "Error in coap2oscore");
375 : :
376 : 1 : zassert_mem_equal__(&buf_oscore, T8__COAP_ACK, T8__COAP_ACK_LEN,
377 : : "coap2oscore failed");
378 : :
379 : 1 : zassert_equal(buf_oscore_len, T8__COAP_ACK_LEN, "coap2oscore failed");
380 : 1 : }
381 : :
382 : : /**
383 : : * @brief This function test the behavior of a server and a client in a typical
384 : : * observe exchange as depicted:
385 : : *
386 : : * client server
387 : : * --------- ---------
388 : : * | |
389 : : * |------registration------------>|
390 : : * | |
391 : : * |<-----notification1------------|
392 : : * rejected msg | x---replayed notification1----|
393 : : * | |
394 : : *
395 : : * See as well Appendix A.1. in RFC7641
396 : : */
397 : 1 : void t9_oscore_client_server_observe(void)
398 : : {
399 : : /*
400 : : *
401 : : * Initialize contexts for the client and server
402 : : *
403 : : */
404 : 1 : enum err r;
405 : 1 : struct context c_client;
406 : 1 : struct oscore_init_params params_client =
407 : 1 : get_default_params(NORMAL, FRESH);
408 : 1 : r = oscore_context_init(¶ms_client, &c_client);
409 : 1 : zassert_equal(r, ok, "Error in oscore_context_init for client");
410 : :
411 : 1 : struct context c_server;
412 : 1 : struct oscore_init_params params_server =
413 : 1 : get_default_params(REVERSED, FRESH);
414 : 1 : r = oscore_context_init(¶ms_server, &c_server);
415 : 1 : zassert_equal(r, ok, "Error in oscore_context_init for server");
416 : :
417 : : /*
418 : : *
419 : : *test the registration (first request)
420 : : *
421 : : */
422 : 1 : PRINT_MSG("\n\n |------registration---->| \n\n");
423 : 1 : uint8_t observe_val[] = { 0x00 }; /*0x00 indicates registration*/
424 : 1 : uint8_t uri_path_val[] = { 't', 'e', 'm', 'p', 'e', 'r',
425 : : 'a', 't', 'u', 'r', 'e' };
426 : 1 : uint8_t token[] = { 0x4a };
427 : 1 : uint8_t ser_coap_pkt_registration[40];
428 : 1 : uint32_t ser_coap_pkt_registration_len =
429 : : sizeof(ser_coap_pkt_registration);
430 : 1 : uint8_t ser_oscore_pkt[40];
431 : 1 : uint32_t ser_oscore_pkt_len = sizeof(ser_oscore_pkt);
432 : 1 : memset(ser_coap_pkt_registration, 0, ser_coap_pkt_registration_len);
433 : 1 : memset(ser_oscore_pkt, 0, ser_oscore_pkt_len);
434 : :
435 : 1 : struct o_coap_packet coap_pkt_registration = {
436 : : .header = {
437 : : .ver = 1,
438 : : .type = TYPE_CON,
439 : : .TKL = 1,
440 : : .code = CODE_REQ_GET,
441 : : .MID = 0x0
442 : : },
443 : : .token = token,
444 : : .options_cnt = 2,
445 : : .options = {
446 : : { .delta = 6,
447 : : .len = sizeof(observe_val),
448 : : .value = observe_val,
449 : : .option_number = OBSERVE },
450 : : { .delta = 5,
451 : : .len = sizeof(uri_path_val),
452 : : .value = uri_path_val,
453 : : .option_number = URI_PATH},/*E, opt num 11*/
454 : : },
455 : : .payload.len = 0,
456 : : .payload.ptr = NULL,
457 : : };
458 : :
459 : 1 : r = coap_serialize(&coap_pkt_registration, ser_coap_pkt_registration,
460 : : &ser_coap_pkt_registration_len);
461 : 1 : zassert_equal(
462 : : r, ok,
463 : : "Error in coap_serialize during registration packet serialization!");
464 : :
465 : 1 : PRINT_ARRAY("CoAP observe registration", ser_coap_pkt_registration,
466 : 1 : ser_coap_pkt_registration_len);
467 : :
468 : 1 : r = coap2oscore(ser_coap_pkt_registration,
469 : : ser_coap_pkt_registration_len, ser_oscore_pkt,
470 : : &ser_oscore_pkt_len, &c_client);
471 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
472 : 1 : uint8_t EXPECTED_OSCORE_REGISTRATION[] = {
473 : : 0x41, 0x05, 0x00, 0x00, 0x4A, 0x61, 0x00, 0x32, 0x09,
474 : : 0x00, 0xFF, 0xAE, 0x58, 0x5E, 0x2E, 0x65, 0x89, 0x40,
475 : : 0xE6, 0xDB, 0xF4, 0xB7, 0x08, 0xB7, 0x93, 0x37, 0x03,
476 : : 0x41, 0x1E, 0x50, 0x8E, 0xEA, 0x79, 0x70
477 : : };
478 : 1 : zassert_mem_equal__(&ser_oscore_pkt, EXPECTED_OSCORE_REGISTRATION,
479 : : sizeof(EXPECTED_OSCORE_REGISTRATION),
480 : : "coap2oscore failed");
481 : :
482 : 1 : PRINT_ARRAY("OSCORE observe registration", ser_oscore_pkt,
483 : 1 : ser_oscore_pkt_len);
484 : :
485 : 1 : uint8_t ser_conv_coap_pkt[40];
486 : 1 : uint32_t ser_conv_coap_pkt_len = sizeof(ser_conv_coap_pkt);
487 : :
488 : 1 : r = oscore2coap(ser_oscore_pkt, ser_oscore_pkt_len, ser_conv_coap_pkt,
489 : : &ser_conv_coap_pkt_len, &c_server);
490 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
491 : : /*check if we recovered the coap packet that the client sent*/
492 : 1 : zassert_mem_equal__(ser_coap_pkt_registration, ser_conv_coap_pkt,
493 : : ser_conv_coap_pkt_len, "oscore2coap failed");
494 : :
495 : 1 : PRINT_ARRAY("Converted CoAP observe registration", ser_conv_coap_pkt,
496 : 1 : ser_conv_coap_pkt_len);
497 : :
498 : : /*
499 : : *
500 : : *test the first notification (first response)
501 : : *
502 : : */
503 : :
504 : 1 : PRINT_MSG("\n\n |<-----notification1----| \n\n");
505 : :
506 : 1 : uint8_t ser_coap_pkt_notification1[40];
507 : 1 : uint32_t ser_coap_pkt_notification1_len =
508 : : sizeof(ser_coap_pkt_notification1);
509 : 1 : uint8_t ser_oscore_pkt_notification1[40];
510 : 1 : uint32_t ser_oscore_pkt_notification1_len =
511 : : sizeof(ser_oscore_pkt_notification1);
512 : 1 : memset(ser_coap_pkt_notification1, 0, ser_coap_pkt_notification1_len);
513 : 1 : memset(ser_oscore_pkt_notification1, 0,
514 : : ser_oscore_pkt_notification1_len);
515 : :
516 : : /*RFC7641: To provide an order among notifications for the client, the server
517 : : sets the value of the Observe Option in each notification to the 24
518 : : least significant bits of a strictly increasing sequence number.*/
519 : : //uint32_t observe_sequence_number = 0;
520 : 1 : uint32_t val = 0;
521 : 1 : struct o_coap_packet coap_pkt_notification1 = {
522 : : .header = { .ver = 1,
523 : : .type = TYPE_ACK,
524 : : .TKL = 1,
525 : : .code = CODE_RESP_CONTENT,
526 : : .MID = 0x0 },
527 : : .token = token,
528 : : .options_cnt = 1,
529 : : .options = { { .delta = 6,
530 : : .len = 3, //take only the lower 24 bit
531 : : .value =
532 : : (uint8_t *)&val, //convert to network byte order
533 : : .option_number = OBSERVE } },
534 : : .payload.len = 0,
535 : : .payload.ptr = NULL,
536 : : };
537 : :
538 : 1 : r = coap_serialize(&coap_pkt_notification1, ser_coap_pkt_notification1,
539 : : &ser_coap_pkt_notification1_len);
540 : 1 : zassert_equal(
541 : : r, ok,
542 : : "Error in coap_serialize during notification1 packet serialization!");
543 : :
544 : 1 : PRINT_ARRAY("CoAP observe notification1", ser_coap_pkt_notification1,
545 : 1 : ser_coap_pkt_notification1_len);
546 : :
547 : 1 : r = coap2oscore(ser_coap_pkt_notification1,
548 : : ser_coap_pkt_notification1_len, ser_oscore_pkt,
549 : : &ser_oscore_pkt_len, &c_server);
550 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
551 : 1 : uint8_t EXPECTED_OSCORE_NOTIFICATION1[] = {
552 : : 0x61, 0x45, 0x00, 0x00, 0x4A, 0x63, 0x00, 0x00,
553 : : 0x00, 0x33, 0x09, 0x00, 0x01, 0xFF, 0x4D, 0xD3,
554 : : 0x4F, 0x59, 0x4E, 0x54, 0x7B, 0x25, 0x0E, 0x1B
555 : : };
556 : 1 : zassert_mem_equal__(&ser_oscore_pkt, EXPECTED_OSCORE_NOTIFICATION1,
557 : : sizeof(EXPECTED_OSCORE_NOTIFICATION1),
558 : : "coap2oscore failed");
559 : :
560 : 1 : PRINT_ARRAY("OSCORE observe notification1", ser_oscore_pkt,
561 : 1 : ser_oscore_pkt_len);
562 : :
563 : 1 : ser_conv_coap_pkt_len = sizeof(ser_conv_coap_pkt);
564 : 1 : r = oscore2coap(ser_oscore_pkt, ser_oscore_pkt_len, ser_conv_coap_pkt,
565 : : &ser_conv_coap_pkt_len, &c_client);
566 : :
567 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
568 : 1 : uint8_t EXPECTED_CONVERTED_COAP[] = {
569 : : 0x61, 0x45, 0x00, 0x00, 0x4A, 0x60
570 : : };
571 : 1 : zassert_mem_equal__(&ser_conv_coap_pkt, EXPECTED_CONVERTED_COAP,
572 : : sizeof(EXPECTED_CONVERTED_COAP),
573 : : "oscore2coap failed");
574 : :
575 : 1 : PRINT_ARRAY("Converted CoAP observe notification", ser_conv_coap_pkt,
576 : 1 : ser_conv_coap_pkt_len);
577 : :
578 : : /*try replay notification 1*/
579 : 1 : PRINT_MSG("Try to replay previous notification\n");
580 : 1 : r = oscore2coap(ser_oscore_pkt, ser_oscore_pkt_len, ser_conv_coap_pkt,
581 : : &ser_conv_coap_pkt_len, &c_client);
582 : 1 : zassert_equal(r, oscore_replay_notification_protection_error,
583 : : "Error in oscore2coap!");
584 : 1 : }
585 : :
586 : : /**
587 : : * @brief This function test the behavior of a server and a client for contexts
588 : : * stored in FLASH, after reboot of the server and the rejection of a replayed request.
589 : : *
590 : : * client server
591 : : * --------- ---------
592 : : * | |
593 : : * 1) |------request----------------------------->|
594 : : * |<-----response with ECHO option (ECHO1)----|
595 : : * | |
596 : : * 2) |------new request without ECHO opt-------->|
597 : : * |<-----response with new ECHO option (ECHO2)|
598 : : * | |
599 : : * 3) |------request with old ECHO option-(ECHO1)>|
600 : : * |<-----response with new ECHO option (ECHO3)|
601 : : * | |
602 : : * 4) |------request with ECHO option-(ECHO3)---->|
603 : : * |<-----response-----------------------------|
604 : : * | |
605 : : * 5) |------request----------------------------->|
606 : : * |------replayed request----------X | rejected message
607 : : *
608 : : * See as RFC8613 Appendix B1.2 and RFC9175
609 : : *
610 : : * - 1) and 4) are represent the normal flow.
611 : : * - 2), 3) and 5) represent special cases.
612 : : *
613 : : *
614 : : *
615 : : * 1) The client send a first request. The server responds with ECHO option.
616 : : * This flow is mandatory for contexts restored from FLASH and should be executed after
617 : : * every reboot of the server. Then the client should send the ECHO option that it
618 : : * received in the next request.
619 : : *
620 : : * 2) The client sends a new request without an ECHO option. This may happen
621 : : * if for some reason the client did not received the first ECHO option.
622 : : *
623 : : * 3) The client responds with wrong option -- not ECHO2 but ECHO1. The
624 : : * client receives a new option ECHO3 from the server.
625 : : *
626 : : * 4) The client sends the expected ECHO option ECHO3
627 : : * 5) The client replays an request which gets detected.
628 : : */
629 : 1 : void t10_oscore_client_server_after_reboot(void)
630 : : {
631 : : /*
632 : : *
633 : : * Initialize contexts for the client and server
634 : : *
635 : : */
636 : 1 : enum err r;
637 : 1 : struct context cc; //context of the client
638 : 1 : struct oscore_init_params params_client =
639 : 1 : get_default_params(NORMAL, RESTORED);
640 : 1 : r = oscore_context_init(¶ms_client, &cc);
641 : 1 : zassert_equal(r, ok, "Error in oscore_context_init for client");
642 : :
643 : 1 : struct context cs; //context of the server
644 : 1 : struct oscore_init_params params_server =
645 : 1 : get_default_params(REVERSED, RESTORED);
646 : 1 : r = oscore_context_init(¶ms_server, &cs);
647 : 1 : zassert_equal(r, ok, "Error in oscore_context_init for server");
648 : :
649 : : /*coap and oscore buffers*/
650 : 1 : uint8_t coap_pkt[40];
651 : 1 : uint8_t oscore_pkt[60];
652 : 1 : uint8_t conv_coap_pkt[40];
653 : 1 : uint32_t coap_pkt_len;
654 : 1 : uint32_t oscore_pkt_len;
655 : 1 : uint32_t conv_coap_pkt_len;
656 : :
657 : : /*Expected OSCORE values*/
658 : 1 : const uint8_t OSCORE_REQ1[] = { 0x41, 0x02, 0x00, 0x00, 0x4A, 0x92,
659 : : 0x09, 0x14, 0xFF, 0x61, 0x27, 0x10,
660 : : 0x81, 0xAD, 0xF0, 0x0E, 0xEA, 0x55,
661 : : 0xF1, 0x52, 0x39, 0x6C, 0xA3, 0x72,
662 : : 0x46, 0x96, 0x73, 0xB2, 0x09, 0xF7 };
663 : :
664 : 1 : const uint8_t OSCORE_RESP1[] = { 0x61, 0x44, 0x00, 0x00, 0x4A, 0x93,
665 : : 0x09, 0x14, 0x01, 0xFF, 0xBC, 0xB9,
666 : : 0x3C, 0xA6, 0x0E, 0xF7, 0x11, 0x52,
667 : : 0x39, 0x45, 0x1B, 0xEA, 0x4C, 0x81,
668 : : 0x90, 0xCA, 0x60, 0x38, 0x76, 0xD6,
669 : : 0x09, 0xDE, 0x46 };
670 : :
671 : 1 : const uint8_t OSCORE_RESP2[] = { 0x61, 0x44, 0x00, 0x00, 0x4A, 0x93,
672 : : 0x09, 0x15, 0x01, 0xFF, 0x97, 0xA4,
673 : : 0x25, 0x7B, 0x17, 0x39, 0xC0, 0x1D,
674 : : 0x5E, 0x9D, 0xDA, 0x02, 0x74, 0xDB,
675 : : 0xD4, 0xBF, 0xE6, 0x82, 0x18, 0x9B,
676 : : 0x3B, 0xBF, 0x0E };
677 : :
678 : 1 : const uint8_t OSCORE_REQ3[] = {
679 : : 0x41, 0x02, 0x00, 0x00, 0x4B, 0x92, 0x09, 0x16, 0xFF,
680 : : 0x8C, 0x2F, 0xED, 0xB3, 0xBB, 0xCD, 0xEE, 0x17, 0xB0,
681 : : 0x12, 0x03, 0x95, 0x74, 0xD8, 0x08, 0x55, 0x40, 0x53,
682 : : 0x82, 0x2B, 0x3C, 0x79, 0xA5, 0x1B, 0xCA, 0xFC, 0xC9,
683 : : 0xD0, 0xC6, 0x35, 0x50, 0xDC, 0x5D, 0x1D, 0x13
684 : : };
685 : :
686 : 1 : const uint8_t OSCORE_RESP3[] = { 0x61, 0x44, 0x00, 0x00, 0x4B, 0x93,
687 : : 0x09, 0x16, 0x01, 0xFF, 0x9B, 0xE4,
688 : : 0x04, 0x05, 0x9F, 0x1C, 0xCE, 0x6A,
689 : : 0x43, 0x85, 0xD2, 0xD7, 0x12, 0x52,
690 : : 0x49, 0xB2, 0x8A, 0xD7, 0xD5, 0x0A,
691 : : 0x67, 0x09, 0x82 };
692 : :
693 : 1 : const uint8_t OSCORE_REQ4[] = {
694 : : 0x41, 0x02, 0x00, 0x00, 0x4B, 0x92, 0x09, 0x17, 0xFF,
695 : : 0xCD, 0x4A, 0x87, 0x1E, 0xCD, 0xE0, 0x07, 0xD2, 0xCB,
696 : : 0xF5, 0xC4, 0x76, 0x84, 0x1E, 0x4C, 0x94, 0x39, 0xCE,
697 : : 0x82, 0x6F, 0x1A, 0xF6, 0xB4, 0xC1, 0x68, 0xE6, 0xB3,
698 : : 0xBB, 0xDB, 0x8B, 0x84, 0x4F, 0xDE, 0x95, 0x94
699 : : };
700 : :
701 : 1 : const uint8_t OSCORE_RESP4[] = { 0x61, 0x44, 0x00, 0x00, 0x4B, 0x90,
702 : : 0xFF, 0x5E, 0x04, 0x3E, 0xD6, 0x11,
703 : : 0x1F, 0xE7, 0xF7, 0x9D, 0x1E, 0x5F,
704 : : 0x30, 0x27, 0x30 };
705 : :
706 : : /**********************************************************************/
707 : : /*1) |------request----------------------------->| */
708 : : /* |<-----response with ECHO option (ECHO1)----| */
709 : : /**********************************************************************/
710 : : /*
711 : : *
712 : : * First request
713 : : *
714 : : */
715 : 1 : PRINT_MSG("\n\n |------request----------------------------->| \n\n");
716 : 1 : uint8_t uri_path_val[] = { 't', 'e', 'm', 'p', 'e', 'r',
717 : : 'a', 't', 'u', 'r', 'e' };
718 : 1 : uint8_t token[] = { 0x4a };
719 : :
720 : 1 : struct o_coap_packet coap_pkt_req1 = {
721 : : .header = {
722 : : .ver = 1,
723 : : .type = TYPE_CON,
724 : : .TKL = 1,
725 : : .code = CODE_REQ_GET,
726 : : .MID = 0x0
727 : : },
728 : : .token = token,
729 : : .options_cnt = 1,
730 : : .options = {
731 : : { .delta = 11,
732 : : .len = sizeof(uri_path_val),
733 : : .value = uri_path_val,
734 : : .option_number = URI_PATH},/*E, opt num 11*/
735 : : },
736 : : .payload.len = 0,
737 : : .payload.ptr = NULL,
738 : : };
739 : :
740 : 1 : coap_pkt_len = sizeof(coap_pkt);
741 : 1 : r = coap_serialize(&coap_pkt_req1, coap_pkt, &coap_pkt_len);
742 : 1 : zassert_equal(r, ok, "req1 serialization failed!");
743 : :
744 : 1 : PRINT_ARRAY("CoAP req1", coap_pkt, coap_pkt_len);
745 : :
746 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
747 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
748 : : &cc);
749 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
750 : 1 : PRINT_ARRAY("OSCORE req1", oscore_pkt, oscore_pkt_len);
751 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_REQ1, sizeof(OSCORE_REQ1),
752 : : "coap2oscore failed");
753 : :
754 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
755 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
756 : : &conv_coap_pkt_len, &cs);
757 : :
758 : 1 : zassert_equal(r, first_request_after_reboot, "Error in oscore2coap!");
759 : :
760 : : /*
761 : : *
762 : : * Response with ECHO option
763 : : *
764 : : *
765 : : */
766 : 1 : PRINT_MSG("\n\n |<-----response with ECHO option (ECHO1)----| \n\n");
767 : :
768 : : /*Test first the rejection of CoAP packets without an echo option*/
769 : 1 : PRINT_MSG(
770 : 1 : "Try first supplying a CoAP message without an ECHO option\n");
771 : 1 : uint8_t COAP_RESP_WITHOUT_ECHO[] = { 0x61, 0x81, 0x00, 0x00, 0x4A };
772 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
773 : 1 : r = coap2oscore(COAP_RESP_WITHOUT_ECHO, sizeof(COAP_RESP_WITHOUT_ECHO),
774 : : oscore_pkt, &oscore_pkt_len, &cs);
775 : 1 : zassert_equal(r, no_echo_option, "Error in coap2oscore!");
776 : :
777 : : /* do it now the correct way -- with ECHO option*/
778 : 1 : uint8_t echo_opt_val1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
779 : : 0x06, 0x07, 0x08, 0x09, 0x10, 0x11 };
780 : :
781 : 1 : struct o_coap_packet coap_pkt_resp1 = {
782 : : .header = { .ver = 1,
783 : : .type = TYPE_ACK,
784 : : .TKL = 1,
785 : : .code = CODE_RESP_UNAUTHORIZED,
786 : : .MID = 0x0 },
787 : : .token = token,
788 : : .options_cnt = 1,
789 : : .options = { { .delta = 252,
790 : : .len = sizeof(echo_opt_val1),
791 : : .value = echo_opt_val1,
792 : : .option_number = ECHO } },
793 : : .payload.len = 0,
794 : : .payload.ptr = NULL,
795 : : };
796 : :
797 : 1 : coap_pkt_len = sizeof(coap_pkt);
798 : 1 : r = coap_serialize(&coap_pkt_resp1, coap_pkt, &coap_pkt_len);
799 : 1 : zassert_equal(r, ok, "Error in coap_serialize");
800 : :
801 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
802 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
803 : : &cs);
804 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
805 : :
806 : 1 : PRINT_ARRAY("OSCORE resp1", oscore_pkt, oscore_pkt_len);
807 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_RESP1, sizeof(OSCORE_RESP1),
808 : : "coap2oscore failed");
809 : :
810 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
811 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
812 : : &conv_coap_pkt_len, &cc);
813 : :
814 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
815 : 1 : zassert_mem_equal__(conv_coap_pkt, coap_pkt, conv_coap_pkt_len,
816 : : "oscore2coap failed");
817 : :
818 : : /**************************************************************************/
819 : : /* 2) |------new request without ECHO opt-------->| */
820 : : /* |<-----response with new ECHO option (ECHO2)| */
821 : : /**************************************************************************/
822 : : /*
823 : : *
824 : : * Request
825 : : *
826 : : */
827 : 1 : PRINT_MSG("\n\n|------new request without ECHO opt-------->| \n\n");
828 : 1 : uint8_t COAP_REQ_WITHOUT_ECHO[] = { 0x41, 0x01, 0x00, 0x00, 0x4A };
829 : :
830 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
831 : 1 : r = coap2oscore(COAP_REQ_WITHOUT_ECHO, sizeof(COAP_REQ_WITHOUT_ECHO),
832 : : oscore_pkt, &oscore_pkt_len, &cc);
833 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
834 : :
835 : 1 : PRINT_ARRAY("OSCORE req2", oscore_pkt, oscore_pkt_len);
836 : :
837 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
838 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
839 : : &conv_coap_pkt_len, &cs);
840 : :
841 : 1 : zassert_equal(r, echo_validation_failed, "Error in oscore2coap!");
842 : :
843 : : /*
844 : : *
845 : : * Response
846 : : *
847 : : */
848 : 1 : PRINT_MSG("\n\n|<-----response with new ECHO option (ECHO2)|\n\n");
849 : 1 : uint8_t echo_opt_val2[] = {
850 : : 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
851 : : 0x06, 0x07, 0x08, 0x09, 0x10, 0x22
852 : : }; /*last byte is different*/
853 : 1 : struct o_coap_packet coap_pkt_resp2 = {
854 : : .header = { .ver = 1,
855 : : .type = TYPE_ACK,
856 : : .TKL = 1,
857 : : .code = CODE_RESP_UNAUTHORIZED,
858 : : .MID = 0x0 },
859 : : .token = token,
860 : : .options_cnt = 1,
861 : : .options = { { .delta = 252,
862 : : .len = sizeof(echo_opt_val2),
863 : : .value = echo_opt_val2,
864 : : .option_number = ECHO } },
865 : : .payload.len = 0,
866 : : .payload.ptr = NULL,
867 : : };
868 : :
869 : 1 : coap_pkt_len = sizeof(coap_pkt);
870 : 1 : r = coap_serialize(&coap_pkt_resp2, coap_pkt, &coap_pkt_len);
871 : 1 : zassert_equal(r, ok, "Error in coap_serialize!");
872 : :
873 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
874 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
875 : : &cs);
876 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
877 : :
878 : 1 : PRINT_ARRAY("OSCORE resp2", oscore_pkt, oscore_pkt_len);
879 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_RESP2, oscore_pkt_len,
880 : : "coap2oscore failed");
881 : :
882 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
883 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
884 : : &conv_coap_pkt_len, &cc);
885 : :
886 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
887 : :
888 : 1 : zassert_mem_equal__(conv_coap_pkt, coap_pkt, coap_pkt_len,
889 : : "oscore2coap failed");
890 : :
891 : : /**************************************************************************/
892 : : /* 3) |------request with old ECHO option-(ECHO1)>|*/
893 : : /* |<-----response with new ECHO option (ECHO3)|*/
894 : : /**************************************************************************/
895 : : /*
896 : : *
897 : : * Request with old ECHO option-(ECHO1)
898 : : *
899 : : */
900 : 1 : PRINT_MSG("\n\n |-------request with old ECHO option-(ECHO1)>|| \n\n");
901 : 1 : token[0] = 0x4b;
902 : :
903 : 1 : struct o_coap_packet coap_pkt_req2 = {
904 : : .header = {
905 : : .ver = 1,
906 : : .type = TYPE_CON,
907 : : .TKL = 1,
908 : : .code = CODE_REQ_GET,
909 : : .MID = 0x0
910 : : },
911 : : .token = token,
912 : : .options_cnt = 2,
913 : : .options = {
914 : : {
915 : : .delta = 11,
916 : : .len = sizeof(uri_path_val),
917 : : .value = uri_path_val,
918 : : .option_number = URI_PATH},/*E, opt num 11*/
919 : : {
920 : : .delta = 241,
921 : : .len = sizeof(echo_opt_val1),
922 : : .value = echo_opt_val1,
923 : : .option_number = ECHO},/*ECHO, opt num 252*/
924 : : },
925 : : .payload.len = 0,
926 : : .payload.ptr = NULL,
927 : : };
928 : :
929 : 1 : coap_pkt_len = sizeof(coap_pkt);
930 : 1 : r = coap_serialize(&coap_pkt_req2, coap_pkt, &coap_pkt_len);
931 : 1 : zassert_equal(r, ok, "Error in coap_serialize !");
932 : :
933 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
934 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
935 : : &cc);
936 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
937 : :
938 : 1 : PRINT_ARRAY("OSCORE req3", oscore_pkt, oscore_pkt_len);
939 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_REQ3, oscore_pkt_len,
940 : : "coap2oscore failed");
941 : :
942 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
943 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
944 : : &conv_coap_pkt_len, &cs);
945 : :
946 : 1 : zassert_equal(r, echo_validation_failed, "Error in oscore2coap!");
947 : :
948 : : /*
949 : : *
950 : : * Response option ECHO3
951 : : *
952 : : */
953 : 1 : PRINT_MSG("\n\n|<-----response with new ECHO option (ECHO2)|\n\n");
954 : 1 : uint8_t echo_opt_val3[] = {
955 : : 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
956 : : 0x06, 0x07, 0x08, 0x09, 0x10, 0x33
957 : : }; /*last byte is different*/
958 : 1 : struct o_coap_packet coap_pkt_resp3 = {
959 : : .header = { .ver = 1,
960 : : .type = TYPE_ACK,
961 : : .TKL = 1,
962 : : .code = CODE_RESP_UNAUTHORIZED,
963 : : .MID = 0x0 },
964 : : .token = token,
965 : : .options_cnt = 1,
966 : : .options = { { .delta = 252,
967 : : .len = sizeof(echo_opt_val3),
968 : : .value = echo_opt_val3,
969 : : .option_number = ECHO } },
970 : : .payload.len = 0,
971 : : .payload.ptr = NULL,
972 : : };
973 : :
974 : 1 : coap_pkt_len = sizeof(coap_pkt);
975 : 1 : r = coap_serialize(&coap_pkt_resp3, coap_pkt, &coap_pkt_len);
976 : 1 : zassert_equal(r, ok, "Error in coap_serialize!");
977 : :
978 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
979 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
980 : : &cs);
981 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
982 : :
983 : 1 : PRINT_ARRAY("OSCORE resp3", oscore_pkt, oscore_pkt_len);
984 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_RESP3, oscore_pkt_len,
985 : : "coap2oscore failed");
986 : :
987 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
988 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
989 : : &conv_coap_pkt_len, &cc);
990 : :
991 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
992 : :
993 : 1 : zassert_mem_equal__(conv_coap_pkt, coap_pkt, coap_pkt_len,
994 : : "oscore2coap failed");
995 : :
996 : : /**************************************************************************/
997 : : /* 4) |------request with ECHO option-(ECHO3)---->|*/
998 : : /* |<-----response-----------------------------|*/
999 : : /**************************************************************************/
1000 : :
1001 : : /*
1002 : : *
1003 : : * Request with ECHO option
1004 : : *
1005 : : */
1006 : 1 : PRINT_MSG("\n\n |------request with ECHO option-(ECHO3)---->| \n\n");
1007 : 1 : struct o_coap_packet coap_pkt_req4 = {
1008 : : .header = {
1009 : : .ver = 1,
1010 : : .type = TYPE_CON,
1011 : : .TKL = 1,
1012 : : .code = CODE_REQ_GET,
1013 : : .MID = 0x0
1014 : : },
1015 : : .token = token,
1016 : : .options_cnt = 2,
1017 : : .options = {
1018 : : {
1019 : : .delta = 11,
1020 : : .len = sizeof(uri_path_val),
1021 : : .value = uri_path_val,
1022 : : .option_number = URI_PATH},/*E, opt num 11*/
1023 : : {
1024 : : .delta = 241,
1025 : : .len = sizeof(echo_opt_val3),
1026 : : .value = echo_opt_val3,
1027 : : .option_number = ECHO},/*ECHO, opt num 252*/
1028 : : },
1029 : : .payload.len = 0,
1030 : : .payload.ptr = NULL,
1031 : : };
1032 : :
1033 : 1 : coap_pkt_len = sizeof(coap_pkt);
1034 : 1 : r = coap_serialize(&coap_pkt_req4, coap_pkt, &coap_pkt_len);
1035 : 1 : zassert_equal(r, ok, "Error in coap_serialize!");
1036 : :
1037 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
1038 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
1039 : : &cc);
1040 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
1041 : :
1042 : 1 : PRINT_ARRAY("OSCORE req4", oscore_pkt, oscore_pkt_len);
1043 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_REQ4, oscore_pkt_len,
1044 : : "coap2oscore failed");
1045 : :
1046 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
1047 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
1048 : : &conv_coap_pkt_len, &cs);
1049 : :
1050 : 1 : zassert_equal(r, 0, "Error in oscore2coap!");
1051 : 1 : zassert_mem_equal__(conv_coap_pkt, coap_pkt, coap_pkt_len,
1052 : : "oscore2coap failed");
1053 : :
1054 : : /*
1055 : : *
1056 : : * Normal response
1057 : : *
1058 : : */
1059 : 1 : PRINT_MSG("\n\n |<------response2 ----| \n\n");
1060 : 1 : uint8_t payload[] = { 0xde, 0xad, 0xbe, 0xaf };
1061 : :
1062 : 1 : struct o_coap_packet coap_pkt_resp4 = {
1063 : : .header = { .ver = 1,
1064 : : .type = TYPE_ACK,
1065 : : .TKL = 1,
1066 : : .code = CODE_RESP_CONTENT,
1067 : : .MID = 0x0 },
1068 : : .token = token,
1069 : : .options_cnt = 0,
1070 : : .options = {},
1071 : : .payload.len = sizeof(payload),
1072 : : .payload.ptr = payload,
1073 : : };
1074 : :
1075 : 1 : coap_pkt_len = sizeof(coap_pkt);
1076 : 1 : r = coap_serialize(&coap_pkt_resp4, coap_pkt, &coap_pkt_len);
1077 : 1 : zassert_equal(r, ok, "Error in coap_serialize !");
1078 : :
1079 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
1080 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
1081 : : &cs);
1082 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
1083 : :
1084 : 1 : PRINT_ARRAY("OSCORE resp4", oscore_pkt, oscore_pkt_len);
1085 : 1 : zassert_mem_equal__(oscore_pkt, OSCORE_RESP4, oscore_pkt_len,
1086 : : "coap2oscore failed");
1087 : :
1088 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
1089 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
1090 : : &conv_coap_pkt_len, &cc);
1091 : :
1092 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
1093 : 1 : zassert_mem_equal__(conv_coap_pkt, coap_pkt, coap_pkt_len,
1094 : : "oscore2coap failed");
1095 : :
1096 : : /**************************************************************************/
1097 : : /* 5) |------request----------------------------->| */
1098 : : /* | -- -- --replayed request-- -- -- -- --X | rejected message*/
1099 : : /**************************************************************************/
1100 : :
1101 : : /*
1102 : : *
1103 : : * Test replay protection on the server side
1104 : : *
1105 : : *
1106 : : */
1107 : 1 : PRINT_MSG(
1108 : 1 : "\n\n |------ regular request (to be replayed later)---->| \n\n");
1109 : 1 : token[0] = 0x4a;
1110 : :
1111 : 1 : struct o_coap_packet coap_pkt_req5 = {
1112 : : .header = {
1113 : : .ver = 1,
1114 : : .type = TYPE_CON,
1115 : : .TKL = 1,
1116 : : .code = CODE_REQ_GET,
1117 : : .MID = 0x0
1118 : : },
1119 : : .token = token,
1120 : : .options_cnt = 1,
1121 : : .options = {
1122 : : { .delta = 11,
1123 : : .len = sizeof(uri_path_val),
1124 : : .value = uri_path_val,
1125 : : .option_number = URI_PATH},/*E, opt num 11*/
1126 : : },
1127 : : .payload.len = 0,
1128 : : .payload.ptr = NULL,
1129 : : };
1130 : :
1131 : 1 : coap_pkt_len = sizeof(coap_pkt);
1132 : 1 : r = coap_serialize(&coap_pkt_req5, coap_pkt, &coap_pkt_len);
1133 : 1 : zassert_equal(r, ok, "Error in coap_serialize!");
1134 : :
1135 : 1 : oscore_pkt_len = sizeof(oscore_pkt);
1136 : 1 : r = coap2oscore(coap_pkt, coap_pkt_len, oscore_pkt, &oscore_pkt_len,
1137 : : &cc);
1138 : 1 : zassert_equal(r, ok, "Error in coap2oscore!");
1139 : :
1140 : 1 : conv_coap_pkt_len = sizeof(conv_coap_pkt);
1141 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
1142 : : &conv_coap_pkt_len, &cs);
1143 : 1 : zassert_equal(r, ok, "Error in oscore2coap!");
1144 : :
1145 : : /*try to replay the request*/
1146 : 1 : r = oscore2coap(oscore_pkt, oscore_pkt_len, conv_coap_pkt,
1147 : : &conv_coap_pkt_len, &cs);
1148 : :
1149 : 1 : zassert_equal(r, oscore_replay_window_protection_error,
1150 : : "Error in oscore2coap!");
1151 : 1 : }
1152 : :
1153 : : /**
1154 : : * Test 11:
1155 : : * According to RFC8613 p. 7.2.1, endpoint must not process any more message after reaching its final SSN value.
1156 : : */
1157 : 0 : void t11_oscore_ssn_overflow_protection(void)
1158 : : {
1159 : 0 : enum err result;
1160 : 0 : struct context security_context;
1161 : 0 : struct oscore_init_params params = get_default_params(NORMAL, RESTORED);
1162 : :
1163 : 0 : uint8_t buf_oscore[256];
1164 : 0 : uint32_t buf_oscore_len = sizeof(buf_oscore);
1165 : 0 : uint8_t buf_coap[256];
1166 : 0 : uint32_t buf_coap_len = sizeof(buf_coap);
1167 : :
1168 : 0 : result = oscore_context_init(¶ms, &security_context);
1169 : 0 : zassert_equal(result, ok, "Error in oscore_context_init");
1170 : :
1171 : : /* mimic reaching final value of SSN */
1172 : 0 : security_context.sc.ssn = OSCORE_SSN_OVERFLOW_VALUE;
1173 : :
1174 : : /* test SSN overflow protection in coap2oscore */
1175 : 0 : result = coap2oscore((uint8_t *)T1__COAP_REQ, T1__COAP_REQ_LEN,
1176 : : (uint8_t *)&buf_oscore, &buf_oscore_len,
1177 : : &security_context);
1178 : 0 : zassert_equal(result, oscore_ssn_overflow,
1179 : : "SSN overflow not detected in coap2oscore");
1180 : :
1181 : : /* test SSN overflow protection in oscore2coap */
1182 : 0 : result = oscore2coap((uint8_t *)T1__OSCORE_RESP, T1__OSCORE_RESP_LEN,
1183 : : (uint8_t *)&buf_coap, &buf_coap_len,
1184 : : &security_context);
1185 : 0 : zassert_equal(result, oscore_ssn_overflow,
1186 : : "SSN overflow not detected in oscore2coap");
1187 : 0 : }
|