| From 64e759f58f128730b97a3c3a26d283c075ad7c86 Mon Sep 17 00:00:00 2001 |
| From: Szymon Janc <szymon.janc@codecoup.pl> |
| Date: Mon, 26 Feb 2018 15:41:53 +0100 |
| Subject: Bluetooth: Fix missing encryption refresh on Security Request |
| |
| From: Szymon Janc <szymon.janc@codecoup.pl> |
| |
| commit 64e759f58f128730b97a3c3a26d283c075ad7c86 upstream. |
| |
| If Security Request is received on connection that is already encrypted |
| with sufficient security master should perform encryption key refresh |
| procedure instead of just ignoring Slave Security Request |
| (Core Spec 5.0 Vol 3 Part H 2.4.6). |
| |
| > ACL Data RX: Handle 3585 flags 0x02 dlen 6 |
| SMP: Security Request (0x0b) len 1 |
| Authentication requirement: Bonding, No MITM, SC, No Keypresses (0x09) |
| < HCI Command: LE Start Encryption (0x08|0x0019) plen 28 |
| Handle: 3585 |
| Random number: 0x0000000000000000 |
| Encrypted diversifier: 0x0000 |
| Long term key: 44264272a5c426a9e868f034cf0e69f3 |
| > HCI Event: Command Status (0x0f) plen 4 |
| LE Start Encryption (0x08|0x0019) ncmd 1 |
| Status: Success (0x00) |
| > HCI Event: Encryption Key Refresh Complete (0x30) plen 3 |
| Status: Success (0x00) |
| Handle: 3585 |
| |
| Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl> |
| Signed-off-by: Marcel Holtmann <marcel@holtmann.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/bluetooth/smp.c | 8 +++++++- |
| 1 file changed, 7 insertions(+), 1 deletion(-) |
| |
| --- a/net/bluetooth/smp.c |
| +++ b/net/bluetooth/smp.c |
| @@ -2233,8 +2233,14 @@ static u8 smp_cmd_security_req(struct l2 |
| else |
| sec_level = authreq_to_seclevel(auth); |
| |
| - if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) |
| + if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { |
| + /* If link is already encrypted with sufficient security we |
| + * still need refresh encryption as per Core Spec 5.0 Vol 3, |
| + * Part H 2.4.6 |
| + */ |
| + smp_ltk_encrypt(conn, hcon->sec_level); |
| return 0; |
| + } |
| |
| if (sec_level > hcon->pending_sec_level) |
| hcon->pending_sec_level = sec_level; |