public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi
@ 2026-01-14 21:49 Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 2/6] advertising: Use bt_crypto_rsi to generate RSI Luiz Augusto von Dentz
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 21:49 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds bt_cryptor_rsi which can be used to generate a Resolvable Set
Identifier as per CSIS spec:

https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/28085-CSIS-html5/out/en/index-en.html#UUID-4dc0c19a-2900-d43e-6ea5-e651151d3c3e
---
 src/shared/crypto.c | 39 +++++++++++++++++++++++++++++++++++++++
 src/shared/crypto.h |  2 ++
 2 files changed, 41 insertions(+)

diff --git a/src/shared/crypto.c b/src/shared/crypto.c
index 43d7f7c5c4b7..cb9911682c81 100644
--- a/src/shared/crypto.c
+++ b/src/shared/crypto.c
@@ -788,6 +788,45 @@ bool bt_crypto_sih(struct bt_crypto *crypto, const uint8_t k[16],
 	return bt_crypto_ah(crypto, k, r, hash);
 }
 
+/*
+ * The hash is generated by using the RSI hash function sih, with the input
+ * parameter k set to the device’s SIRK, and the input parameter r set to
+ * prand:
+ *
+ * hash = sih(SIRK, prand)
+ *
+ * The prand and hash are concatenated to generate the RSI
+ * resolvableSetIdentifier in the following manner:
+ *
+ * resolvableSetIdentifier = hash || prand
+ */
+bool bt_crypto_rsi(struct bt_crypto *crypto, const uint8_t sirk[16],
+					uint8_t rsi[6])
+{
+	uint8_t prand[3];
+	uint8_t hash[3];
+
+	/* The random number prand shall meet the following requirements:
+	 *
+	 * - The two most significant bits (MSBs) of prand shall be equal to 0
+	 * - At least one bit of the random part of prand shall be 0.
+	 * - At least one bit of the random part of prand shall be 1.
+	 */
+	if (!bt_crypto_random_bytes(crypto, prand, 3))
+		return false;
+
+	prand[2] &= 0x3f;
+	prand[2] |= 0x40;
+
+	if (!bt_crypto_sih(crypto, sirk, prand, hash))
+		return false;
+
+	memcpy(rsi, hash, 3);
+	memcpy(rsi + 3, prand, 3);
+
+	return true;
+}
+
 static bool aes_cmac_zero(struct bt_crypto *crypto, const uint8_t *msg,
 					size_t msg_len, uint8_t res[16])
 {
diff --git a/src/shared/crypto.h b/src/shared/crypto.h
index d45308abf90a..d85f807fe468 100644
--- a/src/shared/crypto.h
+++ b/src/shared/crypto.h
@@ -60,3 +60,5 @@ bool bt_crypto_sih(struct bt_crypto *crypto, const uint8_t k[16],
 bool bt_crypto_sirk(struct bt_crypto *crypto, const char *str, uint16_t vendor,
 			uint16_t product, uint16_t version, uint16_t source,
 			uint8_t sirk[16]);
+bool bt_crypto_rsi(struct bt_crypto *crypto, const uint8_t sirk[16],
+					uint8_t rsi[6]);
-- 
2.52.0


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

* [PATCH BlueZ v1 2/6] advertising: Use bt_crypto_rsi to generate RSI
  2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
@ 2026-01-14 21:49 ` Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 3/6] advtest: " Luiz Augusto von Dentz
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 21:49 UTC (permalink / raw)
  To: linux-bluetooth

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

This makes use of bt_crypto_rsi to generate a valid RSI.
---
 src/advertising.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/advertising.c b/src/advertising.c
index ebdefcdb0586..5dc33c004f93 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -526,11 +526,7 @@ static bool set_rsi(struct btd_adv_client *client)
 	if (!crypto)
 		return false;
 
-	ret = bt_crypto_random_bytes(crypto, data + 3, sizeof(data) - 3);
-	if (!ret)
-		goto done;
-
-	ret = bt_crypto_sih(crypto, btd_opts.csis.sirk, data + 3, data);
+	ret = bt_crypto_rsi(crypto, btd_opts.csis.sirk, data);
 	if (!ret)
 		goto done;
 
-- 
2.52.0


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

* [PATCH BlueZ v1 3/6] advtest: Use bt_crypto_rsi to generate RSI
  2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 2/6] advertising: Use bt_crypto_rsi to generate RSI Luiz Augusto von Dentz
@ 2026-01-14 21:49 ` Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 4/6] shared/ad: Make bt_ad_has_data return the data Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 21:49 UTC (permalink / raw)
  To: linux-bluetooth

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

This makes use of bt_crypto_rsi to generate a valid RSI.
---
 tools/advtest.c | 29 ++---------------------------
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/tools/advtest.c b/tools/advtest.c
index 8df6923d2f2e..706b2503b74c 100644
--- a/tools/advtest.c
+++ b/tools/advtest.c
@@ -75,37 +75,13 @@ static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
 	return len;
 }
 
