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