Linux-Bluetooth Archive on lore.kernel.org
 help / 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	[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	[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	[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	[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	[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, Stotland, Inga; +Cc: luiz.dentz, johan.hedberg

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, back to index

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

Linux-Bluetooth Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-bluetooth/0 linux-bluetooth/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-bluetooth linux-bluetooth/ https://lore.kernel.org/linux-bluetooth \
		linux-bluetooth@vger.kernel.org linux-bluetooth@archiver.kernel.org
	public-inbox-index linux-bluetooth


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-bluetooth


AGPL code for this site: git clone https://public-inbox.org/ public-inbox