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