|
25 | 25 | #include "hci_core.h" |
26 | 26 | #include "conn_internal.h" |
27 | 27 | #include "l2cap_internal.h" |
| 28 | +#include "keys.h" |
28 | 29 |
|
29 | 30 | #define LE_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, chan.rtx_work) |
30 | 31 | #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, |
1032 | 1033 | return BT_L2CAP_LE_SUCCESS; |
1033 | 1034 | } |
1034 | 1035 |
|
1035 | | -static bool l2cap_check_security(struct bt_conn *conn, |
| 1036 | +static uint16_t l2cap_check_security(struct bt_conn *conn, |
1036 | 1037 | struct bt_l2cap_server *server) |
1037 | 1038 | { |
| 1039 | + const struct bt_keys *keys = bt_keys_find_addr(conn->id, &conn->le.dst); |
| 1040 | + bool ltk_present; |
| 1041 | + |
1038 | 1042 | 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; |
1040 | 1071 | } |
1041 | 1072 |
|
1042 | | - return conn->sec_level >= server->sec_level; |
| 1073 | + return BT_L2CAP_LE_ERR_AUTHENTICATION; |
1043 | 1074 | } |
1044 | 1075 |
|
1045 | 1076 | 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, |
1090 | 1121 | } |
1091 | 1122 |
|
1092 | 1123 | /* 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); |
1095 | 1127 | goto rsp; |
1096 | 1128 | } |
1097 | 1129 |
|
@@ -1170,8 +1202,8 @@ static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident, |
1170 | 1202 | } |
1171 | 1203 |
|
1172 | 1204 | /* 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) { |
1175 | 1207 | goto response; |
1176 | 1208 | } |
1177 | 1209 |
|
|
0 commit comments