All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys
@ 2019-02-07  3:55 Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 1/5 v2] mesh: Separate functions for net key add and update Inga Stotland
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Inga Stotland @ 2019-02-07  3:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

Rev.2: addressed Brina's comments.

This set of patches fixes the network key add/update processing.
Network keys need to be saved to a local node configuration file
when:
	- a new node is provisioned
	- new network key are added by a configuration client
    - existing network key is updated by a configuration client
	  during key refresh procedure.

Also, each saved network key is accompanied by a proper key
refresh phase setting.

Inga Stotland (5):
  mesh: Separate functions for net key add and update
  mesh: Add function to restore net key state from storage
  mesh: Declare internal functions as static
  mesh: Save key refresh phase state to node config file
  mesh: Save newly added or updated net key to config file

 mesh/cfgmod-server.c |   8 +-
 mesh/mesh-db.c       | 178 +++++++++++++++++-----------
 mesh/mesh-db.h       |   6 +-
 mesh/net.c           | 268 +++++++++++++++++++++++++++----------------
 mesh/net.h           |  12 +-
 mesh/node.c          |  19 ++-
 mesh/storage.c       |  22 ++--
 mesh/storage.h       |   7 +-
 8 files changed, 326 insertions(+), 194 deletions(-)

-- 
2.17.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 1/5 v2] mesh: Separate functions for net key add and update
  2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
@ 2019-02-07  3:55 ` Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 2/5 v2] mesh: Add function to restore net key state from storage Inga Stotland
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Inga Stotland @ 2019-02-07  3:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This splits mesh_net_key_add() into two separate functions:
mesh_net_key_add() and mesh_net_key_update().
mesh_net_key_update() essentially replaces mesh_net_kr_phase_one()
since switching to Key Refresh phase one can only be triggered
by successful network key update.
---
 mesh/cfgmod-server.c |  8 ++++++--
 mesh/net.c           | 27 +++++++++++----------------
 mesh/net.h           |  8 ++++----
 mesh/node.c          |  4 ++--
 mesh/storage.c       |  2 +-
 5 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 062bdaaf2..899bdde2e 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -981,8 +981,12 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst,
 		if (size != 18)
 			return true;
 
-		b_res = mesh_net_add_key(net, opcode == OP_NETKEY_UPDATE,
-						l_get_le16(pkt), pkt + 2);
+		net_idx = l_get_le16(pkt);
+
+		if (opcode == OP_NETKEY_ADD)
+			b_res = mesh_net_add_key(net, net_idx, pkt + 2);
+		else
+			b_res = mesh_net_update_key(net, net_idx, pkt + 2);
 
 		l_debug("NetKey Add/Update %s",
 			(b_res == MESH_STATUS_SUCCESS) ? "success" : "fail");
diff --git a/mesh/net.c b/mesh/net.c
index 9e509a8ea..91823c724 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -970,27 +970,13 @@ int mesh_net_del_key(struct mesh_net *net, uint16_t idx)
 	return MESH_STATUS_SUCCESS;
 }
 
-int mesh_net_add_key(struct mesh_net *net, bool update, uint16_t idx,
-							const void *value)
+int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
 {
-	int status;
 	struct mesh_subnet *subnet;
 
 	subnet = l_queue_find(net->subnets, match_key_index,
 							L_UINT_TO_PTR(idx));
 
-	if (update) {
-		if (subnet && subnet->kr_phase == KEY_REFRESH_PHASE_NONE) {
-			l_info("Start key refresh");
-			status = mesh_net_kr_phase_one(net, idx, value);
-			if (status == MESH_STATUS_SUCCESS &&
-				!storage_net_key_add(net, idx,
-						value, KEY_REFRESH_PHASE_ONE))
-				return MESH_STATUS_STORAGE_FAIL;
-		} else
-			return MESH_STATUS_CANNOT_UPDATE;
-	}
-
 	if (subnet) {
 		if (net_key_confirm(subnet->net_key_cur, value))
 			return MESH_STATUS_SUCCESS;
@@ -3570,7 +3556,7 @@ uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t idx,
 	return MESH_STATUS_SUCCESS;
 }
 
-int mesh_net_kr_phase_one(struct mesh_net *net, uint16_t idx,
+int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
 							const uint8_t *value)
 {
 	struct mesh_subnet *subnet;
@@ -3580,9 +3566,15 @@ int mesh_net_kr_phase_one(struct mesh_net *net, uint16_t idx,
 
 	subnet = l_queue_find(net->subnets, match_key_index,
 							L_UINT_TO_PTR(idx));
+
 	if (!subnet)
 		return MESH_STATUS_CANNOT_UPDATE;
 
+	/* Check if the key has been already successfully updated */
+	if (subnet->kr_phase == KEY_REFRESH_PHASE_ONE &&
+				net_key_confirm(subnet->net_key_upd, value))
+		return MESH_STATUS_SUCCESS;
+
 	if (subnet->net_key_upd) {
 		net_key_unref(subnet->net_key_upd);
 		l_info("Warning: overwriting new keys");
@@ -3606,6 +3598,9 @@ int mesh_net_kr_phase_one(struct mesh_net *net, uint16_t idx,
 
 	l_info("key refresh phase 1: Key ID %d", subnet->net_key_upd);
 
+	if (!storage_net_key_add(net, idx, value, KEY_REFRESH_PHASE_ONE))
+		return MESH_STATUS_STORAGE_FAIL;
+
 	subnet->kr_phase = KEY_REFRESH_PHASE_ONE;
 
 	return MESH_STATUS_SUCCESS;
diff --git a/mesh/net.h b/mesh/net.h
index 0ef01b63e..b27a4e614 100644
--- a/mesh/net.h
+++ b/mesh/net.h
@@ -280,8 +280,10 @@ bool mesh_net_set_relay_mode(struct mesh_net *net, bool enable, uint8_t cnt,
 							uint8_t interval);
 bool mesh_net_set_friend_mode(struct mesh_net *net, bool enable);
 int mesh_net_del_key(struct mesh_net *net, uint16_t net_idx);
-int mesh_net_add_key(struct mesh_net *net, bool update,
-					uint16_t net_idx, const void *key);
+int mesh_net_add_key(struct mesh_net *net, uint16_t net_idx,
+							const uint8_t *key);
+int mesh_net_update_key(struct mesh_net *net, uint16_t net_idx,
+							const uint8_t *key);
 uint32_t mesh_net_get_iv_index(struct mesh_net *net);
 void mesh_net_get_snb_state(struct mesh_net *net,
 					uint8_t *flags, uint32_t *iv_index);
@@ -335,8 +337,6 @@ uint8_t mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t net_idx,
 							uint8_t transition);
 uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t net_idx,
 							uint8_t *phase);
-int mesh_net_kr_phase_one(struct mesh_net *net, uint16_t net_idx,
-							const uint8_t *key);
 int mesh_net_key_refresh_phase_two(struct mesh_net *net, uint16_t net_idx);
 int mesh_net_key_refresh_finish(struct mesh_net *net, uint16_t net_idx);
 void mesh_net_send_seg(struct mesh_net *net, uint32_t key_id,
diff --git a/mesh/node.c b/mesh/node.c
index e921b72b7..1845f9a32 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -1726,8 +1726,8 @@ bool node_add_pending_local(struct mesh_node *node, void *prov_node_info,
 	if (!mesh_db_write_device_key(node->jconfig, info->device_key))
 		return false;
 
-	if (mesh_net_add_key(node->net, kr, info->net_index,
-			info->net_key) != MESH_STATUS_SUCCESS)
+	if (mesh_net_add_key(node->net, info->net_index, info->net_key) !=
+							MESH_STATUS_SUCCESS)
 		return false;
 
 	if (!storage_net_key_add(node->net, info->net_index, info->net_key,
diff --git a/mesh/storage.c b/mesh/storage.c
index 3a6614eb2..1b52000b0 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -120,7 +120,7 @@ static bool read_net_keys_cb(uint16_t idx, uint8_t *key, uint8_t *new_key,
 	if (!net)
 		return false;
 
-	if (mesh_net_add_key(net, false, idx, key) != MESH_STATUS_SUCCESS)
+	if (mesh_net_add_key(net, idx, key) != MESH_STATUS_SUCCESS)
 		return false;
 	/* TODO: handle restoring key refresh phase and new keys */
 
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 2/5 v2] mesh: Add function to restore net key state from storage
  2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 1/5 v2] mesh: Separate functions for net key add and update Inga Stotland
@ 2019-02-07  3:55 ` Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 3/5 v2] mesh: Declare internal functions as static Inga Stotland
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Inga Stotland @ 2019-02-07  3:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This creates subnet state based on saved network key state:
current keys and, if present, updated keys.
Secure network beacon is generated according to key refresh phase.
---
 mesh/net.c     | 90 ++++++++++++++++++++++++++++++++++++++++++++------
 mesh/net.h     |  2 ++
 mesh/storage.c |  6 +---
 3 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/mesh/net.c b/mesh/net.c
