Commit 3a0259bb80cec7595a2d085a150412d23ba28c81
Committed by
Gustavo F. Padovan
1 parent
88ba43b662
Exists in
master
and in
38 other branches
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
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)"); |
net/bluetooth/smp.c
... | ... | @@ -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; |