All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end
@ 2019-05-23 16:13 Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 1/6] mesh: Add new method for Key Refresh procedure Brian Gix
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

This is version 3 of the patch set that now implements the following:

On interface org.bluez.mesh.Management1:
    CreateSubnet()
    ImportSubnet()
    UpdateSubnet()
    DeleteSubnet()
    CreateAppKey()
    ImportAppKey()
    UpdateAppKey()
    DeleteAppKey()
    CompleteAppKeyUpdate()
    SetKeyPhase()
    ImportRemoteNode()
    DeleteRemoteNode()

Brian Gix (6):
  mesh: Add new method for Key Refresh procedure
  mesh: Centralize definition of PRIMARY_NET_IDX
  mesh: Implement Net Key keyring storage handling
  mesh: Implement App Key keyring storage handling
  mesh: Implement Key Refresh Phasing in keyring
  mesh: Implement remote dev key methods for keyring

 doc/mesh-api.txt |  66 ++++++++++----
 mesh/manager.c   | 264 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 mesh/mesh-defs.h |   1 +
 mesh/node.c      |  12 ++-
 4 files changed, 285 insertions(+), 58 deletions(-)

-- 
2.14.5


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

* [PATCH BlueZ v3 1/6] mesh: Add new method for Key Refresh procedure
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
@ 2019-05-23 16:13 ` Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 2/6] mesh: Centralize definition of PRIMARY_NET_IDX Brian Gix
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

This adds a new method CompleteAppKeyUpdate() on
org.bluez.mesh.Management1 interface to be used by the application
at the completion of a Key Refresh procedure. This method should
be called for each app key that is being updated during the
procedure, and must be performed prior to changing the phase of
the bound net key to phase 3.
---
 doc/mesh-api.txt | 66 ++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 48 insertions(+), 18 deletions(-)

diff --git a/doc/mesh-api.txt b/doc/mesh-api.txt
index 112990a5d..2a800468b 100644
--- a/doc/mesh-api.txt
+++ b/doc/mesh-api.txt
@@ -24,10 +24,10 @@ Methods:
 		DBus.ObjectManager interface must be available on the
 		app_defined_root path.
 
-		The uuid parameter is a 16-byte array that contains Device UUID. This
-		UUID must be unique (at least from the daemon perspective), therefore
-		attempting to call this function using already registered UUID results
-		in an error.
+		The uuid parameter is a 16-byte array that contains Device UUID.
+		This UUID must be unique (at least from the daemon perspective),
+		therefore attempting to call this function using already
+		registered UUID results in an error.
 
 		PossibleErrors:
 			org.bluez.mesh.Error.InvalidArguments
@@ -131,10 +131,10 @@ Methods:
 		interface. The standard DBus.ObjectManager interface must be
 		available on the app_root path.
 
-		The uuid parameter is a 16-byte array that contains Device UUID. This
-		UUID must be unique (at least from the daemon perspective), therefore
-		attempting to call this function using already registered UUID results
-		in an error.
+		The uuid parameter is a 16-byte array that contains Device UUID.
+		This UUID must be unique (at least from the daemon perspective),
+		therefore attempting to call this function using already
+		registered UUID results in an error.
 
 		The returned token must be preserved by the application in
 		order to authenticate itself to the mesh daemon and attach to
@@ -168,8 +168,8 @@ Methods:
 		permanently remove the identity of the mesh node by calling
 		Leave() method.
 
-		It is an error to attempt importing a node with already registered
-		Device UUID.
+		It is an error to attempt importing a node with already
+		registered Device UUID.
 
 		PossibleErrors:
 			org.bluez.mesh.Error.InvalidArguments,
@@ -182,8 +182,8 @@ Mesh Node Hierarchy
 Service		org.bluez.mesh
 Interface	org.bluez.mesh.Node1
 Object path	/org/bluez/mesh/node<uuid>
-		where <uuid> is the Device UUID passed to Join(), CreateNetwork() or
-		ImportLocalNode()
+		where <uuid> is the Device UUID passed to Join(),
+		CreateNetwork() or ImportLocalNode()
 
 Methods:
 	void Send(object element_path, uint16 destination, uint16 key_index,
@@ -348,8 +348,8 @@ Mesh Provisioning Hierarchy
 Service		org.bluez.mesh
 Interface	org.bluez.mesh.Management1
 Object path	/org/bluez/mesh/node<uuid>
-		where <uuid> is the Device UUID passed to Join(), CreateNetwork() or
-		ImportLocalNode()
+		where <uuid> is the Device UUID passed to Join(),
+		CreateNetwork() or ImportLocalNode()
 
 Methods:
 	void UnprovisionedScan(uint16 seconds)
@@ -400,6 +400,7 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.AlreadyExists
 
@@ -417,6 +418,7 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.AlreadyExists
 
@@ -432,8 +434,10 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.DoesNotExist
+			org.bluez.mesh.Error.Busy
 
 	void DeleteSubnet(uint16 net_index)
 
@@ -447,11 +451,12 @@ Methods:
 
 		PossibleErrors:
 			org.bluez.mesh.Error.InvalidArguments
-			org.bluez.mesh.Error.DoesNotExist
 
 	void SetKeyPhase(uint16 net_index, uint8 phase)
 		This method is used to set the master key update phase of the
-		given subnet.
+		given subnet. When finalizing the procedure, it is important
+		to CompleteAppKeyUpdate() on all app keys that have been
+		updated during the procedure prior to setting phase 3.
 
 		The net_index parameter is a 12-bit value (0x000-0xFFF)
 		specifying which subnet phase to set.
@@ -472,6 +477,7 @@ Methods:
 		refresh phases per the Mesh Profile Specification.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.DoesNotExist
 
@@ -489,8 +495,10 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.AlreadyExists
+			org.bluez.mesh.Error.DoesNotExist
 
 	void ImportAppKey(uint16 net_index, uint16 app_index,
 						array{byte}[16] app_key)
@@ -510,8 +518,10 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.AlreadyExists
+			org.bluez.mesh.Error.DoesNotExist
 
 	void UpdateAppKey(uint16 app_index)
 
@@ -525,6 +535,27 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
+			org.bluez.mesh.Error.InvalidArguments
+			org.bluez.mesh.Error.DoesNotExist
+			org.bluez.mesh.Error.Busy
+
+	void CompleteAppKeyUpdate(uint16 app_index)
+
+		This method is used by the application at the completion of
+		a Key Refresh Procedure.  This method should be called for each
+		app key being updated during the procedure, and must be
+		performed prior to changing the phase of the bound net key
+		to phase 3. (See SetKeyPhase() method).
+
+		The app_index parameter is a 12-bit value (0x000-0xFFF)
+		specifying which app key was updated. Note that the subnet that
+		the key is bound to must exist and be in Phase 2.
+
+		This call affects the local bluetooth-meshd key database only.
+
+		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 			org.bluez.mesh.Error.DoesNotExist
 
@@ -540,7 +571,6 @@ Methods:
 
 		PossibleErrors:
 			org.bluez.mesh.Error.InvalidArguments
-			org.bluez.mesh.Error.DoesNotExist
 
 	void ImportRemoteNode(uint16 primary, uint8 count,
 					array{byte}[16] device_key)
@@ -560,6 +590,7 @@ Methods:
 		This call affects the local bluetooth-meshd key database only.
 
 		PossibleErrors:
+			org.bluez.mesh.Error.Failed
 			org.bluez.mesh.Error.InvalidArguments
 
 	void DeleteRemoteNode(uint16 primary, uint8 count)
@@ -577,7 +608,6 @@ Methods:
 
 		PossibleErrors:
 			org.bluez.mesh.Error.InvalidArguments
-			org.bluez.mesh.Error.DoesNotExist
 
 Properties:
 	dict Features [read-only]
-- 
2.14.5


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

* [PATCH BlueZ v3 2/6] mesh: Centralize definition of PRIMARY_NET_IDX
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 1/6] mesh: Add new method for Key Refresh procedure Brian Gix
@ 2019-05-23 16:13 ` Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 3/6] mesh: Implement Net Key keyring storage handling Brian Gix
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

