aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-06-09 17:50:43 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-13 14:48:22 -0400
commit3a0259bb80cec7595a2d085a150412d23ba28c81 (patch)
treeeec4da988424125848d09261a015f8930a3b96c6
parent88ba43b662b6b944c6278ad81a114fa559807776 (diff)
Bluetooth: Add support for using the crypto subsystem
This will allow using the crypto subsystem for encrypting data. As SMP (Security Manager Protocol) is implemented almost entirely on the host side and the crypto module already implements the needed methods (AES-128), it makes sense to use it. There's now a new module option to enable/disable SMP support. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--net/bluetooth/Kconfig8
-rw-r--r--net/bluetooth/hci_core.c22
-rw-r--r--net/bluetooth/smp.c22
4 files changed, 50 insertions, 4 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 836d3e8c4bf..7837f326086 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -177,6 +177,8 @@ struct hci_dev {
177 177
178 __u16 init_last_cmd; 178 __u16 init_last_cmd;
179 179
180 struct crypto_blkcipher *tfm;
181
180 struct inquiry_cache inq_cache; 182 struct inquiry_cache inq_cache;
181 struct hci_conn_hash conn_hash; 183 struct hci_conn_hash conn_hash;
182 struct list_head blacklist; 184 struct list_head blacklist;
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 6ae5ec50858..f495dea741e 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -22,6 +22,7 @@ menuconfig BT
22 BNEP Module (Bluetooth Network Encapsulation Protocol) 22 BNEP Module (Bluetooth Network Encapsulation Protocol)
23 CMTP Module (CAPI Message Transport Protocol) 23 CMTP Module (CAPI Message Transport Protocol)
24 HIDP Module (Human Interface Device Protocol) 24 HIDP Module (Human Interface Device Protocol)
25 SMP Module (Security Manager Protocol)
25 26
26 Say Y here to compile Bluetooth support into the kernel or say M to 27 Say Y here to compile Bluetooth support into the kernel or say M to
27 compile it as module (bluetooth). 28 compile it as module (bluetooth).
@@ -36,11 +37,18 @@ if BT != n
36config BT_L2CAP 37config BT_L2CAP
37 bool "L2CAP protocol support" 38 bool "L2CAP protocol support"
38 select CRC16 39 select CRC16
40 select CRYPTO
41 select CRYPTO_BLKCIPHER
42 select CRYPTO_AES
43 select CRYPTO_ECB
39 help 44 help
40 L2CAP (Logical Link Control and Adaptation Protocol) provides 45 L2CAP (Logical Link Control and Adaptation Protocol) provides
41 connection oriented and connection-less data transport. L2CAP 46 connection oriented and connection-less data transport. L2CAP
42 support is required for most Bluetooth applications. 47 support is required for most Bluetooth applications.
43 48
49 Also included is support for SMP (Security Manager Protocol) which
50 is the security layer on top of LE (Low Energy) links.
51
44config BT_SCO 52config BT_SCO
45 bool "SCO links support" 53 bool "SCO links support"
46 help 54 help
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e14e8a1cb04..f62ca1935f5 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -42,6 +42,7 @@
42#include <linux/notifier.h> 42#include <linux/notifier.h>
43#include <linux/rfkill.h> 43#include <linux/rfkill.h>
44#include <linux/timer.h> 44#include <linux/timer.h>
45#include <linux/crypto.h>
45#include <net/sock.h> 46#include <net/sock.h>
46 47
47#include <asm/system.h> 48#include <asm/system.h>
@@ -59,6 +60,8 @@ static void hci_tx_task(unsigned long arg);
59 60
60static DEFINE_RWLOCK(hci_task_lock); 61static DEFINE_RWLOCK(hci_task_lock);
61 62
63static int enable_smp;
64
62/* HCI device list */ 65/* HCI device list */
63LIST_HEAD(hci_dev_list); 66LIST_HEAD(hci_dev_list);
64DEFINE_RWLOCK(hci_dev_list_lock); 67DEFINE_RWLOCK(hci_dev_list_lock);
@@ -1274,6 +1277,14 @@ int hci_add_adv_entry(struct hci_dev *hdev,
1274 return 0; 1277 return 0;
1275} 1278}
1276 1279
1280static struct crypto_blkcipher *alloc_cypher(void)
1281{
1282 if (enable_smp)
1283 return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
1284
1285 return ERR_PTR(-ENOTSUPP);
1286}
1287
1277/* Register HCI device */ 1288/* Register HCI device */
1278int hci_register_dev(struct hci_dev *hdev) 1289int hci_register_dev(struct hci_dev *hdev)
1279{ 1290{
@@ -1358,6 +1369,11 @@ int hci_register_dev(struct hci_dev *hdev)
1358 if (!hdev->workqueue) 1369 if (!hdev->workqueue)
1359 goto nomem; 1370 goto nomem;
1360 1371
1372 hdev->tfm = alloc_cypher();
1373 if (IS_ERR(hdev->tfm))
1374 BT_INFO("Failed to load transform for ecb(aes): %ld",
1375 PTR_ERR(hdev->tfm));
1376
1361 hci_register_sysfs(hdev); 1377 hci_register_sysfs(hdev);
1362 1378
1363 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1379 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -1406,6 +1422,9 @@ int hci_unregister_dev(struct hci_dev *hdev)
1406 !test_bit(HCI_SETUP, &hdev->flags)) 1422 !test_bit(HCI_SETUP, &hdev->flags))
1407 mgmt_index_removed(hdev->id); 1423 mgmt_index_removed(hdev->id);
1408 1424
1425 if (!IS_ERR(hdev->tfm))
1426 crypto_free_blkcipher(hdev->tfm);
1427
1409 hci_notify(hdev, HCI_DEV_UNREG); 1428 hci_notify(hdev, HCI_DEV_UNREG);
1410 1429
1411 if (hdev->rfkill) { 1430 if (hdev->rfkill) {
@@ -2242,3 +2261,6 @@ static void hci_cmd_task(unsigned long arg)
2242 } 2261 }
2243 } 2262 }
2244} 2263}
2264
2265module_param(enable_smp, bool, 0644);
2266MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)");
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 2240e96552f..aa20bee9750 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -154,9 +154,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
154 154
155int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) 155int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
156{ 156{
157 struct hci_conn *hcon = conn->hcon;
157 __u8 authreq; 158 __u8 authreq;
158 159
159 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level); 160 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
161
162 if (IS_ERR(hcon->hdev->tfm))
163 return 1;
160 164
161 switch (sec_level) { 165 switch (sec_level) {
162 case BT_SECURITY_MEDIUM: 166 case BT_SECURITY_MEDIUM:
@@ -174,7 +178,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
174 return 1; 178 return 1;
175 } 179 }
176 180
177 if (conn->hcon->link_mode & HCI_LM_MASTER) { 181 if (hcon->link_mode & HCI_LM_MASTER) {
178 struct smp_cmd_pairing cp; 182 struct smp_cmd_pairing cp;
179 cp.io_capability = 0x00; 183 cp.io_capability = 0x00;
180 cp.oob_flag = 0x00; 184 cp.oob_flag = 0x00;
@@ -198,6 +202,12 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
198 __u8 reason; 202 __u8 reason;
199 int err = 0; 203 int err = 0;
200 204
205 if (IS_ERR(conn->hcon->hdev->tfm)) {
206 err = PTR_ERR(conn->hcon->hdev->tfm);
207 reason = SMP_PAIRING_NOTSUPP;
208 goto done;
209 }
210
201 skb_pull(skb, sizeof(code)); 211 skb_pull(skb, sizeof(code));
202 212
203 switch (code) { 213 switch (code) {
@@ -233,11 +243,15 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
233 BT_DBG("Unknown command code 0x%2.2x", code); 243 BT_DBG("Unknown command code 0x%2.2x", code);
234 244
235 reason = SMP_CMD_NOTSUPP; 245 reason = SMP_CMD_NOTSUPP;
236 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
237 &reason);
238 err = -EOPNOTSUPP; 246 err = -EOPNOTSUPP;
247 goto done;
239 } 248 }
240 249
250done:
251 if (reason)
252 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
253 &reason);
254
241 kfree_skb(skb); 255 kfree_skb(skb);
242 return err; 256 return err;
243} 257}