index 91823c724..8cd547663 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -970,20 +970,10 @@ int mesh_net_del_key(struct mesh_net *net, uint16_t idx)
 	return MESH_STATUS_SUCCESS;
 }
 
-int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
+static int add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
 {
 	struct mesh_subnet *subnet;
 
-	subnet = l_queue_find(net->subnets, match_key_index,
-							L_UINT_TO_PTR(idx));
-
-	if (subnet) {
-		if (net_key_confirm(subnet->net_key_cur, value))
-			return MESH_STATUS_SUCCESS;
-		else
-			return MESH_STATUS_IDX_ALREADY_STORED;
-	}
-
 	subnet = subnet_new(net, idx);
 	if (!subnet)
 		return MESH_STATUS_INSUFF_RESOURCES;
@@ -1000,6 +990,32 @@ int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
 		return MESH_STATUS_INSUFF_RESOURCES;
 	}
 
+	return MESH_STATUS_SUCCESS;
+}
+
+/*
+ * This function is called when Configuration Server Model receives
+ * a NETKEY_ADD command
+ */
+int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
+{
+	struct mesh_subnet *subnet;
+	int status;
+
+	subnet = l_queue_find(net->subnets, match_key_index,
+							L_UINT_TO_PTR(idx));
+
+	if (subnet) {
+		if (net_key_confirm(subnet->net_key_cur, value))
+			return MESH_STATUS_SUCCESS;
+		else
+			return MESH_STATUS_IDX_ALREADY_STORED;
+	}
+
+	status = add_key(net, idx, value);
+	if (status != MESH_STATUS_SUCCESS)
+		return status;
+
 	if (!storage_net_key_add(net, idx, value,
 					KEY_REFRESH_PHASE_NONE)) {
 		l_queue_remove(net->subnets, subnet);
@@ -2923,6 +2939,54 @@ bool mesh_net_set_beacon_mode(struct mesh_net *net, bool enable)
 	return true;
 }
 
+/* This function is called when network keys are restored from storage. */
+bool mesh_net_set_key(struct mesh_net *net, uint16_t idx, const uint8_t *key,
+					const uint8_t *new_key, uint8_t phase)
+{
+	struct mesh_subnet *subnet;
+	int status;
+
+	subnet = l_queue_find(net->subnets, match_key_index,
+							L_UINT_TO_PTR(idx));
+	if (subnet)
+		return false;
+
+	/* Current key must be always present */
+	if (!key)
+		return false;
+
+	/* If key refresh is in progress, a new key must be present */
+	if (phase != KEY_REFRESH_PHASE_NONE && !new_key)
+		return false;
+
+	status = add_key(net, idx, key);
+	if (status != MESH_STATUS_SUCCESS)
+		return false;
+
+	subnet = l_queue_find(net->subnets, match_key_index,
+							L_UINT_TO_PTR(idx));
+	if (!subnet)
+		return false;
+
+	if (new_key)
+		subnet->net_key_upd = net_key_add(new_key);
+
+	/* Preserve key refresh state to generate secure beacon flags*/
+	if (phase == KEY_REFRESH_PHASE_TWO) {
+		subnet->key_refresh = 1;
+		subnet->net_key_tx = subnet->net_key_upd;
+	}
+
+	subnet->kr_phase = phase;
+
+	set_network_beacon(subnet, net);
+
+	if (net->io)
+		start_network_beacon(subnet, net);
+
+	return true;
+}
+
 static bool is_this_net(const void *a, const void *b)
 {
 	return a == b;
@@ -3556,6 +3620,10 @@ uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t idx,
 	return MESH_STATUS_SUCCESS;
 }
 
+/*
+ * This function is called when Configuration Server Model receives
+ * a NETKEY_UPDATE command
+ */
 int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
 							const uint8_t *value)
 {
diff --git a/mesh/net.h b/mesh/net.h
index b27a4e614..591a6898e 100644
--- a/mesh/net.h
+++ b/mesh/net.h
@@ -284,6 +284,8 @@ int mesh_net_add_key(struct mesh_net *net, uint16_t net_idx,
 							const uint8_t *key);
 int mesh_net_update_key(struct mesh_net *net, uint16_t net_idx,
 							const uint8_t *key);
+bool mesh_net_set_key(struct mesh_net *net, uint16_t idx, const uint8_t *key,
+					const uint8_t *new_key, uint8_t phase);
 uint32_t mesh_net_get_iv_index(struct mesh_net *net);
 void mesh_net_get_snb_state(struct mesh_net *net,
 					uint8_t *flags, uint32_t *iv_index);
diff --git a/mesh/storage.c b/mesh/storage.c
index 1b52000b0..84f7c6161 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -120,11 +120,7 @@ static bool read_net_keys_cb(uint16_t idx, uint8_t *key, uint8_t *new_key,
 	if (!net)
 		return false;
 
-	if (mesh_net_add_key(net, idx, key) != MESH_STATUS_SUCCESS)
-		return false;
-	/* TODO: handle restoring key refresh phase and new keys */
-
-	return true;
+	return mesh_net_set_key(net, idx, key, new_key, phase);
 }
 
 static bool read_app_keys_cb(uint16_t net_idx, uint16_t app_idx, uint8_t *key,
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 3/5 v2] mesh: Declare internal functions as static
  2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 1/5 v2] mesh: Separate functions for net key add and update Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 2/5 v2] mesh: Add function to restore net key state from storage Inga Stotland