---
 mesh/mesh-defs.h |  1 +
 mesh/node.c      | 12 +++++-------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/mesh/mesh-defs.h b/mesh/mesh-defs.h
index aba0d318f..1a199f156 100644
--- a/mesh/mesh-defs.h
+++ b/mesh/mesh-defs.h
@@ -74,6 +74,7 @@
 
 #define VENDOR_ID_MASK		0xffff0000
 
+#define PRIMARY_NET_IDX		0x0000
 #define MAX_KEY_IDX		0x0fff
 #define MAX_MODEL_COUNT		0xff
 #define MAX_ELE_COUNT		0xff
diff --git a/mesh/node.c b/mesh/node.c
index 394f5bfa9..e99858623 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -51,7 +51,6 @@
 /* Default values for a new locally created node */
 #define DEFAULT_NEW_UNICAST 0x0001
 #define DEFAULT_IV_INDEX 0x0000
-#define DEFAULT_PRIMARY_NET_INDEX 0x0000
 
 /* Default element location: unknown */
 #define DEFAULT_LOCATION 0x0000
@@ -1564,21 +1563,20 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
 		/* Generate device and primary network keys */
 		l_getrandom(dev_key, sizeof(dev_key));
 		l_getrandom(net_key.old_key, sizeof(net_key.old_key));