-static bool get_random_bytes(void *buf, size_t num_bytes)
-{
-	ssize_t len;
-	int fd;
-
-	fd = open("/dev/urandom", O_RDONLY);
-	if (fd < 0)
-		return false;
-
-	len = read(fd, buf, num_bytes);
-
-	close(fd);
-
-	if (len < 0)
-		return false;
-
-	return true;
-}
-
 static void generate_rsi(char *val)
 {
-	uint8_t sirk[16], hash[3];
+	uint8_t sirk[16];
 	uint8_t  rsi[6] = {0};
 
 	hex2bin(val, sirk, sizeof(sirk));
 
-	get_random_bytes(&rsi[3], 3);
-
-	rsi[5] &= 0x3f; /* Clear 2 msb */
-	rsi[5] |= 0x40; /* Set 2nd msb */
-
 	crypto = bt_crypto_new();
 	if (!crypto) {
 		fprintf(stderr, "Failed to open crypto interface\n");
@@ -113,8 +89,7 @@ static void generate_rsi(char *val)
 		return;
 	}
 
-	bt_crypto_ah(crypto, sirk, rsi + 3, hash);
-	memcpy(rsi, hash, 3);
+	bt_crypto_rsi(crypto, sirk, rsi);
 
 	print_rpa(rsi);
 }
-- 
2.52.0


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

* [PATCH BlueZ v1 4/6] shared/ad: Make bt_ad_has_data return the data
  2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 2/6] advertising: Use bt_crypto_rsi to generate RSI Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 3/6] advtest: " Luiz Augusto von Dentz
@ 2026-01-14 21:49 ` Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 5/6] advertising: Fix not verifying if RSI set is valid Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 21:49 UTC (permalink / raw)
  To: linux-bluetooth

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

This makes bt_ad_has_data return the data found rather then true of
false.
---
 src/device.c    | 2 +-
 src/shared/ad.c | 9 +++++----
 src/shared/ad.h | 3 ++-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/device.c b/src/device.c
index 0842becde195..af8df5f29b97 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1616,7 +1616,7 @@ dev_property_advertising_data_exist(const GDBusPropertyTable *property,
 {
 	struct btd_device *device = data;
 
-	return bt_ad_has_data(device->ad, NULL);
+	return bt_ad_has_data(device->ad, NULL) ? TRUE : FALSE;
 }
 
 static bool device_get_wake_support(struct btd_device *device)
diff --git a/src/shared/ad.c b/src/shared/ad.c
index 9e21cbf61a29..ac238014bcea 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -1229,6 +1229,9 @@ static bool data_match(const void *data, const void *user_data)
 	const struct bt_ad_data *d1 = data;
 	const struct bt_ad_data *d2 = user_data;
 
+	if (!d2)
+		return true;
+
 	if (d1->type != d2->type)
 		return false;
 
@@ -1241,14 +1244,12 @@ static bool data_match(const void *data, const void *user_data)
 	return !memcmp(d1->data, d2->data, d1->len);
 }
 
-bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data)
+struct bt_ad_data *bt_ad_has_data(struct bt_ad *ad,
+					const struct bt_ad_data *data)
 {
 	if (!ad)
 		return false;
 
-	if (!data)
-		return !queue_isempty(ad->data);
-
 	return queue_find(ad->data, data_match, data);
 }
 
diff --git a/src/shared/ad.h b/src/shared/ad.h
index 7c5d94db0458..71be8727b372 100644
--- a/src/shared/ad.h
+++ b/src/shared/ad.h
@@ -174,7 +174,8 @@ void bt_ad_clear_flags(struct bt_ad *ad);
 
 bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len);
 
-bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data);
+struct bt_ad_data *bt_ad_has_data(struct bt_ad *ad,
+					const struct bt_ad_data *data);
 
 void bt_ad_foreach_data(struct bt_ad *ad, bt_ad_func_t func, void *user_data);
 
-- 
2.52.0


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

* [PATCH BlueZ v1 5/6] advertising: Fix not verifying if RSI set is valid
  2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2026-01-14 21:49 ` [PATCH BlueZ v1 4/6] shared/ad: Make bt_ad_has_data return the data Luiz Augusto von Dentz
