1 /*
2 * Copyright (c) 2017 Intel Corporation
3 * Copyright (c) 2020 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/kernel.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <zephyr/sys/atomic.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/sys/iterable_sections.h>
17 #include <zephyr/net/buf.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/conn.h>
20 #include <zephyr/bluetooth/mesh.h>
21
22 #include "common/bt_str.h"
23
24 #include "crypto.h"
25 #include "adv.h"
26 #include "mesh.h"
27 #include "net.h"
28 #include "lpn.h"
29 #include "friend.h"
30 #include "proxy.h"
31 #include "transport.h"
32 #include "access.h"
33 #include "foundation.h"
34 #include "beacon.h"
35 #include "rpl.h"
36 #include "settings.h"
37 #include "prov.h"
38
39 #define LOG_LEVEL CONFIG_BT_MESH_KEYS_LOG_LEVEL
40 #include <zephyr/logging/log.h>
41 LOG_MODULE_REGISTER(bt_mesh_net_keys);
42
43 /* Tracking of what storage changes are pending for Net Keys. We track this in
44 * a separate array here instead of within the respective bt_mesh_subnet
45 * struct itself, since once a key gets deleted its struct becomes invalid
46 * and may be reused for other keys.
47 */
48 struct net_key_update {
49 uint16_t key_idx:12, /* NetKey Index */
50 valid:1, /* 1 if this entry is valid, 0 if not */
51 clear:1; /* 1 if key needs clearing, 0 if storing */
52 };
53
54 /* NetKey storage information */
55 struct net_key_val {
56 uint8_t kr_flag:1,
57 kr_phase:7;
58 uint8_t val[2][16];
59 } __packed;
60
61 static struct net_key_update net_key_updates[CONFIG_BT_MESH_SUBNET_COUNT];
62
63 static struct bt_mesh_subnet subnets[CONFIG_BT_MESH_SUBNET_COUNT] = {
64 [0 ... (CONFIG_BT_MESH_SUBNET_COUNT - 1)] = {
65 .net_idx = BT_MESH_KEY_UNUSED,
66 },
67 };
68
subnet_evt(struct bt_mesh_subnet * sub,enum bt_mesh_key_evt evt)69 static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
70 {
71 STRUCT_SECTION_FOREACH(bt_mesh_subnet_cb, cb) {
72 cb->evt_handler(sub, evt);
73 }
74 }
75
clear_net_key(uint16_t net_idx)76 static void clear_net_key(uint16_t net_idx)
77 {
78 char path[20];
79 int err;
80
81 LOG_DBG("NetKeyIndex 0x%03x", net_idx);
82
83 snprintk(path, sizeof(path), "bt/mesh/NetKey/%x", net_idx);
84 err = settings_delete(path);
85 if (err) {
86 LOG_ERR("Failed to clear NetKeyIndex 0x%03x", net_idx);
87 } else {
88 LOG_DBG("Cleared NetKeyIndex 0x%03x", net_idx);
89 }
90 }
91
store_subnet(uint16_t net_idx)92 static void store_subnet(uint16_t net_idx)
93 {
94 const struct bt_mesh_subnet *sub;
95 struct net_key_val key;
96 char path[20];
97 int err;
98
99 sub = bt_mesh_subnet_get(net_idx);
100 if (!sub) {
101 LOG_WRN("NetKeyIndex 0x%03x not found", net_idx);
102 return;
103 }
104
105 LOG_DBG("NetKeyIndex 0x%03x", net_idx);
106
107 snprintk(path, sizeof(path), "bt/mesh/NetKey/%x", net_idx);
108
109 memcpy(&key.val[0], sub->keys[0].net, 16);
110 memcpy(&key.val[1], sub->keys[1].net, 16);
111 key.kr_flag = 0U; /* Deprecated */
112 key.kr_phase = sub->kr_phase;
113
114 err = settings_save_one(path, &key, sizeof(key));
115 if (err) {
116 LOG_ERR("Failed to store NetKey value");
117 } else {
118 LOG_DBG("Stored NetKey value");
119 }
120 }
121
net_key_update_find(uint16_t key_idx,struct net_key_update ** free_slot)122 static struct net_key_update *net_key_update_find(uint16_t key_idx,
123 struct net_key_update **free_slot)
124 {
125 struct net_key_update *match;
126 int i;
127
128 match = NULL;
129 *free_slot = NULL;
130
131 for (i = 0; i < ARRAY_SIZE(net_key_updates); i++) {
132 struct net_key_update *update = &net_key_updates[i];
133
134 if (!update->valid) {
135 *free_slot = update;
136 continue;
137 }
138
139 if (update->key_idx == key_idx) {
140 match = update;
141 }
142 }
143
144 return match;
145 }
146
bt_mesh_net_flags(struct bt_mesh_subnet * sub)147 uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub)
148 {
149 uint8_t flags = 0x00;
150
151 if (sub && (sub->kr_phase == BT_MESH_KR_PHASE_2)) {
152 flags |= BT_MESH_NET_FLAG_KR;
153 }
154
155 if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) {
156 flags |= BT_MESH_NET_FLAG_IVU;
157 }
158
159 return flags;
160 }
161
update_subnet_settings(uint16_t net_idx,bool store)162 static void update_subnet_settings(uint16_t net_idx, bool store)
163 {
164 struct net_key_update *update, *free_slot;
165 uint8_t clear = store ? 0U : 1U;
166
167 LOG_DBG("NetKeyIndex 0x%03x", net_idx);
168
169 update = net_key_update_find(net_idx, &free_slot);
170 if (update) {
171 update->clear = clear;
172 bt_mesh_settings_store_schedule(
173 BT_MESH_SETTINGS_NET_KEYS_PENDING);
174 return;
175 }
176
177 if (!free_slot) {
178 if (store) {
179 store_subnet(net_idx);
180 } else {
181 clear_net_key(net_idx);
182 }
183 return;
184 }
185
186 free_slot->valid = 1U;
187 free_slot->key_idx = net_idx;
188 free_slot->clear = clear;
189
190 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_KEYS_PENDING);
191 }
192
bt_mesh_subnet_store(uint16_t net_idx)193 void bt_mesh_subnet_store(uint16_t net_idx)
194 {
195 update_subnet_settings(net_idx, true);
196 }
197
key_refresh(struct bt_mesh_subnet * sub,uint8_t new_phase)198 static void key_refresh(struct bt_mesh_subnet *sub, uint8_t new_phase)
199 {
200 LOG_DBG("Phase 0x%02x -> 0x%02x", sub->kr_phase, new_phase);
201
202 switch (new_phase) {
203 /* Added second set of keys */
204 case BT_MESH_KR_PHASE_1:
205 sub->kr_phase = new_phase;
206 subnet_evt(sub, BT_MESH_KEY_UPDATED);
207 break;
208 /* Now using new keys for TX */
209 case BT_MESH_KR_PHASE_2:
210 sub->kr_phase = new_phase;
211 subnet_evt(sub, BT_MESH_KEY_SWAPPED);
212 break;
213 /* Revoking keys */
214 case BT_MESH_KR_PHASE_3:
215 if (sub->kr_phase == BT_MESH_KR_NORMAL) {
216 return;
217 }
218 __fallthrough;
219 case BT_MESH_KR_NORMAL:
220 sub->kr_phase = BT_MESH_KR_NORMAL;
221 memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0]));
222 sub->keys[1].valid = 0U;
223 subnet_evt(sub, BT_MESH_KEY_REVOKED);
224 break;
225 }
226
227 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
228 LOG_DBG("Storing Updated NetKey persistently");
229 bt_mesh_subnet_store(sub->net_idx);
230 }
231 }
232
bt_mesh_kr_update(struct bt_mesh_subnet * sub,bool kr_flag,bool new_key)233 void bt_mesh_kr_update(struct bt_mesh_subnet *sub, bool kr_flag, bool new_key)
234 {
235 if (!new_key) {
236 return;
237 }
238
239 if (sub->kr_phase == BT_MESH_KR_PHASE_1) {
240 /* Bluetooth Mesh Profile Specification Section 3.10.4.1:
241 * Can skip phase 2 if we get KR=0 on new key.
242 */
243 key_refresh(sub, (kr_flag ? BT_MESH_KR_PHASE_2 :
244 BT_MESH_KR_PHASE_3));
245 } else if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !kr_flag) {
246 key_refresh(sub, BT_MESH_KR_PHASE_3);
247 }
248 }
249
subnet_alloc(uint16_t net_idx)250 static struct bt_mesh_subnet *subnet_alloc(uint16_t net_idx)
251 {
252 struct bt_mesh_subnet *sub = NULL;
253
254 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
255 /* Check for already existing subnet */
256 if (subnets[i].net_idx == net_idx) {
257 return &subnets[i];
258 }
259
260 if (!sub && subnets[i].net_idx == BT_MESH_KEY_UNUSED) {
261 sub = &subnets[i];
262 }
263 }
264
265 return sub;
266 }
267
subnet_del(struct bt_mesh_subnet * sub)268 static void subnet_del(struct bt_mesh_subnet *sub)
269 {
270 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
271 update_subnet_settings(sub->net_idx, false);
272 }
273
274 bt_mesh_net_loopback_clear(sub->net_idx);
275
276 subnet_evt(sub, BT_MESH_KEY_DELETED);
277 (void)memset(sub, 0, sizeof(*sub));
278 sub->net_idx = BT_MESH_KEY_UNUSED;
279 }
280
msg_cred_create(struct bt_mesh_net_cred * cred,const uint8_t * p,size_t p_len,const uint8_t key[16])281 static int msg_cred_create(struct bt_mesh_net_cred *cred, const uint8_t *p,
282 size_t p_len, const uint8_t key[16])
283 {
284 return bt_mesh_k2(key, p, p_len, &cred->nid, cred->enc, cred->privacy);
285 }
286
net_keys_create(struct bt_mesh_subnet_keys * keys,const uint8_t key[16])287 static int net_keys_create(struct bt_mesh_subnet_keys *keys,
288 const uint8_t key[16])
289 {
290 uint8_t p = 0;
291 int err;
292
293 err = msg_cred_create(&keys->msg, &p, 1, key);
294 if (err) {
295 LOG_ERR("Unable to generate NID, EncKey & PrivacyKey");
296 return err;
297 }
298
299 memcpy(keys->net, key, 16);
300
301 LOG_DBG("NID 0x%02x EncKey %s", keys->msg.nid, bt_hex(keys->msg.enc, 16));
302 LOG_DBG("PrivacyKey %s", bt_hex(keys->msg.privacy, 16));
303
304 err = bt_mesh_k3(key, keys->net_id);
305 if (err) {
306 LOG_ERR("Unable to generate Net ID");
307 return err;
308 }
309
310 LOG_DBG("NetID %s", bt_hex(keys->net_id, 8));
311
312 #if defined(CONFIG_BT_MESH_GATT_PROXY)
313 err = bt_mesh_identity_key(key, keys->identity);
314 if (err) {
315 LOG_ERR("Unable to generate IdentityKey");
316 return err;
317 }
318
319 LOG_DBG("IdentityKey %s", bt_hex(keys->identity, 16));
320 #endif /* GATT_PROXY */
321
322 err = bt_mesh_beacon_key(key, keys->beacon);
323 if (err) {
324 LOG_ERR("Unable to generate beacon key");
325 return err;
326 }
327
328 LOG_DBG("BeaconKey %s", bt_hex(keys->beacon, 16));
329
330 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
331 err = bt_mesh_private_beacon_key(key, keys->priv_beacon);
332 if (err) {
333 LOG_ERR("Unable to generate private beacon key");
334 return err;
335 }
336
337 LOG_DBG("PrivateBeaconKey %s", bt_hex(keys->priv_beacon, 16));
338 #endif
339
340 keys->valid = 1U;
341
342 return 0;
343 }
344
bt_mesh_subnet_add(uint16_t net_idx,const uint8_t key[16])345 uint8_t bt_mesh_subnet_add(uint16_t net_idx, const uint8_t key[16])
346 {
347 struct bt_mesh_subnet *sub = NULL;
348 int err;
349
350 LOG_DBG("0x%03x", net_idx);
351
352 sub = subnet_alloc(net_idx);
353 if (!sub) {
354 return STATUS_INSUFF_RESOURCES;
355 }
356
357 if (sub->net_idx == net_idx) {
358 if (memcmp(key, sub->keys[0].net, 16)) {
359 return STATUS_IDX_ALREADY_STORED;
360 }
361
362 return STATUS_SUCCESS;
363 }
364
365 err = net_keys_create(&sub->keys[0], key);
366 if (err) {
367 return STATUS_UNSPECIFIED;
368 }
369
370 sub->net_idx = net_idx;
371 sub->kr_phase = BT_MESH_KR_NORMAL;
372
373 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
374 sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
375 } else {
376 sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
377 }
378
379 subnet_evt(sub, BT_MESH_KEY_ADDED);
380
381 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
382 LOG_DBG("Storing NetKey persistently");
383 bt_mesh_subnet_store(sub->net_idx);
384 }
385
386 return STATUS_SUCCESS;
387 }
388
bt_mesh_subnet_exists(uint16_t net_idx)389 bool bt_mesh_subnet_exists(uint16_t net_idx)
390 {
391 return !!bt_mesh_subnet_get(net_idx);
392 }
393
bt_mesh_subnet_update(uint16_t net_idx,const uint8_t key[16])394 uint8_t bt_mesh_subnet_update(uint16_t net_idx, const uint8_t key[16])
395 {
396 struct bt_mesh_subnet *sub;
397 int err;
398
399 LOG_DBG("0x%03x", net_idx);
400
401 sub = bt_mesh_subnet_get(net_idx);
402 if (!sub) {
403 return STATUS_INVALID_NETKEY;
404 }
405
406 /* The node shall successfully process a NetKey Update message on a
407 * valid NetKeyIndex when the NetKey value is different and the Key
408 * Refresh procedure has not been started, or when the NetKey value is
409 * the same in Phase 1. The NetKey Update message shall generate an
410 * error when the node is in Phase 2, or Phase 3.
411 */
412 switch (sub->kr_phase) {
413 case BT_MESH_KR_NORMAL:
414 if (!memcmp(key, sub->keys[0].net, 16)) {
415 return STATUS_IDX_ALREADY_STORED;
416 }
417 break;
418 case BT_MESH_KR_PHASE_1:
419 if (!memcmp(key, sub->keys[1].net, 16)) {
420 return STATUS_SUCCESS;
421 }
422 __fallthrough;
423 case BT_MESH_KR_PHASE_2:
424 case BT_MESH_KR_PHASE_3:
425 return STATUS_CANNOT_UPDATE;
426 }
427
428 err = net_keys_create(&sub->keys[1], key);
429 if (err) {
430 return STATUS_CANNOT_UPDATE;
431 }
432
433 key_refresh(sub, BT_MESH_KR_PHASE_1);
434
435 return STATUS_SUCCESS;
436 }
437
bt_mesh_subnet_del(uint16_t net_idx)438 uint8_t bt_mesh_subnet_del(uint16_t net_idx)
439 {
440 struct bt_mesh_subnet *sub;
441
442 LOG_DBG("0x%03x", net_idx);
443
444 sub = bt_mesh_subnet_get(net_idx);
445 if (!sub) {
446 /* This could be a retry of a previous attempt that had its
447 * response lost, so pretend that it was a success.
448 */
449 return STATUS_INVALID_NETKEY;
450 }
451
452 subnet_del(sub);
453
454 return STATUS_SUCCESS;
455 }
456
bt_mesh_friend_cred_create(struct bt_mesh_net_cred * cred,uint16_t lpn_addr,uint16_t frnd_addr,uint16_t lpn_counter,uint16_t frnd_counter,const uint8_t key[16])457 int bt_mesh_friend_cred_create(struct bt_mesh_net_cred *cred, uint16_t lpn_addr,
458 uint16_t frnd_addr, uint16_t lpn_counter,
459 uint16_t frnd_counter, const uint8_t key[16])
460 {
461 uint8_t p[9];
462
463 p[0] = 0x01;
464 sys_put_be16(lpn_addr, p + 1);
465 sys_put_be16(frnd_addr, p + 3);
466 sys_put_be16(lpn_counter, p + 5);
467 sys_put_be16(frnd_counter, p + 7);
468
469 return msg_cred_create(cred, p, sizeof(p), key);
470 }
471
bt_mesh_subnet_kr_phase_set(uint16_t net_idx,uint8_t * phase)472 uint8_t bt_mesh_subnet_kr_phase_set(uint16_t net_idx, uint8_t *phase)
473 {
474 /* Table in Bluetooth Mesh Profile Specification Section 4.2.14: */
475 const uint8_t valid_transitions[] = {
476 BIT(BT_MESH_KR_PHASE_3), /* Normal phase: KR is started by key update */
477 BIT(BT_MESH_KR_PHASE_2) | BIT(BT_MESH_KR_PHASE_3), /* Phase 1 */
478 BIT(BT_MESH_KR_PHASE_3), /* Phase 2 */
479 /* Subnet is never in Phase 3 */
480 };
481 struct bt_mesh_subnet *sub;
482
483 LOG_DBG("0x%03x", net_idx);
484
485 sub = bt_mesh_subnet_get(net_idx);
486 if (!sub) {
487 *phase = 0x00;
488 return STATUS_INVALID_NETKEY;
489 }
490
491 if (*phase == sub->kr_phase) {
492 return STATUS_SUCCESS;
493 }
494
495 if (sub->kr_phase < ARRAY_SIZE(valid_transitions) &&
496 valid_transitions[sub->kr_phase] & BIT(*phase)) {
497 key_refresh(sub, *phase);
498
499 *phase = sub->kr_phase;
500
501 return STATUS_SUCCESS;
502 }
503
504 LOG_WRN("Invalid KR transition: 0x%02x -> 0x%02x", sub->kr_phase, *phase);
505
506 *phase = sub->kr_phase;
507
508 return STATUS_CANNOT_UPDATE;
509 }
510
bt_mesh_subnet_kr_phase_get(uint16_t net_idx,uint8_t * phase)511 uint8_t bt_mesh_subnet_kr_phase_get(uint16_t net_idx, uint8_t *phase)
512 {
513 struct bt_mesh_subnet *sub;
514
515 sub = bt_mesh_subnet_get(net_idx);
516 if (!sub) {
517 *phase = BT_MESH_KR_NORMAL;
518 return STATUS_INVALID_NETKEY;
519 }
520
521 *phase = sub->kr_phase;
522
523 return STATUS_SUCCESS;
524 }
525
bt_mesh_subnet_node_id_set(uint16_t net_idx,enum bt_mesh_feat_state node_id)526 uint8_t bt_mesh_subnet_node_id_set(uint16_t net_idx,
527 enum bt_mesh_feat_state node_id)
528 {
529 struct bt_mesh_subnet *sub;
530
531 if (node_id == BT_MESH_FEATURE_NOT_SUPPORTED) {
532 return STATUS_CANNOT_SET;
533 }
534
535 sub = bt_mesh_subnet_get(net_idx);
536 if (!sub) {
537 return STATUS_INVALID_NETKEY;
538 }
539
540 if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
541 return STATUS_FEAT_NOT_SUPP;
542 }
543
544 if (node_id) {
545 bt_mesh_proxy_identity_start(sub, false);
546 } else {
547 bt_mesh_proxy_identity_stop(sub);
548 }
549
550 bt_mesh_adv_gatt_update();
551
552 return STATUS_SUCCESS;
553 }
554
bt_mesh_subnet_node_id_get(uint16_t net_idx,enum bt_mesh_feat_state * node_id)555 uint8_t bt_mesh_subnet_node_id_get(uint16_t net_idx,
556 enum bt_mesh_feat_state *node_id)
557 {
558 struct bt_mesh_subnet *sub;
559
560 sub = bt_mesh_subnet_get(net_idx);
561 if (!sub) {
562 *node_id = 0x00;
563 return STATUS_INVALID_NETKEY;
564 }
565
566 *node_id = sub->node_id;
567
568 return STATUS_SUCCESS;
569 }
570
571
bt_mesh_subnet_priv_node_id_set(uint16_t net_idx,enum bt_mesh_feat_state priv_node_id)572 uint8_t bt_mesh_subnet_priv_node_id_set(uint16_t net_idx,
573 enum bt_mesh_feat_state priv_node_id)
574 {
575 struct bt_mesh_subnet *sub;
576
577 if (priv_node_id == BT_MESH_FEATURE_NOT_SUPPORTED) {
578 return STATUS_CANNOT_SET;
579 }
580
581 sub = bt_mesh_subnet_get(net_idx);
582 if (!sub) {
583 return STATUS_INVALID_NETKEY;
584 }
585
586 if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) ||
587 !IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
588 return STATUS_FEAT_NOT_SUPP;
589 }
590
591 if (priv_node_id) {
592 bt_mesh_proxy_identity_start(sub, true);
593 } else {
594 bt_mesh_proxy_identity_stop(sub);
595 }
596
597 bt_mesh_adv_gatt_update();
598
599 return STATUS_SUCCESS;
600 }
601
bt_mesh_subnet_priv_node_id_get(uint16_t net_idx,enum bt_mesh_feat_state * priv_node_id)602 uint8_t bt_mesh_subnet_priv_node_id_get(uint16_t net_idx,
603 enum bt_mesh_feat_state *priv_node_id)
604 {
605 struct bt_mesh_subnet *sub;
606
607 sub = bt_mesh_subnet_get(net_idx);
608 if (!sub) {
609 *priv_node_id = 0x00;
610 return STATUS_INVALID_NETKEY;
611 }
612
613 #if CONFIG_BT_MESH_GATT_PROXY && CONFIG_BT_MESH_PRIV_BEACONS
614 if (sub->node_id == BT_MESH_FEATURE_ENABLED && sub->priv_beacon_ctx.node_id) {
615 *priv_node_id = sub->node_id;
616 } else {
617 *priv_node_id = BT_MESH_FEATURE_DISABLED;
618 }
619 #else
620 *priv_node_id = BT_MESH_FEATURE_NOT_SUPPORTED;
621 #endif
622
623 return STATUS_SUCCESS;
624 }
625
bt_mesh_subnets_get(uint16_t net_idxs[],size_t max,off_t skip)626 ssize_t bt_mesh_subnets_get(uint16_t net_idxs[], size_t max, off_t skip)
627 {
628 size_t count = 0;
629
630 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
631 struct bt_mesh_subnet *sub = &subnets[i];
632
633 if (sub->net_idx == BT_MESH_KEY_UNUSED) {
634 continue;
635 }
636
637 if (skip) {
638 skip--;
639 continue;
640 }
641
642 if (count >= max) {
643 return -ENOMEM;
644 }
645
646 net_idxs[count++] = sub->net_idx;
647 }
648
649 return count;
650 }
651
bt_mesh_subnet_get(uint16_t net_idx)652 struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx)
653 {
654 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
655 struct bt_mesh_subnet *sub = &subnets[i];
656
657 if (sub->net_idx == net_idx) {
658 return sub;
659 }
660 }
661
662 return NULL;
663 }
664
bt_mesh_subnet_set(uint16_t net_idx,uint8_t kr_phase,const uint8_t old_key[16],const uint8_t new_key[16])665 int bt_mesh_subnet_set(uint16_t net_idx, uint8_t kr_phase,
666 const uint8_t old_key[16], const uint8_t new_key[16])
667 {
668 const uint8_t *keys[] = { old_key, new_key };
669 struct bt_mesh_subnet *sub;
670
671 sub = subnet_alloc(net_idx);
672 if (!sub) {
673 return -ENOMEM;
674 }
675
676 if (sub->net_idx == net_idx) {
677 return -EALREADY;
678 }
679
680 for (int i = 0; i < ARRAY_SIZE(keys); i++) {
681 if (!keys[i]) {
682 continue;
683 }
684
685 if (net_keys_create(&sub->keys[i], keys[i])) {
686 return -EIO;
687 }
688 }
689
690 sub->net_idx = net_idx;
691 sub->kr_phase = kr_phase;
692
693 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
694 sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
695 } else {
696 sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
697 }
698
699 /* Make sure we have valid beacon data to be sent */
700 bt_mesh_beacon_update(sub);
701
702 return 0;
703 }
704
bt_mesh_subnet_find(bool (* cb)(struct bt_mesh_subnet * sub,void * cb_data),void * cb_data)705 struct bt_mesh_subnet *bt_mesh_subnet_find(bool (*cb)(struct bt_mesh_subnet *sub, void *cb_data),
706 void *cb_data)
707 {
708 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
709 if (subnets[i].net_idx == BT_MESH_KEY_UNUSED) {
710 continue;
711 }
712
713 if (!cb || cb(&subnets[i], cb_data)) {
714 return &subnets[i];
715 }
716 }
717
718 return NULL;
719 }
720
bt_mesh_subnet_foreach(void (* cb)(struct bt_mesh_subnet * sub))721 size_t bt_mesh_subnet_foreach(void (*cb)(struct bt_mesh_subnet *sub))
722 {
723 size_t count = 0;
724
725 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
726 if (subnets[i].net_idx == BT_MESH_KEY_UNUSED) {
727 continue;
728 }
729
730 cb(&subnets[i]);
731 count++;
732 }
733
734 return count;
735 }
736
bt_mesh_subnet_next(struct bt_mesh_subnet * sub)737 struct bt_mesh_subnet *bt_mesh_subnet_next(struct bt_mesh_subnet *sub)
738 {
739 if (sub) {
740 sub++;
741 } else {
742 sub = &subnets[0];
743 }
744
745 for (int i = 0; i < ARRAY_SIZE(subnets); i++, sub++) {
746 /* Roll over once we reach the end */
747 if (sub == &subnets[ARRAY_SIZE(subnets)]) {
748 sub = &subnets[0];
749 }
750
751 if (sub->net_idx != BT_MESH_KEY_UNUSED) {
752 return sub;
753 }
754 }
755
756 return NULL;
757 }
758
bt_mesh_net_keys_reset(void)759 void bt_mesh_net_keys_reset(void)
760 {
761 int i;
762
763 /* Delete all net keys, which also takes care of all app keys which
764 * are associated with each net key.
765 */
766 for (i = 0; i < ARRAY_SIZE(subnets); i++) {
767 struct bt_mesh_subnet *sub = &subnets[i];
768
769 if (sub->net_idx != BT_MESH_KEY_UNUSED) {
770 subnet_del(sub);
771 }
772 }
773 }
774
bt_mesh_net_cred_find(struct bt_mesh_net_rx * rx,struct net_buf_simple * in,struct net_buf_simple * out,bool (* cb)(struct bt_mesh_net_rx * rx,struct net_buf_simple * in,struct net_buf_simple * out,const struct bt_mesh_net_cred * cred))775 bool bt_mesh_net_cred_find(struct bt_mesh_net_rx *rx, struct net_buf_simple *in,
776 struct net_buf_simple *out,
777 bool (*cb)(struct bt_mesh_net_rx *rx,
778 struct net_buf_simple *in,
779 struct net_buf_simple *out,
780 const struct bt_mesh_net_cred *cred))
781 {
782 int i, j;
783
784 LOG_DBG("");
785
786 #if defined(CONFIG_BT_MESH_LOW_POWER)
787 if (bt_mesh_lpn_waiting_update()) {
788 rx->sub = bt_mesh.lpn.sub;
789
790 for (j = 0; j < ARRAY_SIZE(bt_mesh.lpn.cred); j++) {
791 if (!rx->sub->keys[j].valid) {
792 continue;
793 }
794
795 if (cb(rx, in, out, &bt_mesh.lpn.cred[j])) {
796 rx->new_key = (j > 0);
797 rx->friend_cred = 1U;
798 rx->ctx.net_idx = rx->sub->net_idx;
799 return true;
800 }
801 }
802
803 /* LPN Should only receive on the friendship credentials when in
804 * a friendship.
805 */
806 return false;
807 }
808 #endif
809
810 #if defined(CONFIG_BT_MESH_FRIEND)
811 /** Each friendship has unique friendship credentials */
812 for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
813 struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
814
815 if (!frnd->subnet) {
816 continue;
817 }
818
819 rx->sub = frnd->subnet;
820
821 for (j = 0; j < ARRAY_SIZE(frnd->cred); j++) {
822 if (!rx->sub->keys[j].valid) {
823 continue;
824 }
825
826 if (cb(rx, in, out, &frnd->cred[j])) {
827 rx->new_key = (j > 0);
828 rx->friend_cred = 1U;
829 rx->ctx.net_idx = rx->sub->net_idx;
830 return true;
831 }
832 }
833 }
834 #endif
835
836 for (i = 0; i < ARRAY_SIZE(subnets); i++) {
837 rx->sub = &subnets[i];
838 if (rx->sub->net_idx == BT_MESH_KEY_UNUSED) {
839 continue;
840 }
841
842 for (j = 0; j < ARRAY_SIZE(rx->sub->keys); j++) {
843 if (!rx->sub->keys[j].valid) {
844 continue;
845 }
846
847 if (cb(rx, in, out, &rx->sub->keys[j].msg)) {
848 rx->new_key = (j > 0);
849 rx->friend_cred = 0U;
850 rx->ctx.net_idx = rx->sub->net_idx;
851 return true;
852 }
853 }
854 }
855
856 return false;
857 }
858
net_key_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)859 static int net_key_set(const char *name, size_t len_rd,
860 settings_read_cb read_cb, void *cb_arg)
861 {
862 struct net_key_val key;
863 int err;
864 uint16_t net_idx;
865
866 if (!name) {
867 LOG_ERR("Insufficient number of arguments");
868 return -ENOENT;
869 }
870
871 net_idx = strtol(name, NULL, 16);
872 err = bt_mesh_settings_set(read_cb, cb_arg, &key, sizeof(key));
873 if (err) {
874 LOG_ERR("Failed to set \'net-key\'");
875 return err;
876 }
877
878 LOG_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx);
879
880 return bt_mesh_subnet_set(
881 net_idx, key.kr_phase, key.val[0],
882 (key.kr_phase != BT_MESH_KR_NORMAL) ? key.val[1] : NULL);
883 }
884
885 BT_MESH_SETTINGS_DEFINE(subnet, "NetKey", net_key_set);
886
bt_mesh_subnet_pending_store(void)887 void bt_mesh_subnet_pending_store(void)
888 {
889 int i;
890
891 for (i = 0; i < ARRAY_SIZE(net_key_updates); i++) {
892 struct net_key_update *update = &net_key_updates[i];
893
894 if (!update->valid) {
895 continue;
896 }
897
898 update->valid = 0U;
899
900 if (update->clear) {
901 clear_net_key(update->key_idx);
902 } else {
903 store_subnet(update->key_idx);
904 }
905 }
906 }
907