Bluetooth: host: Log security keys needed by sniffer
Log the security keys that the sniffer needs in order to sucessfully decrypt the connection. This option allows the sniffer to work in the cases where enabling using the SMP debug keys is not wanted, either because it changes the way the peer behaves or is denied by the peer. It also enables the sniffer to decrypt a connection where the bond already exists. Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
parent
ecfda097d1
commit
200f4687e0
8 changed files with 123 additions and 7 deletions
|
@ -52,6 +52,7 @@ BT_DEBUG_SMP,n
|
|||
BT_OOB_DATA_FIXED,n
|
||||
BT_FIXED_PASSKEY,n
|
||||
BT_DEBUG_KEYS,n
|
||||
BT_LOG_SNIFFER_INFO,n
|
||||
BT_USE_DEBUG_KEYS,n
|
||||
BT_STORE_DEBUG_KEYS,n
|
||||
BT_CONN_DISABLE_SECURITY,n
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 44.
|
|
@ -76,9 +76,9 @@ if(CONFIG_BT_HCI_HOST)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_DEBUG_SMP OR CONFIG_BT_DEBUG_KEYS)
|
||||
message(WARNING "One or both these options are enabled:
|
||||
CONFIG_BT_DEBUG_SMP CONFIG_BT_DEBUG_KEYS.
|
||||
if(CONFIG_BT_DEBUG_SMP OR CONFIG_BT_DEBUG_KEYS OR CONFIG_BT_LOG_SNIFFER_INFO)
|
||||
message(WARNING "One of these options are enabled:
|
||||
CONFIG_BT_DEBUG_SMP CONFIG_BT_DEBUG_KEYS CONFIG_BT_LOG_SNIFFER_INFO.
|
||||
Private security keys such as the LTK will be printed out, do not use in
|
||||
production."
|
||||
)
|
||||
|
|
|
@ -754,6 +754,17 @@ config BT_DEBUG_SERVICE
|
|||
|
||||
endif # BT_DEBUG
|
||||
|
||||
config BT_LOG_SNIFFER_INFO
|
||||
bool "Bluetooth log information for sniffer"
|
||||
help
|
||||
This option enables the Bluetooth stack to log information such as
|
||||
DH private key and LTK keys, which can be used by sniffers to decrypt
|
||||
the connection without the use of Debug keys.
|
||||
|
||||
WARNING: This option prints out private security keys such as
|
||||
the Long Term Key.
|
||||
Use of this feature in production is strongly discouraged
|
||||
|
||||
config BT_TESTING
|
||||
bool "Bluetooth Testing"
|
||||
help
|
||||
|
|
|
@ -664,7 +664,16 @@ static int le_set_private_addr(uint8_t id)
|
|||
}
|
||||
|
||||
le_rpa_timeout_submit();
|
||||
return err;
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
BT_INFO("RPA: %s", bt_addr_str(&rpa));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int le_adv_set_private_addr(struct bt_le_ext_adv *adv)
|
||||
|
@ -711,7 +720,15 @@ static int le_adv_set_private_addr(struct bt_le_ext_adv *adv)
|
|||
le_rpa_timeout_submit();
|
||||
}
|
||||
|
||||
return err;
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
BT_INFO("RPA: %s", bt_addr_str(&rpa));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int le_set_private_addr(uint8_t id)
|
||||
|
@ -726,7 +743,16 @@ static int le_set_private_addr(uint8_t id)
|
|||
|
||||
BT_ADDR_SET_NRPA(&nrpa);
|
||||
|
||||
return set_random_address(&nrpa);
|
||||
err = set_random_address(&nrpa);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
BT_INFO("NRPA: %s", bt_addr_str(&nrpa));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int le_adv_set_private_addr(struct bt_le_ext_adv *adv)
|
||||
|
@ -741,7 +767,16 @@ static int le_adv_set_private_addr(struct bt_le_ext_adv *adv)
|
|||
|
||||
BT_ADDR_SET_NRPA(&nrpa);
|
||||
|
||||
return set_adv_random_address(adv, &nrpa);
|
||||
err = set_adv_random_address(adv, &nrpa);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
BT_INFO("NRPA: %s", bt_addr_str(&nrpa));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(CONFIG_BT_PRIVACY) */
|
||||
|
||||
|
@ -6017,9 +6052,32 @@ static void bt_dev_show_info(void)
|
|||
BT_INFO("Identity%s: %s", bt_dev.id_count > 1 ? "[0]" : "",
|
||||
bt_addr_le_str(&bt_dev.id_addr[0]));
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
uint8_t irk[16];
|
||||
|
||||
sys_memcpy_swap(irk, bt_dev.irk[0], 16);
|
||||
BT_INFO("IRK%s: 0x%s", bt_dev.id_count > 1 ? "[0]" : "",
|
||||
bt_hex(irk, 16));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 1; i < bt_dev.id_count; i++) {
|
||||
BT_INFO("Identity[%d]: %s",
|
||||
i, bt_addr_le_str(&bt_dev.id_addr[i]));
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
uint8_t irk[16];
|
||||
|
||||
sys_memcpy_swap(irk, bt_dev.irk[i], 16);
|
||||
BT_INFO("IRK[%d]: 0x%s", i, bt_hex(irk, 16));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
bt_keys_foreach(BT_KEYS_ALL, bt_keys_show_sniffer_info, NULL);
|
||||
}
|
||||
|
||||
BT_INFO("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x",
|
||||
|
|
|
@ -111,6 +111,10 @@ static uint8_t generate_keys(void)
|
|||
/* make sure generated key isn't debug key */
|
||||
} while (memcmp(ecc.private_key_be, debug_private_key_be, 32) == 0);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
BT_INFO("SC private key 0x%s", bt_hex(ecc.private_key_be, 32));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/atomic.h>
|
||||
#include <sys/util.h>
|
||||
#include <sys/byteorder.h>
|
||||
|
||||
#include <settings/settings.h>
|
||||
|
||||
|
@ -435,3 +436,27 @@ void bt_keys_update_usage(uint8_t id, const bt_addr_le_t *addr)
|
|||
}
|
||||
|
||||
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
|
||||
|
||||
#if defined(CONFIG_BT_LOG_SNIFFER_INFO)
|
||||
void bt_keys_show_sniffer_info(struct bt_keys *keys, void *data)
|
||||
{
|
||||
uint8_t ltk[16];
|
||||
|
||||
if (keys->keys & BT_KEYS_LTK_P256) {
|
||||
sys_memcpy_swap(ltk, keys->ltk.val, keys->enc_size);
|
||||
BT_INFO("SC LTK: 0x%s", bt_hex(ltk, keys->enc_size));
|
||||
}
|
||||
|
||||
if (keys->keys & BT_KEYS_SLAVE_LTK) {
|
||||
sys_memcpy_swap(ltk, keys->slave_ltk.val, keys->enc_size);
|
||||
BT_INFO("Legacy LTK: 0x%s (peripheral)",
|
||||
bt_hex(ltk, keys->enc_size));
|
||||
}
|
||||
|
||||
if (keys->keys & BT_KEYS_LTK) {
|
||||
sys_memcpy_swap(ltk, keys->ltk.val, keys->enc_size);
|
||||
BT_INFO("Legacy LTK: 0x%s (central)",
|
||||
bt_hex(ltk, keys->enc_size));
|
||||
}
|
||||
}
|
||||
#endif /* defined(CONFIG_BT_LOG_SNIFFER_INFO) */
|
||||
|
|
|
@ -124,3 +124,5 @@ void bt_keys_link_key_store(struct bt_keys_link_key *link_key);
|
|||
/* BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING is enabled */
|
||||
void bt_keys_update_usage(uint8_t id, const bt_addr_le_t *addr);
|
||||
void bt_keys_link_key_update_usage(const bt_addr_t *addr);
|
||||
|
||||
void bt_keys_show_sniffer_info(struct bt_keys *keys, void *data);
|
||||
|
|
|
@ -1839,6 +1839,10 @@ static void smp_pairing_complete(struct bt_smp *smp, uint8_t status)
|
|||
#endif /* CONFIG_BT_BREDR */
|
||||
bool bond_flag = atomic_test_bit(smp->flags, SMP_FLAG_BOND);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
bt_keys_show_sniffer_info(conn->le.keys, NULL);
|
||||
}
|
||||
|
||||
if (bond_flag) {
|
||||
bt_keys_store(conn->le.keys);
|
||||
}
|
||||
|
@ -2339,6 +2343,10 @@ static uint8_t legacy_request_tk(struct bt_smp *smp)
|
|||
passkey %= 1000000;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
BT_INFO("Legacy passkey %u", passkey);
|
||||
}
|
||||
|
||||
if (bt_auth && bt_auth->passkey_display) {
|
||||
atomic_set_bit(smp->flags, SMP_FLAG_DISPLAY);
|
||||
bt_auth->passkey_display(conn, passkey);
|
||||
|
@ -5287,6 +5295,13 @@ int bt_smp_le_oob_set_tk(struct bt_conn *conn, const uint8_t *tk)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
|
||||
uint8_t oob[16];
|
||||
|
||||
sys_memcpy_swap(oob, tk, 16);
|
||||
BT_INFO("Legacy OOB data 0x%s", bt_hex(oob, 16));
|
||||
}
|
||||
|
||||
memcpy(smp->tk, tk, 16*sizeof(uint8_t));
|
||||
|
||||
legacy_user_tk_entry(smp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue