diff options
author | Andrzej Kaczmarek <andrzej.kaczmarek@tieto.com> | 2011-01-17 15:46:48 +0100 |
---|---|---|
committer | Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | 2011-01-24 10:53:13 +0100 |
commit | 00a7a4be41014b2bfb92b2083dd0cc392a6e2d8d (patch) | |
tree | 72f692e80afd55390b31d17823d523010ed1321c /net | |
parent | b743fcd7d4e315136abd89ab631c72ede9b5eab2 (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.c | 15 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 20 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 6 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 8 |
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; |