aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm/core.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-01-15 15:58:04 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:25 -0500
commit8c1b235594fbab9a13240a1dac12ea9fd99b6440 (patch)
treeeb137a23e0fd8199144a4c3e36902af411e44269 /net/bluetooth/rfcomm/core.c
parentc89b6e6bda4c8021195778f47567d0cc9dbfe7ec (diff)
Bluetooth: Add enhanced security model for Simple Pairing
The current security model is based around the flags AUTH, ENCRYPT and SECURE. Starting with support for the Bluetooth 2.1 specification this is no longer sufficient. The different security levels are now defined as SDP, LOW, MEDIUM and SECURE. Previously it was possible to set each security independently, but this actually doesn't make a lot of sense. For Bluetooth the encryption depends on a previous successful authentication. Also you can only update your existing link key if you successfully created at least one before. And of course the update of link keys without having proper encryption in place is a security issue. The new security levels from the Bluetooth 2.1 specification are now used internally. All old settings are mapped to the new values and this way it ensures that old applications still work. The only limitation is that it is no longer possible to set authentication without also enabling encryption. No application should have done this anyway since this is actually a security issue. Without encryption the integrity of the authentication can't be guaranteed. As default for a new L2CAP or RFCOMM connection, the LOW security level is used. The only exception here are the service discovery sessions on PSM 1 where SDP level is used. To have similar security strength as with a Bluetooth 2.0 and before combination key, the MEDIUM level should be used. This is according to the Bluetooth specification. The MEDIUM level will not require any kind of man-in-the-middle (MITM) protection. Only the HIGH security level will require this. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/rfcomm/core.c')
-rw-r--r--net/bluetooth/rfcomm/core.c81
1 files changed, 24 insertions, 57 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index edee49e00fbf..68f70c5270c6 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -226,16 +226,18 @@ static int rfcomm_l2sock_create(struct socket **sock)
226static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) 226static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
227{ 227{
228 struct sock *sk = d->session->sock->sk; 228 struct sock *sk = d->session->sock->sk;
229 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
229 230
230 if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { 231 if (d->link_mode & RFCOMM_LM_SECURE)
231 if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) 232 return hci_conn_security(conn->hcon, BT_SECURITY_HIGH);
232 return 1;
233 } else if (d->link_mode & RFCOMM_LM_AUTH) {
234 if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon))
235 return 1;
236 }
237 233
238 return 0; 234 if (d->link_mode & RFCOMM_LM_ENCRYPT)
235 return hci_conn_security(conn->hcon, BT_SECURITY_MEDIUM);
236
237 if (d->link_mode & RFCOMM_LM_AUTH)
238 return hci_conn_security(conn->hcon, BT_SECURITY_LOW);
239
240 return 1;
239} 241}
240 242
241/* ---- RFCOMM DLCs ---- */ 243/* ---- RFCOMM DLCs ---- */
@@ -389,9 +391,9 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
389 391
390 if (s->state == BT_CONNECTED) { 392 if (s->state == BT_CONNECTED) {
391 if (rfcomm_check_link_mode(d)) 393 if (rfcomm_check_link_mode(d))
392 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
393 else
394 rfcomm_send_pn(s, 1, d); 394 rfcomm_send_pn(s, 1, d);
395 else
396 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
395 } 397 }
396 398
397 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); 399 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
@@ -1199,14 +1201,14 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1199static void rfcomm_check_accept(struct rfcomm_dlc *d) 1201static void rfcomm_check_accept(struct rfcomm_dlc *d)
1200{ 1202{
1201 if (rfcomm_check_link_mode(d)) { 1203 if (rfcomm_check_link_mode(d)) {
1202 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1203 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1204 } else {
1205 if (d->defer_setup) { 1204 if (d->defer_setup) {
1206 set_bit(RFCOMM_DEFER_SETUP, &d->flags); 1205 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1207 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); 1206 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1208 } else 1207 } else
1209 rfcomm_dlc_accept(d); 1208 rfcomm_dlc_accept(d);
1209 } else {
1210 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1211 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1210 } 1212 }
1211} 1213}
1212 1214
@@ -1659,10 +1661,11 @@ static void rfcomm_process_connect(struct rfcomm_session *s)
1659 if (d->state == BT_CONFIG) { 1661 if (d->state == BT_CONFIG) {
1660 d->mtu = s->mtu; 1662 d->mtu = s->mtu;
1661 if (rfcomm_check_link_mode(d)) { 1663 if (rfcomm_check_link_mode(d)) {
1664 rfcomm_send_pn(s, 1, d);
1665 } else {
1662 set_bit(RFCOMM_AUTH_PENDING, &d->flags); 1666 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1663 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); 1667 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1664 } else 1668 }
1665 rfcomm_send_pn(s, 1, d);
1666 } 1669 }
1667 } 1670 }
1668} 1671}
@@ -1973,42 +1976,7 @@ static int rfcomm_run(void *unused)
1973 return 0; 1976 return 0;
1974} 1977}
1975 1978
1976static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status) 1979static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
1977{
1978 struct rfcomm_session *s;
1979 struct rfcomm_dlc *d;
1980 struct list_head *p, *n;
1981
1982 BT_DBG("conn %p status 0x%02x", conn, status);
1983
1984 s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
1985 if (!s)
1986 return;
1987
1988 rfcomm_session_hold(s);
1989
1990 list_for_each_safe(p, n, &s->dlcs) {
1991 d = list_entry(p, struct rfcomm_dlc, list);
1992
1993 if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) &&
1994 !(conn->link_mode & HCI_LM_ENCRYPT) && !status)
1995 continue;
1996
1997 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
1998 continue;
1999
2000 if (!status)
2001 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2002 else
2003 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
2004 }
2005
2006 rfcomm_session_put(s);
2007
2008 rfcomm_schedule(RFCOMM_SCHED_AUTH);
2009}
2010
2011static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2012{ 1980{
2013 struct rfcomm_session *s; 1981 struct rfcomm_session *s;
2014 struct rfcomm_dlc *d; 1982 struct rfcomm_dlc *d;
@@ -2025,10 +1993,10 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2025 list_for_each_safe(p, n, &s->dlcs) { 1993 list_for_each_safe(p, n, &s->dlcs) {
2026 d = list_entry(p, struct rfcomm_dlc, list); 1994 d = list_entry(p, struct rfcomm_dlc, list);
2027 1995
2028 if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && 1996 if (!status && encrypt == 0x00 &&
1997 (d->link_mode & RFCOMM_LM_ENCRYPT) &&
2029 (d->state == BT_CONNECTED || 1998 (d->state == BT_CONNECTED ||
2030 d->state == BT_CONFIG) && 1999 d->state == BT_CONFIG)) {
2031 !status && encrypt == 0x00) {
2032 __rfcomm_dlc_close(d, ECONNREFUSED); 2000 __rfcomm_dlc_close(d, ECONNREFUSED);
2033 continue; 2001 continue;
2034 } 2002 }
@@ -2036,7 +2004,7 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2036 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) 2004 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2037 continue; 2005 continue;
2038 2006
2039 if (!status && encrypt) 2007 if (!status)
2040 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags); 2008 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2041 else 2009 else
2042 set_bit(RFCOMM_AUTH_REJECT, &d->flags); 2010 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
@@ -2049,8 +2017,7 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2049 2017
2050static struct hci_cb rfcomm_cb = { 2018static struct hci_cb rfcomm_cb = {
2051 .name = "RFCOMM", 2019 .name = "RFCOMM",
2052 .auth_cfm = rfcomm_auth_cfm, 2020 .security_cfm = rfcomm_security_cfm
2053 .encrypt_cfm = rfcomm_encrypt_cfm
2054}; 2021};
2055 2022
2056static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) 2023static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)