@ 2019-02-07  3:55 ` Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 4/5 v2] mesh: Save key refresh phase state to node config file Inga Stotland
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Inga Stotland @ 2019-02-07  3:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This renames mesh_net_key_refresh_finish() to key_refresh_finish() and
mesh_net_key_phase_two() to key_refresh_phase_wo() and changes the
function declaration to static since they are called only within net.c
---
 mesh/net.c | 146 ++++++++++++++++++++++++++---------------------------
 mesh/net.h |   2 -
 2 files changed, 73 insertions(+), 75 deletions(-)

diff --git a/mesh/net.c b/mesh/net.c
index 8cd547663..1be722181 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -1016,8 +1016,7 @@ int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
 	if (status != MESH_STATUS_SUCCESS)
 		return status;
 
-	if (!storage_net_key_add(net, idx, value,
-					KEY_REFRESH_PHASE_NONE)) {
+	if (!storage_net_key_add(net, idx, value, KEY_REFRESH_PHASE_NONE)) {
 		l_queue_remove(net->subnets, subnet);
 		subnet_free(subnet);
 		return MESH_STATUS_STORAGE_FAIL;
@@ -2629,6 +2628,70 @@ static void iv_upd_to(struct l_timeout *upd_timeout, void *user_data)
 	}
 }
 
+
+static int key_refresh_phase_two(struct mesh_net *net, uint16_t idx)
+{
+	struct mesh_subnet *subnet;
+
+	if (!net)
+		return MESH_STATUS_UNSPECIFIED_ERROR;
+
+	subnet = l_queue_find(net->subnets, match_key_index,
+							L_UINT_TO_PTR(idx));
+
+	if (!subnet || !subnet->net_key_upd)
+		return MESH_STATUS_INVALID_NETKEY;
+
+	l_info("Key refresh procedure phase 2: start using new net TX keys");
+	subnet->key_refresh = 1;
+	subnet->net_key_tx = subnet->net_key_upd;
+	/* TODO: Provisioner may need to stay in phase three until
+	 * it hears beacons from all the nodes
+	 */
+	subnet->kr_phase = KEY_REFRESH_PHASE_TWO;
+	set_network_beacon(subnet, net);
+
+	if (net->friend_addr)
+		frnd_key_refresh(net, 2);
+	else
+		l_queue_foreach(net->friends, frnd_kr_phase2, net);
+
+	return MESH_STATUS_SUCCESS;
+}
+
+static int key_refresh_finish(struct mesh_net *net, uint16_t idx)
+{
+	struct mesh_subnet *subnet;
+
+	if (!net)
+		return MESH_STATUS_UNSPECIFIED_ERROR;
+
+	subnet = l_queue_find(net->subnets, match_key_index,
+							L_UINT_TO_PTR(idx));
+	if (!subnet || !subnet->net_key_upd)
+		return MESH_STATUS_INVALID_NETKEY;
+
+	if (subnet->kr_phase == KEY_REFRESH_PHASE_NONE)
+		return MESH_STATUS_SUCCESS;
+
+	l_info("Key refresh phase 3: use new keys only, discard old ones");
+
+	/* Switch to using new keys, discard old ones */
+	net_key_unref(subnet->net_key_cur);
+	subnet->net_key_tx = subnet->net_key_cur = subnet->net_key_upd;
+	subnet->net_key_upd = 0;
+	subnet->key_refresh = 0;
+	subnet->kr_phase = KEY_REFRESH_PHASE_NONE;
+	set_network_beacon(subnet, net);
+
+	if (net->friend_addr)
+		frnd_key_refresh(net, 3);
+	else
+		l_queue_foreach(net->friends, frnd_kr_phase3, net);
+
+	return MESH_STATUS_SUCCESS;
+}
+
 static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
 				bool iv_update, bool kr_transition,
 				bool rxed_key_refresh, bool lpn)
@@ -2680,11 +2743,11 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
 
 		/* Figure out the key refresh phase */
 		if (kr_transition) {
+			l_debug("Beacon based KR phase change");
 			if (rxed_key_refresh)
-				mesh_net_key_refresh_phase_two(net,
-								subnet->idx);
+				key_refresh_phase_two(net, subnet->idx);
 			else
-				mesh_net_key_refresh_finish(net, subnet->idx);
+				key_refresh_finish(net, subnet->idx);
 		}
 
 		if (!lpn)
@@ -2717,9 +2780,9 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
 	/* Figure out the key refresh phase */
 	if (kr_transition) {
 		if (rxed_key_refresh)
-			mesh_net_key_refresh_phase_two(net, subnet->idx);
+			key_refresh_phase_two(net, subnet->idx);
 		else
-			mesh_net_key_refresh_finish(net, subnet->idx);
+			key_refresh_finish(net, subnet->idx);
 	}
 
 	if (!lpn)
@@ -3588,18 +3651,19 @@ uint8_t mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t idx,
 
 	switch (transition) {
 	case 2:
-		if (mesh_net_key_refresh_phase_two(net, idx)
+		if (key_refresh_phase_two(net, idx)
 							!= MESH_STATUS_SUCCESS)
 			return MESH_STATUS_CANNOT_SET;
 		break;
 	case 3:
-		if (mesh_net_key_refresh_finish(net, idx)
+		if (key_refresh_finish(net, idx)
 							!= MESH_STATUS_SUCCESS)
 			return MESH_STATUS_CANNOT_SET;
 		break;
 	default:
 		return MESH_STATUS_CANNOT_SET;
 	}
+
 	return MESH_STATUS_SUCCESS;
 }
 
@@ -3674,70 +3738,6 @@ int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
 	return MESH_STATUS_SUCCESS;
 }
 
-int mesh_net_key_refresh_phase_two(struct mesh_net *net, uint16_t idx)
-{
-	struct mesh_subnet *subnet;
-
-	if (!net)
-		return MESH_STATUS_UNSPECIFIED_ERROR;
-
-	subnet = l_queue_find(net->subnets, match_key_index,
-							L_UINT_TO_PTR(idx));
-
-	if (!subnet || !subnet->net_key_upd)
-		return MESH_STATUS_INVALID_NETKEY;
-
-	l_info("Key refresh procedure phase 2: start using new net TX keys");
-	subnet->key_refresh = 1;
-	subnet->net_key_tx = subnet->net_key_upd;
-	/* TODO: Provisioner may need to stay in phase three until
-	 * it hears beacons from all the nodes
-	 */
-	subnet->kr_phase = KEY_REFRESH_PHASE_TWO;
-	set_network_beacon(subnet, net);
-
-	if (net->friend_addr)
-		frnd_key_refresh(net, 2);
-	else
-		l_queue_foreach(net->friends, frnd_kr_phase2, net);
-
-	return MESH_STATUS_SUCCESS;
-}
-
-int mesh_net_key_refresh_finish(struct mesh_net *net, uint16_t idx)
-{
-	struct mesh_subnet *subnet;
-
-	if (!net)
-		return MESH_STATUS_UNSPECIFIED_ERROR;
-
-	subnet = l_queue_find(net->subnets, match_key_index,
-							L_UINT_TO_PTR(idx));
-
-	if (!subnet || !subnet->net_key_upd)
-		return MESH_STATUS_INVALID_NETKEY;
-
-	if (subnet->kr_phase == KEY_REFRESH_PHASE_NONE)
-		return MESH_STATUS_SUCCESS;
-
-	l_info("Key refresh phase 3: use new keys only, discard old ones");
-
-	/* Switch to using new keys, discard old ones */
-	net_key_unref(subnet->net_key_cur);
-	subnet->net_key_tx = subnet->net_key_cur = subnet->net_key_upd;
-	subnet->net_key_upd = 0;
-	subnet->key_refresh = 0;
-	subnet->kr_phase = KEY_REFRESH_PHASE_NONE;
-	set_network_beacon(subnet, net);
-
-	if (net->friend_addr)
-		frnd_key_refresh(net, 3);
-	else
-		l_queue_foreach(net->friends, frnd_kr_phase3, net);
-
-	return MESH_STATUS_SUCCESS;
-}
-
 uint16_t mesh_net_get_features(struct mesh_net *net)
 {
 	uint16_t features = 0;
diff --git a/mesh/net.h b/mesh/net.h
index 591a6898e..e040e19fa 100644
--- a/mesh/net.h
+++ b/mesh/net.h
@@ -339,8 +339,6 @@ uint8_t mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t net_idx,
 							uint8_t transition);
 uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t net_idx,
 							uint8_t *phase);
-int mesh_net_key_refresh_phase_two(struct mesh_net *net, uint16_t net_idx);
-int mesh_net_key_refresh_finish(struct mesh_net *net, uint16_t net_idx);
 void mesh_net_send_seg(struct mesh_net *net, uint32_t key_id,
 				uint32_t iv_index, uint8_t ttl, uint32_t seq,
 				uint16_t src, uint16_t dst, uint32_t hdr,
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 4/5 v2] mesh: Save key refresh phase state to node config file
  2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
                   ` (2 preceding siblings ...)
  2019-02-07  3:55 ` [PATCH BlueZ 3/5 v2] mesh: Declare internal functions as static Inga Stotland
@ 2019-02-07  3:55 ` Inga Stotland
  2019-02-07  3:55 ` [PATCH BlueZ 5/5 v2] mesh: Save newly added or updated net key to " Inga Stotland
  2019-02-12 23:42 ` [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Gix, Brian
  5 siblings, 0 replies; 7+ messages in thread
From: Inga Stotland @ 2019-02-07  3:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This adds implementation for saving the key refresh phase to
a node configuration file in JSON format. When the key refresh
procedure is finished, the old network keys are remove from the
configuration file.
---
 mesh/mesh-db.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 mesh/mesh-db.h |  2 +-
 mesh/net.c     |  4 ++++
 mesh/storage.c |  9 ++++++++
 mesh/storage.h |  2 ++
 5 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index 5c0b72551..b9bbef912 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -1491,3 +1491,59 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
 
 	return true;
 }