-		net_key.net_idx = DEFAULT_PRIMARY_NET_INDEX;
-		net_key.phase = 0;
+		net_key.net_idx = PRIMARY_NET_IDX;
+		net_key.phase = KEY_REFRESH_PHASE_NONE;
 
 		if (!add_local_node(node, DEFAULT_NEW_UNICAST, false, false,
 						DEFAULT_IV_INDEX, dev_key,
-						DEFAULT_PRIMARY_NET_INDEX,
-							net_key.old_key))
+						PRIMARY_NET_IDX,
+						net_key.old_key))
 			goto fail;
 
 		if (!keyring_put_remote_dev_key(node, DEFAULT_NEW_UNICAST,
 							num_ele, dev_key))
 			goto fail;
 
-		if (!keyring_put_net_key(node, DEFAULT_PRIMARY_NET_INDEX,
-								&net_key))
+		if (!keyring_put_net_key(node, PRIMARY_NET_IDX, &net_key))
 			goto fail;
 
 		cb(req->user_data, MESH_ERROR_NONE, node);
-- 
2.14.5


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

* [PATCH BlueZ v3 3/6] mesh: Implement Net Key keyring storage handling
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 1/6] mesh: Add new method for Key Refresh procedure Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 2/6] mesh: Centralize definition of PRIMARY_NET_IDX Brian Gix
@ 2019-05-23 16:13 ` Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 4/6] mesh: Implement App " Brian Gix
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

Implements following org.bluez.mesh.Management1 methods:
CreateSubnet()
ImportSubnet()
UpdateSubnet()
DeleteSubnet()

These methods are used to maintain Net Key keyring storage.
---
 mesh/manager.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 12 deletions(-)

diff --git a/mesh/manager.c b/mesh/manager.c
index d990ceec2..e0cad8c3f 100644
--- a/mesh/manager.c
+++ b/mesh/manager.c
@@ -24,9 +24,12 @@
 #define _GNU_SOURCE
 #include <ell/ell.h>
 
+#include "mesh/mesh-defs.h"
 #include "mesh/dbus.h"
 #include "mesh/error.h"
 #include "mesh/mesh.h"
+#include "mesh/node.h"
+#include "mesh/keyring.h"
 #include "mesh/manager.h"
 
 static struct l_dbus_message *add_node_call(struct l_dbus *dbus,
@@ -86,51 +89,112 @@ static struct l_dbus_message *cancel_scan_call(struct l_dbus *dbus,
 	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
 }
 
+static struct l_dbus_message *store_new_subnet(struct mesh_node *node,
+					struct l_dbus_message *msg,
+					uint16_t net_idx, uint8_t *new_key)
+{
+	struct keyring_net_key key;
+
+	if (net_idx > MAX_KEY_IDX)
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	if (keyring_get_net_key(node, net_idx, &key)) {
+		/* Allow redundent calls only if key values match */
+		if (!memcmp(key.old_key, new_key, 16))
+			return l_dbus_message_new_method_return(msg);
+
+		return dbus_error(msg, MESH_ERROR_ALREADY_EXISTS, NULL);
+	}
+
+	memcpy(key.old_key, new_key, 16);
+	key.net_idx = net_idx;
+	key.phase = KEY_REFRESH_PHASE_NONE;
+
+	if (!keyring_put_net_key(node, net_idx, &key))
+		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+	return l_dbus_message_new_method_return(msg);
+}
+
 static struct l_dbus_message *create_subnet_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
+	struct mesh_node *node = user_data;
+	uint8_t key[16];
 	uint16_t net_idx;
 
-	if (!l_dbus_message_get_arguments(msg, "q", &net_idx))
+	if (!l_dbus_message_get_arguments(msg, "q", &net_idx) ||
+						net_idx == PRIMARY_NET_IDX)
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	/* Generate key and store */
+	l_getrandom(key, sizeof(key));
+
+	return store_new_subnet(node, msg, net_idx, key);
 }
 
 static struct l_dbus_message *update_subnet_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
+	struct mesh_node *node = user_data;
+	struct keyring_net_key key;
 	uint16_t net_idx;
 
-	if (!l_dbus_message_get_arguments(msg, "q", &net_idx))
+	if (!l_dbus_message_get_arguments(msg, "q", &net_idx) ||
+						net_idx > MAX_KEY_IDX)
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	if (!keyring_get_net_key(node, net_idx, &key))
+		return dbus_error(msg, MESH_ERROR_DOES_NOT_EXIST, NULL);
+
+	switch (key.phase) {
+	case KEY_REFRESH_PHASE_NONE:
+		/* Generate Key and update phase */
+		l_getrandom(key.new_key, sizeof(key.new_key));
+		key.phase = KEY_REFRESH_PHASE_ONE;
+
+		if (!keyring_put_net_key(node, net_idx, &key))
+			return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+		/* Fall Through */
+
+	case KEY_REFRESH_PHASE_ONE:
+		/* Allow redundant calls to start Key Refresh */
+		return l_dbus_message_new_method_return(msg);
+
+	default:
+		break;
+	}
+
+	/* All other phases mean KR already in progress over-the-air */
+	return dbus_error(msg, MESH_ERROR_BUSY, "Key Refresh in progress");
 }
 
 static struct l_dbus_message *delete_subnet_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
+	struct mesh_node *node = user_data;
 	uint16_t net_idx;
 
-	if (!l_dbus_message_get_arguments(msg, "q", &net_idx))
+	if (!l_dbus_message_get_arguments(msg, "q", &net_idx) ||
+						net_idx > MAX_KEY_IDX)
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	keyring_del_net_key(node, net_idx);
+
+	return l_dbus_message_new_method_return(msg);
 }
 
 static struct l_dbus_message *import_subnet_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
-	uint16_t net_idx;
+	struct mesh_node *node = user_data;
 	struct l_dbus_message_iter iter_key;
+	uint16_t net_idx;
 	uint8_t *key;
 	uint32_t n;
 
@@ -142,8 +206,7 @@ static struct l_dbus_message *import_subnet_call(struct l_dbus *dbus,
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
 							"Bad network key");
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	return store_new_subnet(node, msg, net_idx, key);
 }
 
 static struct l_dbus_message *create_appkey_call(struct l_dbus *dbus,
-- 
2.14.5


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

* [PATCH BlueZ v3 4/6] mesh: Implement App Key keyring storage handling
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
                   ` (2 preceding siblings ...)
  2019-05-23 16:13 ` [PATCH BlueZ v3 3/6] mesh: Implement Net Key keyring storage handling Brian Gix
@ 2019-05-23 16:13 ` Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 5/6] mesh: Implement Key Refresh Phasing in keyring Brian Gix
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

