diff options
author | David S. Miller <davem@davemloft.net> | 2014-03-26 03:25:39 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-26 03:25:39 +0400 |
commit | 0fc31966035d7a540c011b6c967ce8eae1db121b (patch) | |
tree | 83f328a064cb123a10f5977c69ec3e28396970bc /net/bluetooth | |
parent | 2c5f4f8422e8cf3dd15638226e964f2e13132267 (diff) | |
parent | 49c0ca17ee8dd3530f688052d4eb2ae6d3e55119 (diff) | |
download | linux-0fc31966035d7a540c011b6c967ce8eae1db121b.tar.xz |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says:
====================
Please pull this batch of wireless updates intended for 3.15!
For the mac80211 bits, Johannes says:
"This has a whole bunch of bugfixes for things that went into -next
previously as well as some other bugfixes I didn't want to rush into
3.14 at this point. The rest of it is some cleanups and a few small
features, the biggest of which is probably Janusz's regulatory DFS CAC
time code."
For the Bluetooth bits, Gustavo says:
"One more pull request to 3.15. This is mostly and bug fix pull request, it
contains several fixes and clean up all over the tree, plus some small new
features."
For the NFC bits, Samuel says:
"This is the NFC pull request for 3.15. With this one we have:
- Support for ISO 15693 a.k.a. NFC vicinity a.k.a. Type 5 tags. ISO
15693 are long range (1 - 2 meters) vicinity tags/cards. The kernel
now supports those through the NFC netlink and digital APIs.
- Support for TI's trf7970a chipset. This chipset relies on the NFC
digital layer and the driver currently supports type 2, 4A and 5 tags.
- Support for NXP's pn544 secure firmare download. The pn544 C3 chipsets
relies on a different firmware download protocal than the C2 one. We
now support both and use the right one depending on the version we
detect at runtime.
- Support for 4A tags from the NFC digital layer.
- A bunch of cleanups and minor fixes from Axel Lin and Thierry Escande."
For the iwlwifi bits, Emmanuel says:
"We were sending a host command while the mutex wasn't held. This
led to hard-to-catch races."
And...
"I have a fix for a "merge damage" which is not really a merge
damage: it enables scheduled scan which has been disabled in
wireless.git. Since you merged wireless.git into wireless-next.git,
this can now be fixed in wireless-next.git.
Besides this, Alex made a workaround for a hardware bug. This fix
allows us to consume less power in S3. Arik and Eliad continue to
work on D0i3 which is a run-time power saving feature. Eliad also
contributes a few bits to the rate scaling logic to which Eyal adds his
own contribution. Avri dives deep in the power code - newer firmware
will allow to enable power save in newer scenarios. Johannes made a few
clean-ups. I have the regular amount of BT Coex boring stuff. I disable
uAPSD since we identified firmware bugs that cause packet loss. One
thing that do stand out is the udev event that we now send when the
FW asserts. I hope it will allow us to debug the FW more easily."
Also included is one last iwlwifi pull for a build breakage fix...
For the Atheros bits, Kalle says:
"Michal now did some optimisations and was able to improve throughput by
100 Mbps on our MIPS based AP135 platform. Chun-Yeow added some
workarounds to be able to better use ad-hoc mode. Ben improved log
messages and added support for MSDU chaining. And, as usual, also some
smaller fixes."
Beyond that...
Andrea Merello continues his rtl8180 refactoring, in preparation for
a long-awaited rtl8187 driver. We get a new driver (rsi) for the
RS9113 chip, from Fariya Fatima. And, of course, we get the usual
round of updates for ath9k, brcmfmac, mwifiex, wil6210, etc. as well.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/6lowpan.h | 21 | ||||
-rw-r--r-- | net/bluetooth/Kconfig | 8 | ||||
-rw-r--r-- | net/bluetooth/Makefile | 3 | ||||
-rw-r--r-- | net/bluetooth/a2mp.c | 12 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 37 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 14 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 27 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 16 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 90 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 6 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 83 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 4 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 10 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 208 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 4 |
15 files changed, 360 insertions, 183 deletions
diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h index 680eac808d74..5d281f1eaf55 100644 --- a/net/bluetooth/6lowpan.h +++ b/net/bluetooth/6lowpan.h @@ -14,13 +14,34 @@ #ifndef __6LOWPAN_H #define __6LOWPAN_H +#include <linux/errno.h> #include <linux/skbuff.h> #include <net/bluetooth/l2cap.h> +#if IS_ENABLED(CONFIG_BT_6LOWPAN) int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb); int bt_6lowpan_add_conn(struct l2cap_conn *conn); int bt_6lowpan_del_conn(struct l2cap_conn *conn); int bt_6lowpan_init(void); void bt_6lowpan_cleanup(void); +#else +static int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb) +{ + return -EOPNOTSUPP; +} +static int bt_6lowpan_add_conn(struct l2cap_conn *conn) +{ + return -EOPNOTSUPP; +} +int bt_6lowpan_del_conn(struct l2cap_conn *conn) +{ + return -EOPNOTSUPP; +} +static int bt_6lowpan_init(void) +{ + return -EOPNOTSUPP; +} +static void bt_6lowpan_cleanup(void) { } +#endif #endif /* __6LOWPAN_H */ diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 985b56070d26..06ec14499ca1 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -6,13 +6,13 @@ menuconfig BT tristate "Bluetooth subsystem support" depends on NET && !S390 depends on RFKILL || !RFKILL + select 6LOWPAN_IPHC if BT_6LOWPAN select CRC16 select CRYPTO select CRYPTO_BLKCIPHER select CRYPTO_AES select CRYPTO_ECB select CRYPTO_SHA256 - select 6LOWPAN_IPHC help Bluetooth is low-cost, low-power, short-range wireless technology. It was designed as a replacement for cables and other short-range @@ -40,6 +40,12 @@ menuconfig BT to Bluetooth kernel modules are provided in the BlueZ packages. For more information, see <http://www.bluez.org/>. +config BT_6LOWPAN + bool "Bluetooth 6LoWPAN support" + depends on BT && IPV6 + help + IPv6 compression over Bluetooth. + source "net/bluetooth/rfcomm/Kconfig" source "net/bluetooth/bnep/Kconfig" diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 80cb215826e8..ca51246b1016 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_BT_HIDP) += hidp/ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ - a2mp.o amp.o 6lowpan.o + a2mp.o amp.o +bluetooth-$(CONFIG_BT_6LOWPAN) += 6lowpan.o subdir-ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index f986b9968bdb..9514cc9e850c 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -162,7 +162,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, return -ENOMEM; } - rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); + rsp->mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); rsp->ext_feat = 0; __a2mp_add_cl(mgr, rsp->cl); @@ -649,7 +649,7 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) if (err) { struct a2mp_cmd_rej rej; - rej.reason = __constant_cpu_to_le16(0); + rej.reason = cpu_to_le16(0); hdr = (void *) skb->data; BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err); @@ -695,7 +695,13 @@ static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, unsigned long len, int nb) { - return bt_skb_alloc(len, GFP_KERNEL); + struct sk_buff *skb; + + skb = bt_skb_alloc(len, GFP_KERNEL); + if (!skb) + return ERR_PTR(-ENOMEM); + + return skb; } static struct l2cap_ops a2mp_chan_ops = { diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 7c713c4675ba..d958e2dca52f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -82,7 +82,7 @@ static void hci_acl_create_connection(struct hci_conn *conn) cp.pscan_rep_mode = ie->data.pscan_rep_mode; cp.pscan_mode = ie->data.pscan_mode; cp.clock_offset = ie->data.clock_offset | - __constant_cpu_to_le16(0x8000); + cpu_to_le16(0x8000); } memcpy(conn->dev_class, ie->data.dev_class, 3); @@ -182,8 +182,8 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle) cp.handle = cpu_to_le16(handle); - cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); - cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); cp.voice_setting = cpu_to_le16(conn->setting); switch (conn->setting & SCO_AIRMODE_MASK) { @@ -225,8 +225,8 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, cp.conn_interval_max = cpu_to_le16(max); cp.conn_latency = cpu_to_le16(latency); cp.supervision_timeout = cpu_to_le16(to_multiplier); - cp.min_ce_len = __constant_cpu_to_le16(0x0000); - cp.max_ce_len = __constant_cpu_to_le16(0x0000); + cp.min_ce_len = cpu_to_le16(0x0000); + cp.max_ce_len = cpu_to_le16(0x0000); hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); } @@ -337,9 +337,9 @@ static void hci_conn_idle(struct work_struct *work) if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { struct hci_cp_sniff_subrate cp; cp.handle = cpu_to_le16(conn->handle); - cp.max_latency = __constant_cpu_to_le16(0); - cp.min_remote_timeout = __constant_cpu_to_le16(0); - cp.min_local_timeout = __constant_cpu_to_le16(0); + cp.max_latency = cpu_to_le16(0); + cp.min_remote_timeout = cpu_to_le16(0); + cp.min_local_timeout = cpu_to_le16(0); hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); } @@ -348,8 +348,8 @@ static void hci_conn_idle(struct work_struct *work) cp.handle = cpu_to_le16(conn->handle); cp.max_interval = cpu_to_le16(hdev->sniff_max_interval); cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); - cp.attempt = __constant_cpu_to_le16(4); - cp.timeout = __constant_cpu_to_le16(1); + cp.attempt = cpu_to_le16(4); + cp.timeout = cpu_to_le16(1); hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); } } @@ -596,9 +596,9 @@ static void hci_req_add_le_create_conn(struct hci_request *req, cp.own_address_type = own_addr_type; cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval); cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval); - cp.supervision_timeout = __constant_cpu_to_le16(0x002a); - cp.min_ce_len = __constant_cpu_to_le16(0x0000); - cp.max_ce_len = __constant_cpu_to_le16(0x0000); + cp.supervision_timeout = cpu_to_le16(0x002a); + cp.min_ce_len = cpu_to_le16(0x0000); + cp.max_ce_len = cpu_to_le16(0x0000); hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); @@ -781,6 +781,17 @@ int hci_conn_check_link_mode(struct hci_conn *conn) { BT_DBG("hcon %p", conn); + /* In Secure Connections Only mode, it is required that Secure + * Connections is used and the link is encrypted with AES-CCM + * using a P-256 authenticated combination key. + */ + if (test_bit(HCI_SC_ONLY, &conn->hdev->flags)) { + if (!hci_conn_sc_enabled(conn) || + !test_bit(HCI_CONN_AES_CCM, &conn->flags) || + conn->key_type != HCI_LK_AUTH_COMBINATION_P256) + return 0; + } + if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) return 0; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8bbfdea9cbec..1c6ffaa8902f 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1349,7 +1349,7 @@ static void bredr_setup(struct hci_request *req) hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); /* Connection accept timeout ~20 secs */ - param = __constant_cpu_to_le16(0x7d00); + param = cpu_to_le16(0x7d00); hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, @@ -5270,7 +5270,7 @@ void hci_req_add_le_passive_scan(struct hci_request *req) memset(&enable_cp, 0, sizeof(enable_cp)); enable_cp.enable = LE_SCAN_ENABLE; - enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE; + enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), &enable_cp); } @@ -5313,10 +5313,6 @@ void hci_update_background_scan(struct hci_dev *hdev) * keep the background scan running. */ - /* If controller is already scanning we are done. */ - if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) - return; - /* If controller is connecting, we should not start scanning * since some controllers are not able to scan and connect at * the same time. @@ -5325,6 +5321,12 @@ void hci_update_background_scan(struct hci_dev *hdev) if (conn) return; + /* If controller is currently scanning, we stop it to ensure we + * don't miss any advertising (due to duplicates filter). + */ + if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) + hci_req_add_le_scan_disable(&req); + hci_req_add_le_passive_scan(&req); BT_DBG("%s starting background scanning", hdev->name); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c3b0a08f5ab4..a6a3d32553c5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1924,9 +1924,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) bacpy(&cp.bdaddr, &ev->bdaddr); cp.pkt_type = cpu_to_le16(conn->pkt_type); - cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); - cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); - cp.max_latency = __constant_cpu_to_le16(0xffff); + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + cp.max_latency = cpu_to_le16(0xffff); cp.content_format = cpu_to_le16(hdev->voice_setting); cp.retrans_effort = 0xff; @@ -2183,6 +2183,18 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) if (!ev->status) conn->state = BT_CONNECTED; + /* In Secure Connections Only mode, do not allow any + * connections that are not encrypted with AES-CCM + * using a P-256 authenticated combination key. + */ + if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) && + (!test_bit(HCI_CONN_AES_CCM, &conn->flags) || + conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) { + hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE); + hci_conn_drop(conn); + goto unlock; + } + hci_proto_connect_cfm(conn, ev->status); hci_conn_drop(conn); } else @@ -3157,6 +3169,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, case 0x1c: /* SCO interval rejected */ case 0x1a: /* Unsupported Remote Feature */ case 0x1f: /* Unspecified error */ + case 0x20: /* Unsupported LMP Parameter value */ if (conn->out) { conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | (hdev->esco_type & EDR_ESCO_MASK); @@ -3961,7 +3974,13 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); - if (ltk->type & HCI_SMP_STK) { + /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a + * temporary key used to encrypt a connection following + * pairing. It is used during the Encrypted Session Setup to + * distribute the keys. Later, security can be re-established + * using a distributed LTK. + */ + if (ltk->type == HCI_SMP_STK_SLAVE) { list_del(<k->list); kfree(ltk); } diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 68e51a84e72d..b9a418e578e0 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -211,22 +211,22 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: - opcode = __constant_cpu_to_le16(HCI_MON_COMMAND_PKT); + opcode = cpu_to_le16(HCI_MON_COMMAND_PKT); break; case HCI_EVENT_PKT: - opcode = __constant_cpu_to_le16(HCI_MON_EVENT_PKT); + opcode = cpu_to_le16(HCI_MON_EVENT_PKT); break; case HCI_ACLDATA_PKT: if (bt_cb(skb)->incoming) - opcode = __constant_cpu_to_le16(HCI_MON_ACL_RX_PKT); + opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT); else - opcode = __constant_cpu_to_le16(HCI_MON_ACL_TX_PKT); + opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT); break; case HCI_SCODATA_PKT: if (bt_cb(skb)->incoming) - opcode = __constant_cpu_to_le16(HCI_MON_SCO_RX_PKT); + opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT); else - opcode = __constant_cpu_to_le16(HCI_MON_SCO_TX_PKT); + opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT); break; default: return; @@ -319,7 +319,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) bacpy(&ni->bdaddr, &hdev->bdaddr); memcpy(ni->name, hdev->name, 8); - opcode = __constant_cpu_to_le16(HCI_MON_NEW_INDEX); + opcode = cpu_to_le16(HCI_MON_NEW_INDEX); break; case HCI_DEV_UNREG: @@ -327,7 +327,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) if (!skb) return NULL; - opcode = __constant_cpu_to_le16(HCI_MON_DEL_INDEX); + opcode = cpu_to_le16(HCI_MON_DEL_INDEX); break; default: diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9ed2168fa59f..a1e5bb7d06e8 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -665,7 +665,7 @@ static void l2cap_chan_connect_reject(struct l2cap_chan *chan) rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); rsp.result = cpu_to_le16(result); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); } @@ -727,7 +727,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) } break; case L2CAP_CHAN_CONN_LESS: - if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) { + if (chan->psm == cpu_to_le16(L2CAP_PSM_3DSP)) { if (chan->sec_level == BT_SECURITY_LOW) chan->sec_level = BT_SECURITY_SDP; } @@ -738,7 +738,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) return HCI_AT_NO_BONDING; break; case L2CAP_CHAN_CONN_ORIENTED: - if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) { + if (chan->psm == cpu_to_le16(L2CAP_PSM_SDP)) { if (chan->sec_level == BT_SECURITY_LOW) chan->sec_level = BT_SECURITY_SDP; @@ -1273,7 +1273,7 @@ static void l2cap_do_start(struct l2cap_chan *chan) } } else { struct l2cap_info_req req; - req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); + req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; conn->info_ident = l2cap_get_ident(conn); @@ -1370,18 +1370,18 @@ static void l2cap_conn_start(struct l2cap_conn *conn) if (l2cap_chan_check_security(chan)) { if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { - rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); + rsp.result = cpu_to_le16(L2CAP_CR_PEND); + rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); chan->ops->defer(chan); } else { l2cap_state_change(chan, BT_CONFIG); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); } } else { - rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND); + rsp.result = cpu_to_le16(L2CAP_CR_PEND); + rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); } l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, @@ -2895,9 +2895,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); if (conn->hcon->type == LE_LINK) - lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING); + lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING); else - lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING); + lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); cmd->code = code; @@ -3010,8 +3010,8 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) efs.stype = chan->local_stype; efs.msdu = cpu_to_le16(chan->local_msdu); efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); - efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); - efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO); + efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); + efs.flush_to = cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO); break; case L2CAP_MODE_STREAMING: @@ -3152,8 +3152,8 @@ static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, rfc->retrans_timeout = cpu_to_le16((u16) ertm_to); rfc->monitor_timeout = rfc->retrans_timeout; } else { - rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); - rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); + rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); + rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); } } @@ -3285,7 +3285,7 @@ done: } req->dcid = cpu_to_le16(chan->dcid); - req->flags = __constant_cpu_to_le16(0); + req->flags = cpu_to_le16(0); return ptr - data; } @@ -3499,7 +3499,7 @@ done: } rsp->scid = cpu_to_le16(chan->dcid); rsp->result = cpu_to_le16(result); - rsp->flags = __constant_cpu_to_le16(0); + rsp->flags = cpu_to_le16(0); return ptr - data; } @@ -3608,7 +3608,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, } req->dcid = cpu_to_le16(chan->dcid); - req->flags = __constant_cpu_to_le16(0); + req->flags = cpu_to_le16(0); return ptr - data; } @@ -3639,7 +3639,7 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan) rsp.mtu = cpu_to_le16(chan->imtu); rsp.mps = cpu_to_le16(chan->mps); rsp.credits = cpu_to_le16(chan->rx_credits); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp); @@ -3654,8 +3654,8 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); if (chan->hs_hcon) rsp_code = L2CAP_CREATE_CHAN_RSP; @@ -3684,8 +3684,8 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) u16 txwin_ext = chan->ack_win; struct l2cap_conf_rfc rfc = { .mode = chan->mode, - .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO), - .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO), + .retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO), + .monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO), .max_pdu_size = cpu_to_le16(chan->imtu), .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW), }; @@ -3776,7 +3776,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, l2cap_chan_lock(pchan); /* Check if the ACL is secure enough (if not SDP) */ - if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && + if (psm != cpu_to_le16(L2CAP_PSM_SDP) && !hci_conn_check_link_mode(conn->hcon)) { conn->disc_reason = HCI_ERROR_AUTH_FAILURE; result = L2CAP_CR_SEC_BLOCK; @@ -3861,7 +3861,7 @@ sendresp: if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { struct l2cap_info_req info; - info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); + info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; conn->info_ident = l2cap_get_ident(conn); @@ -4010,7 +4010,7 @@ static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident, { struct l2cap_cmd_rej_cid rej; - rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); + rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID); rej.scid = __cpu_to_le16(scid); rej.dcid = __cpu_to_le16(dcid); @@ -4342,8 +4342,8 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, u8 buf[8]; u32 feat_mask = l2cap_feat_mask; struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; - rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); - rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); + rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); + rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); if (!disable_ertm) feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | L2CAP_FEAT_FCS; @@ -4363,15 +4363,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, else l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; - rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); - rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); + rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); + rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), buf); } else { struct l2cap_info_rsp rsp; rsp.type = cpu_to_le16(type); - rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP); + rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP); l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp); } @@ -4416,7 +4416,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) { struct l2cap_info_req req; - req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); + req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); conn->info_ident = l2cap_get_ident(conn); @@ -4510,8 +4510,8 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, error: rsp.dcid = 0; rsp.scid = cpu_to_le16(scid); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = cpu_to_le16(L2CAP_CR_BAD_AMP); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, sizeof(rsp), &rsp); @@ -4575,7 +4575,7 @@ static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) BT_DBG("conn %p, icid 0x%4.4x", conn, icid); cfm.icid = cpu_to_le16(icid); - cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED); + cfm.result = cpu_to_le16(L2CAP_MC_UNCONFIRMED); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm); @@ -4758,12 +4758,12 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result, if (result == L2CAP_CR_SUCCESS) { /* Send successful response */ - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); } else { /* Send negative response */ - rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = cpu_to_le16(L2CAP_CR_NO_MEM); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); } l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP, @@ -4891,7 +4891,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, chan = l2cap_get_chan_by_dcid(conn, icid); if (!chan) { rsp.icid = cpu_to_le16(icid); - rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED); + rsp.result = cpu_to_le16(L2CAP_MR_NOT_ALLOWED); l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp); return 0; @@ -5235,9 +5235,9 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, err = l2cap_check_conn_param(min, max, latency, to_multiplier); if (err) - rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); + rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); else - rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); + rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, sizeof(rsp), &rsp); @@ -5650,7 +5650,7 @@ static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, BT_ERR("Wrong link type (%d)", err); - rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); + rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); } @@ -5695,7 +5695,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, BT_ERR("Wrong link type (%d)", err); - rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); + rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); } diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index b247f9d27fed..33cd5615ff1e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -111,7 +111,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) if (bdaddr_type_is_le(la.l2_bdaddr_type)) { /* We only allow ATT user space socket */ if (la.l2_cid && - la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) + la.l2_cid != cpu_to_le16(L2CAP_CID_ATT)) return -EINVAL; } @@ -209,7 +209,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, * ATT. Anything else is an invalid combination. */ if (chan->scid != L2CAP_CID_ATT || - la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) + la.l2_cid != cpu_to_le16(L2CAP_CID_ATT)) return -EINVAL; /* We don't have the hdev available here to make a @@ -227,7 +227,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, if (bdaddr_type_is_le(la.l2_bdaddr_type)) { /* We only allow ATT user space socket */ if (la.l2_cid && - la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) + la.l2_cid != cpu_to_le16(L2CAP_CID_ATT)) return -EINVAL; } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 98e9df3556e7..96670f581bb0 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -108,6 +108,7 @@ static const u16 mgmt_events[] = { MGMT_EV_DEVICE_UNPAIRED, MGMT_EV_PASSKEY_NOTIFY, MGMT_EV_NEW_IRK, + MGMT_EV_NEW_CSRK, }; #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) @@ -212,7 +213,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) hdr = (void *) skb_put(skb, sizeof(*hdr)); - hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_STATUS); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); hdr->index = cpu_to_le16(index); hdr->len = cpu_to_le16(sizeof(*ev)); @@ -243,7 +244,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, hdr = (void *) skb_put(skb, sizeof(*hdr)); - hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_COMPLETE); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); hdr->index = cpu_to_le16(index); hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); @@ -269,7 +270,7 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("sock %p", sk); rp.version = MGMT_VERSION; - rp.revision = __constant_cpu_to_le16(MGMT_REVISION); + rp.revision = cpu_to_le16(MGMT_REVISION); return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp, sizeof(rp)); @@ -293,8 +294,8 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, if (!rp) return -ENOMEM; - rp->num_commands = __constant_cpu_to_le16(num_commands); - rp->num_events = __constant_cpu_to_le16(num_events); + rp->num_commands = cpu_to_le16(num_commands); + rp->num_events = cpu_to_le16(num_events); for (i = 0, opcode = rp->opcodes; i < num_commands; i++, opcode++) put_unaligned_le16(mgmt_commands[i], opcode); @@ -857,8 +858,8 @@ static void enable_advertising(struct hci_request *req) return; memset(&cp, 0, sizeof(cp)); - cp.min_interval = __constant_cpu_to_le16(0x0800); - cp.max_interval = __constant_cpu_to_le16(0x0800); + cp.min_interval = cpu_to_le16(0x0800); + cp.max_interval = cpu_to_le16(0x0800); cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND; cp.own_address_type = own_addr_type; cp.channel_map = hdev->le_adv_channel_map; @@ -1180,7 +1181,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, if (hdev) hdr->index = cpu_to_le16(hdev->id); else - hdr->index = __constant_cpu_to_le16(MGMT_INDEX_NONE); + hdr->index = cpu_to_le16(MGMT_INDEX_NONE); hdr->len = cpu_to_le16(data_len); if (data) @@ -1492,15 +1493,15 @@ static void write_fast_connectable(struct hci_request *req, bool enable) type = PAGE_SCAN_TYPE_INTERLACED; /* 160 msec page scan interval */ - acp.interval = __constant_cpu_to_le16(0x0100); + acp.interval = cpu_to_le16(0x0100); } else { type = PAGE_SCAN_TYPE_STANDARD; /* default */ /* default 1.28 sec page scan */ - acp.interval = __constant_cpu_to_le16(0x0800); + acp.interval = cpu_to_le16(0x0800); } - acp.window = __constant_cpu_to_le16(0x0012); + acp.window = cpu_to_le16(0x0012); if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval || __cpu_to_le16(hdev->page_scan_window) != acp.window) @@ -2351,7 +2352,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, sizeof(struct mgmt_link_key_info); if (expected_len != len) { BT_ERR("load_link_keys: expected %u bytes, got %u bytes", - len, expected_len); + expected_len, len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, MGMT_STATUS_INVALID_PARAMS); } @@ -2761,11 +2762,23 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn) static void pairing_complete(struct pending_cmd *cmd, u8 status) { + const struct mgmt_cp_pair_device *cp = cmd->param; struct mgmt_rp_pair_device rp; struct hci_conn *conn = cmd->user_data; - bacpy(&rp.addr.bdaddr, &conn->dst); - rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); + /* If we had a pairing failure we might have already received + * the remote Identity Address Information and updated the + * hci_conn variables with it, however we would not yet have + * notified user space of the resolved identity. Therefore, use + * the address given in the Pair Device command in case the + * pairing failed. + */ + if (status) { + memcpy(&rp.addr, &cp->addr, sizeof(rp.addr)); + } else { + bacpy(&rp.addr.bdaddr, &conn->dst); + rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); + } cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, &rp, sizeof(rp)); @@ -4427,7 +4440,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info); if (expected_len != len) { BT_ERR("load_irks: expected %u bytes, got %u bytes", - len, expected_len); + expected_len, len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, MGMT_STATUS_INVALID_PARAMS); } @@ -4507,7 +4520,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, sizeof(struct mgmt_ltk_info); if (expected_len != len) { BT_ERR("load_keys: expected %u bytes, got %u bytes", - len, expected_len); + expected_len, len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, MGMT_STATUS_INVALID_PARAMS); } @@ -5004,7 +5017,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); } -void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key) +void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) { struct mgmt_ev_new_long_term_key ev; @@ -5025,7 +5038,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key) (key->bdaddr.b[5] & 0xc0) != 0xc0) ev.store_hint = 0x00; else - ev.store_hint = 0x01; + ev.store_hint = persistent; bacpy(&ev.key.addr.bdaddr, &key->bdaddr); ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); @@ -5072,6 +5085,36 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk) mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); } +void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, + bool persistent) +{ + struct mgmt_ev_new_csrk ev; + + memset(&ev, 0, sizeof(ev)); + + /* Devices using resolvable or non-resolvable random addresses + * without providing an indentity resolving key don't require + * to store signature resolving keys. Their addresses will change + * the next time around. + * + * Only when a remote device provides an identity address + * make sure the signature resolving key is stored. So allow + * static random and public addresses here. + */ + if (csrk->bdaddr_type == ADDR_LE_DEV_RANDOM && + (csrk->bdaddr.b[5] & 0xc0) != 0xc0) + ev.store_hint = 0x00; + else + ev.store_hint = persistent; + + bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr); + ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type); + ev.key.master = csrk->master; + memcpy(ev.key.val, csrk->val, sizeof(csrk->val)); + + mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL); +} + static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, u8 data_len) { @@ -5665,9 +5708,9 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->rssi = rssi; if (cfm_name) - ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); if (!ssp) - ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); if (eir_len > 0) memcpy(ev->eir, eir, eir_len); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 21e15318937c..633cceeb943e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -768,7 +768,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bacpy(&addr.l2_bdaddr, dst); addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); + addr.l2_psm = cpu_to_le16(RFCOMM_PSM); addr.l2_cid = 0; addr.l2_bdaddr_type = BDADDR_BREDR; *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); @@ -2032,7 +2032,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) /* Bind socket */ bacpy(&addr.l2_bdaddr, ba); addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); + addr.l2_psm = cpu_to_le16(RFCOMM_PSM); addr.l2_cid = 0; addr.l2_bdaddr_type = BDADDR_BREDR; err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 24fa3964b3c8..ab1e6fcca4c5 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -676,20 +676,20 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) bacpy(&cp.bdaddr, &conn->dst); cp.pkt_type = cpu_to_le16(conn->pkt_type); - cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); - cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); cp.content_format = cpu_to_le16(setting); switch (setting & SCO_AIRMODE_MASK) { case SCO_AIRMODE_TRANSP: if (conn->pkt_type & ESCO_2EV3) - cp.max_latency = __constant_cpu_to_le16(0x0008); + cp.max_latency = cpu_to_le16(0x0008); else - cp.max_latency = __constant_cpu_to_le16(0x000D); + cp.max_latency = cpu_to_le16(0x000D); cp.retrans_effort = 0x02; break; case SCO_AIRMODE_CVSD: - cp.max_latency = __constant_cpu_to_le16(0xffff); + cp.max_latency = cpu_to_le16(0xffff); cp.retrans_effort = 0xff; break; } diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index f886bcae1b7e..2a7ee7f6cd8b 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -35,14 +35,14 @@ #define AUTH_REQ_MASK 0x07 -static inline void swap128(u8 src[16], u8 dst[16]) +static inline void swap128(const u8 src[16], u8 dst[16]) { int i; for (i = 0; i < 16; i++) dst[15 - i] = src[i]; } -static inline void swap56(u8 src[7], u8 dst[7]) +static inline void swap56(const u8 src[7], u8 dst[7]) { int i; for (i = 0; i < 7; i++) @@ -53,6 +53,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) { struct blkcipher_desc desc; struct scatterlist sg; + uint8_t tmp[16], data[16]; int err; if (tfm == NULL) { @@ -63,34 +64,40 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) desc.tfm = tfm; desc.flags = 0; - err = crypto_blkcipher_setkey(tfm, k, 16); + /* The most significant octet of key corresponds to k[0] */ + swap128(k, tmp); + + err = crypto_blkcipher_setkey(tfm, tmp, 16); if (err) { BT_ERR("cipher setkey failed: %d", err); return err; } - sg_init_one(&sg, r, 16); + /* Most significant octet of plaintextData corresponds to data[0] */ + swap128(r, data); + + sg_init_one(&sg, data, 16); err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); if (err) BT_ERR("Encrypt data error %d", err); + /* Most significant octet of encryptedData corresponds to data[0] */ + swap128(data, r); + return err; } static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) { - u8 _res[16], k[16]; + u8 _res[16]; int err; /* r' = padding || r */ - memset(_res, 0, 13); - _res[13] = r[2]; - _res[14] = r[1]; - _res[15] = r[0]; + memcpy(_res, r, 3); + memset(_res + 3, 0, 13); - swap128(irk, k); - err = smp_e(tfm, k, _res); + err = smp_e(tfm, irk, _res); if (err) { BT_ERR("Encrypt error"); return err; @@ -102,9 +109,7 @@ static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) * by taking the least significant 24 bits of the output of e as the * result of ah. */ - res[0] = _res[15]; - res[1] = _res[14]; - res[2] = _res[13]; + memcpy(res, _res, 3); return 0; } @@ -152,16 +157,15 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], memset(p1, 0, 16); /* p1 = pres || preq || _rat || _iat */ - swap56(pres, p1); - swap56(preq, p1 + 7); - p1[14] = _rat; - p1[15] = _iat; - - memset(p2, 0, 16); + p1[0] = _iat; + p1[1] = _rat; + memcpy(p1 + 2, preq, 7); + memcpy(p1 + 9, pres, 7); /* p2 = padding || ia || ra */ - baswap((bdaddr_t *) (p2 + 4), ia); - baswap((bdaddr_t *) (p2 + 10), ra); + memcpy(p2, ra, 6); + memcpy(p2 + 6, ia, 6); + memset(p2 + 12, 0, 4); /* res = r XOR p1 */ u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); @@ -190,8 +194,8 @@ static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16], int err; /* Just least significant octets from r1 and r2 are considered */ - memcpy(_r, r1 + 8, 8); - memcpy(_r + 8, r2 + 8, 8); + memcpy(_r, r2, 8); + memcpy(_r + 8, r1, 8); err = smp_e(tfm, k, _r); if (err) @@ -218,7 +222,7 @@ static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); lh->len = cpu_to_le16(sizeof(code) + dlen); - lh->cid = __constant_cpu_to_le16(L2CAP_CID_SMP); + lh->cid = cpu_to_le16(L2CAP_CID_SMP); memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); @@ -273,8 +277,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn, u8 local_dist = 0, remote_dist = 0; if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) { - local_dist = SMP_DIST_ENC_KEY; - remote_dist = SMP_DIST_ENC_KEY; + local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; + remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; authreq |= SMP_AUTH_BONDING; } else { authreq &= ~SMP_AUTH_BONDING; @@ -403,16 +407,14 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, method = REQ_PASSKEY; } - /* Generate random passkey. Not valid until confirmed. */ + /* Generate random passkey. */ if (method == CFM_PASSKEY) { - u8 key[16]; - - memset(key, 0, sizeof(key)); + memset(smp->tk, 0, sizeof(smp->tk)); get_random_bytes(&passkey, sizeof(passkey)); passkey %= 1000000; - put_unaligned_le32(passkey, key); - swap128(key, smp->tk); + put_unaligned_le32(passkey, smp->tk); BT_DBG("PassKey: %d", passkey); + set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); } hci_dev_lock(hcon->hdev); @@ -421,7 +423,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type); else - ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, + ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, cpu_to_le32(passkey), 0); @@ -438,7 +440,7 @@ static void confirm_work(struct work_struct *work) struct crypto_blkcipher *tfm = hdev->tfm_aes; struct smp_cmd_pairing_confirm cp; int ret; - u8 res[16], reason; + u8 reason; BT_DBG("conn %p", conn); @@ -447,7 +449,8 @@ static void confirm_work(struct work_struct *work) ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, conn->hcon->init_addr_type, &conn->hcon->init_addr, - conn->hcon->resp_addr_type, &conn->hcon->resp_addr, res); + conn->hcon->resp_addr_type, &conn->hcon->resp_addr, + cp.confirm_val); hci_dev_unlock(hdev); @@ -458,7 +461,6 @@ static void confirm_work(struct work_struct *work) clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); - swap128(res, cp.confirm_val); smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); return; @@ -474,7 +476,7 @@ static void random_work(struct work_struct *work) struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; struct crypto_blkcipher *tfm = hdev->tfm_aes; - u8 reason, confirm[16], res[16], key[16]; + u8 reason, confirm[16]; int ret; if (IS_ERR_OR_NULL(tfm)) { @@ -489,7 +491,7 @@ static void random_work(struct work_struct *work) ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, hcon->init_addr_type, &hcon->init_addr, - hcon->resp_addr_type, &hcon->resp_addr, res); + hcon->resp_addr_type, &hcon->resp_addr, confirm); hci_dev_unlock(hdev); @@ -498,8 +500,6 @@ static void random_work(struct work_struct *work) goto error; } - swap128(res, confirm); - if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { BT_ERR("Pairing failed (confirmation values mismatch)"); reason = SMP_CONFIRM_FAILED; @@ -511,8 +511,7 @@ static void random_work(struct work_struct *work) __le64 rand = 0; __le16 ediv = 0; - smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key); - swap128(key, stk); + smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk); memset(stk + smp->enc_key_size, 0, SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); @@ -525,15 +524,14 @@ static void random_work(struct work_struct *work) hci_le_start_enc(hcon, ediv, rand, stk); hcon->enc_key_size = smp->enc_key_size; } else { - u8 stk[16], r[16]; + u8 stk[16]; __le64 rand = 0; __le16 ediv = 0; - swap128(smp->prnd, r); - smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), + smp->prnd); - smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key); - swap128(key, stk); + smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk); memset(stk + smp->enc_key_size, 0, SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); @@ -596,6 +594,9 @@ void smp_chan_destroy(struct l2cap_conn *conn) complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); mgmt_smp_complete(conn->hcon, complete); + kfree(smp->csrk); + kfree(smp->slave_csrk); + /* If pairing failed clean up any keys we might have */ if (!complete) { if (smp->ltk) { @@ -625,7 +626,6 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) struct l2cap_conn *conn = hcon->smp_conn; struct smp_chan *smp; u32 value; - u8 key[16]; BT_DBG(""); @@ -637,10 +637,9 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) switch (mgmt_op) { case MGMT_OP_USER_PASSKEY_REPLY: value = le32_to_cpu(passkey); - memset(key, 0, sizeof(key)); + memset(smp->tk, 0, sizeof(smp->tk)); BT_DBG("PassKey: %d", value); - put_unaligned_le32(value, key); - swap128(key, smp->tk); + put_unaligned_le32(value, smp->tk); /* Fall Through */ case MGMT_OP_USER_CONFIRM_REPLY: set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); @@ -745,6 +744,11 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) smp->prsp[0] = SMP_CMD_PAIRING_RSP; memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); + /* Update remote key distribution in case the remote cleared + * some bits that we had enabled in our request. + */ + smp->remote_key_dist &= rsp->resp_key_dist; + if ((req->auth_req & SMP_AUTH_BONDING) && (rsp->auth_req & SMP_AUTH_BONDING)) auth = SMP_AUTH_BONDING; @@ -758,10 +762,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); /* Can't compose response until we have been confirmed */ - if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) - return 0; - - queue_work(hdev->workqueue, &smp->confirm); + if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) + queue_work(hdev->workqueue, &smp->confirm); return 0; } @@ -779,17 +781,13 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); skb_pull(skb, sizeof(smp->pcnf)); - if (conn->hcon->out) { - u8 random[16]; - - swap128(smp->prnd, random); - smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), - random); - } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) { + if (conn->hcon->out) + smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), + smp->prnd); + else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) queue_work(hdev->workqueue, &smp->confirm); - } else { + else set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); - } return 0; } @@ -804,7 +802,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(smp->rrnd)) return SMP_UNSPECIFIED; - swap128(skb->data, smp->rrnd); + memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); skb_pull(skb, sizeof(smp->rrnd)); queue_work(hdev->workqueue, &smp->random); @@ -910,6 +908,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) authreq = seclevel_to_authreq(sec_level); + /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM + * flag is set we should also set it for the SMP request. + */ + if ((hcon->auth_type & 0x01)) + authreq |= SMP_AUTH_MITM; + if (hcon->link_mode & HCI_LM_MASTER) { struct smp_cmd_pairing cp; @@ -1065,6 +1069,41 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, return 0; } +static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) +{ + struct smp_cmd_sign_info *rp = (void *) skb->data; + struct smp_chan *smp = conn->smp_chan; + struct hci_dev *hdev = conn->hcon->hdev; + struct smp_csrk *csrk; + + BT_DBG("conn %p", conn); + + if (skb->len < sizeof(*rp)) + return SMP_UNSPECIFIED; + + /* Ignore this PDU if it wasn't requested */ + if (!(smp->remote_key_dist & SMP_DIST_SIGN)) + return 0; + + /* Mark the information as received */ + smp->remote_key_dist &= ~SMP_DIST_SIGN; + + skb_pull(skb, sizeof(*rp)); + + hci_dev_lock(hdev); + csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); + if (csrk) { + csrk->master = 0x01; + memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); + } + smp->csrk = csrk; + if (!(smp->remote_key_dist & SMP_DIST_SIGN)) + smp_distribute_keys(conn); + hci_dev_unlock(hdev); + + return 0; +} + int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) { struct hci_conn *hcon = conn->hcon; @@ -1147,8 +1186,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) break; case SMP_CMD_SIGN_INFO: - /* Just ignored */ - reason = 0; + reason = smp_cmd_sign_info(conn, skb); break; default: @@ -1172,20 +1210,40 @@ static void smp_notify_keys(struct l2cap_conn *conn) struct smp_chan *smp = conn->smp_chan; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; + struct smp_cmd_pairing *req = (void *) &smp->preq[1]; + struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; + bool persistent; if (smp->remote_irk) mgmt_new_irk(hdev, smp->remote_irk); + /* The LTKs and CSRKs should be persistent only if both sides + * had the bonding bit set in their authentication requests. + */ + persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); + + if (smp->csrk) { + smp->csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->csrk, persistent); + } + + if (smp->slave_csrk) { + smp->slave_csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->slave_csrk, persistent); + } + if (smp->ltk) { smp->ltk->bdaddr_type = hcon->dst_type; bacpy(&smp->ltk->bdaddr, &hcon->dst); - mgmt_new_ltk(hdev, smp->ltk); + mgmt_new_ltk(hdev, smp->ltk, persistent); } if (smp->slave_ltk) { smp->slave_ltk->bdaddr_type = hcon->dst_type; bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); - mgmt_new_ltk(hdev, smp->slave_ltk); + mgmt_new_ltk(hdev, smp->slave_ltk, persistent); } } @@ -1274,10 +1332,18 @@ int smp_distribute_keys(struct l2cap_conn *conn) if (*keydist & SMP_DIST_SIGN) { struct smp_cmd_sign_info sign; + struct smp_csrk *csrk; - /* Send a dummy key */ + /* Generate a new random key */ get_random_bytes(sign.csrk, sizeof(sign.csrk)); + csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); + if (csrk) { + csrk->master = 0x00; + memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); + } + smp->slave_csrk = csrk; + smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); *keydist &= ~SMP_DIST_SIGN; diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index f55d83617218..b6913471815a 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -121,7 +121,7 @@ struct smp_cmd_security_req { #define SMP_FLAG_LTK_ENCRYPT 4 #define SMP_FLAG_COMPLETE 5 -#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(250) +#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(500) struct smp_chan { struct l2cap_conn *conn; @@ -136,6 +136,8 @@ struct smp_chan { bdaddr_t id_addr; u8 id_addr_type; u8 irk[16]; + struct smp_csrk *csrk; + struct smp_csrk *slave_csrk; struct smp_ltk *ltk; struct smp_ltk *slave_ltk; struct smp_irk *remote_irk; |