All of lore.kernel.org
 help / color / mirror / Atom feed
From: Magdalena Kasenberg <magdalena.kasenberg@codecoup.pl>
To: linux-bluetooth@vger.kernel.org
Cc: Magdalena Kasenberg <magdalena.kasenberg@codecoup.pl>,
	Szymon Janc <szymon.janc@codecoup.pl>
Subject: [PATCH] Bluetooth: Fix for L2CAP/LE/CFC/BV-15-C
Date: Mon, 22 Feb 2021 11:30:21 +0100	[thread overview]
Message-ID: <20210222103021.20923-1-magdalena.kasenberg@codecoup.pl> (raw)

This is required for the qualification test L2CAP/LE/CFC/BV-15-C

Implementation does not allow to set different key size for SMP and
L2CAP, which is needed for a current specification of the test. This fix
workarounds it with the debugfs variable le_l2cap_min_key_size.

Logs from the test when the IUT uses a min and max l2cap encryption key size 16.
$ echo 16 > /sys/kernel/debug/bluetooth/hci0/le_l2cap_min_key_size
The lower tester uses a key size 7.

> ACL Data RX: Handle 99 flags 0x02 dlen 11                #34 [hci0] 25.007392
      SMP: Pairing Request (0x01) len 6
        IO capability: DisplayYesNo (0x01)
        OOB data: Authentication data not present (0x00)
        Authentication requirement: Bonding, No MITM, SC, No Keypresses (0x09)
        Max encryption key size: 7
        Initiator key distribution: <none> (0x00)
        Responder key distribution: <none> (0x00)
< ACL Data TX: Handle 99 flags 0x00 dlen 11                #35 [hci0] 25.007591
      SMP: Pairing Response (0x02) len 6
        IO capability: KeyboardDisplay (0x04)
        OOB data: Authentication data not present (0x00)
        Authentication requirement: Bonding, No MITM, SC, No Keypresses (0x09)
        Max encryption key size: 16
        Initiator key distribution: <none> (0x00)
        Responder key distribution: <none> (0x00)
@ MGMT Event: New Long Term Key (0x000a) plen 37      {0x0001} [hci0] 28.788872
        Store hint: Yes (0x01)
        LE Address: C0:DE:C0:FF:FF:01 (OUI C0-DE-C0)
        Key type: Unauthenticated key from P-256 (0x02)
        Master: 0x00
        Encryption size: 7
        Diversifier: 0000
        Randomizer: 0000000000000000
        Key: 529e11e8c7b9f5000000000000000000

<snip>

After pairing with key size 7, L2CAP connection is requested which
requires key size 16.

> ACL Data RX: Handle 99 flags 0x02 dlen 18                #56 [hci0] 34.998084
      LE L2CAP: LE Connection Request (0x14) ident 3 len 10
        PSM: 244 (0x00f4)
        Source CID: 64
        MTU: 256
        MPS: 284
        Credits: 1
< ACL Data TX: Handle 99 flags 0x00 dlen 18                #57 [hci0] 34.998325
      LE L2CAP: LE Connection Response (0x15) ident 3 len 10
        Destination CID: 0
        MTU: 0
        MPS: 0
        Credits: 0
        Result: Connection refused - insufficient encryption key size (0x0007)