Implements following org.bluez.mesh.Management1 methods:
CreateAppKey()
ImportAppKey()
UpdateAppKey()
DeleteAppKey()

These methods are used to maintain App Key keyring storage.
---
 mesh/manager.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 15 deletions(-)

diff --git a/mesh/manager.c b/mesh/manager.c
index e0cad8c3f..c79c873f2 100644
--- a/mesh/manager.c
+++ b/mesh/manager.c
@@ -209,51 +209,108 @@ static struct l_dbus_message *import_subnet_call(struct l_dbus *dbus,
 	return store_new_subnet(node, msg, net_idx, key);
 }
 
+static struct l_dbus_message *store_new_appkey(struct mesh_node *node,
+					struct l_dbus_message *msg,
+					uint16_t net_idx, uint16_t app_idx,
+					uint8_t *new_key)
+{
+	struct keyring_net_key net_key;
+	struct keyring_app_key app_key;
+
+	if (net_idx > MAX_KEY_IDX || app_idx > MAX_KEY_IDX)
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	if (!keyring_get_net_key(node, net_idx, &net_key))
+		return dbus_error(msg, MESH_ERROR_DOES_NOT_EXIST,
+						"Bound net key not found");
+
+	if (keyring_get_app_key(node, app_idx, &app_key)) {
+		/* Allow redundant calls with identical values */
+		if (!memcmp(app_key.old_key, new_key, 16) &&
+						app_key.net_idx == net_idx)
+			return l_dbus_message_new_method_return(msg);
+
+		return dbus_error(msg, MESH_ERROR_ALREADY_EXISTS, NULL);
+	}
+
+	memcpy(app_key.old_key, new_key, 16);
+	memcpy(app_key.new_key, new_key, 16);
+	app_key.net_idx = net_idx;
+	app_key.app_idx = app_idx;
+
+	if (!keyring_put_app_key(node, app_idx, net_idx, &app_key))
+		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+	return l_dbus_message_new_method_return(msg);
+}
+
 static struct l_dbus_message *create_appkey_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