+
+static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
+{
+	json_object *jarray;
+	int i, len;
+
+	/* Clean up all the bound appkeys */
+	json_object_object_get_ex(jobj, "appKeys", &jarray);
+	if (!jarray)
+		return;
+
+	len = json_object_array_length(jarray);
+
+	for (i = 0; i < len; ++i) {
+		json_object *jentry;
+		uint16_t idx;
+
+		jentry = json_object_array_get_idx(jarray, i);
+
+		if (!get_key_index(jentry, "boundNetKey", &idx))
+			continue;
+
+		if (idx != net_idx)
+			continue;
+
+		json_object_object_del(jentry, "oldKey");
+
+		if (!get_key_index(jentry, "index", &idx))
+			continue;
+	}
+
+}
+
+bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
+{
+	json_object *jarray, *jentry = NULL;
+
+	json_object_object_get_ex(jobj, "netKeys", &jarray);
+
+	if (jarray)
+		jentry = get_key_object(jarray, idx);
+
+	if (!jentry)
+		return false;
+
+	json_object_object_del(jentry, "keyRefresh");
+	json_object_object_add(jentry, "keyRefresh",
+					json_object_new_int(phase));
+
+	if (phase == KEY_REFRESH_PHASE_NONE) {
+		json_object_object_del(jentry, "oldKey");
+		finish_key_refresh(jobj, idx);
+	}
+
+	return true;
+}
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index 40e60f72d..db7ea6045 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -135,7 +135,7 @@ bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
 bool mesh_db_net_key_add(json_object *jobj, uint16_t net_idx,
 					const uint8_t key[16], int phase);
 bool mesh_db_net_key_del(json_object *jobj, uint16_t net_idx);
