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
next 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.