+	struct mesh_node *node = user_data;
 	uint16_t net_idx, app_idx;
+	uint8_t key[16];
 
 	if (!l_dbus_message_get_arguments(msg, "qq", &net_idx, &app_idx))
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	l_getrandom(key, sizeof(key));
+
+	return store_new_appkey(node, msg, net_idx, app_idx, key);
 }
 
 static struct l_dbus_message *update_appkey_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
-	uint16_t net_idx, app_idx;
+	struct mesh_node *node = user_data;
+	struct keyring_net_key net_key;
+	struct keyring_app_key app_key;
+	uint16_t app_idx;
 
-	if (!l_dbus_message_get_arguments(msg, "qq", &net_idx, &app_idx))
+	if (!l_dbus_message_get_arguments(msg, "q", &app_idx) ||
+			app_idx > MAX_KEY_IDX)
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	if (!keyring_get_app_key(node, app_idx, &app_key) ||
+			!keyring_get_net_key(node, app_key.net_idx, &net_key))
+		return dbus_error(msg, MESH_ERROR_DOES_NOT_EXIST, NULL);
+
+	if (net_key.phase != KEY_REFRESH_PHASE_ONE)
+		return dbus_error(msg, MESH_ERROR_FAILED, "Invalid Phase");
+
+	/* Generate Key if in acceptable phase */
+	l_getrandom(app_key.new_key, sizeof(app_key.new_key));
+
+	if (!keyring_put_app_key(node, app_idx, app_key.net_idx, &app_key))
+		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+	return l_dbus_message_new_method_return(msg);
 }
 
 static struct l_dbus_message *delete_appkey_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
-	uint16_t net_idx, app_idx;
+	struct mesh_node *node = user_data;
+	uint16_t app_idx;
 
