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 struct bt_mesh_key val[2];
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, sizeof(struct bt_mesh_key));
110 memcpy(&key.val[1], &sub->keys[1].net, sizeof(struct bt_mesh_key));
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
subnet_keys_destroy(struct bt_mesh_subnet_keys * key)198 static void subnet_keys_destroy(struct bt_mesh_subnet_keys *key)
199 {
200 bt_mesh_key_destroy(&key->net);
201 bt_mesh_key_destroy(&key->msg.enc);
202 bt_mesh_key_destroy(&key->msg.privacy);
203 bt_mesh_key_destroy(&key->beacon);
204 #if defined(CONFIG_BT_MESH_GATT_PROXY)
205 bt_mesh_key_destroy(&key->identity);
206 #endif
207 #if defined(CONFIG_BT_MESH_V1d1)
208 bt_mesh_key_destroy(&key->priv_beacon);
209 #endif
210 }
211
key_refresh(struct bt_mesh_subnet * sub,uint8_t new_phase)212 static void key_refresh(struct bt_mesh_subnet *sub, uint8_t new_phase)
213 {
214 LOG_DBG("Phase 0x%02x -> 0x%02x", sub->kr_phase, new_phase);
215
216 switch (new_phase) {
217 /* Added second set of keys */
218 case BT_MESH_KR_PHASE_1:
219 sub->kr_phase = new_phase;
220 subnet_evt(sub, BT_MESH_KEY_UPDATED);
221 break;
222 /* Now using new keys for TX */
223 case BT_MESH_KR_PHASE_2:
224 sub->kr_phase = new_phase;
225 subnet_evt(sub, BT_MESH_KEY_SWAPPED);
226 break;
227 /* Revoking keys */
228 case BT_MESH_KR_PHASE_3:
229 if (sub->kr_phase == BT_MESH_KR_NORMAL) {
230 return;
231 }
232 __fallthrough;
233 case BT_MESH_KR_NORMAL:
234 sub->kr_phase = BT_MESH_KR_NORMAL;
235 subnet_keys_destroy(&sub->keys[0]);
236 memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0]));
237 sub->keys[1].valid = 0U;
238 subnet_evt(sub, BT_MESH_KEY_REVOKED);
239 break;
240 }
241
242 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
243 LOG_DBG("Storing Updated NetKey persistently");
244 bt_mesh_subnet_store(sub->net_idx);
245 }
246 }
247
bt_mesh_kr_update(struct bt_mesh_subnet * sub,bool kr_flag,bool new_key)248 void bt_mesh_kr_update(struct bt_mesh_subnet *sub, bool kr_flag, bool new_key)
249 {
250 if (!new_key) {
251 return;
252 }
253
254 if (sub->kr_phase == BT_MESH_KR_PHASE_1) {
255 /* Bluetooth Mesh Profile Specification Section 3.10.4.1:
256 * Can skip phase 2 if we get KR=0 on new key.
257 */
258 key_refresh(sub, (kr_flag ? BT_MESH_KR_PHASE_2 :
259 BT_MESH_KR_PHASE_3));
260 } else if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !kr_flag) {
261 key_refresh(sub, BT_MESH_KR_PHASE_3);
262 }
263 }
264
subnet_alloc(uint16_t net_idx)265 static struct bt_mesh_subnet *subnet_alloc(uint16_t net_idx)
266 {
267 struct bt_mesh_subnet *sub = NULL;
268
269 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
270 /* Check for already existing subnet */
271 if (subnets[i].net_idx == net_idx) {
272 return &subnets[i];
273 }
274
275 if (!sub && subnets[i].net_idx == BT_MESH_KEY_UNUSED) {
276 sub = &subnets[i];
277 }
278 }
279
280 return sub;
281 }
282
subnet_del(struct bt_mesh_subnet * sub)283 static void subnet_del(struct bt_mesh_subnet *sub)
284 {
285 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
286 update_subnet_settings(sub->net_idx, false);
287 }
288
289 for (int i = 0; i < ARRAY_SIZE(sub->keys); i++) {
290 if (sub->keys[i].valid) {
291 subnet_keys_destroy(&sub->keys[i]);
292 }
293 }
294
295 bt_mesh_net_loopback_clear(sub->net_idx);
296
297 subnet_evt(sub, BT_MESH_KEY_DELETED);
298 (void)memset(sub, 0, sizeof(*sub));
299 sub->net_idx = BT_MESH_KEY_UNUSED;
300 }
301
msg_cred_create(struct bt_mesh_net_cred * cred,const uint8_t * p,size_t p_len,const uint8_t key[16])302 static int msg_cred_create(struct bt_mesh_net_cred *cred, const uint8_t *p,
303 size_t p_len, const uint8_t key[16])
304 {
305 return bt_mesh_k2(key, p, p_len, &cred->nid, &cred->enc, &cred->privacy);
306 }
307
net_keys_create(struct bt_mesh_subnet_keys * keys,bool import,const uint8_t key[16])308 static int net_keys_create(struct bt_mesh_subnet_keys *keys, bool import, const uint8_t key[16])
309 {
310 uint8_t p = 0;
311 int err;
312
313 err = msg_cred_create(&keys->msg, &p, 1, key);
314 if (err) {
315 LOG_ERR("Unable to generate NID, EncKey & PrivacyKey");
316 return err;
317 }
318
319 if (import) {
320 err = bt_mesh_key_import(BT_MESH_KEY_TYPE_NET, key, &keys->net);
321 if (err) {
322 LOG_ERR("Unable to import network key");
323 return err;
324 }
325 }
326
327 LOG_DBG("NID 0x%02x EncKey %s", keys->msg.nid,
328 bt_hex(&keys->msg.enc, sizeof(struct bt_mesh_key)));
329 LOG_DBG("PrivacyKey %s", bt_hex(&keys->msg.privacy, sizeof(struct bt_mesh_key)));
330
331 err = bt_mesh_k3(key, keys->net_id);
332 if (err) {
333 LOG_ERR("Unable to generate Net ID");
334 return err;
335 }
336
337 LOG_DBG("NetID %s", bt_hex(keys->net_id, 8));
338
339 #if defined(CONFIG_BT_MESH_GATT_PROXY)
340 err = bt_mesh_identity_key(key, &keys->identity);
341 if (err) {
342 LOG_ERR("Unable to generate IdentityKey");
343 return err;
344 }
345
346 LOG_DBG("IdentityKey %s", bt_hex(&keys->identity, sizeof(struct bt_mesh_key)));
347 #endif /* GATT_PROXY */
348
349 err = bt_mesh_beacon_key(key, &keys->beacon);
350 if (err) {
351 LOG_ERR("Unable to generate beacon key");
352 return err;
353 }
354
355 LOG_DBG("BeaconKey %s", bt_hex(&keys->beacon, sizeof(struct bt_mesh_key)));
356
357 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
358 err = bt_mesh_private_beacon_key(key, &keys->priv_beacon);
359 if (err) {
360 LOG_ERR("Unable to generate private beacon key");
361 return err;
362 }
363
364 LOG_DBG("PrivateBeaconKey %s", bt_hex(&keys->priv_beacon, sizeof(struct bt_mesh_key)));
365 #endif
366
367 keys->valid = 1U;
368
369 return 0;
370 }
371
bt_mesh_subnet_add(uint16_t net_idx,const uint8_t key[16])372 uint8_t bt_mesh_subnet_add(uint16_t net_idx, const uint8_t key[16])
373 {
374 struct bt_mesh_subnet *sub = NULL;
375 int err;
376
377 LOG_DBG("0x%03x", net_idx);
378
379 sub = subnet_alloc(net_idx);
380 if (!sub) {
381 return STATUS_INSUFF_RESOURCES;
382 }
383
384 if (sub->net_idx == net_idx) {
385 if (bt_mesh_key_compare(key, &sub->keys[0].net)) {
386 return STATUS_IDX_ALREADY_STORED;
387 }
388
389 return STATUS_SUCCESS;
390 }
391
392 err = net_keys_create(&sub->keys[0], true, key);
393 if (err) {
394 return STATUS_UNSPECIFIED;
395 }
396
397 sub->net_idx = net_idx;
398 sub->kr_phase = BT_MESH_KR_NORMAL;
399
400 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
401 sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
402 } else {
403 sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
404 }
405
406 subnet_evt(sub, BT_MESH_KEY_ADDED);
407
408 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
409 LOG_DBG("Storing NetKey persistently");
410 bt_mesh_subnet_store(sub->net_idx);
411 }
412
413 return STATUS_SUCCESS;
414 }
415
bt_mesh_subnet_exists(uint16_t net_idx)416 bool bt_mesh_subnet_exists(uint16_t net_idx)
417 {
418 return !!bt_mesh_subnet_get(net_idx);
419 }
420
bt_mesh_subnet_update(uint16_t net_idx,const uint8_t key[16])421 uint8_t bt_mesh_subnet_update(uint16_t net_idx, const uint8_t key[16])
422 {
423 struct bt_mesh_subnet *sub;
424 int err;
425
426 LOG_DBG("0x%03x", net_idx);
427
428 sub = bt_mesh_subnet_get(net_idx);
429 if (!sub) {
430 return STATUS_INVALID_NETKEY;
431 }
432
433 /* The node shall successfully process a NetKey Update message on a
434 * valid NetKeyIndex when the NetKey value is different and the Key
435 * Refresh procedure has not been started, or when the NetKey value is
436 * the same in Phase 1. The NetKey Update message shall generate an
437 * error when the node is in Phase 2, or Phase 3.
438 */
439 switch (sub->kr_phase) {
440 case BT_MESH_KR_NORMAL:
441 if (!bt_mesh_key_compare(key, &sub->keys[0].net)) {
442 return STATUS_IDX_ALREADY_STORED;
443 }
444 break;
445 case BT_MESH_KR_PHASE_1:
446 if (!bt_mesh_key_compare(key, &sub->keys[1].net)) {
447 return STATUS_SUCCESS;
448 }
449 __fallthrough;
450 case BT_MESH_KR_PHASE_2:
451 case BT_MESH_KR_PHASE_3:
452 return STATUS_CANNOT_UPDATE;
453 }
454
455 err = net_keys_create(&sub->keys[1], true, key);
456 if (err) {
457 return STATUS_CANNOT_UPDATE;
458 }
459
460 key_refresh(sub, BT_MESH_KR_PHASE_1);
461
462 return STATUS_SUCCESS;
463 }
464
bt_mesh_subnet_del(uint16_t net_idx)465 uint8_t bt_mesh_subnet_del(uint16_t net_idx)
466 {
467 struct bt_mesh_subnet *sub;
468
469 LOG_DBG("0x%03x", net_idx);
470
471 sub = bt_mesh_subnet_get(net_idx);
472 if (!sub) {
473 /* This could be a retry of a previous attempt that had its
474 * response lost, so pretend that it was a success.
475 */
476 return STATUS_INVALID_NETKEY;
477 }
478
479 subnet_del(sub);
480
481 return STATUS_SUCCESS;
482 }
483
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 struct bt_mesh_key * key)484 int bt_mesh_friend_cred_create(struct bt_mesh_net_cred *cred, uint16_t lpn_addr,
485 uint16_t frnd_addr, uint16_t lpn_counter,
486 uint16_t frnd_counter, const struct bt_mesh_key *key)
487 {
488 uint8_t p[9];
489 uint8_t raw_key[16];
490 int err;
491
492 p[0] = 0x01;
493 sys_put_be16(lpn_addr, p + 1);
494 sys_put_be16(frnd_addr, p + 3);
495 sys_put_be16(lpn_counter, p + 5);
496 sys_put_be16(frnd_counter, p + 7);
497
498 err = bt_mesh_key_export(raw_key, key);
499 if (err) {
500 return err;
501 }
502
503 return msg_cred_create(cred, p, sizeof(p), raw_key);
504 }
505
bt_mesh_friend_cred_destroy(struct bt_mesh_net_cred * cred)506 void bt_mesh_friend_cred_destroy(struct bt_mesh_net_cred *cred)
507 {
508 bt_mesh_key_destroy(&cred->enc);
509 bt_mesh_key_destroy(&cred->privacy);
510 }
511
bt_mesh_subnet_kr_phase_set(uint16_t net_idx,uint8_t * phase)512 uint8_t bt_mesh_subnet_kr_phase_set(uint16_t net_idx, uint8_t *phase)
513 {
514 /* Table in Bluetooth Mesh Profile Specification Section 4.2.14: */
515 const uint8_t valid_transitions[] = {
516 BIT(BT_MESH_KR_PHASE_3), /* Normal phase: KR is started by key update */
517 BIT(BT_MESH_KR_PHASE_2) | BIT(BT_MESH_KR_PHASE_3), /* Phase 1 */
518 BIT(BT_MESH_KR_PHASE_3), /* Phase 2 */
519 /* Subnet is never in Phase 3 */
520 };
521 struct bt_mesh_subnet *sub;
522
523 LOG_DBG("0x%03x", net_idx);
524
525 sub = bt_mesh_subnet_get(net_idx);
526 if (!sub) {
527 *phase = 0x00;
528 return STATUS_INVALID_NETKEY;
529 }
530
531 if (*phase == sub->kr_phase) {
532 return STATUS_SUCCESS;
533 }
534
535 if (sub->kr_phase < ARRAY_SIZE(valid_transitions) &&
536 valid_transitions[sub->kr_phase] & BIT(*phase)) {
537 key_refresh(sub, *phase);
538
539 *phase = sub->kr_phase;
540
541 return STATUS_SUCCESS;
542 }
543
544 LOG_WRN("Invalid KR transition: 0x%02x -> 0x%02x", sub->kr_phase, *phase);
545
546 *phase = sub->kr_phase;
547
548 return STATUS_CANNOT_UPDATE;
549 }
550
bt_mesh_subnet_kr_phase_get(uint16_t net_idx,uint8_t * phase)551 uint8_t bt_mesh_subnet_kr_phase_get(uint16_t net_idx, uint8_t *phase)
552 {
553 struct bt_mesh_subnet *sub;
554
555 sub = bt_mesh_subnet_get(net_idx);
556 if (!sub) {
557 *phase = BT_MESH_KR_NORMAL;
558 return STATUS_INVALID_NETKEY;
559 }
560
561 *phase = sub->kr_phase;
562
563 return STATUS_SUCCESS;
564 }
565
bt_mesh_subnet_node_id_set(uint16_t net_idx,enum bt_mesh_feat_state node_id)566 uint8_t bt_mesh_subnet_node_id_set(uint16_t net_idx,
567 enum bt_mesh_feat_state node_id)
568 {
569 struct bt_mesh_subnet *sub;
570
571 if (node_id == BT_MESH_FEATURE_NOT_SUPPORTED) {
572 return STATUS_CANNOT_SET;
573 }
574
575 sub = bt_mesh_subnet_get(net_idx);
576 if (!sub) {
577 return STATUS_INVALID_NETKEY;
578 }
579
580 if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
581 return STATUS_FEAT_NOT_SUPP;
582 }
583
584 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
585 /* Implements binding from section 4.2.46.1 of MshPRTv1.1. When enabling non-private node
586 * identity state, disable its private counterpart.
587 */
588 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
589 if (subnets[i].net_idx != BT_MESH_KEY_UNUSED &&
590 subnets[i].node_id == BT_MESH_FEATURE_ENABLED &&
591 subnets[i].priv_beacon_ctx.node_id) {
592 bt_mesh_proxy_identity_stop(&subnets[i]);
593 }
594 }
595 #endif
596
597 if (node_id) {
598 bt_mesh_proxy_identity_start(sub, false);
599 } else {
600 bt_mesh_proxy_identity_stop(sub);
601 }
602
603 bt_mesh_adv_gatt_update();
604
605 return STATUS_SUCCESS;
606 }
607
bt_mesh_subnet_node_id_get(uint16_t net_idx,enum bt_mesh_feat_state * node_id)608 uint8_t bt_mesh_subnet_node_id_get(uint16_t net_idx,
609 enum bt_mesh_feat_state *node_id)
610 {
611 struct bt_mesh_subnet *sub;
612
613 sub = bt_mesh_subnet_get(net_idx);
614 if (!sub) {
615 *node_id = 0x00;
616 return STATUS_INVALID_NETKEY;
617 }
618
619 *node_id = sub->node_id;
620 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
621 *node_id &= !sub->priv_beacon_ctx.node_id;
622 #endif
623
624 return STATUS_SUCCESS;
625 }
626
627
bt_mesh_subnet_priv_node_id_set(uint16_t net_idx,enum bt_mesh_feat_state priv_node_id)628 uint8_t bt_mesh_subnet_priv_node_id_set(uint16_t net_idx,
629 enum bt_mesh_feat_state priv_node_id)
630 {
631 struct bt_mesh_subnet *sub;
632
633 if (priv_node_id == BT_MESH_FEATURE_NOT_SUPPORTED) {
634 return STATUS_CANNOT_SET;
635 }
636
637 sub = bt_mesh_subnet_get(net_idx);
638 if (!sub) {
639 return STATUS_INVALID_NETKEY;
640 }
641
642 if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) ||
643 !IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
644 return STATUS_FEAT_NOT_SUPP;
645 }
646
647 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
648 /* Reverse binding from section 4.2.46.1 doesn't allow to set private state if non-private
649 * state is enabled.
650 */
651 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
652 if (subnets[i].net_idx != BT_MESH_KEY_UNUSED &&
653 subnets[i].node_id == BT_MESH_FEATURE_ENABLED &&
654 !subnets[i].priv_beacon_ctx.node_id) {
655 return STATUS_CANNOT_SET;
656 }
657 }
658 #endif
659
660 if (priv_node_id) {
661 bt_mesh_proxy_identity_start(sub, true);
662 } else {
663 bt_mesh_proxy_identity_stop(sub);
664 }
665
666 bt_mesh_adv_gatt_update();
667
668 return STATUS_SUCCESS;
669 }
670
bt_mesh_subnet_priv_node_id_get(uint16_t net_idx,enum bt_mesh_feat_state * priv_node_id)671 uint8_t bt_mesh_subnet_priv_node_id_get(uint16_t net_idx,
672 enum bt_mesh_feat_state *priv_node_id)
673 {
674 struct bt_mesh_subnet *sub;
675
676 sub = bt_mesh_subnet_get(net_idx);
677 if (!sub) {
678 *priv_node_id = 0x00;
679 return STATUS_INVALID_NETKEY;
680 }
681
682 #if CONFIG_BT_MESH_GATT_PROXY && CONFIG_BT_MESH_PRIV_BEACONS
683 if (sub->node_id == BT_MESH_FEATURE_ENABLED && sub->priv_beacon_ctx.node_id) {
684 *priv_node_id = sub->node_id;
685 } else {
686 *priv_node_id = BT_MESH_FEATURE_DISABLED;
687 }
688 #else
689 *priv_node_id = BT_MESH_FEATURE_NOT_SUPPORTED;
690 #endif
691
692 return STATUS_SUCCESS;
693 }
694
bt_mesh_subnets_node_id_state_get(void)695 enum bt_mesh_subnets_node_id_state bt_mesh_subnets_node_id_state_get(void)
696 {
697 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
698 if (subnets[i].node_id) {
699 #if CONFIG_BT_MESH_PRIV_BEACONS
700 if (subnets[i].priv_beacon_ctx.node_id) {
701 return BT_MESH_SUBNETS_NODE_ID_STATE_ENABLED_PRIVATE;
702 }
703 #endif
704 return BT_MESH_SUBNETS_NODE_ID_STATE_ENABLED;
705 }
706 }
707
708 return BT_MESH_SUBNETS_NODE_ID_STATE_NONE;
709 }
710
bt_mesh_subnets_get(uint16_t net_idxs[],size_t max,off_t skip)711 ssize_t bt_mesh_subnets_get(uint16_t net_idxs[], size_t max, off_t skip)
712 {
713 size_t count = 0;
714
715 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
716 struct bt_mesh_subnet *sub = &subnets[i];
717
718 if (sub->net_idx == BT_MESH_KEY_UNUSED) {
719 continue;
720 }
721
722 if (skip) {
723 skip--;
724 continue;
725 }
726
727 if (count >= max) {
728 return -ENOMEM;
729 }
730
731 net_idxs[count++] = sub->net_idx;
732 }
733
734 return count;
735 }
736
bt_mesh_subnet_get(uint16_t net_idx)737 struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx)
738 {
739 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
740 struct bt_mesh_subnet *sub = &subnets[i];
741
742 if (sub->net_idx == net_idx) {
743 return sub;
744 }
745 }
746
747 return NULL;
748 }
749
subnet_key_set(struct bt_mesh_subnet * sub,int key_idx,const struct bt_mesh_key * key)750 static int subnet_key_set(struct bt_mesh_subnet *sub, int key_idx, const struct bt_mesh_key *key)
751 {
752 uint8_t raw_key[16];
753 int err;
754
755 err = bt_mesh_key_export(raw_key, key);
756 if (err) {
757 return err;
758 }
759
760 bt_mesh_key_assign(&sub->keys[key_idx].net, key);
761 err = net_keys_create(&sub->keys[key_idx], false, raw_key);
762 if (err) {
763 return err;
764 }
765
766 return 0;
767 }
768
bt_mesh_subnet_set(uint16_t net_idx,uint8_t kr_phase,const struct bt_mesh_key * old_key,const struct bt_mesh_key * new_key)769 int bt_mesh_subnet_set(uint16_t net_idx, uint8_t kr_phase, const struct bt_mesh_key *old_key,
770 const struct bt_mesh_key *new_key)
771 {
772 struct bt_mesh_subnet *sub;
773 int err;
774
775 sub = subnet_alloc(net_idx);
776 if (!sub) {
777 return -ENOMEM;
778 }
779
780 if (sub->net_idx == net_idx) {
781 return -EALREADY;
782 }
783
784 if (old_key != NULL) {
785 err = subnet_key_set(sub, 0, old_key);
786 if (err) {
787 return err;
788 }
789 }
790
791 if (new_key != NULL) {
792 err = subnet_key_set(sub, 1, new_key);
793 if (err) {
794 return err;
795 }
796 }
797
798 sub->net_idx = net_idx;
799 sub->kr_phase = kr_phase;
800
801 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
802 sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
803 } else {
804 sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
805 }
806
807 /* Make sure we have valid beacon data to be sent */
808 bt_mesh_beacon_update(sub);
809
810 return 0;
811 }
812
bt_mesh_subnet_find(bool (* cb)(struct bt_mesh_subnet * sub,void * cb_data),void * cb_data)813 struct bt_mesh_subnet *bt_mesh_subnet_find(bool (*cb)(struct bt_mesh_subnet *sub, void *cb_data),
814 void *cb_data)
815 {
816 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
817 if (subnets[i].net_idx == BT_MESH_KEY_UNUSED) {
818 continue;
819 }
820
821 if (!cb || cb(&subnets[i], cb_data)) {
822 return &subnets[i];
823 }
824 }
825
826 return NULL;
827 }
828
bt_mesh_subnet_foreach(void (* cb)(struct bt_mesh_subnet * sub))829 size_t bt_mesh_subnet_foreach(void (*cb)(struct bt_mesh_subnet *sub))
830 {
831 size_t count = 0;
832
833 for (int i = 0; i < ARRAY_SIZE(subnets); i++) {
834 if (subnets[i].net_idx == BT_MESH_KEY_UNUSED) {
835 continue;
836 }
837
838 cb(&subnets[i]);
839 count++;
840 }
841
842 return count;
843 }
844
bt_mesh_subnet_next(struct bt_mesh_subnet * sub)845 struct bt_mesh_subnet *bt_mesh_subnet_next(struct bt_mesh_subnet *sub)
846 {
847 if (sub) {
848 sub++;
849 } else {
850 sub = &subnets[0];
851 }
852
853 for (int i = 0; i < ARRAY_SIZE(subnets); i++, sub++) {
854 /* Roll over once we reach the end */
855 if (sub == &subnets[ARRAY_SIZE(subnets)]) {
856 sub = &subnets[0];
857 }
858
859 if (sub->net_idx != BT_MESH_KEY_UNUSED) {
860 return sub;
861 }
862 }
863
864 return NULL;
865 }
866
bt_mesh_net_keys_reset(void)867 void bt_mesh_net_keys_reset(void)
868 {
869 int i;
870
871 /* Delete all net keys, which also takes care of all app keys which
872 * are associated with each net key.
873 */
874 for (i = 0; i < ARRAY_SIZE(subnets); i++) {
875 struct bt_mesh_subnet *sub = &subnets[i];
876
877 if (sub->net_idx != BT_MESH_KEY_UNUSED) {
878 subnet_del(sub);
879 }
880 }
881 }
882
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))883 bool bt_mesh_net_cred_find(struct bt_mesh_net_rx *rx, struct net_buf_simple *in,
884 struct net_buf_simple *out,
885 bool (*cb)(struct bt_mesh_net_rx *rx,
886 struct net_buf_simple *in,
887 struct net_buf_simple *out,
888 const struct bt_mesh_net_cred *cred))
889 {
890 int i, j;
891
892 LOG_DBG("");
893
894 #if defined(CONFIG_BT_MESH_LOW_POWER)
895 if (bt_mesh_lpn_waiting_update()) {
896 rx->sub = bt_mesh.lpn.sub;
897
898 for (j = 0; j < ARRAY_SIZE(bt_mesh.lpn.cred); j++) {
899 if (!rx->sub->keys[j].valid) {
900 continue;
901 }
902
903 if (cb(rx, in, out, &bt_mesh.lpn.cred[j])) {
904 rx->new_key = (j > 0);
905 rx->friend_cred = 1U;
906 rx->ctx.net_idx = rx->sub->net_idx;
907 return true;
908 }
909 }
910
911 /* LPN Should only receive on the friendship credentials when in
912 * a friendship.
913 */
914 return false;
915 }
916 #endif
917
918 #if defined(CONFIG_BT_MESH_FRIEND)
919 /** Each friendship has unique friendship credentials */
920 for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
921 struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
922
923 if (!frnd->subnet) {
924 continue;
925 }
926
927 rx->sub = frnd->subnet;
928
929 for (j = 0; j < ARRAY_SIZE(frnd->cred); j++) {
930 if (!rx->sub->keys[j].valid) {
931 continue;
932 }
933
934 if (cb(rx, in, out, &frnd->cred[j])) {
935 rx->new_key = (j > 0);
936 rx->friend_cred = 1U;
937 rx->ctx.net_idx = rx->sub->net_idx;
938 return true;
939 }
940 }
941 }
942 #endif
943
944 for (i = 0; i < ARRAY_SIZE(subnets); i++) {
945 rx->sub = &subnets[i];
946 if (rx->sub->net_idx == BT_MESH_KEY_UNUSED) {
947 continue;
948 }
949
950 for (j = 0; j < ARRAY_SIZE(rx->sub->keys); j++) {
951 if (!rx->sub->keys[j].valid) {
952 continue;
953 }
954
955 if (cb(rx, in, out, &rx->sub->keys[j].msg)) {
956 rx->new_key = (j > 0);
957 rx->friend_cred = 0U;
958 rx->ctx.net_idx = rx->sub->net_idx;
959 return true;
960 }
961 }
962 }
963
964 return false;
965 }
966
net_key_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)967 static int net_key_set(const char *name, size_t len_rd,
968 settings_read_cb read_cb, void *cb_arg)
969 {
970 struct net_key_val key;
971 struct bt_mesh_key val[2];
972 int err;
973 uint16_t net_idx;
974
975 if (!name) {
976 LOG_ERR("Insufficient number of arguments");
977 return -ENOENT;
978 }
979
980 net_idx = strtol(name, NULL, 16);
981 err = bt_mesh_settings_set(read_cb, cb_arg, &key, sizeof(key));
982 if (err) {
983 LOG_ERR("Failed to set \'net-key\'");
984 return err;
985 }
986
987 /* One extra copying since key.val array is from packed structure
988 * and might be unaligned.
989 */
990 memcpy(val, key.val, sizeof(key.val));
991
992 LOG_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx);
993
994 return bt_mesh_subnet_set(
995 net_idx, key.kr_phase, &val[0],
996 (key.kr_phase != BT_MESH_KR_NORMAL) ? &val[1] : NULL);
997 }
998
999 BT_MESH_SETTINGS_DEFINE(subnet, "NetKey", net_key_set);
1000
bt_mesh_subnet_pending_store(void)1001 void bt_mesh_subnet_pending_store(void)
1002 {
1003 int i;
1004
1005 for (i = 0; i < ARRAY_SIZE(net_key_updates); i++) {
1006 struct net_key_update *update = &net_key_updates[i];
1007
1008 if (!update->valid) {
1009 continue;
1010 }
1011
1012 update->valid = 0U;
1013
1014 if (update->clear) {
1015 clear_net_key(update->key_idx);
1016 } else {
1017 store_subnet(update->key_idx);
1018 }
1019 }
1020 }
1021