Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0684e5f9 authored by Marcel Holtmann's avatar Marcel Holtmann
Browse files

Bluetooth: Use general bonding whenever possible



When receiving incoming connection to specific services, always use
general bonding. This ensures that the link key gets stored and can be
used for further authentications.

Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent efc7688b
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -328,7 +328,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);


struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
int hci_conn_check_link_mode(struct hci_conn *conn);
int hci_conn_check_link_mode(struct hci_conn *conn);
int hci_conn_security(struct hci_conn *conn, __u8 sec_level);
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
int hci_conn_change_link_key(struct hci_conn *conn);
int hci_conn_change_link_key(struct hci_conn *conn);
int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
int hci_conn_switch_role(struct hci_conn *conn, __u8 role);


+9 −14
Original line number Original line Diff line number Diff line
@@ -391,19 +391,14 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
EXPORT_SYMBOL(hci_conn_check_link_mode);
EXPORT_SYMBOL(hci_conn_check_link_mode);


/* Authenticate remote device */
/* Authenticate remote device */
static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
{
	BT_DBG("conn %p", conn);
	BT_DBG("conn %p", conn);


	if (sec_level > conn->sec_level)
	if (sec_level > conn->sec_level) {
		conn->link_mode &= ~HCI_LM_AUTH;

		conn->sec_level = sec_level;
		conn->sec_level = sec_level;

		conn->auth_type = auth_type;
	if (sec_level == BT_SECURITY_HIGH)
	} else if (conn->link_mode & HCI_LM_AUTH)
		conn->auth_type |= 0x01;

	if (conn->link_mode & HCI_LM_AUTH)
		return 1;
		return 1;


	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
@@ -417,7 +412,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
}
}


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


@@ -426,18 +421,18 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level)


	if (sec_level == BT_SECURITY_LOW) {
	if (sec_level == BT_SECURITY_LOW) {
		if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
		if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
			return hci_conn_auth(conn, sec_level);
			return hci_conn_auth(conn, sec_level, auth_type);
		else
		else
			return 1;
			return 1;
	}
	}


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


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


	if (hci_conn_auth(conn, sec_level)) {
	if (hci_conn_auth(conn, sec_level, auth_type)) {
		struct hci_cp_set_conn_encrypt cp;
		struct hci_cp_set_conn_encrypt cp;
		cp.handle  = cpu_to_le16(conn->handle);
		cp.handle  = cpu_to_le16(conn->handle);
		cp.encrypt = 1;
		cp.encrypt = 1;
+15 −1
Original line number Original line Diff line number Diff line
@@ -263,8 +263,22 @@ static void l2cap_chan_del(struct sock *sk, int err)
static inline int l2cap_check_security(struct sock *sk)
static inline int l2cap_check_security(struct sock *sk)
{
{
	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
	__u8 auth_type;

	switch (l2cap_pi(sk)->sec_level) {
	case BT_SECURITY_HIGH:
		auth_type = HCI_AT_GENERAL_BONDING_MITM;
		break;
	case BT_SECURITY_MEDIUM:
		auth_type = HCI_AT_GENERAL_BONDING;
		break;
	default:
		auth_type = HCI_AT_NO_BONDING;
		break;
	}


	return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level);
	return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
								auth_type);
}
}


static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
+15 −1
Original line number Original line Diff line number Diff line
@@ -226,8 +226,22 @@ static int rfcomm_l2sock_create(struct socket **sock)
static inline int rfcomm_check_security(struct rfcomm_dlc *d)
static inline int rfcomm_check_security(struct rfcomm_dlc *d)
{
{
	struct sock *sk = d->session->sock->sk;
	struct sock *sk = d->session->sock->sk;
	__u8 auth_type;


	return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level);
	switch (d->sec_level) {
	case BT_SECURITY_HIGH:
		auth_type = HCI_AT_GENERAL_BONDING_MITM;
		break;
	case BT_SECURITY_MEDIUM:
		auth_type = HCI_AT_GENERAL_BONDING;
		break;
	default:
		auth_type = HCI_AT_NO_BONDING;
		break;
	}

	return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level,
								auth_type);
}
}


/* ---- RFCOMM DLCs ---- */
/* ---- RFCOMM DLCs ---- */