-	if (!l_dbus_message_get_arguments(msg, "qq", &net_idx, &app_idx))
+	if (!l_dbus_message_get_arguments(msg, "q", &app_idx))
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	keyring_del_app_key(node, app_idx);
+
+	return l_dbus_message_new_method_return(msg);
 }
 
 static struct l_dbus_message *import_appkey_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
-	uint16_t net_idx, app_idx;
+	struct mesh_node *node = user_data;
 	struct l_dbus_message_iter iter_key;
+	uint16_t net_idx, app_idx;
 	uint8_t *key;
 	uint32_t n;
 
@@ -266,8 +323,7 @@ static struct l_dbus_message *import_appkey_call(struct l_dbus *dbus,
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
 							"Bad application key");
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	return store_new_appkey(node, msg, net_idx, app_idx, key);
 }
 
 static struct l_dbus_message *set_key_phase_call(struct l_dbus *dbus,
@@ -305,9 +361,9 @@ static void setup_management_interface(struct l_dbus_interface *iface)
 	l_dbus_interface_method(iface, "CreateAppKey", 0, create_appkey_call,
 					"", "qq", "", "net_index", "app_index");
 	l_dbus_interface_method(iface, "UpdateAppKey", 0, update_appkey_call,
-					"", "qq", "", "net_index", "app_index");
+						"", "q", "", "app_index");
 	l_dbus_interface_method(iface, "DeleteAppKey", 0, delete_appkey_call,
-					"", "qq", "", "net_index", "app_index");
+						"", "q", "", "app_index");
 	l_dbus_interface_method(iface, "ImportAppKey", 0, import_appkey_call,
 				"", "qqay", "", "net_index", "app_index",
 								"app_key");
-- 
2.14.5


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

* [PATCH BlueZ v3 5/6] mesh: Implement Key Refresh Phasing in keyring
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
                   ` (3 preceding siblings ...)
  2019-05-23 16:13 ` [PATCH BlueZ v3 4/6] mesh: Implement App " Brian Gix
