2022-12-22 22:47:40

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ 1/5] shared/crypto: Adds bt_crypto_sih

From: Luiz Augusto von Dentz <[email protected]>

This adds bt_crypto_sih is is used to create a hash as stated on
CSIS[1] spec:

'4.7. Resolvable Set Identifier hash function sih'

https://www.bluetooth.com/specifications/csis-1-0-1/
---
src/shared/crypto.c | 36 ++++++++++++++++++++++++++++++++++++
src/shared/crypto.h | 2 ++
2 files changed, 38 insertions(+)

diff --git a/src/shared/crypto.c b/src/shared/crypto.c
index d5efa416dd99..f164ba69d2a5 100644
--- a/src/shared/crypto.c
+++ b/src/shared/crypto.c
@@ -737,3 +737,39 @@ bool bt_crypto_gatt_hash(struct bt_crypto *crypto, struct iovec *iov,

return true;
}
+
+/*
+ * Resolvable Set Identifier hash function sih
+ *
+ * The RSI hash function sih is used to generate a hash value that is used in
+ * RSIs.
+ *
+ * The following variables are the inputs to the RSI hash function sih:
+ *
+ * k is 128 bits
+ * r is 24 bits
+ * padding is 104 bits, all set to 0
+ *
+ * r is concatenated with padding to generate r', which is used as the 128-bit
+ * input parameter plaintextData to security function e:
+ *
+ * r'=padding||r
+ *
+ * The LSO of r becomes the LSO of r', and the MSO of padding becomes the MSO
+ * of r'.
+ *
+ * For example, if the 24-bit value r is 0x3A98B5, then r' is
+ * 0x000000000000000000000000003A98B5.
+ *
+ * The output of the Resolvable Set Identifier function sih is:
+ *
+ * sih(k, r)=e(k, r') mod 2^24
+ *
+ * The output of the security function e is truncated to 24 bits by taking the
+ * least significant 24 bits of the output of e as the result of sih.
+ */
+bool bt_crypto_sih(struct bt_crypto *crypto, const uint8_t k[16],
+ const uint8_t r[3], uint8_t hash[3])
+{
+ return bt_crypto_ah(crypto, k, r, hash);
+}
diff --git a/src/shared/crypto.h b/src/shared/crypto.h
index 356326d75408..fca52e38e5e2 100644
--- a/src/shared/crypto.h
+++ b/src/shared/crypto.h
@@ -53,3 +53,5 @@ bool bt_crypto_verify_att_sign(struct bt_crypto *crypto, const uint8_t key[16],
const uint8_t *pdu, uint16_t pdu_len);
bool bt_crypto_gatt_hash(struct bt_crypto *crypto, struct iovec *iov,
size_t iov_len, uint8_t res[16]);
+bool bt_crypto_sih(struct bt_crypto *crypto, const uint8_t k[16],
+ const uint8_t r[3], uint8_t hash[3]);
--
2.37.3


2022-12-22 22:47:40

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ 3/5] shared/crypto: Adds bt_crypto_sef

From: Luiz Augusto von Dentz <[email protected]>

This adds bt_crypto_sef is is used to create a hash as stated on CSIS
spec:

'4.5. SIRK encryption function sef'

https://www.bluetooth.com/specifications/csis-1-0-1/
---
src/shared/crypto.c | 171 +++++++++++++++++++++++++++++++++++++++++---
src/shared/crypto.h | 2 +
2 files changed, 164 insertions(+), 9 deletions(-)

diff --git a/src/shared/crypto.c b/src/shared/crypto.c
index f164ba69d2a5..4cb2ea857ea8 100644
--- a/src/shared/crypto.c
+++ b/src/shared/crypto.c
@@ -586,41 +586,55 @@ bool bt_crypto_s1(struct bt_crypto *crypto, const uint8_t k[16],
return bt_crypto_e(crypto, k, res, res);
}

