Skip to content

Commit c2841b5

Browse files
Alex Lumdiewa
authored andcommitted
Bluetooth: Add more enc key size check
When we are slave role and receives l2cap conn req when encryption has started, we should check the enc key size to avoid KNOB attack or BLUFFS attack. From SIG recommendation, implementations are advised to reject service-level connections on an encrypted baseband link with key strengths below 7 octets. A simple and clear way to achieve this is to place the enc key size check in hci_cc_read_enc_key_size() The btmon log below shows the case that lacks enc key size check. > HCI Event: Connect Request (0x04) plen 10 Address: BB:22:33:44:55:99 (OUI BB-22-33) Class: 0x480104 Major class: Computer (desktop, notebook, PDA, organizers) Minor class: Desktop workstation Capturing (Scanner, Microphone) Telephony (Cordless telephony, Modem, Headset) Link type: ACL (0x01) < HCI Command: Accept Connection Request (0x01|0x0009) plen 7 Address: BB:22:33:44:55:99 (OUI BB-22-33) Role: Peripheral (0x01) > HCI Event: Command Status (0x0f) plen 4 Accept Connection Request (0x01|0x0009) ncmd 2 Status: Success (0x00) > HCI Event: Connect Complete (0x03) plen 11 Status: Success (0x00) Handle: 1 Address: BB:22:33:44:55:99 (OUI BB-22-33) Link type: ACL (0x01) Encryption: Disabled (0x00) ... > HCI Event: Encryption Change (0x08) plen 4 Status: Success (0x00) Handle: 1 Address: BB:22:33:44:55:99 (OUI BB-22-33) Encryption: Enabled with E0 (0x01) < HCI Command: Read Encryption Key Size (0x05|0x0008) plen 2 Handle: 1 Address: BB:22:33:44:55:99 (OUI BB-22-33) > HCI Event: Command Complete (0x0e) plen 7 Read Encryption Key Size (0x05|0x0008) ncmd 2 Status: Success (0x00) Handle: 1 Address: BB:22:33:44:55:99 (OUI BB-22-33) Key size: 6 // We should check the enc key size ... > ACL Data RX: Handle 1 flags 0x02 dlen 12 L2CAP: Connection Request (0x02) ident 3 len 4 PSM: 25 (0x0019) Source CID: 64 < ACL Data TX: Handle 1 flags 0x00 dlen 16 L2CAP: Connection Response (0x03) ident 3 len 8 Destination CID: 64 Source CID: 64 Result: Connection pending (0x0001) Status: Authorization pending (0x0002) > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 1 Address: BB:22:33:44:55:99 (OUI BB-22-33) Count: 1 #35: len 16 (25 Kb/s) Latency: 5 msec (2-7 msec ~4 msec) < ACL Data TX: Handle 1 flags 0x00 dlen 16 L2CAP: Connection Response (0x03) ident 3 len 8 Destination CID: 64 Source CID: 64 Result: Connection successful (0x0000) Status: No further information available (0x0000) Cc: [email protected] Signed-off-by: Alex Lu <[email protected]> Signed-off-by: Max Chou <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]> (backported from commit 04a342c) [yuxuan.luo: manually backported. Renamed status to rp_status to avoid name conflict with the function argument "status". ] CVE-2023-24023 Signed-off-by: Yuxuan Luo <[email protected]> Acked-by: Jacob Martin <[email protected]> Acked-by: Roxana Nicolescu <[email protected]> Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent 920496d commit c2841b5

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

net/bluetooth/hci_event.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,6 +3113,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
31133113
const struct hci_rp_read_enc_key_size *rp;
31143114
struct hci_conn *conn;
31153115
u16 handle;
3116+
u8 rp_status;
31163117

31173118
BT_DBG("%s status 0x%02x", hdev->name, status);
31183119

@@ -3122,6 +3123,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
31223123
}
31233124

31243125
rp = (void *)skb->data;
3126+
rp_status = rp->status;
31253127
handle = le16_to_cpu(rp->handle);
31263128

31273129
hci_dev_lock(hdev);
@@ -3134,15 +3136,30 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
31343136
* secure approach is to then assume the key size is 0 to force a
31353137
* disconnection.
31363138
*/
3137-
if (rp->status) {
3139+
if (rp_status) {
31383140
bt_dev_err(hdev, "failed to read key size for handle %u",
31393141
handle);
31403142
conn->enc_key_size = 0;
31413143
} else {
31423144
conn->enc_key_size = rp->key_size;
3145+
rp_status = 0;
3146+
3147+
if (conn->enc_key_size < hdev->min_enc_key_size) {
3148+
/* As slave role, the conn->state has been set to
3149+
* BT_CONNECTED and l2cap conn req might not be received
3150+
* yet, at this moment the l2cap layer almost does
3151+
* nothing with the non-zero status.
3152+
* So we also clear encrypt related bits, and then the
3153+
* handler of l2cap conn req will get the right secure
3154+
* state at a later time.
3155+
*/
3156+
rp_status = HCI_ERROR_AUTH_FAILURE;
3157+
clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
3158+
clear_bit(HCI_CONN_AES_CCM, &conn->flags);
3159+
}
31433160
}
31443161

3145-
hci_encrypt_cfm(conn, 0);
3162+
hci_encrypt_cfm(conn, rp_status);
31463163

31473164
unlock:
31483165
hci_dev_unlock(hdev);

0 commit comments

Comments
 (0)