| From 5b8fa212bc8176ea14395c0cb28c90ea6e9e4f17 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 7 Sep 2023 04:39:34 +0000 |
| Subject: Bluetooth: Avoid redundant authentication |
| |
| From: Ying Hsu <yinghsu@chromium.org> |
| |
| [ Upstream commit 1d8e801422d66e4b8c7b187c52196bef94eed887 ] |
| |
| While executing the Android 13 CTS Verifier Secure Server test on a |
| ChromeOS device, it was observed that the Bluetooth host initiates |
| authentication for an RFCOMM connection after SSP completes. |
| When this happens, some Intel Bluetooth controllers, like AC9560, would |
| disconnect with "Connection Rejected due to Security Reasons (0x0e)". |
| |
| Historically, BlueZ did not mandate this authentication while an |
| authenticated combination key was already in use for the connection. |
| This behavior was changed since commit 7b5a9241b780 |
| ("Bluetooth: Introduce requirements for security level 4"). |
| So, this patch addresses the aforementioned disconnection issue by |
| restoring the previous behavior. |
| |
| Signed-off-by: Ying Hsu <yinghsu@chromium.org> |
| Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/bluetooth/hci_conn.c | 63 ++++++++++++++++++++++------------------ |
| 1 file changed, 35 insertions(+), 28 deletions(-) |
| |
| diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c |
| index 9ffc18c883e24..afdc0afa8ee7d 100644 |
| --- a/net/bluetooth/hci_conn.c |
| +++ b/net/bluetooth/hci_conn.c |
| @@ -1391,34 +1391,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, |
| if (!test_bit(HCI_CONN_AUTH, &conn->flags)) |
| goto auth; |
| |
| - /* An authenticated FIPS approved combination key has sufficient |
| - * security for security level 4. */ |
| - if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 && |
| - sec_level == BT_SECURITY_FIPS) |
| - goto encrypt; |
| - |
| - /* An authenticated combination key has sufficient security for |
| - security level 3. */ |
| - if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 || |
| - conn->key_type == HCI_LK_AUTH_COMBINATION_P256) && |
| - sec_level == BT_SECURITY_HIGH) |
| - goto encrypt; |
| - |
| - /* An unauthenticated combination key has sufficient security for |
| - security level 1 and 2. */ |
| - if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 || |
| - conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) && |
| - (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) |
| - goto encrypt; |
| - |
| - /* A combination key has always sufficient security for the security |
| - levels 1 or 2. High security level requires the combination key |
| - is generated using maximum PIN code length (16). |
| - For pre 2.1 units. */ |
| - if (conn->key_type == HCI_LK_COMBINATION && |
| - (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW || |
| - conn->pin_length == 16)) |
| - goto encrypt; |
| + switch (conn->key_type) { |
| + case HCI_LK_AUTH_COMBINATION_P256: |
| + /* An authenticated FIPS approved combination key has |
| + * sufficient security for security level 4 or lower. |
| + */ |
| + if (sec_level <= BT_SECURITY_FIPS) |
| + goto encrypt; |
| + break; |
| + case HCI_LK_AUTH_COMBINATION_P192: |
| + /* An authenticated combination key has sufficient security for |
| + * security level 3 or lower. |
| + */ |
| + if (sec_level <= BT_SECURITY_HIGH) |
| + goto encrypt; |
| + break; |
| + case HCI_LK_UNAUTH_COMBINATION_P192: |
| + case HCI_LK_UNAUTH_COMBINATION_P256: |
| + /* An unauthenticated combination key has sufficient security |
| + * for security level 2 or lower. |
| + */ |
| + if (sec_level <= BT_SECURITY_MEDIUM) |
| + goto encrypt; |
| + break; |
| + case HCI_LK_COMBINATION: |
| + /* A combination key has always sufficient security for the |
| + * security levels 2 or lower. High security level requires the |
| + * combination key is generated using maximum PIN code length |
| + * (16). For pre 2.1 units. |
| + */ |
| + if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16) |
| + goto encrypt; |
| + break; |
| + default: |
| + break; |
| + } |
| |
| auth: |
| if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) |
| -- |
| 2.40.1 |
| |