-static bool aes_cmac(struct bt_crypto *crypto, const uint8_t key[16],
+static bool aes_cmac_be(struct bt_crypto *crypto, const uint8_t key[16],
const uint8_t *msg, size_t msg_len, uint8_t res[16])
{
- uint8_t key_msb[16], out[16], msg_msb[CMAC_MSG_MAX];
ssize_t len;
int fd;

if (msg_len > CMAC_MSG_MAX)
return false;

- swap_buf(key, key_msb, 16);
- fd = alg_new(crypto->cmac_aes, key_msb, 16);
+ fd = alg_new(crypto->cmac_aes, key, 16);
if (fd < 0)
return false;

- swap_buf(msg, msg_msb, msg_len);
- len = send(fd, msg_msb, msg_len, 0);
+ len = send(fd, msg, msg_len, 0);
if (len < 0) {
close(fd);
return false;
}

- len = read(fd, out, 16);
+ len = read(fd, res, 16);
if (len < 0) {
close(fd);
return false;
}

- swap_buf(out, res, 16);
-
close(fd);

return true;
}

+static bool aes_cmac(struct bt_crypto *crypto, const uint8_t key[16],
+ const uint8_t *msg, size_t msg_len, uint8_t res[16])
+{
+ uint8_t key_msb[16], out[16], msg_msb[CMAC_MSG_MAX];
+
+ if (msg_len > CMAC_MSG_MAX)
+ return false;
+
+ swap_buf(key, key_msb, 16);
+ swap_buf(msg, msg_msb, msg_len);
+
+ if (!aes_cmac_be(crypto, key_msb, msg_msb, msg_len, out))
+ return false;
+
+ swap_buf(out, res, 16);
+
+ return true;
+}
+
bool bt_crypto_f4(struct bt_crypto *crypto, uint8_t u[32], uint8_t v[32],
uint8_t x[16], uint8_t z, uint8_t res[16])
{
@@ -773,3 +787,142 @@ bool bt_crypto_sih(struct bt_crypto *crypto, const uint8_t k[16],
{
return bt_crypto_ah(crypto, k, r, hash);
}
+
+static bool aes_cmac_zero(struct bt_crypto *crypto, const uint8_t *msg,
+ size_t msg_len, uint8_t res[16])
+{
+ const uint8_t zero[16] = {};
+
+ return aes_cmac_be(crypto, zero, msg, msg_len, res);
+}
+
+/* The inputs to function s1 are:
+ *
+ * M is a non-zero length octet array or ASCII encoded string
+ *
+ * If M is an ASCII encoded string, M shall be converted into an integer number
+ * by replacing each string character with its ASCII code preserving the order.
+ * For example, if M is the string “CSIS”, M is converted into the integer
+ * number: 0x4353 4953.
+ *
+ * ZERO is the 128-bit value:
+ *
+ * 0x0000 0000 0000 0000 0000 0000 0000 0000
+ *
+ * The output of the salt generation function s1 shall be calculated as follows:
+ *
+ * s1(M)=AES‐CMACZERO(M)
+ *
+ * Where AES-CMACZERO is the CMAC function defined in Section 4.2.
+ */
+static bool sef_s1(struct bt_crypto *crypto, const uint8_t *m,
+ size_t m_len, uint8_t res[16])
+{
+ /* s1(M)=AES‐CMACZERO(M) */
+ return aes_cmac_zero(crypto, m, m_len, res);
+}
+
+/* The key derivation function k1 is used to derive a key. The derived key is
+ * used to encrypt and decrypt the value of the Set Identity Resolving Key
+ * characteristic (see Section 5.1).
+ *
+ * The definition of this key generation function uses the MAC function
+ * AES-CMACT with a 128-bit key T.
+ *
+ * The inputs to function k1 are:
+ *
+ * N is 0 or more octets
+ *
+ * SALT is 128 bits
+ *
+ * P is 0 or more octets
+ *
+ * The key (T) shall be computed as follows:
+ *
+ * T=AES‐CMACSALT(N)
+ *
+ * Where AES-CMACSALT is the CMAC function defined in Section 4.2.
+ *
+ * The output of the key generation function k1 shall be calculated as follows:
+ *
+ * k1(N, SALT, P)=AES‐CMACT(P)
+ *
+ * Where AES-CMACT is the CMAC function defined in Section 4.2.
+ */
+static bool sef_k1(struct bt_crypto *crypto, const uint8_t n[16],
+ uint8_t salt[16], const uint8_t *p,
+ size_t p_len, uint8_t res[16])
+{
+ uint8_t res1[16];
+
+ /* T=AES‐CMACSALT(N) */
+ if (!aes_cmac_be(crypto, salt, n, 16, res1))
+ return false;
+
+ /* k1(N, SALT, P)=AES‐CMACT(P) */
+ return aes_cmac_be(crypto, res1, p, p_len, res);
+}
+
+/*
+ * SIRK encryption function sef
+ *
+ * The SIRK encryption function sef shall be used by the server to encrypt the
+ * SIRK with a key K. The value of K depends on the transport on which the Set
+ * Identity Resolving Key characteristic is read or notified.
+ *
+ * If the Set Identity Resolving Key characteristic is read or notified on the
+ * Basic Rate/Enhanced Data Rate (BR/EDR) transport, K shall be equal to the
+ * Link Key shared by the server and the client.
+ *
+ * K=LinkKey
+ *
+ * If the Set Identity Resolving Key characteristic is read or notified on the
+ * Bluetooth Low Energy (LE) transport, K shall be equal to the LTK shared by
+ * the server and client. That is,
+ *
+ * K=LTK
+ *
+ * The inputs to the function sef are:
+ *
+ * K is the key defined above in this section
+ *
+ * SIRK is the value of the SIRK to be encrypted
+ *
+ * The output of the SIRK encryption function sef is as follows:
+ *
+ * sef(K, SIRK)=k1(K, s1(“SIRKenc”), “csis”)^SIRK
+ *
+ * Where ^ is the bitwise exclusive or operation.
+ */
+bool bt_crypto_sef(struct bt_crypto *crypto, const uint8_t k[16],
+ const uint8_t sirk[16], uint8_t out[16])
+{
+ const uint8_t m[] = {'S', 'I', 'R', 'K', 'e', 'n', 'c'};
+ const uint8_t p[] = {'c', 's', 'i', 's'};
+ uint8_t k_msb[16];
+ uint8_t salt[16];
+ uint8_t res_msb[16];
+ uint8_t res[16];
+
+ if (!crypto)
+ return false;
+
+ /* salt = s1(“SIRKenc”) */
+ if (!sef_s1(crypto, m, sizeof(m), salt))
+ return false;
+
+ /* Convert K to MSB/BE format */
+ swap_buf(k, k_msb, 16);
+
+ /* res_msb = k1(K, salt, “csis”) */
+ if (!sef_k1(crypto, k_msb, salt, p, sizeof(p), res_msb))
+ return false;
+
+ /* Convert back to LSB/LE format */
+ swap_buf(res_msb, res, 16);
+
+ /* res^SIRK */
+ u128_xor(res, sirk, out);
+
+ return true;
+}
diff --git a/src/shared/crypto.h b/src/shared/crypto.h
index fca52e38e5e2..fc1ba0c4feeb 100644
--- a/src/shared/crypto.h
+++ b/src/shared/crypto.h
@@ -53,5 +53,7 @@ bool bt_crypto_verify_att_sign(struct bt_crypto *crypto, const uint8_t key[16],
const uint8_t *pdu, uint16_t pdu_len);
bool bt_crypto_gatt_hash(struct bt_crypto *crypto, struct iovec *iov,
size_t iov_len, uint8_t res[16]);
+bool bt_crypto_sef(struct bt_crypto *crypto, const uint8_t k[16],
+ const uint8_t sirk[16], uint8_t out[16]);
bool bt_crypto_sih(struct bt_crypto *crypto, const uint8_t k[16],
const uint8_t r[3], uint8_t hash[3]);
--
2.37.3

2022-12-22 22:49:22

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ 4/5] test-crypto: Add /crypto/sef test

From: Luiz Augusto von Dentz <[email protected]>

This adds test /crypto/sef which validas the implementation of
bt_crypto_sef using the sample data from CSIS[1] spec:

A.2. sef SIRK Encryption Function

> unit/test-crypto -s "/crypto/sef"
SIRK:
cd cc 72 dd 86 8c cd ce 22 fd a1 21 09 7d 7d 45 ..r....."..!.}}E
K:
d9 ce e5 3c 22 c6 1e 06 6f 69 48 d4 9b 1b 6e 67 ...<"...oiH...ng
Expected:
46 d3 5f f2 d5 62 25 7e a0 24 35 e1 35 38 0a 17 F._..b%~.$5.58..
Result:
46 d3 5f f2 d5 62 25 7e a0 24 35 e1 35 38 0a 17 F._..b%~.$5.58..

[1]https://www.bluetooth.com/specifications/csis-1-0-1/
---
unit/test-crypto.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)

diff --git a/unit/test-crypto.c b/unit/test-crypto.c
index b5404d542af3..8fd7bec8ea83 100644
--- a/unit/test-crypto.c
+++ b/unit/test-crypto.c
@@ -311,6 +311,44 @@ static void test_verify_sign(gconstpointer data)
tester_test_passed();
}