@ 2026-01-14 21:49 ` Luiz Augusto von Dentz
  2026-01-14 21:49 ` [PATCH BlueZ v1 6/6] advtest: Fix displaying RSI as a byte array rather then an address Luiz Augusto von Dentz
  2026-01-14 22:41 ` [BlueZ,v1,1/6] shared/crypto: Add bt_crypto_rsi bluez.test.bot
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 21:49 UTC (permalink / raw)
  To: linux-bluetooth

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

The hash portion of the RSI can be verified if it was set properly.
---
 src/advertising.c | 69 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 61 insertions(+), 8 deletions(-)

diff --git a/src/advertising.c b/src/advertising.c
index 5dc33c004f93..0543870eea02 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -506,11 +506,52 @@ static bool parse_service_data_sr(DBusMessageIter *iter,
 	return parse_service_data(iter, client->scan);
 }
 
+static bool validate_rsi(const uint8_t *data, uint8_t len)
+{
+	struct bt_crypto *crypto;
+	uint8_t zero[16] = {};
+	uint8_t hash[3];
+	bool ret;
+
+	if (!data || len != 6)
+		return false;
+
+	/* Check if a valid SIRK has been set */
+	if (!memcmp(btd_opts.csis.sirk, zero, sizeof(zero)))
+		return false;
+
+	crypto = bt_crypto_new();
+	if (!crypto)
+		return false;
+
+	/* Generate a hash using SIRK and prand as input */
+	ret = bt_crypto_sih(crypto, btd_opts.csis.sirk, data + 3, hash);
+	if (!ret)
+		goto done;
+
+	/* Check if hash matches  */
+	ret = !(memcmp(hash, data, 3));
+	if (!ret) {
+		error("RSI set invalid: hash mismatch");
+		printf("Random: %02x%02x%02x\n", data[3], data[4], data[5]);
+		printf("Hash:   %02x%02x%02x\n", data[0], data[1], data[2]);
+		printf("Match:   %02x%02x%02x\n", hash[0], hash[1], hash[2]);
+		goto done;
+	}
+
+	DBG("RSI validated");
+
+done:
+	bt_crypto_unref(crypto);
+	return ret;
+}
+
 static bool set_rsi(struct btd_adv_client *client)
 {
 	struct bt_crypto *crypto;
 	uint8_t zero[16] = {};
 	struct bt_ad_data rsi = { .type = BT_AD_CSIP_RSI };
+	struct bt_ad_data *ad;
 	uint8_t data[6];
 	bool ret;
 
@@ -518,23 +559,28 @@ static bool set_rsi(struct btd_adv_client *client)
 	if (!memcmp(btd_opts.csis.sirk, zero, sizeof(zero)))
 		return false;
 
-	/* Check if RSI needs to be set or data already contains RSI data */
-	if (!client || bt_ad_has_data(client->data, &rsi))
+	if (!client)
 		return true;
 
+	/* Check if RSI needs to be set or data already contains RSI data */
+	ad = bt_ad_has_data(client->data, &rsi);
+	if (ad) {
+		ret = validate_rsi(ad->data, ad->len);
+		return ret;
+	}
+
 	crypto = bt_crypto_new();
 	if (!crypto)
 		return false;
 
 	ret = bt_crypto_rsi(crypto, btd_opts.csis.sirk, data);
-	if (!ret)
-		goto done;
 
-	ret = bt_ad_add_data(client->data, BT_AD_CSIP_RSI, data, sizeof(data));
-
-done:
 	bt_crypto_unref(crypto);
-	return ret;
+
+	if (!ret)
+		return ret;
+
+	return bt_ad_add_data(client->data, BT_AD_CSIP_RSI, data, sizeof(data));
 }
 
 static struct adv_include {
@@ -753,6 +799,13 @@ static bool parse_data(DBusMessageIter *iter, struct bt_ad *ad)
 
 		DBG("Adding Data for type 0x%02x len %u", type, len);
 
+		switch (type) {
+		case BT_AD_CSIP_RSI:
+			if (!validate_rsi(data, len))
+				goto fail;
+			break;
+		}
+
 		if (!bt_ad_add_data(ad, type, data, len))
 			goto fail;
 
-- 
2.52.0


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

* [PATCH BlueZ v1 6/6] advtest: Fix displaying RSI as a byte array rather then an address
  2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2026-01-14 21:49 ` [PATCH BlueZ v1 5/6] advertising: Fix not verifying if RSI set is valid Luiz Augusto von Dentz
