summaryrefslogtreecommitdiff
path: root/mesh/friend.c
diff options
context:
space:
mode:
authorBrian Gix <brian.gix@intel.com>2018-09-18 12:40:08 -0700
committerBrian Gix <brian.gix@intel.com>2018-10-03 13:42:52 -0700
commit994932b740c7a31a55fe11aa98e00ad2bb392b4e (patch)
tree08b1c04aead39be005afc3b250b964834e560783 /mesh/friend.c
parentdf337d8d50273c36367757419a8918dc3870bad9 (diff)
downloadbluez-994932b740c7a31a55fe11aa98e00ad2bb392b4e.tar.gz
mesh: Refactor friend.c and net.c for central key DB
To enable multiple local nodes and friendships to coexist, and minimize redundant encryption processing
Diffstat (limited to 'mesh/friend.c')
-rw-r--r--mesh/friend.c188
1 files changed, 73 insertions, 115 deletions
diff --git a/mesh/friend.c b/mesh/friend.c
index 5a4088ef1..9ce499463 100644
--- a/mesh/friend.c
+++ b/mesh/friend.c
@@ -29,6 +29,7 @@
#include "mesh/mesh-defs.h"
#include "mesh/mesh.h"
+#include "mesh/net_keys.h"
#include "mesh/node.h"
#include "mesh/net.h"
#include "mesh/crypto.h"
@@ -56,7 +57,7 @@ static uint8_t frnd_sublist_size = FRND_SUB_LIST_SIZE;
struct frnd_negotiation {
struct l_timeout *timeout;
struct mesh_net *net;
- struct mesh_key_set key_set;
+ uint32_t key_id;
uint32_t poll_timeout;
uint16_t low_power_node;
uint16_t old_relay;
@@ -79,7 +80,7 @@ static void response_timeout(struct l_timeout *timeout, void *user_data)
/* LPN did not choose us */
l_info("Did not win negotiation for %4.4x", neg->low_power_node);
- mesh_net_remove_keyset(neg->net, &neg->key_set);
+ net_key_unref(neg->key_id);
l_queue_remove(frnd_negotiations, neg);
l_timeout_remove(timeout);
l_free(neg);
@@ -89,8 +90,7 @@ static void response_delay(struct l_timeout *timeout, void *user_data)
{
struct frnd_negotiation *neg = user_data;
uint16_t net_idx = mesh_net_get_primary_idx(neg->net);
- uint8_t key[16];
- uint8_t p[9] = { 1 };
+ uint32_t key_id;
uint8_t msg[8];
uint16_t n = 0;
bool res;
@@ -98,27 +98,17 @@ static void response_delay(struct l_timeout *timeout, void *user_data)
l_timeout_remove(timeout);
/* Create key Set for this offer */
- l_put_be16(neg->low_power_node, p + 1);
- l_put_be16(mesh_net_get_address(neg->net), p + 3);
- l_put_be16(neg->lp_cnt, p + 5);
- l_put_be16(counter, p + 7);
- res = mesh_net_get_key(neg->net, false, net_idx, key);
+ res = mesh_net_get_key(neg->net, false, net_idx, &key_id);
if (!res)
goto cleanup;
- print_packet("Friend Key P =", p, 9);
- res = mesh_crypto_k2(key, p, sizeof(p), &neg->key_set.nid,
- neg->key_set.enc_key, neg->key_set.privacy_key);
- if (!res)
+ neg->key_id = net_key_frnd_add(key_id, neg->low_power_node,
+ mesh_net_get_address(neg->net),
+ neg->lp_cnt, counter);
+ if (!neg->key_id)
goto cleanup;
- print_packet("NID =", &neg->key_set.nid, 1);
- print_packet("ENC_KEY =", neg->key_set.enc_key, 16);
- print_packet("PRIV_KEY =", neg->key_set.privacy_key, 16);
-
neg->fn_cnt = counter++;
- neg->key_set.frnd = true;
- mesh_net_add_keyset(neg->net, &neg->key_set);
msg[n++] = NET_OP_FRND_OFFER;
msg[n++] = frnd_relay_window;
@@ -128,7 +118,7 @@ static void response_delay(struct l_timeout *timeout, void *user_data)
l_put_be16(neg->fn_cnt, msg + n);
n += 2;
print_packet("Tx-NET_OP_FRND_OFFER", msg, n);
- mesh_net_transport_send(neg->net, NULL, true,
+ mesh_net_transport_send(neg->net, 0, true,
mesh_net_get_iv_index(neg->net), 0,
0, 0, neg->low_power_node,
msg, n);
@@ -142,7 +132,7 @@ static void response_delay(struct l_timeout *timeout, void *user_data)
return;
cleanup:
- mesh_net_remove_keyset(neg->net, &neg->key_set);
+ net_key_unref(neg->key_id);
l_queue_remove(frnd_negotiations, neg);
l_free(neg);
}
@@ -357,7 +347,7 @@ void friend_clear(struct mesh_net *net, uint16_t src, uint16_t lpn,
l_put_be16(lpn, msg + 1);
l_put_be16(lpnCounter, msg + 3);
- mesh_net_transport_send(net, NULL, false,
+ mesh_net_transport_send(net, 0, false,
mesh_net_get_iv_index(net), DEFAULT_TTL,
0, 0, src,
msg, sizeof(msg));
@@ -372,7 +362,7 @@ static void clear_retry(struct l_timeout *timeout, void *user_data)
l_put_be16(neg->low_power_node, msg + 1);
l_put_be16(neg->lp_cnt, msg + 3);
- mesh_net_transport_send(neg->net, NULL, false,
+ mesh_net_transport_send(neg->net, 0, false,
mesh_net_get_iv_index(neg->net), DEFAULT_TTL,
0, 0, neg->old_relay,
msg, sizeof(msg));
@@ -422,7 +412,7 @@ static void friend_delay_rsp(struct l_timeout *timeout, void *user_data)
pkt->iv_index);
pkt->u.one[0].sent = true;
- mesh_net_ack_send(net, &frnd->key_set,
+ mesh_net_ack_send(net, frnd->net_key_cur,
pkt->iv_index, pkt->ttl,
pkt->u.one[0].seq, pkt->src, pkt->dst,
rly, seqZero,
@@ -438,7 +428,7 @@ static void friend_delay_rsp(struct l_timeout *timeout, void *user_data)
pkt->u.one[0].data, pkt->last_len);
pkt->u.one[0].sent = true;
- mesh_net_transport_send(net, &frnd->key_set, false,
+ mesh_net_transport_send(net, frnd->net_key_cur, false,
pkt->iv_index, pkt->ttl,
pkt->u.one[0].seq, pkt->src, pkt->dst,
pkt->u.one[0].data, pkt->last_len);
@@ -458,7 +448,7 @@ static void friend_delay_rsp(struct l_timeout *timeout, void *user_data)
print_packet("Frnd-Msg", pkt->u.s12[pkt->cnt_out].data, len);
pkt->u.s12[pkt->cnt_out].sent = true;
- mesh_net_send_seg(net, &frnd->key_set,
+ mesh_net_send_seg(net, frnd->net_key_cur,
pkt->iv_index,
pkt->ttl,
pkt->u.s12[pkt->cnt_out].seq,
@@ -470,16 +460,16 @@ static void friend_delay_rsp(struct l_timeout *timeout, void *user_data)
return;
update:
- // No More Data -- send Update message with md = false
+ /* No More Data -- send Update message with md = false */
net_seq = mesh_net_get_seq_num(net);
l_info("Fwd FRND UPDATE %6.6x with MD == 0", net_seq);
frnd->last = frnd->seq;
mesh_net_get_snb_state(net, upd + 1, &iv_index);
l_put_be32(iv_index, upd + 2);
- upd[6] = false; // Queue is Empty
+ upd[6] = false; /* Queue is Empty */
print_packet("Update", upd, sizeof(upd));
- mesh_net_transport_send(net, &frnd->key_set, false,
+ mesh_net_transport_send(net, frnd->net_key_cur, false,
mesh_net_get_iv_index(net), 0,
net_seq, 0, frnd->dst,
upd, sizeof(upd));
@@ -512,7 +502,8 @@ void friend_poll(struct mesh_net *net, uint16_t src, bool seq,
friend_poll_timeout, frnd, NULL);
l_timeout_remove(neg->timeout);
- mesh_net_remove_keyset(neg->net, &neg->key_set);
+ net_key_unref(neg->key_id);
+ neg->key_id = 0;
if (neg->old_relay == 0 ||
neg->old_relay == mesh_net_get_address(net)) {
@@ -522,7 +513,7 @@ void friend_poll(struct mesh_net *net, uint16_t src, bool seq,
neg->clearing = true;
l_put_be16(neg->low_power_node, msg + 1);
l_put_be16(neg->lp_cnt, msg + 3);
- mesh_net_transport_send(net, NULL, false,
+ mesh_net_transport_send(net, 0, false,
mesh_net_get_iv_index(net), DEFAULT_TTL,
0, 0, neg->old_relay,
msg, sizeof(msg));
@@ -630,7 +621,7 @@ void friend_sub_add(struct mesh_net *net, struct mesh_friend *frnd,
print_packet("Tx-NET_OP_PROXY_SUB_CONFIRM", msg, sizeof(msg));
net_seq = mesh_net_get_seq_num(net);
- mesh_net_transport_send(net, &frnd->key_set, false,
+ mesh_net_transport_send(net, frnd->net_key_cur, false,
mesh_net_get_iv_index(net), 0,
net_seq, 0, frnd->dst,
msg, sizeof(msg));
@@ -668,7 +659,7 @@ void friend_sub_del(struct mesh_net *net, struct mesh_friend *frnd,
print_packet("Tx-NET_OP_PROXY_SUB_CONFIRM", msg, sizeof(msg));
net_seq = mesh_net_get_seq_num(net);
- mesh_net_transport_send(net, &frnd->key_set, false,
+ mesh_net_transport_send(net, frnd->net_key_cur, false,
mesh_net_get_iv_index(net), 0,
net_seq, 0, frnd->dst,
msg, sizeof(msg));
@@ -695,8 +686,8 @@ static uint16_t fn_cnt, cnt = 0xffff;
static uint32_t poll_period_ms;
static struct l_timeout *poll_retry_to;
static struct l_timeout *poll_period_to;
-static struct mesh_key_set lpn_set;
-static struct mesh_key_set new_lpn_set;
+static uint32_t lpn_key_id;
+static uint32_t new_lpn_id;
void frnd_offer(struct mesh_net *net, uint16_t src, uint8_t window,
uint8_t cache, uint8_t sub_list_size,
@@ -763,13 +754,13 @@ void frnd_poll_cancel(struct mesh_net *net)
void frnd_poll(struct mesh_net *net, bool retry)
{
- struct mesh_key_set *key_set = &lpn_set;
+ uint32_t key_id = lpn_key_id;
uint32_t net_seq;
uint8_t msg[2] = { NET_OP_FRND_POLL };
bool seq = mesh_net_get_frnd_seq(net);
/* Check if we are in Phase 2 of Key Refresh */
- if (new_lpn_set.nid != 0xff) {
+ if (new_lpn_id) {
uint8_t phase;
uint16_t net_idx = mesh_net_get_primary_idx(net);
uint8_t status =
@@ -777,7 +768,7 @@ void frnd_poll(struct mesh_net *net, bool retry)
if (status == MESH_STATUS_SUCCESS &&
phase == KEY_REFRESH_PHASE_TWO)
- key_set = &new_lpn_set;
+ key_id = new_lpn_id;
}
if (!retry) {
@@ -789,8 +780,9 @@ void frnd_poll(struct mesh_net *net, bool retry)
l_timeout_remove(poll_period_to);
poll_period_to = NULL;
frnd_poll_cancel(net);
- mesh_net_remove_keyset(net, &lpn_set);
- mesh_net_remove_keyset(net, &new_lpn_set);
+ net_key_unref(lpn_key_id);
+ net_key_unref(new_lpn_id);
+ new_lpn_id = lpn_key_id = 0;
mesh_net_set_friend(net, 0);
return;
}
@@ -801,7 +793,7 @@ void frnd_poll(struct mesh_net *net, bool retry)
l_info("TX-FRIEND POLL %d", seq);
msg[1] = seq;
net_seq = mesh_net_get_seq_num(net);
- mesh_net_transport_send(net, key_set, true,
+ mesh_net_transport_send(net, key_id, true,
mesh_net_get_iv_index(net), 0,
net_seq, 0, mesh_net_get_friend(net),
msg, sizeof(msg));
@@ -828,8 +820,7 @@ static void req_timeout(struct l_timeout *timeout, void *user_data)
struct mesh_net *net = user_data;
struct frnd_offers *best;
struct frnd_offers *offer = l_queue_pop_head(offers);
- uint8_t p[9] = { 1 };
- uint8_t key[16];
+ uint32_t key_id = 0;
bool res;
l_timeout_remove(timeout);
@@ -860,8 +851,9 @@ static void req_timeout(struct l_timeout *timeout, void *user_data)
offer = l_queue_pop_head(offers);
}
- mesh_net_remove_keyset(net, &lpn_set);
- mesh_net_remove_keyset(net, &new_lpn_set);
+ net_key_unref(lpn_key_id);
+ net_key_unref(new_lpn_id);
+ new_lpn_id = lpn_key_id = 0;
if (mesh_net_get_friend(net)) {
l_free(best);
return;
@@ -871,41 +863,24 @@ static void req_timeout(struct l_timeout *timeout, void *user_data)
}
fn_cnt = best->fn_cnt;
- l_put_be16(mesh_net_get_address(net), p + 1);
- l_put_be16(best->src, p + 3);
- l_put_be16(cnt, p + 5);
- l_put_be16(best->fn_cnt, p + 7);
- print_packet("Friend Key P =", p, 9);
- res = mesh_net_get_key(net, false, mesh_net_get_primary_idx(net), key);
+ res = mesh_net_get_key(net, false, mesh_net_get_primary_idx(net),
+ &key_id);
if (!res)
return;
- res = mesh_crypto_k2(key, p, sizeof(p), &lpn_set.nid,
- lpn_set.enc_key, lpn_set.privacy_key);
- if (!res)
+ lpn_key_id = net_key_frnd_add(key_id, mesh_net_get_address(net),
+ best->src, cnt, best->fn_cnt);
+ if (!lpn_key_id)
return;
- print_packet("Cur-NID", &lpn_set.nid, 1);
- print_packet("Cur-ENC_KEY", lpn_set.enc_key, 16);
- print_packet("Cur-PRIV_KEY", lpn_set.privacy_key, 16);
-
- mesh_net_add_keyset(net, &lpn_set);
+ res = mesh_net_get_key(net, true, mesh_net_get_primary_idx(net),
+ &key_id);
- res = mesh_net_get_key(net, true, mesh_net_get_primary_idx(net), key);
-
- if (res)
- res = mesh_crypto_k2(key, p, sizeof(p), &new_lpn_set.nid,
- new_lpn_set.enc_key, new_lpn_set.privacy_key);
- if (!res) {
- new_lpn_set.nid = 0xff;
+ if (!res)
goto old_keys_only;
- }
- print_packet("New-NID", &new_lpn_set.nid, 1);
- print_packet("New-ENC_KEY", new_lpn_set.enc_key, 16);
- print_packet("New-PRIV_KEY", new_lpn_set.privacy_key, 16);
-
- mesh_net_add_keyset(net, &new_lpn_set);
+ new_lpn_id = net_key_frnd_add(key_id, mesh_net_get_address(net),
+ best->src, cnt, best->fn_cnt);
old_keys_only:
@@ -935,11 +910,11 @@ void frnd_clear(struct mesh_net *net)
l_put_be16(cnt, msg + n);
n += 2;
- mesh_net_remove_keyset(net, &lpn_set);
- mesh_net_remove_keyset(net, &new_lpn_set);
+ net_key_unref(lpn_key_id);
+ net_key_unref(new_lpn_id);
mesh_net_set_friend(net, 0);
- mesh_net_transport_send(net, NULL, false,
+ mesh_net_transport_send(net, 0, false,
mesh_net_get_iv_index(net), 0,
0, 0, frnd_addr,
msg, n);
@@ -967,7 +942,7 @@ void frnd_request_friend(struct mesh_net *net, uint8_t cache,
l_put_be16(cnt + 1, msg + n); // Next counter
n += 2;
print_packet("Tx-NET_OP_FRND_REQUEST", msg, n);
- mesh_net_transport_send(net, NULL, false,
+ mesh_net_transport_send(net, 0, false,
mesh_net_get_iv_index(net), 0,
0, 0, FRIENDS_ADDRESS,
msg, n);
@@ -979,13 +954,13 @@ void frnd_request_friend(struct mesh_net *net, uint8_t cache,
static uint8_t trans_id;
void frnd_sub_add(struct mesh_net *net, uint32_t parms[7])
{
- struct mesh_key_set *key_set = &lpn_set;
+ uint32_t key_id = lpn_key_id;
uint32_t net_seq;
uint8_t msg[15] = { NET_OP_PROXY_SUB_ADD };
uint8_t i, n = 1;
/* Check if we are in Phase 2 of Key Refresh */
- if (new_lpn_set.nid != 0xff) {
+ if (new_lpn_id) {
uint8_t phase;
uint16_t net_idx = mesh_net_get_primary_idx(net);
uint8_t status = mesh_net_key_refresh_phase_get(net,
@@ -993,7 +968,7 @@ void frnd_sub_add(struct mesh_net *net, uint32_t parms[7])
if (status == MESH_STATUS_SUCCESS &&
phase == KEY_REFRESH_PHASE_TWO)
- key_set = &new_lpn_set;
+ key_id = new_lpn_id;
}
msg[n++] = ++trans_id;
@@ -1007,7 +982,7 @@ void frnd_sub_add(struct mesh_net *net, uint32_t parms[7])
net_seq = mesh_net_get_seq_num(net);
print_packet("Friend Sub Add", msg, n);
- mesh_net_transport_send(net, key_set, false,
+ mesh_net_transport_send(net, key_id, false,
mesh_net_get_iv_index(net), 0,
net_seq, 0, mesh_net_get_friend(net),
msg, n);
@@ -1016,13 +991,13 @@ void frnd_sub_add(struct mesh_net *net, uint32_t parms[7])
void frnd_sub_del(struct mesh_net *net, uint32_t parms[7])
{
- struct mesh_key_set *key_set = &lpn_set;
+ uint32_t key_id = lpn_key_id;
uint32_t net_seq;
uint8_t msg[15] = { NET_OP_PROXY_SUB_REMOVE };
uint8_t i, n = 1;
/* Check if we are in Phase 2 of Key Refresh */
- if (new_lpn_set.nid != 0xff) {
+ if (new_lpn_id) {
uint8_t phase;
uint16_t net_idx = mesh_net_get_primary_idx(net);
uint8_t status = mesh_net_key_refresh_phase_get(net,
@@ -1030,7 +1005,7 @@ void frnd_sub_del(struct mesh_net *net, uint32_t parms[7])
if (status == MESH_STATUS_SUCCESS &&
phase == KEY_REFRESH_PHASE_TWO)
- key_set = &new_lpn_set;
+ key_id = new_lpn_id;
}
msg[n++] = ++trans_id;
@@ -1044,7 +1019,7 @@ void frnd_sub_del(struct mesh_net *net, uint32_t parms[7])
net_seq = mesh_net_get_seq_num(net);
print_packet("Friend Sub Del", msg, n);
- mesh_net_transport_send(net, key_set, false,
+ mesh_net_transport_send(net, key_id, false,
mesh_net_get_iv_index(net), 0,
net_seq, 0, mesh_net_get_friend(net),
msg, n);
@@ -1054,46 +1029,29 @@ void frnd_sub_del(struct mesh_net *net, uint32_t parms[7])
void frnd_key_refresh(struct mesh_net *net, uint8_t phase)
{
uint16_t net_idx = mesh_net_get_primary_idx(net);
- uint8_t p[9] = { 1 };
- uint8_t key[16];
+ uint32_t key_id;
switch (phase) {
default:
case 0:
case 3:
- if (new_lpn_set.nid != 0xff) {
- l_info("LPN Retiring KeySet %2.2x", lpn_set.nid);
- lpn_set = new_lpn_set;
- new_lpn_set.nid = 0xff;
- mesh_net_remove_keyset(net, &new_lpn_set);
+ if (new_lpn_id) {
+ l_info("LPN Retiring KeySet %d", lpn_key_id);
+ net_key_unref(lpn_key_id);
+ lpn_key_id = new_lpn_id;
}
return;
case 1:
- mesh_net_remove_keyset(net, &new_lpn_set);
- if (!mesh_net_get_key(net, true, net_idx, key)) {
- new_lpn_set.nid = 0xff;
- return;
- }
-
- l_put_be16(mesh_net_get_address(net), p + 1);
- l_put_be16(mesh_net_get_friend(net), p + 3);
- l_put_be16(cnt, p + 5);
- l_put_be16(fn_cnt, p + 7);
- print_packet("Friend Key P =", p, 9);
-
- if (!mesh_crypto_k2(key, p, sizeof(p), &new_lpn_set.nid,
- new_lpn_set.enc_key,
- new_lpn_set.privacy_key)) {
- new_lpn_set.nid = 0xff;
+ net_key_unref(new_lpn_id);
+ if (!mesh_net_get_key(net, true, net_idx, &key_id)) {
+ new_lpn_id = 0;
return;
}
- print_packet("New-NID", &new_lpn_set.nid, 1);
- print_packet("New-ENC_KEY", new_lpn_set.enc_key, 16);
- print_packet("New-PRIV_KEY", new_lpn_set.privacy_key, 16);
-
- mesh_net_add_keyset(net, &new_lpn_set);
+ new_lpn_id = net_key_frnd_add(key_id, mesh_net_get_address(net),
+ mesh_net_get_friend(net),
+ cnt, fn_cnt);
return;
case 2:
@@ -1102,7 +1060,7 @@ void frnd_key_refresh(struct mesh_net *net, uint8_t phase)
}
}
-struct mesh_key_set *frnd_get_key(struct mesh_net *net)
+uint32_t frnd_get_key(struct mesh_net *net)
{
uint8_t idx = mesh_net_get_primary_idx(net);
uint8_t phase = 0;
@@ -1110,7 +1068,7 @@ struct mesh_key_set *frnd_get_key(struct mesh_net *net)
mesh_net_key_refresh_phase_get(net, idx, &phase);
if (phase == 2)
- return &new_lpn_set;
+ return new_lpn_id;
else
- return &lpn_set;
+ return lpn_key_id;
}