@ 2019-05-23 16:13 ` Brian Gix
  2019-05-23 16:13 ` [PATCH BlueZ v3 6/6] mesh: Implement remote dev key methods for keyring Brian Gix
  2019-05-24 15:07 ` [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Gix, Brian
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

Implements following org.bluez.mesh.Management1 methods:
CompleteAppKeyUpdate()
SetKeyPhase()

These methods are used to maintain Key Refresh settings
in the keyring storage.
---
 mesh/manager.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/mesh/manager.c b/mesh/manager.c
index c79c873f2..234ab5e2f 100644
--- a/mesh/manager.c
+++ b/mesh/manager.c
@@ -289,6 +289,34 @@ static struct l_dbus_message *update_appkey_call(struct l_dbus *dbus,
 	return l_dbus_message_new_method_return(msg);
 }
 
+static struct l_dbus_message *complete_update_appkey_call(struct l_dbus *dbus,
+						struct l_dbus_message *msg,
+						void *user_data)
+{
+	struct mesh_node *node = user_data;
+	struct keyring_net_key net_key;
+	struct keyring_app_key app_key;
+	uint16_t app_idx;
+
+	if (!l_dbus_message_get_arguments(msg, "q", &app_idx) ||
+			app_idx > MAX_KEY_IDX)
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	if (!keyring_get_app_key(node, app_idx, &app_key) ||
+			!keyring_get_net_key(node, app_key.net_idx, &net_key))
+		return dbus_error(msg, MESH_ERROR_DOES_NOT_EXIST, NULL);
+
+	if (net_key.phase != KEY_REFRESH_PHASE_TWO)
+		return dbus_error(msg, MESH_ERROR_FAILED, "Invalid phase");
+
+	memcpy(app_key.old_key, app_key.new_key, 16);
+
+	if (!keyring_put_app_key(node, app_idx, app_key.net_idx, &app_key))
+		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+	return l_dbus_message_new_method_return(msg);
+}
+
 static struct l_dbus_message *delete_appkey_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
@@ -330,14 +358,30 @@ static struct l_dbus_message *set_key_phase_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
+	struct mesh_node *node = user_data;
+	struct keyring_net_key key;
 	uint16_t net_idx;
 	uint8_t phase;
 
-	if (!l_dbus_message_get_arguments(msg, "qy", &net_idx, &phase))
+	if (!l_dbus_message_get_arguments(msg, "qy", &net_idx, &phase) ||
+					phase == KEY_REFRESH_PHASE_ONE ||
+					phase > KEY_REFRESH_PHASE_THREE)
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	if (!keyring_get_net_key(node, net_idx, &key))
+		return dbus_error(msg, MESH_ERROR_DOES_NOT_EXIST, NULL);
+
+	if (phase == KEY_REFRESH_PHASE_THREE &&
+					key.phase != KEY_REFRESH_PHASE_NONE) {
+		memcpy(key.old_key, key.new_key, 16);
+		key.phase = KEY_REFRESH_PHASE_NONE;
+	} else
+		key.phase = phase;
+
+	if (!keyring_put_net_key(node, net_idx, &key))
+		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+	return l_dbus_message_new_method_return(msg);
 }
 
 static void setup_management_interface(struct l_dbus_interface *iface)
@@ -362,6 +406,9 @@ static void setup_management_interface(struct l_dbus_interface *iface)
 					"", "qq", "", "net_index", "app_index");
 	l_dbus_interface_method(iface, "UpdateAppKey", 0, update_appkey_call,
 						"", "q", "", "app_index");
+	l_dbus_interface_method(iface, "CompleteAppKeyUpdate", 0,
+					complete_update_appkey_call, "", "q",
+							"", "app_index");
 	l_dbus_interface_method(iface, "DeleteAppKey", 0, delete_appkey_call,
 						"", "q", "", "app_index");
 	l_dbus_interface_method(iface, "ImportAppKey", 0, import_appkey_call,
-- 
2.14.5


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

* [PATCH BlueZ v3 6/6] mesh: Implement remote dev key methods for keyring
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
                   ` (4 preceding siblings ...)
  2019-05-23 16:13 ` [PATCH BlueZ v3 5/6] mesh: Implement Key Refresh Phasing in keyring Brian Gix
@ 2019-05-23 16:13 ` Brian Gix
  2019-05-24 15:07 ` [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Gix, Brian
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Gix @ 2019-05-23 16:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: inga.stotland, brian.gix

Implements following org.bluez.mesh.Management1 methods:
ImportRemoteNode()
DeleteRemoteNode()

These methods are used to maintain Device Key keyring storage.
---
 mesh/manager.c | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/mesh/manager.c b/mesh/manager.c
index 234ab5e2f..a79189934 100644
--- a/mesh/manager.c
+++ b/mesh/manager.c
@@ -54,18 +54,47 @@ static struct l_dbus_message *add_node_call(struct l_dbus *dbus,
 	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
 }
 
+
+static struct l_dbus_message *import_node_call(struct l_dbus *dbus,
+						struct l_dbus_message *msg,
+						void *user_data)
+{
+	struct mesh_node *node = user_data;
+	struct l_dbus_message_iter iter_key;
+	uint16_t primary;
+	uint8_t num_ele;
+	uint8_t *key;
+	uint32_t n;
+
+	if (!l_dbus_message_get_arguments(msg, "qyay", &primary, &num_ele,
+								&iter_key))
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+	if (!l_dbus_message_iter_get_fixed_array(&iter_key, &key, &n)
+								|| n != 16)
+		return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
+							"Bad device key");
+
+	if (!keyring_put_remote_dev_key(node, primary, num_ele, key))
+		return dbus_error(msg, MESH_ERROR_FAILED, NULL);
+
+	return l_dbus_message_new_method_return(msg);
+}
+
 static struct l_dbus_message *delete_node_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
+	struct mesh_node *node = user_data;
 	uint16_t primary;
 	uint8_t num_ele;
 
 	if (!l_dbus_message_get_arguments(msg, "qy", &primary, &num_ele))
 		return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
 
-	/* TODO */
-	return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, NULL);
+	keyring_del_remote_dev_key(node, primary, num_ele);
+
+	return l_dbus_message_new_method_return(msg);
 }
 
 static struct l_dbus_message *start_scan_call(struct l_dbus *dbus,
@@ -388,7 +417,10 @@ static void setup_management_interface(struct l_dbus_interface *iface)
 {
 	l_dbus_interface_method(iface, "AddNode", 0, add_node_call, "", "ay",
 								"", "uuid");
-	l_dbus_interface_method(iface, "DeleteRemodeNode", 0, delete_node_call,
+	l_dbus_interface_method(iface, "ImportRemoteNode", 0, import_node_call,
+						"", "qyay", "", "primary",
+						"count", "dev_key");
+	l_dbus_interface_method(iface, "DeleteRemoteNode", 0, delete_node_call,
 					"", "qy", "", "primary", "count");
 	l_dbus_interface_method(iface, "UnprovisionedScan", 0, start_scan_call,
 							"", "q", "", "seconds");
-- 
2.14.5


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

* Re: [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end
  2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
                   ` (5 preceding siblings ...)
  2019-05-23 16:13 ` [PATCH BlueZ v3 6/6] mesh: Implement remote dev key methods for keyring Brian Gix
@ 2019-05-24 15:07 ` Gix, Brian
  6 siblings, 0 replies; 8+ messages in thread
