1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <zephyr/bluetooth/mesh.h>
9 #include "argparse.h"
10 #include "mesh/crypto.h"
11 
12 #define LOG_MODULE_NAME distribute_keys
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
15 
16 /* Mesh requires to keep in persistent memory network keys (2 keys per subnetwork),
17  * application keys (2 real keys per 1 configured) and device key + device key candidate.
18  */
19 #if defined CONFIG_BT_MESH_CDB
20 #define BT_MESH_CDB_KEY_ID_RANGE_SIZE (2 * SUBNET_COUNT + \
21 		2 * APP_KEY_COUNT + NODE_COUNT)
22 #else
23 #define BT_MESH_CDB_KEY_ID_RANGE_SIZE  0
24 #endif
25 #define BT_MESH_KEY_ID_RANGE_SIZE (2 * CONFIG_BT_MESH_SUBNET_COUNT + \
26 		2 * CONFIG_BT_MESH_APP_KEY_COUNT + 1 + BT_MESH_CDB_KEY_ID_RANGE_SIZE)
27 #define BT_MESH_PSA_KEY_ID_USER_MIN (PSA_KEY_ID_USER_MIN + \
28 		CONFIG_BT_MESH_PSA_KEY_ID_USER_MIN_OFFSET)
29 #define BT_MESH_TEST_PSA_KEY_ID_USER_MIN (BT_MESH_PSA_KEY_ID_USER_MIN + \
30 		BT_MESH_KEY_ID_RANGE_SIZE * get_device_nbr())
31 
32 static ATOMIC_DEFINE(pst_keys, BT_MESH_KEY_ID_RANGE_SIZE);
33 
bt_mesh_user_keyid_alloc(void)34 psa_key_id_t bt_mesh_user_keyid_alloc(void)
35 {
36 	for (int i = 0; i < BT_MESH_KEY_ID_RANGE_SIZE; i++) {
37 		if (!atomic_test_bit(pst_keys, i)) {
38 			atomic_set_bit(pst_keys, i);
39 
40 			LOG_INF("key id %d is allocated", BT_MESH_TEST_PSA_KEY_ID_USER_MIN + i);
41 
42 			return BT_MESH_TEST_PSA_KEY_ID_USER_MIN + i;
43 		}
44 	}
45 
46 	return PSA_KEY_ID_NULL;
47 }
48 
bt_mesh_user_keyid_free(psa_key_id_t key_id)49 int bt_mesh_user_keyid_free(psa_key_id_t key_id)
50 {
51 	if (IN_RANGE(key_id, BT_MESH_TEST_PSA_KEY_ID_USER_MIN,
52 			BT_MESH_TEST_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE - 1)) {
53 		atomic_clear_bit(pst_keys, key_id - BT_MESH_TEST_PSA_KEY_ID_USER_MIN);
54 
55 		LOG_INF("key id %d is freed", key_id);
56 
57 		return 0;
58 	}
59 
60 	return -EIO;
61 }
62 
bt_mesh_user_keyid_assign(psa_key_id_t key_id)63 void bt_mesh_user_keyid_assign(psa_key_id_t key_id)
64 {
65 	if (IN_RANGE(key_id, BT_MESH_TEST_PSA_KEY_ID_USER_MIN,
66 			BT_MESH_TEST_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE - 1)) {
67 		atomic_set_bit(pst_keys, key_id - BT_MESH_TEST_PSA_KEY_ID_USER_MIN);
68 		LOG_INF("key id %d is assigned", key_id);
69 	} else {
70 		LOG_WRN("key id %d is out of the reserved id range", key_id);
71 	}
72 }
73