Skip to content

Commit

Permalink
Bluetooth: host: Fix ATT error code on GATT authentication procedure
Browse files Browse the repository at this point in the history
“Insufficient Encryption” shall be returned only if link is not
encrypted and proper LTK is present, otherwise “Insufficient
Authentication” shall be used.

Core Specification 5.4 Vol. 3 Part C 10.3.1

"If neither an LTK nor an STK is available, the service
request shall be rejected with the error code
“Insufficient Authentication”.
Note: When the link is not encrypted, the error code
“Insufficient Authentication” does not indicate that
MITM protection is required.
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 was affecting GAP/SEC/AUT/BV-11-C qualification test case.

Signed-off-by: Szymon Janc <[email protected]>
  • Loading branch information
sjanc authored and fabiobaltieri committed Mar 28, 2023
1 parent c7010c3 commit dc1ca29
Showing 1 changed file with 52 additions and 14 deletions.
66 changes: 52 additions & 14 deletions subsys/bluetooth/host/gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3090,6 +3090,23 @@ 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 All @@ -3109,26 +3126,47 @@ uint8_t bt_gatt_check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr

mask &= attr->perm;

if (mask & BT_GATT_PERM_LESC_MASK) {
if (!IS_ENABLED(CONFIG_BT_SMP) || !conn->le.keys ||
(conn->le.keys->flags & BT_KEYS_SC) == 0) {
return BT_ATT_ERR_AUTHENTICATION;
/*
* Core Specification 5.4 Vol. 3 Part C 10.3.1
*
* If neither an LTK nor an STK is available, the service
* request shall be rejected with the error code
* “Insufficient Authentication”.
* Note: When the link is not encrypted, the error code
* “Insufficient Authentication” does not indicate that
* MITM protection is required.
*
* 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 (mask & (BT_GATT_PERM_ENCRYPT_MASK | BT_GATT_PERM_AUTHEN_MASK)) {
#if defined(CONFIG_BT_SMP)
if (!conn->encrypt) {
if (ltk_present(conn)) {
return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
} else {
return BT_ATT_ERR_AUTHENTICATION;
}
}
}

if (mask & BT_GATT_PERM_AUTHEN_MASK) {
if (bt_conn_get_security(conn) < BT_SECURITY_L3) {
return BT_ATT_ERR_AUTHENTICATION;
if (mask & BT_GATT_PERM_AUTHEN_MASK) {
if (bt_conn_get_security(conn) < BT_SECURITY_L3) {
return BT_ATT_ERR_AUTHENTICATION;
}
}
}

if ((mask & BT_GATT_PERM_ENCRYPT_MASK)) {
#if defined(CONFIG_BT_SMP)
if (!conn->encrypt) {
return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
if (mask & BT_GATT_PERM_LESC_MASK) {
const struct bt_keys *keys = conn->le.keys;

if (!keys || (keys->flags & BT_KEYS_SC) == 0) {
return BT_ATT_ERR_AUTHENTICATION;
}
}
#else
return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
return BT_ATT_ERR_AUTHENTICATION;
#endif /* CONFIG_BT_SMP */
}

Expand Down

0 comments on commit dc1ca29

Please sign in to comment.