-bool mesh_db_write_kr_phase(json_object *jobj, uint16_t net_idx, int phase);
+bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase);
 bool mesh_db_write_address(json_object *jobj, uint16_t address);
 bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update);
 void mesh_db_remove_property(json_object *jobj, const char *desc);
diff --git a/mesh/net.c b/mesh/net.c
index 1be722181..3229d20d4 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -2656,6 +2656,8 @@ static int key_refresh_phase_two(struct mesh_net *net, uint16_t idx)
 	else
 		l_queue_foreach(net->friends, frnd_kr_phase2, net);
 
+	storage_set_key_refresh_phase(net, idx, KEY_REFRESH_PHASE_TWO);
+
 	return MESH_STATUS_SUCCESS;
 }
 
@@ -2689,6 +2691,8 @@ static int key_refresh_finish(struct mesh_net *net, uint16_t idx)
 	else
 		l_queue_foreach(net->friends, frnd_kr_phase3, net);
 
+	storage_set_key_refresh_phase(net, idx, KEY_REFRESH_PHASE_NONE);
+
 	return MESH_STATUS_SUCCESS;
 }
 
diff --git a/mesh/storage.c b/mesh/storage.c
index 84f7c6161..e1d86960a 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -321,6 +321,15 @@ bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
 	return mesh_db_write_iv_index(jnode, iv_index, update);
 }
 
+bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
+								uint8_t phase)
+{
+	struct mesh_node *node = mesh_net_node_get(net);
+	json_object *jnode = node_jconfig_get(node);
+
+	return mesh_db_net_key_set_phase(jnode, net_idx, phase);
+}
+
 bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
diff --git a/mesh/storage.h b/mesh/storage.h
index 91299f0a8..7dad2762e 100644
--- a/mesh/storage.h
+++ b/mesh/storage.h
@@ -47,3 +47,5 @@ bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
 								bool update);
 bool storage_set_device_key(struct mesh_node *node, uint8_t dev_key[16]);
 bool storage_set_unicast(struct mesh_node *node, uint16_t unicast);
+bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
+								uint8_t phase);
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 5/5 v2] mesh: Save newly added or updated net key to config file
  2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
                   ` (3 preceding siblings ...)
  2019-02-07  3:55 ` [PATCH BlueZ 4/5 v2] mesh: Save key refresh phase state to node config file Inga Stotland
@ 2019-02-07  3:55 ` Inga Stotland
  2019-02-12 23:42 ` [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Gix, Brian
  5 siblings, 0 replies; 7+ messages in thread
From: Inga Stotland @ 2019-02-07  3:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This separates mesh_db_net_key_add() into distinct functions:
mesh_db_net_key_add() and mesh_db_net_key_update() which will be called
based on whether a network key was newly added or updated.
---
 mesh/mesh-db.c | 122 +++++++++++++++++++++----------------------------
 mesh/mesh-db.h |   4 +-
 mesh/net.c     |   9 ++--
 mesh/node.c    |  15 ++++--
 mesh/storage.c |   7 ++-
 mesh/storage.h |   5 +-
 6 files changed, 80 insertions(+), 82 deletions(-)

diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index b9bbef912..6486f7cff 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -51,7 +51,7 @@ static bool get_int(json_object *jobj, const char *keyword, int *value)
 	return true;
 }
 
-static bool add_key(json_object *jobject, const char *desc,
+static bool add_key_value(json_object *jobject, const char *desc,
 					const uint8_t key[16])
 {
 	json_object *jstring;
@@ -382,7 +382,7 @@ bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
 }
 
 bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
-					const uint8_t key[16], int phase)
+							const uint8_t key[16])
 {
 	json_object *jarray, *jentry = NULL, *jstring;
 	char buf[5];
@@ -392,91 +392,75 @@ bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
 	if (jarray)
 		jentry = get_key_object(jarray, idx);
 
-	if (jentry) {
-		uint8_t buf[16];
-		json_object *jvalue;
-		char *str;
-
-		json_object_object_get_ex(jentry, "key", &jvalue);
-		if (!jvalue)
-			return false;
-
-		str = (char *)json_object_get_string(jvalue);
-		if (!str2hex(str, strlen(str), buf, sizeof(buf)))
-			return false;
-
-		/* If the same key, return success */
-		if (memcmp(key, buf, 16) == 0)
-			return true;
+	/* Do not allow direct overwrite */
+	if (jentry)
+		return false;
 
+	jentry = json_object_new_object();
+	if (!jentry)
 		return false;
-	}
 
-	if (!jentry) {
-		jentry = json_object_new_object();
-		if (!jentry)
-			goto fail;
+	snprintf(buf, 5, "%4.4x", idx);
+	jstring = json_object_new_string(buf);
+	if (!jstring)
+		goto fail;
 
-		snprintf(buf, 5, "%4.4x", idx);
-		jstring = json_object_new_string(buf);
-		if (!jstring)
-			goto fail;
+	json_object_object_add(jentry, "index", jstring);
 
-		json_object_object_add(jentry, "index", jstring);
+	if (!add_key_value(jentry, "key", key))
+		goto fail;
 
-		snprintf(buf, 5, "%4.4x", idx);
-		jstring = json_object_new_string(buf);
-		if (!jstring)
-			goto fail;
+	json_object_object_add(jentry, "keyRefresh",
+				json_object_new_int(KEY_REFRESH_PHASE_NONE));
 
-		if (!add_key(jentry, "key", key))
+	if (!jarray) {
+		jarray = json_object_new_array();
+		if (!jarray)
 			goto fail;
+		json_object_object_add(jobj, "netKeys", jarray);
+	}
 
-		/* If Key Refresh underway, add placeholder for "Old Key" */
-		if (phase != KEY_REFRESH_PHASE_NONE) {
-			uint8_t buf[16];
-			uint8_t i;
+	json_object_array_add(jarray, jentry);
 
-			/* Flip Bits to differentiate */
-			for (i = 0; i < sizeof(buf); i++)
-				buf[i] = key[i] ^ 0xff;
+	return true;
+fail:
+	if (jentry)
+		json_object_put(jentry);
 
-			if (!add_key(jentry, "oldKey", buf))
-				goto fail;
-		}
+	return false;
+}
 
-		if (!jarray) {
-			jarray = json_object_new_array();
-			if (!jarray)
-				goto fail;
-			json_object_object_add(jobj, "netKeys", jarray);
-		}
+bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+							const uint8_t key[16])
+{
+	json_object *jarray, *jentry, *jstring;
+	const char *str;
 
-		json_object_array_add(jarray, jentry);
+	json_object_object_get_ex(jobj, "netKeys", &jarray);
 
-	} else {
+	if (!jarray)
+		return false;
 
-		if (!json_object_object_get_ex(jentry, "key", &jstring))
-			return false;
+	jentry = get_key_object(jarray, idx);
+	/* Net key must be already recorded */
+	if (!jentry)
+		return false;
 
-		json_object_object_add(jentry, "oldKey", jstring);
-		json_object_object_del(jentry, "key");
+	if (!json_object_object_get_ex(jentry, "key", &jstring))
+		return false;
 
-		if (!add_key(jentry, "key", key))
-			return false;
-	}
+	str = json_object_get_string(jstring);
+	jstring = json_object_new_string(str);
+	json_object_object_add(jentry, "oldKey", jstring);
+	json_object_object_del(jentry, "key");
 
