From 7d1a615b1f49590535cfeee3f5e1d85b36220cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Delawarde?= Date: Thu, 30 Jan 2020 08:23:00 +0100 Subject: [PATCH] bluetooth: host: Add workaround for USB HCI controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a new option CONFIG_BT_SMP_USB_HCI_CTLR_WORKAROUND to support USB HCI controllers that sometimes send out-of-order HCI events and ACL Data due to using different USB endpoints. Enabling this option will make the master role not require the encryption-change event to be received before accepting key-distribution data. It opens up for a potential vulnerability as the master cannot detect if the keys are distributed over an encrypted link. Fixes: #22086 Signed-off-by: François Delawarde --- subsys/bluetooth/host/Kconfig | 13 +++++++++++++ subsys/bluetooth/host/smp.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index a8a355aa6e11..f40e7e58cc37 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -350,6 +350,19 @@ config BT_SMP_ALLOW_UNAUTH_OVERWRITE to create a new bond the old bond has to be explicitly deleted with bt_unpair. +config BT_SMP_USB_HCI_CTLR_WORKAROUND + bool "Workaround for USB HCI controller out-of-order events" + depends on BT_TESTING + help + This option enables support for USB HCI controllers that sometimes + send out-of-order HCI events and ACL Data due to using different USB + endpoints. + Enabling this option will make the master role not require the + encryption-change event to be received before accepting key-distribution + data. + It opens up for a potential vulnerability as the master cannot detect + if the keys are distributed over an encrypted link. + config BT_FIXED_PASSKEY bool "Use a fixed passkey for pairing" help diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 9fd82c879f93..273f74ca9a5d 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -2311,6 +2311,19 @@ static u8_t legacy_pairing_random(struct bt_smp *smp) atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + if (IS_ENABLED(CONFIG_BT_SMP_USB_HCI_CTLR_WORKAROUND)) { + if (smp->remote_dist & BT_SMP_DIST_ENC_KEY) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_ENCRYPT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_ID_KEY) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_IDENT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_SIGNING_INFO); + } + } + return 0; } @@ -3999,6 +4012,17 @@ static u8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf) } atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + + if (IS_ENABLED(CONFIG_BT_SMP_USB_HCI_CTLR_WORKAROUND)) { + if (smp->remote_dist & BT_SMP_DIST_ID_KEY) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_IDENT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_SIGNING_INFO); + } + } + return 0; } @@ -5319,6 +5343,11 @@ int bt_smp_init(void) return -ENOENT; } + if (IS_ENABLED(CONFIG_BT_SMP_USB_HCI_CTLR_WORKAROUND)) { + BT_WARN("BT_SMP_USB_HCI_CTLR_WORKAROUND is enabled, which " + "exposes a security vulnerability!"); + } + BT_DBG("LE SC %s", sc_supported ? "enabled" : "disabled"); bt_pub_key_gen(&pub_key_cb);