+static void test_sef(const void *data)
+{
+ const uint8_t sirk[16] = {
+ 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce,
+ 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 };
+ const uint8_t k[16] = {
+ 0xd9, 0xce, 0xe5, 0x3c, 0x22, 0xc6, 0x1e, 0x06,
+ 0x6f, 0x69, 0x48, 0xd4, 0x9b, 0x1b, 0x6e, 0x67 };
+ const uint8_t exp[16] = {
+ 0x46, 0xd3, 0x5f, 0xf2, 0xd5, 0x62, 0x25, 0x7e,
+ 0xa0, 0x24, 0x35, 0xe1, 0x35, 0x38, 0x0a, 0x17 };
+ uint8_t res[16];
+
+ tester_debug("SIRK:");
+ util_hexdump(' ', sirk, 16, print_debug, NULL);
+
+ tester_debug("K:");
+ util_hexdump(' ', k, 16, print_debug, NULL);
+
+ if (!bt_crypto_sef(crypto, k, sirk, res)) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_debug("Expected:");
+ util_hexdump(' ', exp, 16, print_debug, NULL);
+
+ tester_debug("Result:");
+ util_hexdump(' ', res, 16, print_debug, NULL);
+
+ if (memcmp(res, exp, 16)) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_test_passed();
+}
+
static void test_sih(const void *data)
{
const uint8_t k[16] = {
@@ -371,6 +409,7 @@ int main(int argc, char *argv[])
NULL, test_verify_sign, NULL);
tester_add("/crypto/verify_sign_too_short", &verify_sign_too_short_data,
NULL, test_verify_sign, NULL);
+ tester_add("/crypto/sef", NULL, NULL, test_sef, NULL);
tester_add("/crypto/sih", NULL, NULL, test_sih, NULL);

exit_status = tester_run();
--
2.37.3

2022-12-22 22:50:11

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ 5/5] monitor: Add support for decoding RSI

