diff mbox series

[BlueZ,5/6] csip: Add support for SIRK encryption

Message ID 20231002231311.3104749-5-luiz.dentz@gmail.com
State New
Headers show
Series [BlueZ,1/6] shared/csip: Fix returning invalid data to attribute Size reads | expand

Commit Message

Luiz Augusto von Dentz Oct. 2, 2023, 11:13 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This implements SIRK value encryption using the LTK which is accessed
using btd_device_get_ltk.
---
 profiles/audio/csip.c | 36 ++++++++++++++++++++++++++----
 src/shared/csip.c     | 51 ++++---------------------------------------
 src/shared/csip.h     |  5 ++---
 3 files changed, 38 insertions(+), 54 deletions(-)
diff mbox series

Patch

diff --git a/profiles/audio/csip.c b/profiles/audio/csip.c
index 05bf588d8d6f..a697ebdfbda0 100644
--- a/profiles/audio/csip.c
+++ b/profiles/audio/csip.c
@@ -40,6 +40,7 @@ 
 #include "src/shared/gatt-client.h"
 #include "src/shared/gatt-server.h"
 #include "src/shared/csip.h"
+#include "src/shared/crypto.h"
 
 #include "btio/btio.h"
 #include "src/plugin.h"
@@ -313,10 +314,37 @@  static struct btd_profile csip_profile = {
 	.experimental	= true,
 };
 
-static bool csis_ltk_read(struct bt_csip *csip, uint8_t k[16], void *user_data)
+static bool csis_encrypt(struct bt_att *att, uint8_t val[16])
 {
-	/* TODO: Retrieve LTK using device object */
-	return false;
+	struct btd_device *device;
+	struct bt_crypto *crypto;
+	uint8_t ltk[16];
+	bool ret;
+
+	device = btd_adapter_find_device_by_fd(bt_att_get_fd(att));
+	if (!device) {
+		error("Unable to find device");
+		return false;
+	}
+
+	if (!btd_device_get_ltk(device, ltk, NULL, NULL)) {
+		error("Unable to get device LTK");
+		return false;
+	}
+
+	crypto = bt_crypto_new();
+	if (!crypto) {
+		error("Failed to open crypto");
+		return false;
+	}
+
+	ret = bt_crypto_sef(crypto, ltk, val, val);
+	if (!ret)
+		error("Failed to encrypt SIRK using LTK");
+
+	bt_crypto_unref(crypto);
+
+	return ret;
 }
 
 static void csis_data_add(struct csis_data *data)
@@ -332,7 +360,7 @@  static void csis_data_add(struct csis_data *data)
 
 	bt_csip_set_sirk(data->csip, btd_opts.csis.encrypt, btd_opts.csis.sirk,
 				btd_opts.csis.size, btd_opts.csis.rank,
-				csis_ltk_read, data);
+				csis_encrypt);
 
 	if (!servers)
 		servers = queue_new();
