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 kr_flag: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.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 		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