From: Gix, Brian @ 2019-05-24 15:07 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Stotland, Inga

Patch-set applied

On Thu, 2019-05-23 at 09:13 -0700, Brian Gix wrote:
> This is version 3 of the patch set that now implements the following:
> 
> On interface org.bluez.mesh.Management1:
>     CreateSubnet()
>     ImportSubnet()
>     UpdateSubnet()
>     DeleteSubnet()
>     CreateAppKey()
>     ImportAppKey()
>     UpdateAppKey()
>     DeleteAppKey()
>     CompleteAppKeyUpdate()
>     SetKeyPhase()
>     ImportRemoteNode()
>     DeleteRemoteNode()
> 
> Brian Gix (6):
>   mesh: Add new method for Key Refresh procedure
>   mesh: Centralize definition of PRIMARY_NET_IDX
>   mesh: Implement Net Key keyring storage handling
>   mesh: Implement App Key keyring storage handling
>   mesh: Implement Key Refresh Phasing in keyring
>   mesh: Implement remote dev key methods for keyring
> 
>  doc/mesh-api.txt |  66 ++++++++++----
>  mesh/manager.c   | 264 ++++++++++++++++++++++++++++++++++++++++++++++++-------
>  mesh/mesh-defs.h |   1 +
>  mesh/node.c      |  12 ++-
>  4 files changed, 285 insertions(+), 58 deletions(-)
> 

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

end of thread, other threads:[~2019-05-24 15:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-23 16:13 [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end Brian Gix
2019-05-23 16:13 ` [PATCH BlueZ v3 1/6] mesh: Add new method for Key Refresh procedure Brian Gix
2019-05-23 16:13 ` [PATCH BlueZ v3 2/6] mesh: Centralize definition of PRIMARY_NET_IDX Brian Gix
2019-05-23 16:13 ` [PATCH BlueZ v3 3/6] mesh: Implement Net Key keyring storage handling Brian Gix
2019-05-23 16:13 ` [PATCH BlueZ v3 4/6] mesh: Implement App " Brian Gix
2019-05-23 16:13 ` [PATCH BlueZ v3 5/6] mesh: Implement Key Refresh Phasing in keyring Brian Gix
2019-05-23 16:13 ` [PATCH BlueZ v3 6/6] mesh: Implement remote dev key methods for keyring Brian Gix
2019-05-24 15:07 ` [PATCH BlueZ v3 0/6] mesh: Add App and Net Key Refresh keyring back-end 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.