Linux-Bluetooth Archive on lore.kernel.org
 help / color / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 08/15] shared/gatt-db: Generate database hash
Date: Tue, 29 Jan 2019 15:26:27 +0200
Message-ID: <20190129132634.28786-8-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20190129132634.28786-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This use bt_crypto_hash (AES-CMAC) to generate a database hash
using the content of the attribute:

In ascending order of attribute handles, starting with the first handle,
concatenate the fields Attribute Handle, Attribute Type, and Attribute
Value if the attribute has one of the following types:
«Primary Service», «Secondary Service», «Included Service»,
«Characteristic», or «Characteristic Extended Properties», concatenate
the fields Attribute Handle and Attribute Type if the attribute has one
of the following types: «Characteristic User Description»,
«Client Characteristic Configuration»,
«Server Characteristic Configuration», «Characteristic Format», or
«Characteristic Aggregate Format», and ignore the attribute if it has
any other type (such attributes are not part of the concatenation).
---
 src/shared/gatt-db.c | 68 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index d97dca124..7dc93268b 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -35,6 +35,7 @@
 #include "src/shared/timeout.h"
 #include "src/shared/att.h"
 #include "src/shared/gatt-db.h"
+#include "src/shared/crypto.h"
 
 #ifndef MAX
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -58,6 +59,7 @@ static const bt_uuid_t ext_desc_uuid = { .type = BT_UUID16,
 
 struct gatt_db {
 	int ref_count;
+	struct bt_crypto *crypto;
 	uint8_t hash[16];
 	unsigned int hash_id;
 	uint16_t next_handle;
@@ -225,6 +227,7 @@ struct gatt_db *gatt_db_new(void)
 	struct gatt_db *db;
 
 	db = new0(struct gatt_db, 1);
+	db->crypto = bt_crypto_new();
 	db->services = queue_new();
 	db->notify_list = queue_new();
 	db->next_handle = 0x0001;
@@ -266,12 +269,71 @@ static void handle_notify(void *data, void *user_data)
 		notify->service_removed(notify_data->attr, notify->user_data);
 }
 
+static void gen_hash_m(struct gatt_db_attribute *attr, void *user_data)
+{
+	struct iovec *iov = user_data;
+	uint8_t *data;
+	size_t len;
+
+	if (bt_uuid_len(&attr->uuid) != 2)
+		return;
+
+	switch (attr->uuid.value.u16) {
+	case GATT_PRIM_SVC_UUID:
+	case GATT_SND_SVC_UUID:
+	case GATT_INCLUDE_UUID:
+	case GATT_CHARAC_UUID:
+		/* Allocate space for handle + type + value */
+		len = 2 + 2 + attr->value_len;
+		data = malloc(2 + 2 + attr->value_len);
+		put_le16(attr->handle, data);
+		bt_uuid_to_le(&attr->uuid, data + 2);
+		memcpy(data + 4, attr->value, attr->value_len);
+		break;
+	case GATT_CHARAC_USER_DESC_UUID:
+	case GATT_CLIENT_CHARAC_CFG_UUID:
+	case GATT_SERVER_CHARAC_CFG_UUID:
+	case GATT_CHARAC_FMT_UUID:
+	case GATT_CHARAC_AGREG_FMT_UUID:
+		/* Allocate space for handle + type  */
+		len = 2 + 2;
+		data = malloc(2 + 2 + attr->value_len);
+		put_le16(attr->handle, data);
+		bt_uuid_to_le(&attr->uuid, data + 2);
+		break;
+	default:
+		return;
+	}
+
+	iov[attr->handle].iov_base = data;
+	iov[attr->handle].iov_len = len;
+
+	return;
+}
+
+static void service_gen_hash_m(struct gatt_db_attribute *attr, void *user_data)
+{
+	gatt_db_service_foreach(attr, NULL, gen_hash_m, user_data);
+}
+
 static bool db_hash_update(void *user_data)
 {
 	struct gatt_db *db = user_data;
+	struct iovec *iov;
+	uint16_t i;
 
 	db->hash_id = 0;
 
+	iov = new0(struct iovec, db->next_handle);
+
+	gatt_db_foreach_service(db, NULL, service_gen_hash_m, iov);
+	bt_crypto_gatt_hash(db->crypto, iov, db->next_handle, db->hash);
+
+	for (i = 0; i < db->next_handle; i++)
+		free(iov[i].iov_base);
+
+	free(iov);
+
 	return false;
 }
 
@@ -292,7 +354,7 @@ static void notify_service_changed(struct gatt_db *db,
 	queue_foreach(db->notify_list, handle_notify, &data);
 
 	/* Tigger hash update */
-	if (!db->hash_id)
+	if (!db->hash_id && db->crypto)
 		db->hash_id = timeout_add(HASH_UPDATE_TIMEOUT, db_hash_update,
 								db, NULL);
 
@@ -319,6 +381,8 @@ static void gatt_db_destroy(struct gatt_db *db)
 	if (!db)
 		return;
 
+	bt_crypto_unref(db->crypto);
+
 	/*
 	 * Clear the notify list before clearing the services to prevent the
 	 * latter from sending service_removed events.
@@ -506,7 +570,7 @@ uint8_t *gatt_db_get_hash(struct gatt_db *db)
 {
 	uint8_t hash[16] = {};
 
-	if (!db)
+	if (!db || !db->crypto)
 		return NULL;
 
 	/* Generate hash if if has not been generated yet */
-- 
2.17.2


  parent reply index

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-29 13:26 [PATCH BlueZ 01/15] shared/crypto: Add bt_crypto_gatt_hash Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 02/15] unit/test-crypto: Add test for bt_crypto_gatt_hash Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 03/15] lib/uuid: Introduce definition for GATT caching attributes Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 04/15] shared/util: Add decoding support " Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 05/15] shared/att-types: Add errors introduced by GATT caching Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 06/15] monitor: Decode GATT Caching errors Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 07/15] shared/gatt-db: Introduce Database Hash Luiz Augusto von Dentz
2019-01-29 13:26 ` Luiz Augusto von Dentz [this message]
2019-01-29 13:26 ` [PATCH BlueZ 09/15] gatt: Add caching support for server Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 10/15] shared/gatt-db: Add gatt_db_set_authorize Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 11/15] shared/gatt-server: Add bt_gatt_server_set_authorize Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 12/15] gatt: Implement Robust Caching handling for server Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 13/15] shared/gatt-client: Read database hash if available Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 14/15] shared/gatt-client: Write Client Features Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 15/15] device: Store Database Hash on storage Luiz Augusto von Dentz
2019-02-06 11:49 ` [PATCH BlueZ 01/15] shared/crypto: Add bt_crypto_gatt_hash Luiz Augusto von Dentz

Reply instructions:

You may reply publically 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=20190129132634.28786-8-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /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

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