keys.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <ell/ell.h>
  14. #include "src/shared/shell.h"
  15. #include "mesh/mesh-defs.h"
  16. #include "tools/mesh/mesh-db.h"
  17. #include "tools/mesh/keys.h"
  18. struct net_key {
  19. struct l_queue *app_keys;
  20. uint16_t idx;
  21. uint8_t phase;
  22. };
  23. static struct l_queue *net_keys;
  24. static bool app_key_present(const struct net_key *key, uint16_t app_idx)
  25. {
  26. const struct l_queue_entry *l;
  27. for (l = l_queue_get_entries(key->app_keys); l; l = l->next) {
  28. uint16_t idx = L_PTR_TO_UINT(l->data);
  29. if (idx == app_idx)
  30. return true;
  31. }
  32. return false;
  33. }
  34. static bool net_idx_match(const void *a, const void *b)
  35. {
  36. const struct net_key *key = a;
  37. uint32_t idx = L_PTR_TO_UINT(b);
  38. return key->idx == idx;
  39. }
  40. static void delete_bound_appkey(void *a)
  41. {
  42. uint32_t idx = L_PTR_TO_UINT(a);
  43. mesh_db_del_app_key(idx);
  44. }
  45. void keys_add_net_key(uint16_t net_idx)
  46. {
  47. struct net_key *key;
  48. if (!net_keys)
  49. net_keys = l_queue_new();
  50. if (l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx)))
  51. return;
  52. key = l_new(struct net_key, 1);
  53. key->idx = net_idx;
  54. key->phase = KEY_REFRESH_PHASE_NONE;
  55. l_queue_push_tail(net_keys, key);
  56. }
  57. void keys_del_net_key(uint16_t idx)
  58. {
  59. struct net_key *key;
  60. if (!net_keys)
  61. return;
  62. key = l_queue_remove_if(net_keys, net_idx_match, L_UINT_TO_PTR(idx));
  63. if (!key)
  64. return;
  65. l_queue_destroy(key->app_keys, delete_bound_appkey);
  66. l_free(key);
  67. }
  68. void keys_set_net_key_phase(uint16_t net_idx, uint8_t phase, bool save)
  69. {
  70. struct net_key *key;
  71. if (!net_keys)
  72. return;
  73. key = l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx));
  74. if (!key)
  75. return;
  76. key->phase = phase;
  77. if (save && !mesh_db_set_net_key_phase(net_idx, phase))
  78. bt_shell_printf("Failed to save updated KR phase\n");
  79. }
  80. bool keys_get_net_key_phase(uint16_t net_idx, uint8_t *phase)
  81. {
  82. struct net_key *key;
  83. if (!phase || !net_keys)
  84. return false;
  85. key = l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx));
  86. if (!key)
  87. return false;
  88. *phase = key->phase;
  89. return true;
  90. }
  91. void keys_add_app_key(uint16_t net_idx, uint16_t app_idx)
  92. {
  93. struct net_key *key;
  94. if (!net_keys)
  95. return;
  96. key = l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx));
  97. if (!key)
  98. return;
  99. if (!key->app_keys)
  100. key->app_keys = l_queue_new();
  101. if (app_key_present(key, app_idx))
  102. return;
  103. l_queue_push_tail(key->app_keys, L_UINT_TO_PTR(app_idx));
  104. }
  105. void keys_del_app_key(uint16_t app_idx)
  106. {
  107. const struct l_queue_entry *l;
  108. if (!net_keys)
  109. return;
  110. for (l = l_queue_get_entries(net_keys); l; l = l->next) {
  111. struct net_key *key = l->data;
  112. if (!key->app_keys)
  113. continue;
  114. if (l_queue_remove(key->app_keys, L_UINT_TO_PTR(app_idx)))
  115. return;
  116. }
  117. }
  118. uint16_t keys_get_bound_key(uint16_t app_idx)
  119. {
  120. const struct l_queue_entry *l;
  121. if (!net_keys)
  122. return NET_IDX_INVALID;
  123. for (l = l_queue_get_entries(net_keys); l; l = l->next) {
  124. struct net_key *key = l->data;
  125. if (!key->app_keys)
  126. continue;
  127. if (app_key_present(key, app_idx))
  128. return key->idx;
  129. }
  130. return NET_IDX_INVALID;
  131. }
  132. static void print_appkey(void *app_key, void *user_data)
  133. {
  134. uint16_t app_idx = L_PTR_TO_UINT(app_key);
  135. bt_shell_printf("%u (0x%3.3x), ", app_idx, app_idx);
  136. }
  137. static void print_netkey(void *net_key, void *user_data)
  138. {
  139. struct net_key *key = net_key;
  140. bt_shell_printf(COLOR_YELLOW "NetKey: %u (0x%3.3x), phase: %u\n"
  141. COLOR_OFF, key->idx, key->idx, key->phase);
  142. if (!key->app_keys || l_queue_isempty(key->app_keys))
  143. return;
  144. bt_shell_printf("\t" COLOR_GREEN "app_keys = ");
  145. l_queue_foreach(key->app_keys, print_appkey, NULL);
  146. bt_shell_printf("\n" COLOR_OFF);
  147. }
  148. void keys_print_keys(void)
  149. {
  150. l_queue_foreach(net_keys, print_netkey, NULL);
  151. }
  152. bool keys_subnet_exists(uint16_t idx)
  153. {
  154. if (!l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(idx)))
  155. return false;
  156. return true;
  157. }