From 15c1fed5b65cf51a92b270b0353a039f2512e314 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 25 Apr 2016 11:53:34 +0200 Subject: [PATCH] Bluetooth: SMP: Workaround LE SC bug in iOS iOS BT stack has a bug in LE SC implementation. If EncKey is not set in key distribution it sends Pairing Failed PDU if any (?) keys were distributed. This wasn't visible before as without local privacy no keys were distributed for LE SC with iPhone. Change-Id: I36c2398ea821c6048d970b93a58189eb466ea434 Signed-off-by: Szymon Janc --- net/bluetooth/smp.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 5288e667b08..e91c5bfc3bd 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -67,8 +67,12 @@ #define SEND_KEYS (BT_SMP_DIST_ENC_KEY | SIGN_DIST) #endif -#define RECV_KEYS_SC (RECV_KEYS & ~(BT_SMP_DIST_ENC_KEY | BT_SMP_DIST_LINK_KEY)) -#define SEND_KEYS_SC (SEND_KEYS & ~(BT_SMP_DIST_ENC_KEY | BT_SMP_DIST_LINK_KEY)) +/* + * Don't include BT_SMP_DIST_ENC_KEY in this mask. See comment in + * bt_smp_encrypt_change for details. + */ +#define RECV_KEYS_SC (RECV_KEYS & ~(BT_SMP_DIST_LINK_KEY)) +#define SEND_KEYS_SC (SEND_KEYS & ~(BT_SMP_DIST_LINK_KEY)) #define BT_SMP_AUTH_MASK 0x07 #define BT_SMP_AUTH_MASK_SC 0x0f @@ -2735,6 +2739,18 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan) return; } + /* + * Clear EncKey bit for LE SC. This is legacy key and should not be + * distributed when LE SC is used. We don't clean it initially to + * workaround bug in iOS BT stack where it sends Pairing Failed PDU + * if any (?) keys were distributed but EncKey was not set in key + * distribution. + */ + if (atomic_test_bit(&smp->flags, SMP_FLAG_SC)) { + smp->local_dist &= ~BT_SMP_DIST_ENC_KEY; + smp->remote_dist &= ~BT_SMP_DIST_ENC_KEY; + } + 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) {