Skip to content

Commit

Permalink
bluetooth: host: Add common helper for checking LTK presence
Browse files Browse the repository at this point in the history
Both L2CAP and GATT have same requirements with regards to error code
on no encryption when LTK is or isn't present.

Signed-off-by: Szymon Janc <[email protected]>
  • Loading branch information
sjanc authored and fabiobaltieri committed Mar 28, 2023
1 parent dc1ca29 commit 8fe734c
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 32 deletions.
15 changes: 15 additions & 0 deletions subsys/bluetooth/host/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2059,6 +2059,21 @@ static int bt_hci_connect_br_cancel(struct bt_conn *conn)
#endif /* CONFIG_BT_BREDR */

#if defined(CONFIG_BT_SMP)
bool bt_conn_ltk_present(const struct bt_conn *conn)
{
const struct bt_keys *keys = conn->le.keys;

if (keys) {
if (conn->role == BT_HCI_ROLE_CENTRAL) {
return keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_PERIPH_LTK);
} else {
return keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK);
}
}

return false;
}

void bt_conn_identity_resolved(struct bt_conn *conn)
{
const bt_addr_le_t *rpa;
Expand Down
3 changes: 3 additions & 0 deletions subsys/bluetooth/host/conn_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ void notify_le_phy_updated(struct bt_conn *conn);
bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param);

#if defined(CONFIG_BT_SMP)
/* If role specific LTK is present */
bool bt_conn_ltk_present(const struct bt_conn *conn);

/* rand and ediv should be in BT order */
int bt_conn_le_start_encryption(struct bt_conn *conn, uint8_t rand[8],
uint8_t ediv[2], const uint8_t *ltk, size_t len);
Expand Down
19 changes: 1 addition & 18 deletions subsys/bluetooth/host/gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3090,23 +3090,6 @@ uint16_t bt_gatt_get_mtu(struct bt_conn *conn)
return bt_att_get_mtu(conn);
}

#if defined(CONFIG_BT_SMP)
static bool ltk_present(const struct bt_conn *conn)
{
const struct bt_keys *keys = conn->le.keys;

if (keys) {
if (conn->role == BT_HCI_ROLE_CENTRAL) {
return keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_PERIPH_LTK);
} else {
return keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK);
}
}

return false;
}
#endif /* CONFIG_BT_SMP */

uint8_t bt_gatt_check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr,
uint16_t mask)
{
Expand Down Expand Up @@ -3145,7 +3128,7 @@ uint8_t bt_gatt_check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr
if (mask & (BT_GATT_PERM_ENCRYPT_MASK | BT_GATT_PERM_AUTHEN_MASK)) {
#if defined(CONFIG_BT_SMP)
if (!conn->encrypt) {
if (ltk_present(conn)) {
if (bt_conn_ltk_present(conn)) {
return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
} else {
return BT_ATT_ERR_AUTHENTICATION;
Expand Down
15 changes: 1 addition & 14 deletions subsys/bluetooth/host/l2cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1092,9 +1092,6 @@ static uint16_t l2cap_chan_accept(struct bt_conn *conn,
static uint16_t l2cap_check_security(struct bt_conn *conn,
struct bt_l2cap_server *server)
{
const struct bt_keys *keys = bt_keys_find_addr(conn->id, &conn->le.dst);
bool ltk_present;

if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) {
return BT_L2CAP_LE_SUCCESS;
}
Expand All @@ -1107,22 +1104,12 @@ static uint16_t l2cap_check_security(struct bt_conn *conn,
return BT_L2CAP_LE_ERR_AUTHENTICATION;
}

if (keys) {
if (conn->role == BT_HCI_ROLE_CENTRAL) {
ltk_present = keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_PERIPH_LTK);
} else {
ltk_present = keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK);
}
} else {
ltk_present = false;
}

/* 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".
*/
if (ltk_present) {
if (bt_conn_ltk_present(conn)) {
return BT_L2CAP_LE_ERR_ENCRYPTION;
}

Expand Down

0 comments on commit 8fe734c

Please sign in to comment.