aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--net/bluetooth/hci_conn.c23
-rw-r--r--net/bluetooth/l2cap.c16
-rw-r--r--net/bluetooth/rfcomm/core.c16
4 files changed, 40 insertions, 17 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4b14972c1694..f75028b33883 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -328,7 +328,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
328 328
329struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); 329struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
330int hci_conn_check_link_mode(struct hci_conn *conn); 330int hci_conn_check_link_mode(struct hci_conn *conn);
331int hci_conn_security(struct hci_conn *conn, __u8 sec_level); 331int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
332int hci_conn_change_link_key(struct hci_conn *conn); 332int hci_conn_change_link_key(struct hci_conn *conn);
333int hci_conn_switch_role(struct hci_conn *conn, __u8 role); 333int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
334 334
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2435e830ba60..7fc4c048b57b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -391,19 +391,14 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
391EXPORT_SYMBOL(hci_conn_check_link_mode); 391EXPORT_SYMBOL(hci_conn_check_link_mode);
392 392
393/* Authenticate remote device */ 393/* Authenticate remote device */
394static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level) 394static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
395{ 395{
396 BT_DBG("conn %p", conn); 396 BT_DBG("conn %p", conn);
397 397
398 if (sec_level > conn->sec_level) 398 if (sec_level > conn->sec_level) {
399 conn->link_mode &= ~HCI_LM_AUTH; 399 conn->sec_level = sec_level;
400 400 conn->auth_type = auth_type;
401 conn->sec_level = sec_level; 401 } else if (conn->link_mode & HCI_LM_AUTH)
402
403 if (sec_level == BT_SECURITY_HIGH)
404 conn->auth_type |= 0x01;
405
406 if (conn->link_mode & HCI_LM_AUTH)
407 return 1; 402 return 1;
408 403
409 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 404 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)
417} 412}
418 413
419/* Enable security */ 414/* Enable security */
420int hci_conn_security(struct hci_conn *conn, __u8 sec_level) 415int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
421{ 416{
422 BT_DBG("conn %p", conn); 417 BT_DBG("conn %p", conn);
423 418
@@ -426,18 +421,18 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level)
426 421
427 if (sec_level == BT_SECURITY_LOW) { 422 if (sec_level == BT_SECURITY_LOW) {
428 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) 423 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
429 return hci_conn_auth(conn, sec_level); 424 return hci_conn_auth(conn, sec_level, auth_type);
430 else 425 else
431 return 1; 426 return 1;
432 } 427 }
433 428
434 if (conn->link_mode & HCI_LM_ENCRYPT) 429 if (conn->link_mode & HCI_LM_ENCRYPT)
435 return hci_conn_auth(conn, sec_level); 430 return hci_conn_auth(conn, sec_level, auth_type);
436 431
437 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 432 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
438 return 0; 433 return 0;
439 434
440 if (hci_conn_auth(conn, sec_level)) { 435 if (hci_conn_auth(conn, sec_level, auth_type)) {
441 struct hci_cp_set_conn_encrypt cp; 436 struct hci_cp_set_conn_encrypt cp;
442 cp.handle = cpu_to_le16(conn->handle); 437 cp.handle = cpu_to_le16(conn->handle);
443 cp.encrypt = 1; 438 cp.encrypt = 1;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b677af671f31..8a93dde4095b 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -263,8 +263,22 @@ static void l2cap_chan_del(struct sock *sk, int err)
263static inline int l2cap_check_security(struct sock *sk) 263static inline int l2cap_check_security(struct sock *sk)
264{ 264{
265 struct l2cap_conn *conn = l2cap_pi(sk)->conn; 265 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
266 __u8 auth_type;
267
268 switch (l2cap_pi(sk)->sec_level) {
269 case BT_SECURITY_HIGH:
270 auth_type = HCI_AT_GENERAL_BONDING_MITM;
271 break;
272 case BT_SECURITY_MEDIUM:
273 auth_type = HCI_AT_GENERAL_BONDING;
274 break;
275 default:
276 auth_type = HCI_AT_NO_BONDING;
277 break;
278 }
266 279
267 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level); 280 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
281 auth_type);
268} 282}
269 283
270static inline u8 l2cap_get_ident(struct l2cap_conn *conn) 284static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 3717c25ba33a..1828ec06ad1c 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -226,8 +226,22 @@ static int rfcomm_l2sock_create(struct socket **sock)
226static inline int rfcomm_check_security(struct rfcomm_dlc *d) 226static inline int rfcomm_check_security(struct rfcomm_dlc *d)
227{ 227{
228 struct sock *sk = d->session->sock->sk; 228 struct sock *sk = d->session->sock->sk;
229 __u8 auth_type;
229 230
230 return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level); 231 switch (d->sec_level) {
232 case BT_SECURITY_HIGH:
233 auth_type = HCI_AT_GENERAL_BONDING_MITM;
234 break;
235 case BT_SECURITY_MEDIUM:
236 auth_type = HCI_AT_GENERAL_BONDING;
237 break;
238 default:
239 auth_type = HCI_AT_NO_BONDING;
240 break;
241 }
242
243 return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level,
244 auth_type);
231} 245}
232 246
233/* ---- RFCOMM DLCs ---- */ 247/* ---- RFCOMM DLCs ---- */