diff mbox series

[BlueZ,v3,7/7] tools: Add support to generate RSI using SIRK

Message ID 20221122101232.45320-8-sathish.narasimman@intel.com (mailing list archive)
State New, archived
Headers show
Series Csip - Client role | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Sathish Narasimman Nov. 22, 2022, 10:12 a.m. UTC
The patch helps to generate Resolvable set identifier adv data.
which can be used as ADV data during advertisement.
It will be used to identify the device as part of setmember for
Coordinated set identification profile.
Example:
$<path to advtest/>advtest -i "761FAE703ED681F0C50B34155B6434FB"
SIRK: 761FAE703ED681F0C50B34155B6434FB
  RSI:  0x71 0xcb 0xbc 0x7e 0x01 0x84
    Random: bccb71
    Hash:   84017e
---
 tools/advtest.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 78 insertions(+), 2 deletions(-)

Comments

Luiz Augusto von Dentz Nov. 22, 2022, 8:19 p.m. UTC | #1
Hi Sathish,

On Tue, Nov 22, 2022 at 2:16 AM Sathish Narasimman
<sathish.narasimman@intel.com> wrote:
>
> The patch helps to generate Resolvable set identifier adv data.
> which can be used as ADV data during advertisement.
> It will be used to identify the device as part of setmember for
> Coordinated set identification profile.
> Example:
> $<path to advtest/>advtest -i "761FAE703ED681F0C50B34155B6434FB"
> SIRK: 761FAE703ED681F0C50B34155B6434FB
>   RSI:  0x71 0xcb 0xbc 0x7e 0x01 0x84
>     Random: bccb71
>     Hash:   84017e
> ---
>  tools/advtest.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 78 insertions(+), 2 deletions(-)
>
> diff --git a/tools/advtest.c b/tools/advtest.c
> index de036e783325..9ef69ed5124a 100644
> --- a/tools/advtest.c
> +++ b/tools/advtest.c
> @@ -13,6 +13,13 @@
>  #include <config.h>
>  #endif
>
> +#include <stdlib.h>
> +
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +
>  #include <getopt.h>
>
>  #include "lib/bluetooth.h"
> @@ -32,6 +39,9 @@
>                         "\xe1\x23\x99\xc1\xca\x9a\xc3\x31"
>  #define SCAN_IRK       "\xfa\x73\x09\x11\x3f\x03\x37\x0f" \
>                         "\xf4\xf9\x93\x1e\xf9\xa3\x63\xa6"
> +#ifndef MIN
> +#define MIN(x, y) ((x) < (y) ? (x) : (y))
> +#endif
>
>  static struct mgmt *mgmt;
>  static uint16_t index1 = MGMT_INDEX_NONE;
> @@ -43,13 +53,73 @@ static struct bt_hci *scan_dev;
>
>  static void print_rpa(const uint8_t addr[6])
>  {
> -       printf("  Address:  %02x:%02x:%02x:%02x:%02x:%02x\n",
> +       printf("  RSI:\t0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%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]);
>         printf("    Hash:   %02x%02x%02x\n", addr[0], addr[1], addr[2]);
>  }
>
> +static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
> +{
> +       size_t i, len;
> +
> +       len = MIN((strlen(hexstr) / 2), buflen);
> +       memset(buf, 0, len);
> +
> +       for (i = 0; i < len; i++)
> +               if (sscanf(hexstr + (i * 2), "%02hhX", &buf[i]) != 1)
> +                       continue;
> +
> +
> +       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  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");
> +               mainloop_exit_failure();
> +               return;
> +       }
> +
> +       bt_crypto_ah(crypto, sirk, rsi + 3, hash);
> +       memcpy(rsi, hash, 3);
> +
> +       print_rpa(rsi);
> +}
> +
> +
>  static void scan_le_adv_report(const void *data, uint8_t size,
>                                                         void *user_data)
>  {
> @@ -351,9 +421,11 @@ static void usage(void)
>         printf("\tadvtest [options]\n");
>         printf("options:\n"
>                 "\t-h, --help             Show help options\n");
> +       printf(" \t-i  <128bit SIRK>,     Generate RSI ADV Data\n");
>  }
>
>  static const struct option main_options[] = {
> +       { "hash",   no_argument,       NULL, 'i' },
>         { "version",   no_argument,       NULL, 'v' },
>         { "help",      no_argument,       NULL, 'h' },
>         { }
> @@ -366,11 +438,15 @@ int main(int argc ,char *argv[])
>         for (;;) {
>                 int opt;
>
> -               opt = getopt_long(argc, argv, "vh", main_options, NULL);
> +               opt = getopt_long(argc, argv, "i:vh", main_options, NULL);
>                 if (opt < 0)
>                         break;
>
>                 switch (opt) {
> +               case 'i':
> +                       printf("SIRK: %s\n", optarg);
> +                       generate_rsi(optarg);
> +                       return EXIT_SUCCESS;
>                 case 'v':
>                         printf("%s\n", VERSION);
>                         return EXIT_SUCCESS;
> --
> 2.25.1

I think it would be better if bluetoothd generates the RSI if a
Set.Key has been programmed into the main.conf, that can then check if
there is enough space to enter the RSI in either the ad or scan
response, in the future we may consider having the Sirk be passed on
to the kernel so we can leave it to generate the RSI.
diff mbox series

Patch

diff --git a/tools/advtest.c b/tools/advtest.c
index de036e783325..9ef69ed5124a 100644
--- a/tools/advtest.c
+++ b/tools/advtest.c
@@ -13,6 +13,13 @@ 
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
 #include <getopt.h>
 
 #include "lib/bluetooth.h"
@@ -32,6 +39,9 @@ 
 			"\xe1\x23\x99\xc1\xca\x9a\xc3\x31"
 #define SCAN_IRK	"\xfa\x73\x09\x11\x3f\x03\x37\x0f" \
 			"\xf4\xf9\x93\x1e\xf9\xa3\x63\xa6"
+#ifndef MIN
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#endif
 
 static struct mgmt *mgmt;
 static uint16_t index1 = MGMT_INDEX_NONE;
@@ -43,13 +53,73 @@  static struct bt_hci *scan_dev;
 
 static void print_rpa(const uint8_t addr[6])
 {
-	printf("  Address:  %02x:%02x:%02x:%02x:%02x:%02x\n",
+	printf("  RSI:\t0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%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]);
 	printf("    Hash:   %02x%02x%02x\n", addr[0], addr[1], addr[2]);
 }
 
+static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
+{
+	size_t i, len;
+
+	len = MIN((strlen(hexstr) / 2), buflen);
+	memset(buf, 0, len);
+
+	for (i = 0; i < len; i++)
+		if (sscanf(hexstr + (i * 2), "%02hhX", &buf[i]) != 1)
+			continue;
+
+
+	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  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");
+		mainloop_exit_failure();
+		return;
+	}
+
+	bt_crypto_ah(crypto, sirk, rsi + 3, hash);
+	memcpy(rsi, hash, 3);
+
+	print_rpa(rsi);
+}
+
+
 static void scan_le_adv_report(const void *data, uint8_t size,
 							void *user_data)
 {
@@ -351,9 +421,11 @@  static void usage(void)
 	printf("\tadvtest [options]\n");
 	printf("options:\n"
 		"\t-h, --help             Show help options\n");
+	printf(" \t-i  <128bit SIRK>,     Generate RSI ADV Data\n");
 }
 
 static const struct option main_options[] = {
+	{ "hash",   no_argument,       NULL, 'i' },
 	{ "version",   no_argument,       NULL, 'v' },
 	{ "help",      no_argument,       NULL, 'h' },
 	{ }
@@ -366,11 +438,15 @@  int main(int argc ,char *argv[])
 	for (;;) {
 		int opt;
 
-		opt = getopt_long(argc, argv, "vh", main_options, NULL);
+		opt = getopt_long(argc, argv, "i:vh", main_options, NULL);
 		if (opt < 0)
 			break;
 
 		switch (opt) {
+		case 'i':
+			printf("SIRK: %s\n", optarg);
+			generate_rsi(optarg);
+			return EXIT_SUCCESS;
 		case 'v':
 			printf("%s\n", VERSION);
 			return EXIT_SUCCESS;