1 /*
2  * Copyright (c) 2021 Fraunhofer AISEC.
3  *
4  * SPDX-License-Identifier: Apache-2.0
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 /**
15  * Test 1:
16  * - Client Key derivation with master salt see RFC8613 Appendix C.1.1
17  * - Generating OSCORE request with key form C.1.1 see RFC8613 Appendix C.4
18  */
ZTEST(oscore_tests,test_oscore_client_test1)19 ZTEST(oscore_tests, test_oscore_client_test1)
20 {
21 	enum err r;
22 	struct context c_client;
23 	struct oscore_init_params params = {
24 		.master_secret.ptr = (uint8_t *)T1__MASTER_SECRET,
25 		.master_secret.len = T1__MASTER_SECRET_LEN,
26 		.sender_id.ptr = (uint8_t *)T1__SENDER_ID,
27 		.sender_id.len = T1__SENDER_ID_LEN,
28 		.recipient_id.ptr = (uint8_t *)T1__RECIPIENT_ID,
29 		.recipient_id.len = T1__RECIPIENT_ID_LEN,
30 		.master_salt.ptr = (uint8_t *)T1__MASTER_SALT,
31 		.master_salt.len = T1__MASTER_SALT_LEN,
32 		.id_context.ptr = (uint8_t *)T1__ID_CONTEXT,
33 		.id_context.len = T1__ID_CONTEXT_LEN,
34 		.aead_alg = OSCORE_AES_CCM_16_64_128,
35 		.hkdf = OSCORE_SHA_256,
36 		.fresh_master_secret_salt = true,
37 	};
38 
39 	r = oscore_context_init(&params, &c_client);
40 
41 	zassert_equal(r, ok, "Error in oscore_context_init");
42 
43 	/*
44 	 * required only for the test vector.
45 	 * during normal operation the sender sequence number is
46 	 * increased automatically after every sending
47 	 */
48 	c_client.sc.ssn = 20;
49 
50 	uint8_t buf_oscore[256];
51 	uint32_t buf_oscore_len = sizeof(buf_oscore);
52 
53 	r = coap2oscore((uint8_t *)T1__COAP_REQ, T1__COAP_REQ_LEN,
54 			(uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
55 	zassert_equal(r, ok, "Error in coap2oscore!");
56 
57 	zassert_mem_equal__(c_client.sc.sender_key.ptr, T1__SENDER_KEY,
58 			    c_client.sc.sender_key.len,
59 			    "T1 sender key derivation failed");
60 
61 	zassert_mem_equal__(c_client.rc.recipient_key.ptr, T1__RECIPIENT_KEY,
62 			    c_client.rc.recipient_key.len,
63 			    "T1 recipient key derivation failed");
64 
65 	zassert_mem_equal__(c_client.cc.common_iv.ptr, T1__COMMON_IV,
66 			    c_client.cc.common_iv.len,
67 			    "T1 common IV derivation failed");
68 
69 	zassert_mem_equal__(&buf_oscore, T1__OSCORE_REQ, T1__OSCORE_REQ_LEN,
70 			    "coap2oscore failed");
71 }
72 
73 /**
74  * Test 3:
75  * - Client Key derivation without master salt see RFC8613 Appendix C.2.1
76  * - Generating OSCORE request with key form C.2.1 see RFC8613 Appendix C.5
77  */
ZTEST(oscore_tests,test_oscore_client_test3)78 ZTEST(oscore_tests, test_oscore_client_test3)
79 {
80 	enum err r;
81 	struct context c_client;
82 	struct oscore_init_params params = {
83 		.master_secret.ptr = (uint8_t *)T3__MASTER_SECRET,
84 		.master_secret.len = T3__MASTER_SECRET_LEN,
85 		.sender_id.ptr = (uint8_t *)T3__SENDER_ID,
86 		.sender_id.len = T3__SENDER_ID_LEN,
87 		.recipient_id.ptr = (uint8_t *)T3__RECIPIENT_ID,
88 		.recipient_id.len = T3__RECIPIENT_ID_LEN,
89 		.master_salt.ptr = (uint8_t *)T3__MASTER_SALT,
90 		.master_salt.len = T3__MASTER_SALT_LEN,
91 		.id_context.ptr = (uint8_t *)T3__ID_CONTEXT,
92 		.id_context.len = T3__ID_CONTEXT_LEN,
93 		.aead_alg = OSCORE_AES_CCM_16_64_128,
94 		.hkdf = OSCORE_SHA_256,
95 		.fresh_master_secret_salt = true,
96 	};
97 
98 	r = oscore_context_init(&params, &c_client);
99 
100 	zassert_equal(r, ok, "Error in oscore_context_init");
101 
102 	/*
103 	 * required only for the test vector.
104 	 * during normal operation the sender sequence number is
105 	 * increased automatically after every sending
106 	 */
107 	c_client.sc.ssn = 20;
108 
109 	uint8_t buf_oscore[256];
110 	uint32_t buf_oscore_len = sizeof(buf_oscore);
111 
112 	r = coap2oscore((uint8_t *)T3__COAP_REQ, T3__COAP_REQ_LEN,
113 			(uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
114 
115 	zassert_equal(r, ok, "Error in coap2oscore!");
116 
117 	zassert_mem_equal__(&buf_oscore, T3__OSCORE_REQ, T3__OSCORE_REQ_LEN,
118 			    "coap2oscore failed");
119 }
120 
121 /**
122  * Test 5 :
123  * - Client Key derivation with ID Context see Appendix 3.1
124  * - OSCORE request generation see Appendix C6
125  */
ZTEST(oscore_tests,test_oscore_client_test5)126 ZTEST(oscore_tests, test_oscore_client_test5)
127 {
128 	enum err r;
129 	struct context c_client;
130 	struct oscore_init_params params = {
131 		.master_secret.ptr = (uint8_t *)T5__MASTER_SECRET,
132 		.master_secret.len = T5__MASTER_SECRET_LEN,
133 		.sender_id.ptr = (uint8_t *)T5__SENDER_ID,
134 		.sender_id.len = T5__SENDER_ID_LEN,
135 		.recipient_id.ptr = (uint8_t *)T5__RECIPIENT_ID,
136 		.recipient_id.len = T5__RECIPIENT_ID_LEN,
137 		.master_salt.ptr = (uint8_t *)T5__MASTER_SALT,
138 		.master_salt.len = T5__MASTER_SALT_LEN,
139 		.id_context.ptr = (uint8_t *)T5__ID_CONTEXT,
140 		.id_context.len = T5__ID_CONTEXT_LEN,
141 		.aead_alg = OSCORE_AES_CCM_16_64_128,
142 		.hkdf = OSCORE_SHA_256,
143 		.fresh_master_secret_salt = true,
144 	};
145 
146 	r = oscore_context_init(&params, &c_client);
147 
148 	zassert_equal(r, ok, "Error in oscore_context_init");
149 
150 	/*
151 	 * required only for the test vector.
152 	 * during normal operation the sender sequence number is
153 	 * increased automatically after every sending
154 	 */
155 	c_client.sc.ssn = 20;
156 
157 	uint8_t buf_oscore[256];
158 	uint32_t buf_oscore_len = sizeof(buf_oscore);
159 
160 	r = coap2oscore((uint8_t *)T5__COAP_REQ, T5__COAP_REQ_LEN,
161 			(uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
162 
163 	zassert_equal(r, ok, "Error in coap2oscore!");
164 
165 	zassert_mem_equal__(&buf_oscore, T5__OSCORE_REQ, buf_oscore_len,
166 			    "coap2oscore failed");
167 }
168 
169 /**
170  * Test 2:
171  * - Server Key derivation with master salt see RFC8613 Appendix C.1.2
172  * - Generating OSCORE response with key form C.1.2 see RFC8613 Appendix C.7
173  */
ZTEST(oscore_tests,test_oscore_server_test2)174 ZTEST(oscore_tests, test_oscore_server_test2)
175 {
176 	enum err r;
177 	struct context c_server;
178 	struct oscore_init_params params_server = {
179 		.master_secret.ptr = (uint8_t *)T2__MASTER_SECRET,
180 		.master_secret.len = T2__MASTER_SECRET_LEN,
181 		.sender_id.ptr = (uint8_t *)T2__SENDER_ID,
182 		.sender_id.len = T2__SENDER_ID_LEN,
183 		.recipient_id.ptr = (uint8_t *)T2__RECIPIENT_ID,
184 		.recipient_id.len = T2__RECIPIENT_ID_LEN,
185 		.master_salt.ptr = (uint8_t *)T2__MASTER_SALT,
186 		.master_salt.len = T2__MASTER_SALT_LEN,
187 		.id_context.ptr = (uint8_t *)T2__ID_CONTEXT,
188 		.id_context.len = T2__ID_CONTEXT_LEN,
189 		.aead_alg = OSCORE_AES_CCM_16_64_128,
190 		.hkdf = OSCORE_SHA_256,
191 		.fresh_master_secret_salt = true,
192 	};
193 
194 	r = oscore_context_init(&params_server, &c_server);
195 
196 	zassert_equal(r, ok, "Error in oscore_context_init");
197 
198 	/* Test decrypting of an incoming request */
199 	uint8_t buf_coap[256];
200 	uint32_t buf_coap_len = sizeof(buf_coap);
201 
202 	r = oscore2coap((uint8_t *)T2__OSCORE_REQ, T2__OSCORE_REQ_LEN, buf_coap,
203 			&buf_coap_len, &c_server);
204 
205 	zassert_equal(r, ok, "Error in oscore2coap!");
206 	zassert_mem_equal__(&buf_coap, T2__COAP_REQ, buf_coap_len,
207 			    "oscore2coap failed");
208 
209 	/* Test generating an encrypted response, see Appendix C7 */
210 	uint8_t buf_oscore[256];
211 	uint32_t buf_oscore_len = sizeof(buf_oscore);
212 
213 	r = coap2oscore((uint8_t *)T2__COAP_RESPONSE, T2__COAP_RESPONSE_LEN,
214 			(uint8_t *)&buf_oscore, &buf_oscore_len, &c_server);
215 
216 	zassert_equal(r, ok, "Error in coap2oscore");
217 
218 	zassert_mem_equal__(&buf_oscore, T2__OSCORE_RESP, buf_oscore_len,
219 			    "coap2oscore failed");
220 }
221 
ZTEST(oscore_tests,test_oscore_server_test4)222 ZTEST(oscore_tests, test_oscore_server_test4)
223 {
224 	enum err r;
225 	struct context c_server;
226 	struct oscore_init_params params_server = {
227 		.master_secret.ptr = (uint8_t *)T4__MASTER_SECRET,
228 		.master_secret.len = T4__MASTER_SECRET_LEN,
229 		.sender_id.ptr = (uint8_t *)T4__SENDER_ID,
230 		.sender_id.len = T4__SENDER_ID_LEN,
231 		.recipient_id.ptr = (uint8_t *)T4__RECIPIENT_ID,
232 		.recipient_id.len = T4__RECIPIENT_ID_LEN,
233 		.master_salt.ptr = (uint8_t *)T4__MASTER_SALT,
234 		.master_salt.len = T4__MASTER_SALT_LEN,
235 		.id_context.ptr = (uint8_t *)T4__ID_CONTEXT,
236 		.id_context.len = T4__ID_CONTEXT_LEN,
237 		.aead_alg = OSCORE_AES_CCM_16_64_128,
238 		.hkdf = OSCORE_SHA_256,
239 		.fresh_master_secret_salt = true,
240 	};
241 
242 	r = oscore_context_init(&params_server, &c_server);
243 
244 	zassert_equal(r, ok, "Error in oscore_context_init");
245 
246 	zassert_mem_equal__(c_server.sc.sender_key.ptr, T4__SENDER_KEY,
247 			    c_server.sc.sender_key.len,
248 			    "T4 sender key derivation failed");
249 
250 	zassert_mem_equal__(c_server.rc.recipient_key.ptr, T4__RECIPIENT_KEY,
251 			    c_server.rc.recipient_key.len,
252 			    "T4 recipient key derivation failed");
253 
254 	zassert_mem_equal__(c_server.cc.common_iv.ptr, T4__COMMON_IV,
255 			    c_server.cc.common_iv.len,
256 			    "T4 common IV derivation failed");
257 }
258 
259 /**
260  * Test 6:
261  * - Server Key derivation with ID context see RFC8613 Appendix C.3.2
262  */
ZTEST(oscore_tests,test_oscore_server_test6)263 ZTEST(oscore_tests, test_oscore_server_test6)
264 {
265 	enum err r;
266 	struct context c_server;
267 	struct oscore_init_params params_server = {
268 		.master_secret.ptr = (uint8_t *)T6__MASTER_SECRET,
269 		.master_secret.len = T6__MASTER_SECRET_LEN,
270 		.sender_id.ptr = (uint8_t *)T6__SENDER_ID,
271 		.sender_id.len = T6__SENDER_ID_LEN,
272 		.recipient_id.ptr = (uint8_t *)T6__RECIPIENT_ID,
273 		.recipient_id.len = T6__RECIPIENT_ID_LEN,
274 		.master_salt.ptr = (uint8_t *)T6__MASTER_SALT,
275 		.master_salt.len = T6__MASTER_SALT_LEN,
276 		.id_context.ptr = (uint8_t *)T6__ID_CONTEXT,
277 		.id_context.len = T6__ID_CONTEXT_LEN,
278 		.aead_alg = OSCORE_AES_CCM_16_64_128,
279 		.hkdf = OSCORE_SHA_256,
280 		.fresh_master_secret_salt = true,
281 	};
282 
283 	r = oscore_context_init(&params_server, &c_server);
284 
285 	zassert_equal(r, ok, "Error in oscore_context_init");
286 
287 	zassert_mem_equal__(c_server.sc.sender_key.ptr, T6__SENDER_KEY,
288 			    c_server.sc.sender_key.len,
289 			    "T6 sender key derivation failed");
290 
291 	zassert_mem_equal__(c_server.rc.recipient_key.ptr, T6__RECIPIENT_KEY,
292 			    c_server.rc.recipient_key.len,
293 			    "T6 recipient key derivation failed");
294 
295 	zassert_mem_equal__(c_server.cc.common_iv.ptr, T6__COMMON_IV,
296 			    c_server.cc.common_iv.len,
297 			    "T6 common IV derivation failed");
298 }
299 
300 /**
301  * Test 8:
302  * - Simple ACK packet should not be encrypted and result should be the same as
303  *   input buffer (see RFC8613 Section 4.2)
304  */
ZTEST(oscore_tests,test_oscore_misc_test8)305 ZTEST(oscore_tests, test_oscore_misc_test8)
306 {
307 	enum err r;
308 	struct context c;
309 	struct oscore_init_params params = {
310 		.master_secret.ptr = (uint8_t *)T7__MASTER_SECRET,
311 		.master_secret.len = T7__MASTER_SECRET_LEN,
312 		.sender_id.ptr = (uint8_t *)T7__SENDER_ID,
313 		.sender_id.len = T7__SENDER_ID_LEN,
314 		.recipient_id.ptr = (uint8_t *)T7__RECIPIENT_ID,
315 		.recipient_id.len = T7__RECIPIENT_ID_LEN,
316 		.master_salt.ptr = (uint8_t *)T7__MASTER_SALT,
317 		.master_salt.len = T7__MASTER_SALT_LEN,
318 		.id_context.ptr = (uint8_t *)T7__ID_CONTEXT,
319 		.id_context.len = T7__ID_CONTEXT_LEN,
320 		.aead_alg = OSCORE_AES_CCM_16_64_128,
321 		.hkdf = OSCORE_SHA_256,
322 		.fresh_master_secret_salt = true,
323 	};
324 
325 	r = oscore_context_init(&params, &c);
326 
327 	zassert_equal(r, ok, "Error in oscore_context_init");
328 
329 	/* Test if encrypting simple ACK message results in valid unencrypted
330 	 * message, see Section 4.2
331 	 */
332 	uint8_t buf_oscore[256];
333 	uint32_t buf_oscore_len = sizeof(buf_oscore);
334 
335 	r = coap2oscore((uint8_t *)T8__COAP_ACK, T8__COAP_ACK_LEN,
336 			(uint8_t *)&buf_oscore, &buf_oscore_len, &c);
337 
338 	zassert_equal(r, ok, "Error in coap2oscore");
339 
340 	zassert_mem_equal__(&buf_oscore, T8__COAP_ACK, T8__COAP_ACK_LEN,
341 			    "coap2oscore failed");
342 
343 	zassert_equal(buf_oscore_len, T8__COAP_ACK_LEN, "coap2oscore failed");
344 }
345