aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorAndrzej Kaczmarek <andrzej.kaczmarek@tieto.com>2011-01-17 15:46:48 +0100
committerSrinidhi KASAGAR <srinidhi.kasagar@stericsson.com>2011-01-24 10:53:13 +0100
commit00a7a4be41014b2bfb92b2083dd0cc392a6e2d8d (patch)
tree72f692e80afd55390b31d17823d523010ed1321c /net
parentb743fcd7d4e315136abd89ab631c72ede9b5eab2 (diff)
bluetooth: New security level for SAP connections
New security level is added which enforces proper security settings for SAP connection and allows already existing security levels to be unchanged. ST-Ericsson Linux next: Not tested, 319114 ST-Ericsson ID: 319114 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Ide1d8d9145fd9c335bfbdd744c801551aa2edef5 Signed-off-by: Andrzej Kaczmarek <andrzej.kaczmarek@tieto.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/12650 Reviewed-by: Par-Gunnar HJALMDAHL <par-gunnar.p.hjalmdahl@stericsson.com>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_conn.c15
-rw-r--r--net/bluetooth/l2cap.c20
-rw-r--r--net/bluetooth/rfcomm/core.c6
-rw-r--r--net/bluetooth/rfcomm/sock.c8
4 files changed, 33 insertions, 16 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 66bd1b3377b..9a2b003e2bb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -500,18 +500,15 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
goto do_encrypt;
/* An unauthenticated combination key has sufficient security for
- security level 1 and 2. */
+ any security level other than max (for SAP) */
if (conn->key_type == HCI_LK_UNAUTHENTICATED_COMBINATION
- && (sec_level == BT_SECURITY_MEDIUM
- || sec_level == BT_SECURITY_LOW))
+ && sec_level != BT_SECURITY_MAX)
goto do_encrypt;
- /* A combination key has always sufficient security for the security
- levels 1 or 2. High security level requires that the combination key
- was generated using the maximum PIN code length (16).
- For pre 2.1 units. */
- if ((conn->key_type == HCI_LK_COMBINATION))
- if ((sec_level != BT_SECURITY_HIGH) || (conn->pin_len >= 16))
+ /* For max security, combination key should be generated using
+ 16 digits pincode. For pre-2.1 devices. */
+ if (conn->key_type == HCI_LK_COMBINATION)
+ if (sec_level != BT_SECURITY_MAX || conn->pin_len >= 16)
goto do_encrypt;
do_auth:
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 443460012d0..7dd3461257f 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -289,7 +289,8 @@ static inline int l2cap_check_security(struct sock *sk)
__u8 auth_type;
if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
- if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+ if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH
+ || l2cap_pi(sk)->sec_level == BT_SECURITY_MAX)
auth_type = HCI_AT_NO_BONDING_MITM;
else
auth_type = HCI_AT_NO_BONDING;
@@ -299,6 +300,7 @@ static inline int l2cap_check_security(struct sock *sk)
} else {
switch (l2cap_pi(sk)->sec_level) {
case BT_SECURITY_HIGH:
+ case BT_SECURITY_MAX:
auth_type = HCI_AT_GENERAL_BONDING_MITM;
break;
case BT_SECURITY_MEDIUM:
@@ -986,6 +988,7 @@ static int l2cap_do_connect(struct sock *sk)
if (sk->sk_type == SOCK_RAW) {
switch (l2cap_pi(sk)->sec_level) {
case BT_SECURITY_HIGH:
+ case BT_SECURITY_MAX:
auth_type = HCI_AT_DEDICATED_BONDING_MITM;
break;
case BT_SECURITY_MEDIUM:
@@ -996,7 +999,8 @@ static int l2cap_do_connect(struct sock *sk)
break;
}
} else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
- if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+ if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH
+ || l2cap_pi(sk)->sec_level == BT_SECURITY_MAX)
auth_type = HCI_AT_NO_BONDING_MITM;
else
auth_type = HCI_AT_NO_BONDING;
@@ -1006,6 +1010,7 @@ static int l2cap_do_connect(struct sock *sk)
} else {
switch (l2cap_pi(sk)->sec_level) {
case BT_SECURITY_HIGH:
+ case BT_SECURITY_MAX:
auth_type = HCI_AT_GENERAL_BONDING_MITM;
break;
case BT_SECURITY_MEDIUM:
@@ -1929,6 +1934,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
if (opt & L2CAP_LM_SECURE)
l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
+ if (opt & L2CAP_LM_SECUREMAX)
+ l2cap_pi(sk)->sec_level = BT_SECURITY_MAX;
l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
@@ -1978,7 +1985,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}
if (sec.level < BT_SECURITY_LOW ||
- sec.level > BT_SECURITY_HIGH) {
+ sec.level > BT_SECURITY_MAX) {
err = -EINVAL;
break;
}
@@ -2052,6 +2059,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
L2CAP_LM_SECURE;
break;
+ case BT_SECURITY_MAX:
+ opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
+ L2CAP_LM_SECURE | L2CAP_LM_SECUREMAX;
+ break;
default:
opt = 0;
break;
@@ -4432,7 +4443,8 @@ static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
l2cap_sock_clear_timer(sk);
l2cap_sock_set_timer(sk, HZ * 5);
- } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+ } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH
+ || l2cap_pi(sk)->sec_level == BT_SECURITY_MAX)
__l2cap_sock_close(sk, ECONNREFUSED);
} else {
if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index d32e595576f..665ce1421e5 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -234,6 +234,7 @@ static inline int rfcomm_check_security(struct rfcomm_dlc *d)
switch (d->sec_level) {
case BT_SECURITY_HIGH:
+ case BT_SECURITY_MAX:
auth_type = HCI_AT_GENERAL_BONDING_MITM;
break;
case BT_SECURITY_MEDIUM:
@@ -2034,7 +2035,8 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
set_bit(RFCOMM_SEC_PENDING, &d->flags);
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
continue;
- } else if (d->sec_level == BT_SECURITY_HIGH) {
+ } else if (d->sec_level == BT_SECURITY_HIGH
+ || d->sec_level == BT_SECURITY_MAX) {
__rfcomm_dlc_close(d, ECONNREFUSED);
continue;
}
@@ -2044,7 +2046,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
continue;
if (!status)
- if (d->sec_level != BT_SECURITY_HIGH)
+ if (d->sec_level != BT_SECURITY_MAX)
set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
else
if ((conn->key_type == HCI_LK_AUTHENTICATED_COMBINATION)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 43fbf6b4b4b..17e2764a6e6 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -757,6 +757,8 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
rfcomm_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
if (opt & RFCOMM_LM_SECURE)
rfcomm_pi(sk)->sec_level = BT_SECURITY_HIGH;
+ if (opt & RFCOMM_LM_SECUREMAX)
+ rfcomm_pi(sk)->sec_level = BT_SECURITY_MAX;
rfcomm_pi(sk)->role_switch = (opt & RFCOMM_LM_MASTER);
break;
@@ -802,7 +804,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
break;
}
- if (sec.level > BT_SECURITY_HIGH) {
+ if (sec.level > BT_SECURITY_MAX) {
err = -EINVAL;
break;
}
@@ -861,6 +863,10 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
RFCOMM_LM_SECURE;
break;
+ case BT_SECURITY_MAX:
+ opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
+ RFCOMM_LM_SECURE | RFCOMM_LM_SECUREMAX;
+ break;
default:
opt = 0;
break;