Signed-off-by: Magdalena Kasenberg <magdalena.kasenberg@codecoup.pl>
Reviewed-by: Szymon Janc <szymon.janc@codecoup.pl>
Cc: Szymon Janc <szymon.janc@codecoup.pl>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         |  1 +
 net/bluetooth/hci_debugfs.c      | 30 ++++++++++++++++++++++++++++++
 net/bluetooth/l2cap_core.c       | 25 +++++++++++++++++++++++++
 4 files changed, 57 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ebdd4afe30d2..0bf0543efec5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -379,6 +379,7 @@ struct hci_dev {
 	__u16		auth_payload_timeout;
 	__u8		min_enc_key_size;
 	__u8		max_enc_key_size;
+	__u8		le_l2cap_min_key_size;
 	__u8		pairing_opts;
 	__u8		ssp_debug_mode;
 	__u8		hw_error_code;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b0d9c36acc03..9ef4b39b380c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3788,6 +3788,7 @@ struct hci_dev *hci_alloc_dev(void)
 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
+	hdev->le_l2cap_min_key_size = HCI_MIN_ENC_KEY_SIZE;
 
 	/* default 1.28 sec page scan */
 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 1a0ab58bfad0..dec8b96b8427 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -1096,6 +1096,34 @@ static int max_key_size_get(void *data, u64 *val)
 DEFINE_DEBUGFS_ATTRIBUTE(max_key_size_fops, max_key_size_get,
 			  max_key_size_set, "%llu\n");
 
+static int le_l2cap_min_key_size_set(void *data, u64 val)
+{
+	struct hci_dev *hdev = data;
+
+	if (val > SMP_MAX_ENC_KEY_SIZE || val < SMP_MIN_ENC_KEY_SIZE)
+		return -EINVAL;
+
+	hci_dev_lock(hdev);
+	hdev->le_l2cap_min_key_size = val;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int le_l2cap_min_key_size_get(void *data, u64 *val)
+{
+	struct hci_dev *hdev = data;
+
+	hci_dev_lock(hdev);
+	*val = hdev->le_l2cap_min_key_size;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(le_l2cap_min_key_size_fops, le_l2cap_min_key_size_get,
+			 le_l2cap_min_key_size_set, "%llu\n");
+
 static int auth_payload_timeout_set(void *data, u64 val)
 {
 	struct hci_dev *hdev = data;
@@ -1226,6 +1254,8 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
 			    &min_key_size_fops);
 	debugfs_create_file("max_key_size", 0644, hdev->debugfs, hdev,
 			    &max_key_size_fops);
+	debugfs_create_file("le_l2cap_min_key_size", 0644, hdev->debugfs, hdev,
+			    &le_l2cap_min_key_size_fops);
 	debugfs_create_file("auth_payload_timeout", 0644, hdev->debugfs, hdev,
 			    &auth_payload_timeout_fops);
 	debugfs_create_file("force_no_mitm", 0644, hdev->debugfs, hdev,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 72c2f5226d67..d9a3a1c1f366 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5742,6 +5742,20 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
 	return err;
 }
 
+static bool le_l2cap_key_size_sufficient(struct hci_conn *hcon, u8 sec_level)
+{
+	struct smp_ltk *ltk;
+
+	if (sec_level == BT_SECURITY_LOW)
+		return true;
+
+	ltk = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
+	if (ltk && ltk->enc_size >= hcon->hdev->le_l2cap_min_key_size)
+		return true;
+
+	return false;
+}
+
 static int l2cap_le_connect_req(struct l2cap_conn *conn,
 				struct l2cap_cmd_hdr *cmd, u16 cmd_len,
 				u8 *data)
@@ -5788,6 +5802,12 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
 		goto response_unlock;
 	}
 
+	if (!le_l2cap_key_size_sufficient(conn->hcon, pchan->sec_level)) {
+		result = L2CAP_CR_LE_BAD_KEY_SIZE;
+		chan = NULL;
+		goto response_unlock;
+	}
+
 	/* Check for valid dynamic CID range */
 	if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
 		result = L2CAP_CR_LE_INVALID_SCID;
@@ -5969,6 +5989,11 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
 		goto unlock;
 	}
 
+	if (!le_l2cap_key_size_sufficient(conn->hcon, pchan->sec_level)) {
+		result = L2CAP_CR_LE_BAD_KEY_SIZE;
+		goto unlock;
+	}
+
 	result = L2CAP_CR_LE_SUCCESS;
 	cmd_len -= sizeof(*req);
 	num_scid = cmd_len / sizeof(u16);
-- 
2.25.1


             reply	other threads:[~2021-02-22 10:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-22 10:30 Magdalena Kasenberg [this message]
2021-02-22 11:06 ` Bluetooth: Fix for L2CAP/LE/CFC/BV-15-C bluez.test.bot
2021-02-22 17:46 ` [PATCH] " Luiz Augusto von Dentz
2021-02-26 20:17 ` Marcel Holtmann
2021-02-26 21:42   ` Luiz Augusto von Dentz
2021-02-27 20:14     ` Marcel Holtmann
2021-03-09 10:27       ` Szymon Janc
2021-03-09 18:35         ` Luiz Augusto von Dentz
2021-03-10  6:55           ` Marcel Holtmann

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=20210222103021.20923-1-magdalena.kasenberg@codecoup.pl \
    --to=magdalena.kasenberg@codecoup.pl \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=szymon.janc@codecoup.pl \
    /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.