diff --git a/src/shared/csip.c b/src/shared/csip.c
index 85de63ea626b..53ce155416c7 100644
--- a/src/shared/csip.c
+++ b/src/shared/csip.c
@@ -66,6 +66,7 @@  struct bt_csis {
 	struct gatt_db_attribute *lock;
 	struct gatt_db_attribute *lock_ccc;
 	struct gatt_db_attribute *rank;
+	bt_csip_encrypt_func_t encrypt;
 };
 
 struct bt_csip_cb {
@@ -96,9 +97,6 @@  struct bt_csip {
 	bt_csip_destroy_func_t debug_destroy;
 	void *debug_data;
 
-	bt_csip_ltk_func_t ltk_func;
-	void *ltk_data;
-
 	bt_csip_sirk_func_t sirk_func;
 	void *sirk_data;
 
@@ -218,46 +216,6 @@  static void csip_debug(struct bt_csip *csip, const char *format, ...)
 	va_end(ap);
 }
 
-static bool csip_match_att(const void *data, const void *match_data)
-{
-	const struct bt_csip *csip = data;
-	const struct bt_att *att = match_data;
-
-	return bt_csip_get_att((void *)csip) == att;
-}
-
-static bool csis_sirk_enc(struct bt_csis *csis, struct bt_att *att,
-						struct csis_sirk *sirk)
-{
-	struct bt_csip *csip;
-	uint8_t k[16];
-	struct bt_crypto *crypto;
-	bool ret;
-
-	csip = queue_find(sessions, csip_match_att, att);
-	if (!csip)
-		return false;
-
-	if (!csip->ltk_func(csip, k, csip->ltk_data)) {
-		DBG(csip, "Unable to read sef key");
-		return false;
-	}
-
-	crypto = bt_crypto_new();
-	if (!crypto) {
-		DBG(csip, "Failed to open crypto");
-		return false;
-	}
-
-	ret = bt_crypto_sef(crypto, k, sirk->val, sirk->val);
-	if (!ret)
-		DBG(csip, "Failed to encrypt SIRK using sef");
-
-	bt_crypto_unref(crypto);
-
-	return ret;
-}
-
 static void csis_sirk_read(struct gatt_db_attribute *attrib,
 				unsigned int id, uint16_t offset,
 				uint8_t opcode, struct bt_att *att,
@@ -270,7 +228,7 @@  static void csis_sirk_read(struct gatt_db_attribute *attrib,
 	memcpy(&sirk, csis->sirk_val, sizeof(sirk));
 
 	if (sirk.type == BT_CSIP_SIRK_ENCRYPT &&
-				!csis_sirk_enc(csis, att, &sirk)) {
+				!csis->encrypt(att, sirk.val)) {
 		gatt_db_attribute_read_result(attrib, id, BT_ATT_ERROR_UNLIKELY,
 							NULL, 0);
 		return;
@@ -776,7 +734,7 @@  static struct csis_sirk *sirk_new(struct bt_csis *csis, struct gatt_db *db,
 
 bool bt_csip_set_sirk(struct bt_csip *csip, bool encrypt,
 				uint8_t k[16], uint8_t size, uint8_t rank,
-				bt_csip_ltk_func_t func, void *user_data)
+				bt_csip_encrypt_func_t func)
 {
 	uint8_t zero[16] = {};
 	uint8_t type;
@@ -793,8 +751,7 @@  bool bt_csip_set_sirk(struct bt_csip *csip, bool encrypt,
 	if (!sirk_new(csip->ldb->csis, csip->ldb->db, type, k, size, rank))
 		return false;
 
-	csip->ltk_func = func;
-	csip->ltk_data = user_data;
+	csip->ldb->csis->encrypt = func;
 
 	return true;
 }
diff --git a/src/shared/csip.h b/src/shared/csip.h
index bc5519cfbc49..81c8954aba8d 100644
--- a/src/shared/csip.h
+++ b/src/shared/csip.h
@@ -27,8 +27,7 @@  typedef void (*bt_csip_ready_func_t)(struct bt_csip *csip, void *user_data);
 typedef void (*bt_csip_destroy_func_t)(void *user_data);
 typedef void (*bt_csip_debug_func_t)(const char *str, void *user_data);
 typedef void (*bt_csip_func_t)(struct bt_csip *csip, void *user_data);
-typedef bool (*bt_csip_ltk_func_t)(struct bt_csip *csip, uint8_t k[16],
-							void *user_data);
+typedef bool (*bt_csip_encrypt_func_t)(struct bt_att *att, uint8_t k[16]);
 typedef bool (*bt_csip_sirk_func_t)(struct bt_csip *csip, uint8_t type,
 				    uint8_t k[16], uint8_t size, uint8_t rank,
 				    void *user_data);
@@ -54,7 +53,7 @@  struct bt_csip *bt_csip_new(struct gatt_db *ldb, struct gatt_db *rdb);
 
 bool bt_csip_set_sirk(struct bt_csip *csip, bool encrypt,
 				uint8_t k[16], uint8_t size, uint8_t rank,
-				bt_csip_ltk_func_t func, void *user_data);
+				bt_csip_encrypt_func_t func);
 
 bool bt_csip_get_sirk(struct bt_csip *csip, uint8_t *type,
 				uint8_t k[16], uint8_t *size, uint8_t *rank);