+	if (!add_key_value(jentry, "key", key))
+		return false;
 
 	json_object_object_add(jentry, "keyRefresh",
-					json_object_new_int(phase));
+				json_object_new_int(KEY_REFRESH_PHASE_ONE));
 
 	return true;
-fail:
-
-	if (jentry)
-		json_object_put(jentry);
-
-	return false;
 }
 
 bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
@@ -513,7 +497,7 @@ bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
 
 bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
 {
-	return add_key(jnode, "deviceKey", key);
+	return add_key_value(jnode, "deviceKey", key);
 }
 
 bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
@@ -572,7 +556,7 @@ bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
 
 		json_object_object_add(jentry, "boundNetKey", jstring);
 
-		if (!add_key(jentry, "key", key))
+		if (!add_key_value(jentry, "key", key))
 			goto fail;
 
 		if (!jarray) {
@@ -592,7 +576,7 @@ bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
 		json_object_object_add(jentry, "oldKey", jstring);
 		json_object_object_del(jentry, "key");
 
-		if (!add_key(jentry, "key", key))
+		if (!add_key_value(jentry, "key", key))
 			return false;
 	}
 
@@ -1421,7 +1405,7 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
 		return false;
 
 	/* Device UUID */
-	if (!add_key(jnode, "UUID", node->uuid))
+	if (!add_key_value(jnode, "UUID", node->uuid))
 		return false;
 
 	/* Features: relay, LPN, friend, proxy*/
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index db7ea6045..513ad3861 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -133,7 +133,9 @@ bool mesh_db_app_key_add(json_object *jnode, uint16_t net_idx, uint16_t app_idx,
 					const uint8_t key[16], bool update);
 bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
 bool mesh_db_net_key_add(json_object *jobj, uint16_t net_idx,
-					const uint8_t key[16], int phase);
+							const uint8_t key[16]);
+bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+							const uint8_t key[16]);
 bool mesh_db_net_key_del(json_object *jobj, uint16_t net_idx);
 bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase);
 bool mesh_db_write_address(json_object *jobj, uint16_t address);
diff --git a/mesh/net.c b/mesh/net.c
index 3229d20d4..f00ef7df7 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -1016,7 +1016,7 @@ int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
 	if (status != MESH_STATUS_SUCCESS)
 		return status;
 
