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