linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Inga Stotland <inga.stotland@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: brian.gix@intel.com, johan.hedberg@gmail.com,
	luiz.dentz@gmail.com, Inga Stotland <inga.stotland@intel.com>
Subject: [PATCH BlueZ 2/5] mesh: Add function to restore net key state from storage
Date: Tue,  5 Feb 2019 23:38:45 -0800	[thread overview]
Message-ID: <20190206073845.29030-1-inga.stotland@intel.com> (raw)

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 bfc1a01bb..cf7603053 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


                 reply	other threads:[~2019-02-06  7:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190206073845.29030-1-inga.stotland@intel.com \
    --to=inga.stotland@intel.com \
    --cc=brian.gix@intel.com \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).