-	if (!storage_net_key_add(net, idx, value, KEY_REFRESH_PHASE_NONE)) {
+	if (!storage_net_key_add(net, idx, value, false)) {
 		l_queue_remove(net->subnets, subnet);
 		subnet_free(subnet);
 		return MESH_STATUS_STORAGE_FAIL;
@@ -3704,13 +3704,16 @@ int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
 							L_UINT_TO_PTR(idx));
 
 	if (!subnet)
-		return MESH_STATUS_CANNOT_UPDATE;
+		return MESH_STATUS_INVALID_NETKEY;
 
 	/* Check if the key has been already successfully updated */
 	if (subnet->kr_phase == KEY_REFRESH_PHASE_ONE &&
 				net_key_confirm(subnet->net_key_upd, value))
 		return MESH_STATUS_SUCCESS;
 
+	if (subnet->kr_phase != KEY_REFRESH_PHASE_NONE)
+		return MESH_STATUS_CANNOT_UPDATE;
+
 	if (subnet->net_key_upd) {
 		net_key_unref(subnet->net_key_upd);
 		l_info("Warning: overwriting new keys");
@@ -3734,7 +3737,7 @@ int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
 
 	l_info("key refresh phase 1: Key ID %d", subnet->net_key_upd);
 
-	if (!storage_net_key_add(net, idx, value, KEY_REFRESH_PHASE_ONE))
+	if (!storage_net_key_add(net, idx, value, true))
 		return MESH_STATUS_STORAGE_FAIL;
 
 	subnet->kr_phase = KEY_REFRESH_PHASE_ONE;
diff --git a/mesh/node.c b/mesh/node.c
index 1845f9a32..c815acf2e 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -1730,9 +1730,16 @@ bool node_add_pending_local(struct mesh_node *node, void *prov_node_info,
 							MESH_STATUS_SUCCESS)
 		return false;
 
-	if (!storage_net_key_add(node->net, info->net_index, info->net_key,
-			kr ? KEY_REFRESH_PHASE_TWO : KEY_REFRESH_PHASE_NONE))
-		return false;
+	if (kr) {
+		/* Duplicate net key, if the key refresh is on */
+		if (mesh_net_update_key(node->net, info->net_index,
+				info->net_key) != MESH_STATUS_SUCCESS)
+			return false;
+
+		if (!mesh_db_net_key_set_phase(node->jconfig, info->net_index,
+							KEY_REFRESH_PHASE_TWO))
+			return false;
+	}
 
 	if (!storage_save_config(node, true, NULL, NULL))
 		return false;
@@ -1752,7 +1759,7 @@ void node_jconfig_set(struct mesh_node *node, void *jconfig)
 
 void *node_jconfig_get(struct mesh_node *node)
 {
-	return  node->jconfig;
+	return node->jconfig;
 }
 
 void node_cfg_file_set(struct mesh_node *node, char *cfg)
diff --git a/mesh/storage.c b/mesh/storage.c
index e1d86960a..d6b566a80 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -296,12 +296,15 @@ bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
 }
 
 bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
-					const uint8_t key[16], int phase)
+					const uint8_t key[16], bool update)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
 	json_object *jnode = node_jconfig_get(node);
 
-	return mesh_db_net_key_add(jnode, net_idx, key, phase);
+	if (!update)
+		return mesh_db_net_key_add(jnode, net_idx, key);
+	else
+		return mesh_db_net_key_update(jnode, net_idx, key);
 }
 
 bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
diff --git a/mesh/storage.h b/mesh/storage.h
index 7dad2762e..85f7899bc 100644
--- a/mesh/storage.h
+++ b/mesh/storage.h
@@ -33,10 +33,9 @@ bool storage_set_relay(json_object *jnode, bool enable, uint8_t count,
 							uint8_t interval);
 bool storage_set_transmit_params(json_object *jnode, uint8_t count,
 							uint8_t interval);
-bool storage_set_mode(json_object *jnode, uint8_t mode,
-							const char *mode_name);
+bool storage_set_mode(json_object *jnode, uint8_t mode, const char *mode_name);
 bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
-					const uint8_t key[16], int phase);
+					const uint8_t key[16], bool update);
 bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx);
 bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
 			uint16_t app_idx, const uint8_t key[16], bool update);
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys
  2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
                   ` (4 preceding siblings ...)
  2019-02-07  3:55 ` [PATCH BlueZ 5/5 v2] mesh: Save newly added or updated net key to " Inga Stotland
@ 2019-02-12 23:42 ` Gix, Brian
  5 siblings, 0 replies; 7+ messages in thread
From: Gix, Brian @ 2019-02-12 23:42 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org, Stotland, Inga
  Cc: luiz.dentz@gmail.com, johan.hedberg@gmail.com

Patch set applied


On Wed, 2019-02-06 at 19:55 -0800, Inga Stotland wrote:
> Rev.2: addressed Brina's comments.
> 
> This set of patches fixes the network key add/update processing.
> Network keys need to be saved to a local node configuration file
> when:
> 	- a new node is provisioned
> 	- new network key are added by a configuration client
>     - existing network key is updated by a configuration client
> 	  during key refresh procedure.
> 
> Also, each saved network key is accompanied by a proper key
> refresh phase setting.
> 
> Inga Stotland (5):
>   mesh: Separate functions for net key add and update
>   mesh: Add function to restore net key state from storage
>   mesh: Declare internal functions as static
>   mesh: Save key refresh phase state to node config file
>   mesh: Save newly added or updated net key to config file
> 
>  mesh/cfgmod-server.c |   8 +-
>  mesh/mesh-db.c       | 178 +++++++++++++++++-----------
>  mesh/mesh-db.h       |   6 +-
>  mesh/net.c           | 268 +++++++++++++++++++++++++++----------------
>  mesh/net.h           |  12 +-
>  mesh/node.c          |  19 ++-
>  mesh/storage.c       |  22 ++--
>  mesh/storage.h       |   7 +-
>  8 files changed, 326 insertions(+), 194 deletions(-)
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-02-12 23:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-07  3:55 [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Inga Stotland
2019-02-07  3:55 ` [PATCH BlueZ 1/5 v2] mesh: Separate functions for net key add and update Inga Stotland
2019-02-07  3:55 ` [PATCH BlueZ 2/5 v2] mesh: Add function to restore net key state from storage Inga Stotland
2019-02-07  3:55 ` [PATCH BlueZ 3/5 v2] mesh: Declare internal functions as static Inga Stotland
2019-02-07  3:55 ` [PATCH BlueZ 4/5 v2] mesh: Save key refresh phase state to node config file Inga Stotland
2019-02-07  3:55 ` [PATCH BlueZ 5/5 v2] mesh: Save newly added or updated net key to " Inga Stotland
2019-02-12 23:42 ` [PATCH BlueZ 0/5 v2] mesh: Save/restore network keys Gix, Brian

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.