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