1 /*
2  * Copyright (c) 2021 Nordic Semiconductor
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "mesh_test.h"
7 #include "mesh/mesh.h"
8 #include "mesh/net.h"
9 #include "mesh/rpl.h"
10 #include "mesh/transport.h"
11 
12 #define LOG_MODULE_NAME test_rpc
13 
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
16 
17 #define WAIT_TIME 60 /*seconds*/
18 #define TEST_DATA_WAITING_TIME 5 /* seconds */
19 #define TEST_DATA_SIZE 20
20 
21 static const struct bt_mesh_test_cfg tx_cfg = {
22 	.addr = 0x0001,
23 	.dev_key = { 0x01 },
24 };
25 static const struct bt_mesh_test_cfg rx_cfg = {
26 	.addr = 0x0002,
27 	.dev_key = { 0x02 },
28 };
29 
30 static uint8_t test_data[TEST_DATA_SIZE];
31 static uint8_t rx_cnt;
32 static bool is_tx_succeeded;
33 
test_tx_init(void)34 static void test_tx_init(void)
35 {
36 	bt_mesh_test_cfg_set(&tx_cfg, WAIT_TIME);
37 }
38 
test_rx_init(void)39 static void test_rx_init(void)
40 {
41 	bt_mesh_test_cfg_set(&rx_cfg, WAIT_TIME);
42 }
43 
tx_started(uint16_t dur,int err,void * data)44 static void tx_started(uint16_t dur, int err, void *data)
45 {
46 	if (err) {
47 		FAIL("Couldn't start sending (err: %d)", err);
48 	}
49 
50 	LOG_INF("Sending started");
51 }
52 
tx_ended(int err,void * data)53 static void tx_ended(int err, void *data)
54 {
55 	struct k_sem *sem = data;
56 
57 	if (err) {
58 		is_tx_succeeded = false;
59 		LOG_INF("Sending failed (%d)", err);
60 	} else {
61 		is_tx_succeeded = true;
62 		LOG_INF("Sending succeeded");
63 	}
64 
65 	k_sem_give(sem);
66 }
67 
rx_ended(uint8_t * data,size_t len)68 static void rx_ended(uint8_t *data, size_t len)
69 {
70 	memset(test_data, rx_cnt++, sizeof(test_data));
71 
72 	if (memcmp(test_data, data, len)) {
73 		FAIL("Unexpected rx data");
74 	}
75 
76 	LOG_INF("Receiving succeeded");
77 }
78 
tx_sar_conf(void)79 static void tx_sar_conf(void)
80 {
81 	/* Reconfigure SAR Transmitter state so that the transport layer doesn't
82 	 * retransmit.
83 	 */
84 	struct bt_mesh_sar_tx tx_set = {
85 		.seg_int_step = CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP,
86 		.unicast_retrans_count = 0,
87 		.unicast_retrans_without_prog_count = 0,
88 		.unicast_retrans_int_step = CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP,
89 		.unicast_retrans_int_inc = CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC,
90 		.multicast_retrans_count = CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT,
91 		.multicast_retrans_int = CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT,
92 	};
93 
94 #if defined(CONFIG_BT_MESH_SAR_CFG)
95 	bt_mesh_test_sar_conf_set(&tx_set, NULL);
96 #else
97 	bt_mesh.sar_tx = tx_set;
98 #endif
99 }
100 
rx_sar_conf(void)101 static void rx_sar_conf(void)
102 {
103 	/* Reconfigure SAR Receiver state so that the transport layer does
104 	 * generate Segmented Acks as rarely as possible.
105 	 */
106 	struct bt_mesh_sar_rx rx_set = {
107 		.seg_thresh = 0x1f,
108 		.ack_delay_inc = 0x7,
109 		.discard_timeout = CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT,
110 		.rx_seg_int_step = 0xf,
111 		.ack_retrans_count = CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT,
112 	};
113 
114 #if defined(CONFIG_BT_MESH_SAR_CFG)
115 	bt_mesh_test_sar_conf_set(NULL, &rx_set);
116 #else
117 	bt_mesh.sar_rx = rx_set;
118 #endif
119 }
120 
test_tx_immediate_replay_attack(void)121 static void test_tx_immediate_replay_attack(void)
122 {
123 	bt_mesh_test_setup();
124 	tx_sar_conf();
125 
126 	static const struct bt_mesh_send_cb send_cb = {
127 		.start = tx_started,
128 		.end = tx_ended,
129 	};
130 	struct k_sem sem;
131 
132 	k_sem_init(&sem, 0, 1);
133 
134 	uint32_t seq = bt_mesh.seq;
135 
136 	for (int i = 0; i < 3; i++) {
137 		is_tx_succeeded = false;
138 
139 		memset(test_data, i, sizeof(test_data));
140 		ASSERT_OK(bt_mesh_test_send_data(rx_cfg.addr, NULL, test_data, sizeof(test_data),
141 						 &send_cb, &sem));
142 
143 		if (k_sem_take(&sem, K_SECONDS(TEST_DATA_WAITING_TIME))) {
144 			LOG_ERR("Send timed out");
145 		}
146 
147 		ASSERT_TRUE(is_tx_succeeded);
148 		/* Let complete advertising of the previous transaction to prevent collisions. */
149 		k_sleep(K_SECONDS(1));
150 	}
151 
152 	bt_mesh.seq = seq;
153 
154 	for (int i = 0; i < 3; i++) {
155 		is_tx_succeeded = true;
156 
157 		memset(test_data, i, sizeof(test_data));
158 		ASSERT_OK(bt_mesh_test_send_data(rx_cfg.addr, NULL, test_data, sizeof(test_data),
159 						 &send_cb, &sem));
160 
161 		if (k_sem_take(&sem, K_SECONDS(TEST_DATA_WAITING_TIME))) {
162 			LOG_ERR("Send timed out");
163 		}
164 
165 		ASSERT_TRUE(!is_tx_succeeded);
166 		/* Let complete advertising of the previous transaction to prevent collisions. */
167 		k_sleep(K_SECONDS(1));
168 	}
169 
170 	PASS();
171 }
172 
test_rx_immediate_replay_attack(void)173 static void test_rx_immediate_replay_attack(void)
174 {
175 	bt_mesh_test_setup();
176 	rx_sar_conf();
177 	bt_mesh_test_data_cb_setup(rx_ended);
178 
179 	k_sleep(K_SECONDS(6 * TEST_DATA_WAITING_TIME));
180 
181 	ASSERT_TRUE_MSG(rx_cnt == 3, "Device didn't receive expected data\n");
182 
183 	PASS();
184 }
185 
test_tx_power_replay_attack(void)186 static void test_tx_power_replay_attack(void)
187 {
188 	bt_mesh_test_setup();
189 	tx_sar_conf();
190 
191 	static const struct bt_mesh_send_cb send_cb = {
192 		.start = tx_started,
193 		.end = tx_ended,
194 	};
195 	struct k_sem sem;
196 
197 	k_sem_init(&sem, 0, 1);
198 
199 	for (int i = 0; i < 3; i++) {
200 		is_tx_succeeded = true;
201 
202 		memset(test_data, i, sizeof(test_data));
203 		ASSERT_OK(bt_mesh_test_send_data(rx_cfg.addr, NULL, test_data, sizeof(test_data),
204 						 &send_cb, &sem));
205 
206 		if (k_sem_take(&sem, K_SECONDS(TEST_DATA_WAITING_TIME))) {
207 			LOG_ERR("Send timed out");
208 		}
209 
210 		ASSERT_TRUE(!is_tx_succeeded);
211 		/* Let complete advertising of the previous transaction to prevent collisions. */
212 		k_sleep(K_SECONDS(1));
213 	}
214 
215 	for (int i = 0; i < 3; i++) {
216 		is_tx_succeeded = false;
217 
218 		memset(test_data, i, sizeof(test_data));
219 		ASSERT_OK(bt_mesh_test_send_data(rx_cfg.addr, NULL, test_data, sizeof(test_data),
220 						 &send_cb, &sem));
221 
222 		if (k_sem_take(&sem, K_SECONDS(TEST_DATA_WAITING_TIME))) {
223 			LOG_ERR("Send timed out");
224 		}
225 
226 		ASSERT_TRUE(is_tx_succeeded);
227 		/* Let complete advertising of the previous transaction to prevent collisions. */
228 		k_sleep(K_SECONDS(1));
229 	}
230 
231 	PASS();
232 }
233 
test_rx_power_replay_attack(void)234 static void test_rx_power_replay_attack(void)
235 {
236 	bt_mesh_test_setup();
237 	rx_sar_conf();
238 	bt_mesh_test_data_cb_setup(rx_ended);
239 
240 	k_sleep(K_SECONDS(6 * TEST_DATA_WAITING_TIME));
241 
242 	ASSERT_TRUE_MSG(rx_cnt == 3, "Device didn't receive expected data\n");
243 
244 	PASS();
245 }
246 
send_end_cb(int err,void * cb_data)247 static void send_end_cb(int err, void *cb_data)
248 {
249 	struct k_sem *sem = cb_data;
250 
251 	ASSERT_EQUAL(err, 0);
252 	k_sem_give(sem);
253 }
254 
msg_send(uint16_t src,uint16_t dst)255 static bool msg_send(uint16_t src, uint16_t dst)
256 {
257 	static struct bt_mesh_send_cb cb = {
258 		.end = send_end_cb,
259 	};
260 	struct bt_mesh_msg_ctx ctx = {
261 		.net_idx = 0,
262 		.app_idx = 0,
263 		.addr = dst,
264 		.send_rel = false,
265 		.send_ttl = BT_MESH_TTL_DEFAULT,
266 	};
267 	struct bt_mesh_net_tx tx = {
268 		.ctx = &ctx,
269 		.src = src,
270 	};
271 	struct k_sem sem;
272 	int err;
273 
274 	k_sem_init(&sem, 0, 1);
275 	BT_MESH_MODEL_BUF_DEFINE(msg, TEST_MSG_OP_1, 0);
276 
277 	bt_mesh_model_msg_init(&msg, TEST_MSG_OP_1);
278 
279 	err = bt_mesh_trans_send(&tx, &msg, &cb, &sem);
280 	if (err) {
281 		LOG_ERR("Failed to send message (err %d)", err);
282 		return false;
283 	}
284 
285 	err = k_sem_take(&sem, K_SECONDS(10));
286 	if (err) {
287 		LOG_ERR("Send timed out (err %d)", err);
288 		return false;
289 	}
290 
291 	return true;
292 }
293 
msg_recv(uint16_t expected_addr)294 static bool msg_recv(uint16_t expected_addr)
295 {
296 	struct bt_mesh_test_msg msg;
297 	int err;
298 
299 	err = bt_mesh_test_recv_msg(&msg, K_SECONDS(10));
300 	if (err) {
301 		LOG_ERR("Failed to receive message from %u (err %d)", expected_addr, err);
302 		return false;
303 	}
304 
305 	LOG_DBG("Received msg from %u", msg.ctx.addr);
306 	ASSERT_EQUAL(expected_addr, msg.ctx.addr);
307 
308 	return true;
309 }
310 
ivi_update_toggle(void)311 static bool ivi_update_toggle(void)
312 {
313 	bool res;
314 
315 	bt_mesh_iv_update_test(true);
316 	res = bt_mesh_iv_update();
317 	bt_mesh_iv_update_test(false);
318 
319 	return res;
320 }
321 
322 /* 1 second delays have been added to prevent interfering tail of
323  * the previous rx transaction with the beginning of the new tx transaction.
324  */
test_rx_rpl_frag(void)325 static void test_rx_rpl_frag(void)
326 {
327 	bt_mesh_test_setup();
328 
329 	k_sleep(K_SECONDS(10));
330 
331 	/* Wait 3 messages from different sources. */
332 	for (int i = 0; i < 3; i++) {
333 		ASSERT_TRUE(msg_recv(100 + i));
334 	}
335 
336 	k_sleep(K_SECONDS(1));
337 
338 	/* Ask tx node to proceed to next test step. */
339 	ASSERT_TRUE(msg_send(rx_cfg.addr, tx_cfg.addr));
340 
341 	/* Start IVI Update. This will set old_iv for all entries in RPL to 1. */
342 	ASSERT_TRUE(ivi_update_toggle());
343 
344 	/* Receive messages from even nodes with new IVI. RPL entry with odd address will stay
345 	 * with old IVI.
346 	 */
347 	ASSERT_TRUE(msg_recv(100));
348 	ASSERT_TRUE(msg_recv(102));
349 
350 	k_sleep(K_SECONDS(1));
351 
352 	/* Ask tx node to proceed to next test step. */
353 	ASSERT_TRUE(msg_send(rx_cfg.addr, tx_cfg.addr));
354 
355 	/* Complete IVI Update. */
356 	ASSERT_FALSE(ivi_update_toggle());
357 
358 	/* Bump SeqNum in RPL for even addresses. */
359 	ASSERT_TRUE(msg_recv(100));
360 	ASSERT_TRUE(msg_recv(102));
361 
362 	k_sleep(K_SECONDS(1));
363 
364 	/* Start IVI Update again. */
365 	/* RPL entry with odd address should be removed causing fragmentation in RPL. old_iv flag
366 	 * for even entries will be set to 1.
367 	 */
368 	ASSERT_TRUE(ivi_update_toggle());
369 
370 	/* Ask tx node to proceed to next test step. */
371 	ASSERT_TRUE(msg_send(rx_cfg.addr, tx_cfg.addr));
372 
373 	/* Complete IVI Update. */
374 	ASSERT_FALSE(ivi_update_toggle());
375 
376 	/* Odd address entry should have been removed keeping even addresses accessible. */
377 	struct bt_mesh_rpl *rpl = NULL;
378 	struct bt_mesh_net_rx rx = {
379 		.old_iv = 1,
380 		.seq = 0,
381 		.ctx.addr = 100,
382 		.local_match = 1,
383 	};
384 	ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl, false));
385 	rx.ctx.addr = 101;
386 	ASSERT_FALSE(bt_mesh_rpl_check(&rx, &rpl, false));
387 	rx.ctx.addr = 102;
388 	ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl, false));
389 
390 	/* Let the settings store RPL. */
391 	k_sleep(K_SECONDS(CONFIG_BT_MESH_RPL_STORE_TIMEOUT));
392 
393 	PASS();
394 }
395 
396 /* 1 second delays have been added to prevent interfering tail of
397  * the previous rx transaction with the beginning of the new tx transaction.
398  */
test_tx_rpl_frag(void)399 static void test_tx_rpl_frag(void)
400 {
401 	bt_mesh_test_setup();
402 
403 	k_sleep(K_SECONDS(10));
404 
405 	/* Send message for 3 different addresses. */
406 	for (size_t i = 0; i < 3; i++) {
407 		ASSERT_TRUE(msg_send(100 + i, rx_cfg.addr));
408 	}
409 
410 	/* Wait for the rx node. */
411 	ASSERT_TRUE(msg_recv(rx_cfg.addr));
412 
413 	k_sleep(K_SECONDS(1));
414 
415 	/* Start IVI Update. */
416 	ASSERT_TRUE(ivi_update_toggle());
417 
418 	/* Send msg from elem 1 and 3 with new IVI. 2nd elem should have old IVI. */
419 	ASSERT_TRUE(msg_send(100, rx_cfg.addr));
420 	ASSERT_TRUE(msg_send(102, rx_cfg.addr));
421 
422 	/* Wait for the rx node. */
423 	ASSERT_TRUE(msg_recv(rx_cfg.addr));
424 
425 	k_sleep(K_SECONDS(1));
426 
427 	/* Complete IVI Update. */
428 	ASSERT_FALSE(ivi_update_toggle());
429 
430 	/* Send message from even addresses with new IVI keeping odd address with old IVI. */
431 	ASSERT_TRUE(msg_send(100, rx_cfg.addr));
432 	ASSERT_TRUE(msg_send(102, rx_cfg.addr));
433 
434 	/* Start IVI Update again to be in sync with rx node. */
435 	ASSERT_TRUE(ivi_update_toggle());
436 
437 	/* Wait for rx node. */
438 	ASSERT_TRUE(msg_recv(rx_cfg.addr));
439 
440 	/* Complete IVI Update. */
441 	ASSERT_FALSE(ivi_update_toggle());
442 
443 	PASS();
444 }
445 
test_rx_reboot_after_defrag(void)446 static void test_rx_reboot_after_defrag(void)
447 {
448 	bt_mesh_test_setup();
449 
450 	/* Test that RPL entries are restored correctly after defrag and reboot. */
451 	struct bt_mesh_rpl *rpl = NULL;
452 	struct bt_mesh_net_rx rx = {
453 		.old_iv = 1,
454 		.seq = 0,
455 		.ctx.addr = 100,
456 		.local_match = 1,
457 	};
458 	ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl, false));
459 	rx.ctx.addr = 101;
460 	ASSERT_FALSE(bt_mesh_rpl_check(&rx, &rpl, false));
461 	rx.ctx.addr = 102;
462 	ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl, false));
463 
464 	PASS();
465 }
466 
467 #define TEST_CASE(role, name, description)                     \
468 	{                                                      \
469 		.test_id = "rpc_" #role "_" #name,             \
470 		.test_descr = description,                     \
471 		.test_post_init_f = test_##role##_init,        \
472 		.test_tick_f = bt_mesh_test_timeout,           \
473 		.test_main_f = test_##role##_##name,           \
474 	}
475 
476 static const struct bst_test_instance test_rpc[] = {
477 	TEST_CASE(tx, immediate_replay_attack, "RPC: perform replay attack immediately"),
478 	TEST_CASE(tx, power_replay_attack,     "RPC: perform replay attack after power cycle"),
479 	TEST_CASE(tx, rpl_frag, "RPC: Send messages after double IVI Update"),
480 
481 	TEST_CASE(rx, immediate_replay_attack, "RPC: device under immediate attack"),
482 	TEST_CASE(rx, power_replay_attack,     "RPC: device under power cycle reply attack"),
483 	TEST_CASE(rx, rpl_frag, "RPC: Test RPL fragmentation after double IVI Update"),
484 	TEST_CASE(rx, reboot_after_defrag, "RPC: Test PRL after defrag and reboot"),
485 	BSTEST_END_MARKER
486 };
487 
test_rpc_install(struct bst_test_list * tests)488 struct bst_test_list *test_rpc_install(struct bst_test_list *tests)
489 {
490 	tests = bst_add_tests(tests, test_rpc);
491 	return tests;
492 }
493