From: Luiz Augusto von Dentz <[email protected]>

This adds support for decoding Resolvable Set Identifier[1] advertising
type (0x2e) according to CIS[2] spec:

Resolvable Set Identifier: 46-BB-DB-26-D8-55
Hash: 0x26d855
Random: 0x46bbdb

[1] https://www.bluetooth.com/specifications/assigned-numbers/
[2] https://www.bluetooth.com/specifications/csis-1-0-1/
---
monitor/packet.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/monitor/packet.c b/monitor/packet.c
index 134cf398a66f..44f1941bd30c 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -3123,6 +3123,7 @@ static void print_fec(uint8_t fec)
#define BT_EIR_MESH_PROV 0x29
#define BT_EIR_MESH_DATA 0x2a
#define BT_EIR_MESH_BEACON 0x2b
+#define BT_EIR_CSIP_RSI 0x2e
#define BT_EIR_3D_INFO_DATA 0x3d
#define BT_EIR_MANUFACTURER_DATA 0xff

@@ -4017,6 +4018,14 @@ static void print_eir(const uint8_t *eir, uint8_t eir_len, bool le)
print_mesh_beacon(data, data_len);
break;

+ case BT_EIR_CSIP_RSI:
+ if (data_len < 6)
+ break;
+ print_addr("Resolvable Set Identifier", data, 0xff);
+ print_field(" Hash: 0x%6x", get_le24(data));
+ print_field(" Random: 0x%6x", get_le24(data + 3));
+ break;
+
case BT_EIR_MANUFACTURER_DATA:
if (data_len < 2)
break;
--
2.37.3

2022-12-23 01:39:14

by bluez.test.bot

[permalink] [raw]
Subject: RE: [BlueZ,1/5] shared/crypto: Adds bt_crypto_sih

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=706598

---Test result---

Test Summary:
CheckPatch FAIL 3.15 seconds
GitLint PASS 1.72 seconds
BuildEll PASS 32.60 seconds
BluezMake PASS 1106.86 seconds
MakeCheck PASS 12.66 seconds
MakeDistcheck PASS 179.90 seconds
CheckValgrind PASS 297.90 seconds
bluezmakeextell PASS 118.23 seconds
IncrementalBuild PASS 4631.99 seconds
ScanBuild PASS 1278.64 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,1/5] shared/crypto: Adds bt_crypto_sih
WARNING:REPEATED_WORD: Possible repeated word: 'is'
#80:
This adds bt_crypto_sih is is used to create a hash as stated on

/github/workspace/src/src/13080417.patch total: 0 errors, 1 warnings, 44 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13080417.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.


[BlueZ,3/5] shared/crypto: Adds bt_crypto_sef
WARNING:REPEATED_WORD: Possible repeated word: 'is'
#84:
This adds bt_crypto_sef is is used to create a hash as stated on CSIS

/github/workspace/src/src/13080419.patch total: 0 errors, 1 warnings, 213 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13080419.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.




---
Regards,
Linux Bluetooth

2023-01-03 22:26:40

by patchwork-bot+bluetooth

[permalink] [raw]
Subject: Re: [PATCH BlueZ 1/5] shared/crypto: Adds bt_crypto_sih

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <[email protected]>:

On Thu, 22 Dec 2022 14:43:25 -0800 you wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> This adds bt_crypto_sih is is used to create a hash as stated on
> CSIS[1] spec:
>
> '4.7. Resolvable Set Identifier hash function sih'
>
> [...]

Here is the summary with links:
- [BlueZ,1/5] shared/crypto: Adds bt_crypto_sih
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=5abd9914a1eb
- [BlueZ,2/5] test-crypto: Add /crypto/sih test
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=09293fd22b3e
- [BlueZ,3/5] shared/crypto: Adds bt_crypto_sef
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=a38b6ca525b3
- [BlueZ,4/5] test-crypto: Add /crypto/sef test
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=051ccb1e878b
- [BlueZ,5/5] monitor: Add support for decoding RSI
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=7a32f2918035

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html