All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 3/5] shared/crypto: Adds bt_crypto_sef
Date: Thu, 22 Dec 2022 14:43:27 -0800	[thread overview]
Message-ID: <20221222224329.685837-3-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20221222224329.685837-1-luiz.dentz@gmail.com>

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

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


  parent reply	other threads:[~2022-12-22 22:43 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-22 22:43 [PATCH BlueZ 1/5] shared/crypto: Adds bt_crypto_sih Luiz Augusto von Dentz
2022-12-22 22:43 ` [PATCH BlueZ 2/5] test-crypto: Add /crypto/sih test Luiz Augusto von Dentz
2022-12-22 22:43 ` Luiz Augusto von Dentz [this message]
2022-12-22 22:43 ` [PATCH BlueZ 4/5] test-crypto: Add /crypto/sef test Luiz Augusto von Dentz
2022-12-22 22:43 ` [PATCH BlueZ 5/5] monitor: Add support for decoding RSI Luiz Augusto von Dentz
2022-12-23  1:24 ` [BlueZ,1/5] shared/crypto: Adds bt_crypto_sih bluez.test.bot
2023-01-03 22:20 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth

Reply instructions:

You may reply publicly 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=20221222224329.685837-3-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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.