From 2e98ab6ecc80255b50845de7256901369ee0bf61 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Nov 2016 23:46:31 +0100 Subject: [PATCH] nimble/sm: Use proper key size for encryption This patch adds proper masking of STK/LTK keys depending on encryption key size as defined in Bluetooth Specification 4.2, Vol 3, Part H, Section 2.3.4. This also fixes following PTS test cases for SM: - TP/EKS/BV-01-C - TP/EKS/BV-02-C X-Original-Commit: a034ac10ac6b02413e47f8d74652c99eae3763c3 --- nimble/host/src/ble_sm.c | 10 ++++++++-- nimble/host/src/ble_sm_lgcy.c | 5 ++++- nimble/host/src/ble_sm_priv.h | 1 + nimble/host/src/ble_sm_sc.c | 3 +++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index d6527d4f0..f42a54e36 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -314,11 +314,14 @@ ble_sm_gen_ltk(struct ble_sm_proc *proc, uint8_t *ltk) } #endif - rc = ble_hs_hci_util_rand(ltk, 16); + rc = ble_hs_hci_util_rand(ltk, proc->key_size); if (rc != 0) { return rc; } + /* Ensure proper key size */ + memset(ltk + proc->key_size, 0, sizeof proc->ltk - proc->key_size); + return 0; } @@ -1377,6 +1380,9 @@ ble_sm_pair_cfg(struct ble_sm_proc *proc) if (rx_key_dist & BLE_SM_PAIR_KEY_DIST_SIGN) { proc->rx_key_flags |= BLE_SM_KE_F_SIGN_INFO; } + + proc->key_size = min(proc->pair_req.max_enc_key_size, + proc->pair_rsp.max_enc_key_size); } static void @@ -1393,7 +1399,7 @@ ble_sm_pair_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, cmd.io_cap = ble_hs_cfg.sm_io_cap; cmd.oob_data_flag = ble_hs_cfg.sm_oob_data_flag; cmd.authreq = ble_sm_build_authreq(); - cmd.max_enc_key_size = 16; + cmd.max_enc_key_size = BLE_SM_PAIR_KEY_SZ_MAX; if (is_req) { cmd.init_key_dist = ble_hs_cfg.sm_our_key_dist; diff --git a/nimble/host/src/ble_sm_lgcy.c b/nimble/host/src/ble_sm_lgcy.c index a77671e32..54a2ecb15 100644 --- a/nimble/host/src/ble_sm_lgcy.c +++ b/nimble/host/src/ble_sm_lgcy.c @@ -181,7 +181,10 @@ ble_sm_gen_stk(struct ble_sm_proc *proc) return rc; } - memcpy(proc->ltk, key, sizeof key); + memcpy(proc->ltk, key, proc->key_size); + + /* Ensure proper key size */ + memset(proc->ltk + proc->key_size, 0, sizeof key - proc->key_size); return 0; } diff --git a/nimble/host/src/ble_sm_priv.h b/nimble/host/src/ble_sm_priv.h index 7d96164b0..d75d4756e 100644 --- a/nimble/host/src/ble_sm_priv.h +++ b/nimble/host/src/ble_sm_priv.h @@ -257,6 +257,7 @@ struct ble_sm_proc { uint8_t pair_alg; uint8_t state; uint8_t rx_key_flags; + uint8_t key_size; struct ble_sm_pair_cmd pair_req; struct ble_sm_pair_cmd pair_rsp; diff --git a/nimble/host/src/ble_sm_sc.c b/nimble/host/src/ble_sm_sc.c index f8a698305..647160766 100644 --- a/nimble/host/src/ble_sm_sc.c +++ b/nimble/host/src/ble_sm_sc.c @@ -440,6 +440,9 @@ ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) return; } + /* Ensure proper key size */ + memset(proc->ltk + proc->key_size, 0, sizeof proc->ltk - proc->key_size); + /* Ensure the ltk gets persisted when the pairing procedure succeeds. */ memcpy(proc->our_keys.ltk, proc->ltk, sizeof proc->our_keys.ltk); proc->our_keys.ltk_valid = 1;