Commit 3a0259bb80cec7595a2d085a150412d23ba28c81

Authored by Vinicius Costa Gomes
Committed by Gustavo F. Padovan
1 parent 88ba43b662

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>

Showing 4 changed files with 50 additions and 4 deletions Side-by-side Diff

include/net/bluetooth/hci_core.h
... ... @@ -177,6 +177,8 @@
177 177  
178 178 __u16 init_last_cmd;
179 179  
  180 + struct crypto_blkcipher *tfm;
  181 +
180 182 struct inquiry_cache inq_cache;
181 183 struct hci_conn_hash conn_hash;
182 184 struct list_head blacklist;
net/bluetooth/Kconfig
... ... @@ -22,6 +22,7 @@
22 22 BNEP Module (Bluetooth Network Encapsulation Protocol)
23 23 CMTP Module (CAPI Message Transport Protocol)
24 24 HIDP Module (Human Interface Device Protocol)
  25 + SMP Module (Security Manager Protocol)
25 26  
26 27 Say Y here to compile Bluetooth support into the kernel or say M to
27 28 compile it as module (bluetooth).
28 29  
... ... @@ -36,10 +37,17 @@
36 37 config BT_L2CAP
37 38 bool "L2CAP protocol support"
38 39 select CRC16
  40 + select CRYPTO
  41 + select CRYPTO_BLKCIPHER
  42 + select CRYPTO_AES
  43 + select CRYPTO_ECB
39 44 help
40 45 L2CAP (Logical Link Control and Adaptation Protocol) provides
41 46 connection oriented and connection-less data transport. L2CAP
42 47 support is required for most Bluetooth applications.
  48 +
  49 + Also included is support for SMP (Security Manager Protocol) which
  50 + is the security layer on top of LE (Low Energy) links.
43 51  
44 52 config BT_SCO
45 53 bool "SCO links support"
net/bluetooth/hci_core.c
... ... @@ -42,6 +42,7 @@
42 42 #include <linux/notifier.h>
43 43 #include <linux/rfkill.h>
44 44 #include <linux/timer.h>
  45 +#include <linux/crypto.h>
45 46 #include <net/sock.h>
46 47  
47 48 #include <asm/system.h>
... ... @@ -59,6 +60,8 @@
59 60  
60 61 static DEFINE_RWLOCK(hci_task_lock);
61 62  
  63 +static int enable_smp;
  64 +
62 65 /* HCI device list */
63 66 LIST_HEAD(hci_dev_list);
64 67 DEFINE_RWLOCK(hci_dev_list_lock);
... ... @@ -1274,6 +1277,14 @@
1274 1277 return 0;
1275 1278 }
1276 1279  
  1280 +static 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 1288 /* Register HCI device */
1278 1289 int hci_register_dev(struct hci_dev *hdev)
1279 1290 {
... ... @@ -1358,6 +1369,11 @@
1358 1369 if (!hdev->workqueue)
1359 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 1377 hci_register_sysfs(hdev);
1362 1378  
1363 1379 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
... ... @@ -1406,6 +1422,9 @@
1406 1422 !test_bit(HCI_SETUP, &hdev->flags))
1407 1423 mgmt_index_removed(hdev->id);
1408 1424  
  1425 + if (!IS_ERR(hdev->tfm))
  1426 + crypto_free_blkcipher(hdev->tfm);
  1427 +
1409 1428 hci_notify(hdev, HCI_DEV_UNREG);
1410 1429  
1411 1430 if (hdev->rfkill) {
... ... @@ -2242,4 +2261,7 @@
2242 2261 }
2243 2262 }
2244 2263 }
  2264 +
  2265 +module_param(enable_smp, bool, 0644);
  2266 +MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)");
... ... @@ -154,10 +154,14 @@
154 154  
155 155 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
156 156 {
  157 + struct hci_conn *hcon = conn->hcon;
157 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);
160 161  
  162 + if (IS_ERR(hcon->hdev->tfm))
  163 + return 1;
  164 +
161 165 switch (sec_level) {
162 166 case BT_SECURITY_MEDIUM:
163 167 /* Encrypted, no MITM protection */
... ... @@ -174,7 +178,7 @@
174 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 182 struct smp_cmd_pairing cp;
179 183 cp.io_capability = 0x00;
180 184 cp.oob_flag = 0x00;
... ... @@ -198,6 +202,12 @@
198 202 __u8 reason;
199 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 211 skb_pull(skb, sizeof(code));
202 212  
203 213 switch (code) {
204 214  
205 215  
... ... @@ -233,10 +243,14 @@
233 243 BT_DBG("Unknown command code 0x%2.2x", code);
234 244  
235 245 reason = SMP_CMD_NOTSUPP;
236   - smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
237   - &reason);
238 246 err = -EOPNOTSUPP;
  247 + goto done;
239 248 }
  249 +
  250 +done:
  251 + if (reason)
  252 + smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
  253 + &reason);
240 254  
241 255 kfree_skb(skb);
242 256 return err;