mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-10 15:40:11 +00:00
sm: generate and store ER / IR keys in TLV, unless manually set by application
This commit is contained in:
parent
5b4dd59758
commit
899e6e028a
@ -11,9 +11,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
- Nordic SPP Service Server: GATT service that emulates a serial port over BLE based on Nordic Semiconductor documentation.
|
||||
- uBlox SPP Service Server: GATT service that emulates a serial port over BLE based on uBlox documentation.
|
||||
- SM: ENABLE_LE_CENTRAL_AUTO_ENCRYPTION triggers automatic encryption on connect to bonded devices
|
||||
- SM: generate and store ER / IR keys in TLV, unless manually set by application
|
||||
|
||||
### Fixed
|
||||
- SM: prevent random address updates if gap_random_address_set was used
|
||||
- SM: fix internal buffer overrun during random address generation
|
||||
- SM: fix internal buffer overrun that can cause storing of bonding information to fail
|
||||
- SM: ignore Slave Security Request after sending own Pairing Request
|
||||
- L2CAP: fix use after free on disconnect if ERTM is enabled
|
||||
|
115
src/ble/sm.c
115
src/ble/sm.c
@ -49,6 +49,7 @@
|
||||
#include "btstack_event.h"
|
||||
#include "btstack_linked_list.h"
|
||||
#include "btstack_memory.h"
|
||||
#include "btstack_tlv.h"
|
||||
#include "gap.h"
|
||||
#include "hci.h"
|
||||
#include "hci_dump.h"
|
||||
@ -81,6 +82,8 @@
|
||||
#define USE_CMAC_ENGINE
|
||||
#endif
|
||||
|
||||
#define BTSTACK_TAG32(A,B,C,D) ((A << 24) | (B << 16) | (C << 8) | D)
|
||||
|
||||
//
|
||||
// SM internal types and globals
|
||||
//
|
||||
@ -193,6 +196,11 @@ static void (*sm_sc_oob_callback)(const uint8_t * confirm_value, const uint8_t *
|
||||
static sm_sc_oob_state_t sm_sc_oob_state;
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t sm_persistent_keys_random_active;
|
||||
static const btstack_tlv_t * sm_tlv_impl;
|
||||
static void * sm_tlv_context;
|
||||
|
||||
// Security Manager Master Keys, please use sm_set_er(er) and sm_set_ir(ir) with your own 128 bit random values
|
||||
static sm_key_t sm_persistent_er;
|
||||
static sm_key_t sm_persistent_ir;
|
||||
@ -499,6 +507,31 @@ static void sm_truncate_key(sm_key_t key, int max_encryption_size){
|
||||
}
|
||||
}
|
||||
|
||||
// ER / IR checks
|
||||
static int sm_er_ir_set_default(void){
|
||||
int i;
|
||||
for (i=0;i<16;i++){
|
||||
sm_persistent_er[i] = 0x30 + i;
|
||||
sm_persistent_ir[i] = 0x90 + i;
|
||||
}
|
||||
}
|
||||
|
||||
static int sm_er_is_default(void){
|
||||
int i;
|
||||
for (i=0;i<16;i++){
|
||||
if (sm_persistent_er[i] != (0x30+i)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sm_ir_is_default(void){
|
||||
int i;
|
||||
for (i=0;i<16;i++){
|
||||
if (sm_persistent_ir[i] != (0x90+i)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// SMP Timeout implementation
|
||||
|
||||
// Upon transmission of the Pairing Request command or reception of the Pairing Request command,
|
||||
@ -544,7 +577,7 @@ static btstack_timer_source_t gap_random_address_update_timer;
|
||||
static uint32_t gap_random_adress_update_period;
|
||||
|
||||
static void gap_random_address_trigger(void){
|
||||
log_info("gap_random_address_trigger");
|
||||
log_info("gap_random_address_trigger, state %u", rau_state);
|
||||
if (rau_state != RAU_IDLE) return;
|
||||
rau_state = RAU_GET_RANDOM;
|
||||
sm_run();
|
||||
@ -1783,6 +1816,9 @@ static void sm_run(void){
|
||||
// assert that we can send at least commands
|
||||
if (!hci_can_send_command_packet_now()) return;
|
||||
|
||||
// pause until IR/ER are ready
|
||||
if (sm_persistent_keys_random_active) return;
|
||||
|
||||
//
|
||||
// non-connection related behaviour
|
||||
//
|
||||
@ -2766,7 +2802,6 @@ static void sm_handle_encryption_result_dkg_dhk(void *arg){
|
||||
sm_aes128_state = SM_AES128_IDLE;
|
||||
log_info_key("dhk", sm_persistent_dhk);
|
||||
dkg_state = DKG_READY;
|
||||
// DKG calculation complete => SM Init Finished
|
||||
sm_run();
|
||||
}
|
||||
|
||||
@ -2877,6 +2912,52 @@ static void sm_handle_random_result_ph3_random(void * arg){
|
||||
setup->sm_local_rand[7] = (setup->sm_local_rand[7] & 0xef) + (connection->sm_connection_authenticated << 4);
|
||||
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 2, &sm_handle_random_result_ph3_div, connection);
|
||||
}
|
||||
static void sm_validate_er_ir(void){
|
||||
// warn about default ER/IR
|
||||
int warning = 0;
|
||||
if (sm_ir_is_default()){
|
||||
warning = 1;
|
||||
log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues");
|
||||
}
|
||||
if (sm_er_is_default()){
|
||||
warning = 1;
|
||||
log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure");
|
||||
}
|
||||
log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys");
|
||||
}
|
||||
|
||||
static void sm_handle_random_result_ir(void *arg){
|
||||
sm_persistent_keys_random_active = 0;
|
||||
if (arg){
|
||||
// key generated, store in tlv
|
||||
int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16);
|
||||
log_info("Generated IR key. Store in TLV status: %d", status);
|
||||
}
|
||||
log_info_key("IR", sm_persistent_ir);
|
||||
sm_run();
|
||||
}
|
||||
|
||||
static void sm_handle_random_result_er(void *arg){
|
||||
sm_persistent_keys_random_active = 0;
|
||||
if (arg){
|
||||
// key generated, store in tlv
|
||||
int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16);
|
||||
log_info("Generated ER key. Store in TLV status: %d", status);
|
||||
}
|
||||
log_info_key("ER", sm_persistent_er);
|
||||
|
||||
// try load ir
|
||||
int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16);
|
||||
if (key_size == 16){
|
||||
// ok, let's continue
|
||||
log_info("IR from TLV");
|
||||
sm_handle_random_result_ir( NULL );
|
||||
} else {
|
||||
// invalid, generate new random one
|
||||
sm_persistent_keys_random_active = 1;
|
||||
btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir);
|
||||
}
|
||||
}
|
||||
|
||||
static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
|
||||
@ -2895,6 +2976,23 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
// bt stack activated, get started
|
||||
if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
|
||||
log_info("HCI Working!");
|
||||
|
||||
// setup IR/ER with TLV
|
||||
btstack_tlv_get_instance(&sm_tlv_impl, &sm_tlv_context);
|
||||
if (sm_tlv_impl){
|
||||
int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16);
|
||||
if (key_size == 16){
|
||||
// ok, let's continue
|
||||
log_info("ER from TLV");
|
||||
sm_handle_random_result_er( NULL );
|
||||
} else {
|
||||
// invalid, generate random one
|
||||
sm_persistent_keys_random_active = 1;
|
||||
btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er);
|
||||
}
|
||||
} else {
|
||||
sm_validate_er_ir();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3753,16 +3851,9 @@ void sm_test_set_pairing_failure(int reason){
|
||||
#endif
|
||||
|
||||
void sm_init(void){
|
||||
// set some (BTstack default) ER and IR
|
||||
int i;
|
||||
sm_key_t er;
|
||||
sm_key_t ir;
|
||||
for (i=0;i<16;i++){
|
||||
er[i] = 0x30 + i;
|
||||
ir[i] = 0x90 + i;
|
||||
}
|
||||
sm_set_er(er);
|
||||
sm_set_ir(ir);
|
||||
// set default ER and IR values (should be unique - set by app or sm later using TLV)
|
||||
sm_er_ir_set_default();
|
||||
|
||||
// defaults
|
||||
sm_accepted_stk_generation_methods = SM_STK_GENERATION_METHOD_JUST_WORKS
|
||||
| SM_STK_GENERATION_METHOD_OOB
|
||||
|
@ -61,13 +61,15 @@ typedef struct {
|
||||
void sm_init(void);
|
||||
|
||||
/**
|
||||
* @brief Set secret ER key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
|
||||
* @brief Set secret ER key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
|
||||
* @note If not set and btstack_tlv is configured, ER key is generated and stored in TLV by SM
|
||||
* @param er
|
||||
*/
|
||||
void sm_set_er(sm_key_t er);
|
||||
|
||||
/**
|
||||
* @brief Set secret IR key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
|
||||
* @brief Set secret IR key for key generation as described in Core V4.0, Vol 3, Part G, 5.2.2
|
||||
* @note If not set and btstack_tlv is configured, IR key is generated and stored in TLV by SM
|
||||
*/
|
||||
void sm_set_ir(sm_key_t ir);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user