Skip to content

Commit 556736d

Browse files
sjanccfriedt
authored andcommitted
bluetooth: Fix L2CAP CoC response code if LTK is present
If an LTK or an STK is available and encryption is required (LE security mode 1) but encryption is not enabled, the service request shall be rejected with the error code "Insufficient Encryption". This is affecting L2CAP/LE/CFC/BV-25-C and L2CAP/ECFC/BV-32-C qualification test cases. Signed-off-by: Szymon Janc <[email protected]>
1 parent c32b524 commit 556736d

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

subsys/bluetooth/host/l2cap.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "hci_core.h"
2626
#include "conn_internal.h"
2727
#include "l2cap_internal.h"
28+
#include "keys.h"
2829

2930
#define LE_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, chan.rtx_work)
3031
#define CHAN_RX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, rx_work)
@@ -1032,14 +1033,44 @@ static uint16_t l2cap_chan_accept(struct bt_conn *conn,
10321033
return BT_L2CAP_LE_SUCCESS;
10331034
}
10341035

1035-
static bool l2cap_check_security(struct bt_conn *conn,
1036+
static uint16_t l2cap_check_security(struct bt_conn *conn,
10361037
struct bt_l2cap_server *server)
10371038
{
1039+
const struct bt_keys *keys = bt_keys_find_addr(conn->id, &conn->le.dst);
1040+
bool ltk_present;
1041+
10381042
if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) {
1039-
return true;
1043+
return BT_L2CAP_LE_SUCCESS;
1044+
}
1045+
1046+
if (conn->sec_level >= server->sec_level) {
1047+
return BT_L2CAP_LE_SUCCESS;
1048+
}
1049+
1050+
if (conn->sec_level > BT_SECURITY_L1) {
1051+
return BT_L2CAP_LE_ERR_AUTHENTICATION;
1052+
}
1053+
1054+
if (keys) {
1055+
if (conn->role == BT_HCI_ROLE_CENTRAL) {
1056+
ltk_present = keys->id & (BT_KEYS_LTK_P256 | BT_KEYS_PERIPH_LTK);
1057+
} else {
1058+
ltk_present = keys->id & (BT_KEYS_LTK_P256 | BT_KEYS_LTK);
1059+
}
1060+
} else {
1061+
ltk_present = false;
1062+
}
1063+
1064+
/* If an LTK or an STK is available and encryption is required
1065+
* (LE security mode 1) but encryption is not enabled, the
1066+
* service request shall be rejected with the error code
1067+
* "Insufficient Encryption".
1068+
*/
1069+
if (ltk_present) {
1070+
return BT_L2CAP_LE_ERR_ENCRYPTION;
10401071
}
10411072

1042-
return conn->sec_level >= server->sec_level;
1073+
return BT_L2CAP_LE_ERR_AUTHENTICATION;
10431074
}
10441075

10451076
static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
@@ -1090,8 +1121,9 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
10901121
}
10911122

10921123
/* Check if connection has minimum required security level */
1093-
if (!l2cap_check_security(conn, server)) {
1094-
rsp->result = sys_cpu_to_le16(BT_L2CAP_LE_ERR_AUTHENTICATION);
1124+
result = l2cap_check_security(conn, server);
1125+
if (result != BT_L2CAP_LE_SUCCESS) {
1126+
rsp->result = sys_cpu_to_le16(result);
10951127
goto rsp;
10961128
}
10971129

@@ -1170,8 +1202,8 @@ static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
11701202
}
11711203

11721204
/* Check if connection has minimum required security level */
1173-
if (!l2cap_check_security(conn, server)) {
1174-
result = BT_L2CAP_LE_ERR_AUTHENTICATION;
1205+
result = l2cap_check_security(conn, server);
1206+
if (result != BT_L2CAP_LE_SUCCESS) {
11751207
goto response;
11761208
}
11771209

0 commit comments

Comments
 (0)