__u16 init_last_cmd;
+ struct crypto_blkcipher *tfm;
+
struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash;
struct list_head blacklist;
BNEP Module (Bluetooth Network Encapsulation Protocol)
CMTP Module (CAPI Message Transport Protocol)
HIDP Module (Human Interface Device Protocol)
+ SMP Module (Security Manager Protocol)
Say Y here to compile Bluetooth support into the kernel or say M to
compile it as module (bluetooth).
config BT_L2CAP
bool "L2CAP protocol support"
select CRC16
+ select CRYPTO
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_AES
+ select CRYPTO_ECB
help
L2CAP (Logical Link Control and Adaptation Protocol) provides
connection oriented and connection-less data transport. L2CAP
support is required for most Bluetooth applications.
+ Also included is support for SMP (Security Manager Protocol) which
+ is the security layer on top of LE (Low Energy) links.
+
config BT_SCO
bool "SCO links support"
help
#include <linux/notifier.h>
#include <linux/rfkill.h>
#include <linux/timer.h>
+#include <linux/crypto.h>
#include <net/sock.h>
#include <asm/system.h>
static DEFINE_RWLOCK(hci_task_lock);
+static int enable_smp;
+
/* HCI device list */
LIST_HEAD(hci_dev_list);
DEFINE_RWLOCK(hci_dev_list_lock);
return 0;
}
+static struct crypto_blkcipher *alloc_cypher(void)
+{
+ if (enable_smp)
+ return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+
+ return ERR_PTR(-ENOTSUPP);
+}
+
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
{
if (!hdev->workqueue)
goto nomem;
+ hdev->tfm = alloc_cypher();
+ if (IS_ERR(hdev->tfm))
+ BT_INFO("Failed to load transform for ecb(aes): %ld",
+ PTR_ERR(hdev->tfm));
+
hci_register_sysfs(hdev);
hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
!test_bit(HCI_SETUP, &hdev->flags))
mgmt_index_removed(hdev->id);
+ if (!IS_ERR(hdev->tfm))
+ crypto_free_blkcipher(hdev->tfm);
+
hci_notify(hdev, HCI_DEV_UNREG);
if (hdev->rfkill) {
}
}
}
+
+module_param(enable_smp, bool, 0644);
+MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)");
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
{
+ struct hci_conn *hcon = conn->hcon;
__u8 authreq;
- BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
+ BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
+
+ if (IS_ERR(hcon->hdev->tfm))
+ return 1;
switch (sec_level) {
case BT_SECURITY_MEDIUM:
return 1;
}
- if (conn->hcon->link_mode & HCI_LM_MASTER) {
+ if (hcon->link_mode & HCI_LM_MASTER) {
struct smp_cmd_pairing cp;
cp.io_capability = 0x00;
cp.oob_flag = 0x00;
__u8 reason;
int err = 0;
+ if (IS_ERR(conn->hcon->hdev->tfm)) {
+ err = PTR_ERR(conn->hcon->hdev->tfm);
+ reason = SMP_PAIRING_NOTSUPP;
+ goto done;
+ }
+
skb_pull(skb, sizeof(code));
switch (code) {
BT_DBG("Unknown command code 0x%2.2x", code);
reason = SMP_CMD_NOTSUPP;
- smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
- &reason);
err = -EOPNOTSUPP;
+ goto done;
}
+done:
+ if (reason)
+ smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+ &reason);
+
kfree_skb(skb);
return err;
}