Skip to content

Commit

Permalink
Bluetooth: Map sec_level to link key requirements
Browse files Browse the repository at this point in the history
Keep the link key type together with connection and use it to
map security level to link key requirements. Authenticate and/or
encrypt connection if the link is insufficiently secure.

Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
  • Loading branch information
Waldemar Rymarkiewicz authored and Gustavo F. Padovan committed Apr 28, 2011
1 parent 9003c4e commit 13d3931
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ struct hci_conn {
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
__u8 key_type;
__u8 auth_type;
__u8 sec_level;
__u8 pending_sec_level;
Expand Down
61 changes: 51 additions & 10 deletions net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->io_capability = hdev->io_capability;
conn->remote_auth = 0xff;
conn->key_type = 0xff;

conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Expand Down Expand Up @@ -535,32 +536,72 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
return 0;
}

/* Encrypt the the link */
static void hci_conn_encrypt(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);

if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 0x01;
hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
&cp);
}
}

/* Enable security */
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);

/* For sdp we don't need the link key. */
if (sec_level == BT_SECURITY_SDP)
return 1;

/* For non 2.1 devices and low security level we don't need the link
key. */
if (sec_level == BT_SECURITY_LOW &&
(!conn->ssp_mode || !conn->hdev->ssp_mode))
return 1;

if (conn->link_mode & HCI_LM_ENCRYPT)
return hci_conn_auth(conn, sec_level, auth_type);

/* For other security levels we need the link key. */
if (!(conn->link_mode & HCI_LM_AUTH))
goto auth;

/* An authenticated combination key has sufficient security for any
security level. */
if (conn->key_type == HCI_LK_AUTH_COMBINATION)
goto encrypt;

/* An unauthenticated combination key has sufficient security for
security level 1 and 2. */
if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
(sec_level == BT_SECURITY_MEDIUM ||
sec_level == BT_SECURITY_LOW))
goto encrypt;

/* A combination key has always sufficient security for the security
levels 1 or 2. High security level requires the combination key
is generated using maximum PIN code length (16).
For pre 2.1 units. */
if (conn->key_type == HCI_LK_COMBINATION &&
(sec_level != BT_SECURITY_HIGH ||
conn->pin_length == 16))
goto encrypt;

auth:
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0;

if (hci_conn_auth(conn, sec_level, auth_type)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 1;
hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
sizeof(cp), &cp);
}
hci_conn_auth(conn, sec_level, auth_type);
return 0;

encrypt:
if (conn->link_mode & HCI_LM_ENCRYPT)
return 1;

hci_conn_encrypt(conn);
return 0;
}
EXPORT_SYMBOL(hci_conn_security);
Expand Down
4 changes: 4 additions & 0 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,10 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
pin_len = conn->pin_length;

if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
conn->key_type = ev->key_type;

hci_conn_put(conn);
}

Expand Down

0 comments on commit 13d3931

Please sign in to comment.