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