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