appkey.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2017-2019 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <ell/ell.h>
  15. #include "mesh/mesh-defs.h"
  16. #include "mesh/node.h"
  17. #include "mesh/net.h"
  18. #include "mesh/crypto.h"
  19. #include "mesh/util.h"
  20. #include "mesh/model.h"
  21. #include "mesh/mesh-config.h"
  22. #include "mesh/appkey.h"
  23. struct mesh_app_key {
  24. uint16_t net_idx;
  25. uint16_t app_idx;
  26. uint8_t key[16];
  27. uint8_t key_aid;
  28. uint8_t new_key[16];
  29. uint8_t new_key_aid;
  30. };
  31. static bool match_key_index(const void *a, const void *b)
  32. {
  33. const struct mesh_app_key *key = a;
  34. uint16_t idx = L_PTR_TO_UINT(b);
  35. return key->app_idx == idx;
  36. }
  37. static bool match_bound_key(const void *a, const void *b)
  38. {
  39. const struct mesh_app_key *key = a;
  40. uint16_t idx = L_PTR_TO_UINT(b);
  41. return key->net_idx == idx;
  42. }
  43. static void finalize_key(void *a, void *b)
  44. {
  45. struct mesh_app_key *key = a;
  46. uint16_t net_idx = L_PTR_TO_UINT(b);
  47. if (key->net_idx != net_idx)
  48. return;
  49. if (key->new_key_aid == APP_AID_INVALID)
  50. return;
  51. key->key_aid = key->new_key_aid;
  52. key->new_key_aid = APP_AID_INVALID;
  53. memcpy(key->key, key->new_key, 16);
  54. }
  55. void appkey_finalize(struct mesh_net *net, uint16_t net_idx)
  56. {
  57. struct l_queue *app_keys;
  58. app_keys = mesh_net_get_app_keys(net);
  59. if (!app_keys)
  60. return;
  61. l_queue_foreach(app_keys, finalize_key, L_UINT_TO_PTR(net_idx));
  62. }
  63. static struct mesh_app_key *app_key_new(void)
  64. {
  65. struct mesh_app_key *key = l_new(struct mesh_app_key, 1);
  66. key->new_key_aid = APP_AID_INVALID;
  67. return key;
  68. }
  69. static bool set_key(struct mesh_app_key *key, uint16_t app_idx,
  70. const uint8_t *key_value, bool is_new)
  71. {
  72. uint8_t key_aid;
  73. if (!mesh_crypto_k4(key_value, &key_aid))
  74. return false;
  75. key_aid = KEY_ID_AKF | (key_aid << KEY_AID_SHIFT);
  76. if (!is_new)
  77. key->key_aid = key_aid;
  78. else
  79. key->new_key_aid = key_aid;
  80. memcpy(is_new ? key->new_key : key->key, key_value, 16);
  81. return true;
  82. }
  83. void appkey_key_free(void *data)
  84. {
  85. struct mesh_app_key *key = data;
  86. if (!key)
  87. return;
  88. l_free(key);
  89. }
  90. bool appkey_key_init(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
  91. uint8_t *key_value, uint8_t *new_key_value)
  92. {
  93. struct mesh_app_key *key;
  94. struct l_queue *app_keys;
  95. if (net_idx > MAX_KEY_IDX || app_idx > MAX_KEY_IDX)
  96. return false;
  97. app_keys = mesh_net_get_app_keys(net);
  98. if (!app_keys)
  99. return NULL;
  100. if (!mesh_net_have_key(net, net_idx))
  101. return false;
  102. key = app_key_new();
  103. if (!key)
  104. return false;
  105. key->net_idx = net_idx;
  106. key->app_idx = app_idx;
  107. if (key_value && !set_key(key, app_idx, key_value, false))
  108. return false;
  109. if (new_key_value && !set_key(key, app_idx, new_key_value, true))
  110. return false;
  111. l_queue_push_tail(app_keys, key);
  112. return true;
  113. }
  114. const uint8_t *appkey_get_key(struct mesh_net *net, uint16_t app_idx,
  115. uint8_t *key_aid)
  116. {
  117. struct mesh_app_key *app_key;
  118. uint8_t phase;
  119. struct l_queue *app_keys;
  120. app_keys = mesh_net_get_app_keys(net);
  121. if (!app_keys)
  122. return NULL;
  123. app_key = l_queue_find(app_keys, match_key_index,
  124. L_UINT_TO_PTR(app_idx));
  125. if (!app_key)
  126. return NULL;
  127. if (mesh_net_key_refresh_phase_get(net, app_key->net_idx, &phase) !=
  128. MESH_STATUS_SUCCESS)
  129. return NULL;
  130. if (phase != KEY_REFRESH_PHASE_TWO) {
  131. *key_aid = app_key->key_aid;
  132. return app_key->key;
  133. }
  134. if (app_key->new_key_aid == APP_AID_INVALID)
  135. return NULL;
  136. *key_aid = app_key->new_key_aid;
  137. return app_key->new_key;
  138. }
  139. int appkey_get_key_idx(struct mesh_app_key *app_key,
  140. const uint8_t **key, uint8_t *key_aid,
  141. const uint8_t **new_key, uint8_t *new_key_aid)
  142. {
  143. if (!app_key)
  144. return -1;
  145. if (key && key_aid) {
  146. *key = app_key->key;
  147. *key_aid = app_key->key_aid;
  148. }
  149. if (new_key && new_key_aid) {
  150. *new_key = app_key->new_key;
  151. *new_key_aid = app_key->new_key_aid;
  152. }
  153. return app_key->app_idx;
  154. }
  155. bool appkey_have_key(struct mesh_net *net, uint16_t app_idx)
  156. {
  157. struct mesh_app_key *key;
  158. struct l_queue *app_keys;
  159. app_keys = mesh_net_get_app_keys(net);
  160. if (!app_keys)
  161. return false;
  162. key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
  163. if (!key)
  164. return false;
  165. else
  166. return true;
  167. }
  168. uint16_t appkey_net_idx(struct mesh_net *net, uint16_t app_idx)
  169. {
  170. struct mesh_app_key *key;
  171. struct l_queue *app_keys;
  172. app_keys = mesh_net_get_app_keys(net);
  173. if (!app_keys)
  174. return NET_IDX_INVALID;
  175. key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
  176. if (!key)
  177. return NET_IDX_INVALID;
  178. else
  179. return key->net_idx;
  180. }
  181. int appkey_key_update(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
  182. const uint8_t *new_key)
  183. {
  184. struct mesh_app_key *key;
  185. struct l_queue *app_keys;
  186. uint8_t phase = KEY_REFRESH_PHASE_NONE;
  187. struct mesh_node *node;
  188. app_keys = mesh_net_get_app_keys(net);
  189. if (!app_keys)
  190. return MESH_STATUS_INSUFF_RESOURCES;
  191. if (!mesh_net_have_key(net, net_idx))
  192. return MESH_STATUS_INVALID_NETKEY;
  193. key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
  194. if (!key)
  195. return MESH_STATUS_INVALID_APPKEY;
  196. if (key->net_idx != net_idx)
  197. return MESH_STATUS_INVALID_BINDING;
  198. mesh_net_key_refresh_phase_get(net, net_idx, &phase);
  199. if (phase != KEY_REFRESH_PHASE_ONE)
  200. return MESH_STATUS_CANNOT_UPDATE;
  201. /* Check if the key has been already successfully updated */
  202. if (memcmp(new_key, key->new_key, 16) == 0)
  203. return MESH_STATUS_SUCCESS;
  204. if (!set_key(key, app_idx, new_key, true))
  205. return MESH_STATUS_INSUFF_RESOURCES;
  206. node = mesh_net_node_get(net);
  207. if (!mesh_config_app_key_update(node_config_get(node), app_idx,
  208. new_key))
  209. return MESH_STATUS_STORAGE_FAIL;
  210. return MESH_STATUS_SUCCESS;
  211. }
  212. int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
  213. const uint8_t *new_key)
  214. {
  215. struct mesh_app_key *key;
  216. struct l_queue *app_keys;
  217. struct mesh_node *node;
  218. app_keys = mesh_net_get_app_keys(net);
  219. if (!app_keys)
  220. return MESH_STATUS_INSUFF_RESOURCES;
  221. key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
  222. if (key) {
  223. if (memcmp(new_key, key->key, 16) == 0)
  224. return MESH_STATUS_SUCCESS;
  225. else
  226. return MESH_STATUS_IDX_ALREADY_STORED;
  227. }
  228. if (!mesh_net_have_key(net, net_idx))
  229. return MESH_STATUS_INVALID_NETKEY;
  230. if (l_queue_length(app_keys) >= MAX_APP_KEYS)
  231. return MESH_STATUS_INSUFF_RESOURCES;
  232. key = app_key_new();
  233. if (!set_key(key, app_idx, new_key, false)) {
  234. appkey_key_free(key);
  235. return MESH_STATUS_INSUFF_RESOURCES;
  236. }
  237. node = mesh_net_node_get(net);
  238. if (!mesh_config_app_key_add(node_config_get(node), net_idx, app_idx,
  239. new_key)) {
  240. appkey_key_free(key);
  241. return MESH_STATUS_STORAGE_FAIL;
  242. }
  243. key->net_idx = net_idx;
  244. key->app_idx = app_idx;
  245. l_queue_push_tail(app_keys, key);
  246. return MESH_STATUS_SUCCESS;
  247. }
  248. int appkey_key_delete(struct mesh_net *net, uint16_t net_idx,
  249. uint16_t app_idx)
  250. {
  251. struct mesh_app_key *key;
  252. struct l_queue *app_keys;
  253. struct mesh_node *node;
  254. app_keys = mesh_net_get_app_keys(net);
  255. if (!app_keys)
  256. return MESH_STATUS_INVALID_APPKEY;
  257. key = l_queue_find(app_keys, match_key_index, L_UINT_TO_PTR(app_idx));
  258. if (!key)
  259. return MESH_STATUS_SUCCESS;
  260. if (key->net_idx != net_idx)
  261. return MESH_STATUS_INVALID_NETKEY;
  262. node = mesh_net_node_get(net);
  263. node_app_key_delete(node, net_idx, app_idx);
  264. l_queue_remove(app_keys, key);
  265. appkey_key_free(key);
  266. if (!mesh_config_app_key_del(node_config_get(node), net_idx, app_idx))
  267. return MESH_STATUS_STORAGE_FAIL;
  268. return MESH_STATUS_SUCCESS;
  269. }
  270. void appkey_delete_bound_keys(struct mesh_net *net, uint16_t net_idx)
  271. {
  272. struct l_queue *app_keys;
  273. struct mesh_node *node;
  274. struct mesh_app_key *key;
  275. app_keys = mesh_net_get_app_keys(net);
  276. if (!app_keys)
  277. return;
  278. node = mesh_net_node_get(net);
  279. key = l_queue_remove_if(app_keys, match_bound_key,
  280. L_UINT_TO_PTR(net_idx));
  281. while (key) {
  282. node_app_key_delete(node, net_idx, key->app_idx);
  283. mesh_config_app_key_del(node_config_get(node), net_idx,
  284. key->app_idx);
  285. appkey_key_free(key);
  286. key = l_queue_remove_if(app_keys, match_bound_key,
  287. L_UINT_TO_PTR(net_idx));
  288. }
  289. }
  290. uint8_t appkey_list(struct mesh_net *net, uint16_t net_idx, uint8_t *buf,
  291. uint16_t buf_size, uint16_t *size)
  292. {
  293. const struct l_queue_entry *entry;
  294. uint32_t idx_pair;
  295. int i;
  296. uint16_t datalen;
  297. struct l_queue *app_keys;
  298. *size = 0;
  299. if (!mesh_net_have_key(net, net_idx))
  300. return MESH_STATUS_INVALID_NETKEY;
  301. app_keys = mesh_net_get_app_keys(net);
  302. if (!app_keys || l_queue_isempty(app_keys))
  303. return MESH_STATUS_SUCCESS;
  304. idx_pair = 0;
  305. i = 0;
  306. datalen = 0;
  307. entry = l_queue_get_entries(app_keys);
  308. for (; entry; entry = entry->next) {
  309. struct mesh_app_key *key = entry->data;
  310. if (net_idx != key->net_idx)
  311. continue;
  312. if (!(i & 0x1)) {
  313. idx_pair = key->app_idx;
  314. } else {
  315. idx_pair <<= 12;
  316. idx_pair += key->app_idx;
  317. /* Unlikely, but check for overflow*/
  318. if ((datalen + 3) > buf_size) {
  319. l_warn("Appkey list too large");
  320. goto done;
  321. }
  322. l_put_le32(idx_pair, buf);
  323. buf += 3;
  324. datalen += 3;
  325. }
  326. i++;
  327. }
  328. /* Process the last app key if present */
  329. if (i & 0x1 && ((datalen + 2) <= buf_size)) {
  330. l_put_le16(idx_pair, buf);
  331. datalen += 2;
  332. }
  333. done:
  334. *size = datalen;
  335. return MESH_STATUS_SUCCESS;
  336. }