1 /*
2  * Copyright (c) 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_SUBNET_H_
8 #define ZEPHYR_SUBSYS_BLUETOOTH_MESH_SUBNET_H_
9 
10 #include <stdint.h>
11 #include <sys/types.h>
12 #include <zephyr/net/buf.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/sys/iterable_sections.h>
15 
16 #define BT_MESH_NET_FLAG_KR       BIT(0)
17 #define BT_MESH_NET_FLAG_IVU      BIT(1)
18 
19 #define BT_MESH_KR_NORMAL         0x00
20 #define BT_MESH_KR_PHASE_1        0x01
21 #define BT_MESH_KR_PHASE_2        0x02
22 #define BT_MESH_KR_PHASE_3        0x03
23 
24 /** Which of the two subnet.keys should be used for sending. */
25 #define SUBNET_KEY_TX_IDX(sub) ((sub)->kr_phase == BT_MESH_KR_PHASE_2)
26 
27 struct bt_mesh_net_rx;
28 enum bt_mesh_key_evt;
29 
30 /** Network message encryption credentials */
31 struct bt_mesh_net_cred {
32 	uint8_t nid;                /* NID */
33 	struct bt_mesh_key enc;     /* EncKey */
34 	struct bt_mesh_key privacy; /* PrivacyKey */
35 };
36 
37 struct bt_mesh_beacon {
38 	uint32_t sent;        /* Timestamp of last sent beacon */
39 	uint32_t recv;        /* Timestamp of last received beacon */
40 	uint8_t  last;       /* Number of beacons during last
41 				      * observation window
42 				      */
43 	uint8_t  cur;        /* Number of beacons observed during
44 				      * currently ongoing window.
45 				      */
46 	uint8_t  cache[8];   /* Cached last beacon auth value */
47 	uint8_t  auth[8];    /* Beacon Authentication Value */
48 };
49 
50 /** Subnet instance. */
51 struct bt_mesh_subnet {
52 	uint16_t net_idx;            /* NetKeyIndex */
53 
54 	uint8_t  kr_phase;           /* Key Refresh Phase */
55 
56 	uint8_t  node_id;            /* Node Identity State */
57 	uint32_t node_id_start;      /* Node Identity started timestamp */
58 
59 	struct bt_mesh_beacon secure_beacon;
60 
61 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
62 	struct bt_mesh_beacon priv_beacon;
63 	struct {
64 		uint16_t idx;        /* Private beacon random index */
65 		bool node_id;        /* Private Node Identity enabled */
66 		uint8_t data[5];     /* Private Beacon data */
67 	} priv_beacon_ctx;
68 #endif
69 
70 	struct bt_mesh_subnet_keys {
71 		bool valid;
72 		struct bt_mesh_key net;         /* NetKey */
73 		struct bt_mesh_net_cred msg;
74 		uint8_t net_id[8];              /* Network ID */
75 	#if defined(CONFIG_BT_MESH_GATT_PROXY)
76 		struct bt_mesh_key identity;    /* IdentityKey */
77 	#endif
78 		struct bt_mesh_key beacon;      /* BeaconKey */
79 		struct bt_mesh_key priv_beacon; /* PrivateBeaconKey */
80 	} keys[2];
81 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
82 	bool sol_tx;
83 #endif
84 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
85 	uint32_t priv_net_id_sent; /* Timestamp for Private Network ID advertising
86 				    * started via Proxy Solicitation
87 				    */
88 	bool solicited;      /* Subnet received valid Solicitation PDU */
89 #endif
90 };
91 
92 /** Subnet callback structure. Instantiate with @ref BT_MESH_SUBNET_CB */
93 struct bt_mesh_subnet_cb {
94 	void (*evt_handler)(struct bt_mesh_subnet *subnet,
95 			    enum bt_mesh_key_evt evt);
96 };
97 
98 /**
99  *  @brief Register a subnet event callback.
100  *
101  *  @param _name Handler name.
102  */
103 #define BT_MESH_SUBNET_CB_DEFINE(_name)                                    \
104 	static const STRUCT_SECTION_ITERABLE(                               \
105 		bt_mesh_subnet_cb, _CONCAT(bt_mesh_subnet_cb_, _name))
106 
107 /** @brief Reset all Network keys. */
108 void bt_mesh_net_keys_reset(void);
109 
110 /** @brief Call cb on every valid Subnet until it returns a non-zero value.
111  *
112  *  @param cb Callback to call, or NULL to return first valid subnet. If the callback returns true,
113  *            iteration stops, and the passed subnet is returned.
114  *  @param cb_data Callback data to pass to callback.
115  *
116  *  @return Subnet that returned non-zero value.
117  */
118 struct bt_mesh_subnet *bt_mesh_subnet_find(bool (*cb)(struct bt_mesh_subnet *sub, void *cb_data),
119 					   void *cb_data);
120 
121 /** @brief Iterate through all valid Subnets.
122  *
123  *  @param cb Callback to call on every Subnet.
124  *
125  *  @returns The number of valid subnets.
126  */
127 size_t bt_mesh_subnet_foreach(void (*cb)(struct bt_mesh_subnet *sub));
128 
129 /** @brief Get the next valid Subnet.
130  *
131  *  If there's only one valid Subnet, this will be returned on every call.
132  *
133  *  @param sub Previous Subnet, or NULL to get the first valid.
134  *
135  *  @returns Gets the next valid Subnet after @c sub, or NULL if there are no
136  *           valid Subnets.
137  */
138 struct bt_mesh_subnet *bt_mesh_subnet_next(struct bt_mesh_subnet *sub);
139 
140 /** @brief Get a pointer to the Subnet with the given index.
141  *
142  *  @param net_idx Network index to look for.
143  *
144  *  @returns Subnet with index @c net_idx, or NULL if no such Subnet is known.
145  */
146 struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx);
147 
148 /** @brief Initialize a new Subnet.
149  *
150  *  @param net_idx Network index of the Subnet.
151  *  @param kr_phase Key refresh phase the Subnet should be in.
152  *  @param key The current network key for the Subnet.
153  *  @param new_key New network key, if available.
154  *
155  *  @returns 0 on success, or (negative) error code on failure.
156  */
157 int bt_mesh_subnet_set(uint16_t net_idx, uint8_t kr_phase,
158 		       const struct bt_mesh_key *key, const struct bt_mesh_key *new_key);
159 
160 /** @brief Create Friendship credentials.
161  *
162  *  @param cred Credential object to create.
163  *  @param lpn_addr Address of the LPN node in the friendship.
164  *  @param frnd_addr Address of the Friend node in the friendship.
165  *  @param lpn_counter The LPN's counter parameter.
166  *  @param frnd_counter The Friend node's counter parameter.
167  *  @param key Network key to create the Friendship credentials for.
168  *
169  *  @returns 0 on success, or (negative) error code on failure.
170  */
171 int bt_mesh_friend_cred_create(struct bt_mesh_net_cred *cred,
172 			       uint16_t lpn_addr, uint16_t frnd_addr,
173 			       uint16_t lpn_counter, uint16_t frnd_counter,
174 			       const struct bt_mesh_key *key);
175 
176 /** @brief Destroy Friendship credentials.
177  *
178  *  @param cred Credential object to destroy.
179  */
180 void bt_mesh_friend_cred_destroy(struct bt_mesh_net_cred *cred);
181 
182 /** @brief Iterate through all valid network credentials to decrypt a message.
183  *
184  *  @param rx Network RX parameters, passed to the callback.
185  *  @param in Input message buffer, passed to the callback.
186  *  @param out Output message buffer, passed to the callback.
187  *  @param cb Callback to call for each known network credential. Iteration
188  *            stops when this callback returns @c true.
189  *
190  *  @returns Whether any of the credentials got a @c true return from the
191  *           callback.
192  */
193 bool bt_mesh_net_cred_find(struct bt_mesh_net_rx *rx, struct net_buf_simple *in,
194 			   struct net_buf_simple *out,
195 			   bool (*cb)(struct bt_mesh_net_rx *rx,
196 				      struct net_buf_simple *in,
197 				      struct net_buf_simple *out,
198 				      const struct bt_mesh_net_cred *cred));
199 
200 /** @brief Get the network flags of the given Subnet.
201  *
202  *  @param sub Subnet to get the network flags of.
203  *
204  *  @returns A bitmap of @ref BT_MESH_NET_FLAG_KR and @ref BT_MESH_NET_FLAG_IVU.
205  */
206 uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub);
207 
208 /** @brief Process a Key Refresh event from a beacon.
209  *
210  *  @param sub Subnet the Key Refresh was received on.
211  *  @param kr_flag Key Refresh flag.
212  *  @param new_key Whether the Key Refresh event was received on the new key
213  *                 set.
214  *
215  *  @returns Whether the Key Refresh event caused a change.
216  */
217 void bt_mesh_kr_update(struct bt_mesh_subnet *sub, bool kr_flag, bool new_key);
218 
219 /** @brief Check whether the Subnet has the refreshed keys.
220  *
221  *  @param sub Subnet.
222  *
223  *  @returns Whether the Subnet's second key is valid.
224  */
225 static inline bool
bt_mesh_subnet_has_new_key(const struct bt_mesh_subnet * sub)226 bt_mesh_subnet_has_new_key(const struct bt_mesh_subnet *sub)
227 {
228 	return sub->kr_phase != BT_MESH_KR_NORMAL;
229 }
230 
231 /** Kind of currently enabled Node Identity state on one or more subnets. */
232 enum bt_mesh_subnets_node_id_state {
233 	/* None node identity states are enabled on any subnets. */
234 	BT_MESH_SUBNETS_NODE_ID_STATE_NONE,
235 	/* Node Identity state is enabled on one or more subnets. */
236 	BT_MESH_SUBNETS_NODE_ID_STATE_ENABLED,
237 	/* Private Node Identity state is enabled on one or more subnets. */
238 	BT_MESH_SUBNETS_NODE_ID_STATE_ENABLED_PRIVATE,
239 };
240 
241 /** @brief Returns what kind of node identity state is currently enabled on one or more subnets.
242  *
243  * Only one kind (either non-private or private) can be enabled at the same time on all subnets.
244  *
245  * @returns Kind of node identity state that is currently enabled.
246  */
247 enum bt_mesh_subnets_node_id_state bt_mesh_subnets_node_id_state_get(void);
248 
249 /** @brief Store the Subnet information in persistent storage.
250  *
251  * @param net_idx Network index to store.
252  */
253 void bt_mesh_subnet_store(uint16_t net_idx);
254 
255 /** @brief Store the pending Subnets in persistent storage. */
256 void bt_mesh_subnet_pending_store(void);
257 
258 #endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_SUBNET_H_ */
259