@ 2026-01-14 21:49 ` Luiz Augusto von Dentz
  2026-01-14 22:41 ` [BlueZ,v1,1/6] shared/crypto: Add bt_crypto_rsi bluez.test.bot
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 21:49 UTC (permalink / raw)
  To: linux-bluetooth

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

RSI should be displayed as an address if the intention is to use big
endian format.
---
 tools/advtest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/advtest.c b/tools/advtest.c
index 706b2503b74c..7e744dca8021 100644
--- a/tools/advtest.c
+++ b/tools/advtest.c
@@ -53,7 +53,7 @@ static struct bt_hci *scan_dev;
 
 static void print_rpa(const uint8_t addr[6])
 {
-	printf("  RSI:\t0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+	printf("  RSI:\t%02x-%02x-%02x-%02x-%02x-%02x\n",
 					addr[5], addr[4], addr[3],
 					addr[2], addr[1], addr[0]);
 	printf("    Random: %02x%02x%02x\n", addr[3], addr[4], addr[5]);
-- 
2.52.0


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

* RE: [BlueZ,v1,1/6] shared/crypto: Add bt_crypto_rsi
  2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
                   ` (4 preceding siblings ...)
  2026-01-14 21:49 ` [PATCH BlueZ v1 6/6] advtest: Fix displaying RSI as a byte array rather then an address Luiz Augusto von Dentz
@ 2026-01-14 22:41 ` bluez.test.bot
  5 siblings, 0 replies; 7+ messages in thread
From: bluez.test.bot @ 2026-01-14 22:41 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz

[-- Attachment #1: Type: text/plain, Size: 1766 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1042511

---Test result---

Test Summary:
CheckPatch                    PENDING   0.44 seconds
GitLint                       PENDING   0.39 seconds
BuildEll                      PASS      20.10 seconds
BluezMake                     PASS      649.88 seconds
MakeCheck                     PASS      18.45 seconds
MakeDistcheck                 PASS      244.40 seconds
CheckValgrind                 PASS      296.12 seconds
CheckSmatch                   WARNING   352.55 seconds
bluezmakeextell               PASS      185.09 seconds
IncrementalBuild              PENDING   0.46 seconds
ScanBuild                     PASS      1042.90 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/shared/crypto.c:271:21: warning: Variable length array is used.src/shared/crypto.c:272:23: warning: Variable length array is used.src/shared/crypto.c:271:21: warning: Variable length array is used.src/shared/crypto.c:272:23: warning: Variable length array is used.src/shared/crypto.c:271:21: warning: Variable length array is used.src/shared/crypto.c:272:23: warning: Variable length array is used.
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


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

end of thread, other threads:[~2026-01-14 22:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-14 21:49 [PATCH BlueZ v1 1/6] shared/crypto: Add bt_crypto_rsi Luiz Augusto von Dentz
2026-01-14 21:49 ` [PATCH BlueZ v1 2/6] advertising: Use bt_crypto_rsi to generate RSI Luiz Augusto von Dentz
2026-01-14 21:49 ` [PATCH BlueZ v1 3/6] advtest: " Luiz Augusto von Dentz
2026-01-14 21:49 ` [PATCH BlueZ v1 4/6] shared/ad: Make bt_ad_has_data return the data Luiz Augusto von Dentz
2026-01-14 21:49 ` [PATCH BlueZ v1 5/6] advertising: Fix not verifying if RSI set is valid Luiz Augusto von Dentz
2026-01-14 21:49 ` [PATCH BlueZ v1 6/6] advtest: Fix displaying RSI as a byte array rather then an address Luiz Augusto von Dentz
2026-01-14 22:41 ` [BlueZ,v1,1/6] shared/crypto: Add bt_crypto_rsi bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox