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