add encryption info to central db

This commit is contained in:
matthias.ringwald@gmail.com 2015-03-02 21:12:29 +00:00
parent 4685dbaa3a
commit d2d764240d
5 changed files with 149 additions and 27 deletions

View File

@ -203,7 +203,7 @@ static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
// update sequence number
uint32_t counter_packet = READ_BT_32(att_request_buffer, att_request_size-12);
central_device_db_counter_set(att_ir_central_device_db_index, counter_packet+1);
central_device_db_remote_counter_set(att_ir_central_device_db_index, counter_packet+1);
att_server_state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
att_run();
}
@ -237,7 +237,7 @@ static void att_run(void){
// check counter
uint32_t counter_packet = READ_BT_32(att_request_buffer, att_request_size-12);
uint32_t counter_db = central_device_db_counter_get(att_ir_central_device_db_index);
uint32_t counter_db = central_device_db_remote_counter_get(att_ir_central_device_db_index);
log_info("ATT Signed Write, DB counter %u, packet counter %u", counter_db, counter_packet);
if (counter_packet < counter_db){
log_info("ATT Signed Write, db reports higher counter, abort");
@ -247,7 +247,7 @@ static void att_run(void){
// signature is { sequence counter, secure hash }
sm_key_t csrk;
central_device_db_csrk(att_ir_central_device_db_index, csrk);
central_device_db_csrk_get(att_ir_central_device_db_index, csrk);
att_server_state = ATT_SERVER_W4_SIGNED_WRITE_VALIDATION;
log_info("Orig Signature: ");
hexdump( &att_request_buffer[att_request_size-8], 8);

View File

@ -69,10 +69,10 @@ void central_device_db_init();
/**
* @brief add device to db
* @param addr_type, address of the device
* @param irk and csrk of the device
* @param irk of the device
* @returns index if successful, -1 otherwise
*/
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk, sm_key_t csrk);
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk);
/**
* @brief get number of devices in db for enumeration
@ -88,26 +88,66 @@ int central_device_db_count(void);
*/
void central_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk);
/**
* @brief set remote encryption info
* @brief index
* @brief ediv
* @brief rand
* @brief ltk
*/
void central_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk);
/**
* @brief get remote encryption info
* @brief index
* @brief ediv
* @brief rand
* @brief ltk
*/
void central_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk);
/**
* @brief set signing key for this device
* @param index
* @param signing key as input
*/
void central_device_db_csrk_set(int index, sm_key_t csrk);
/**
* @brief get signing key for this device
* @param index
* @param signing key as output
*/
void central_device_db_csrk(int index, sm_key_t csrk);
void central_device_db_csrk_get(int index, sm_key_t csrk);
/**
* @brief query last used/seen signing counter
* @param index
* @returns next expected counter, 0 after devices was added
*/
uint32_t central_device_db_counter_get(int index);
uint32_t central_device_db_remote_counter_get(int index);
/**
* @brief update signing counter
* @param index
* @param counter to store
*/
void central_device_db_counter_set(int index, uint32_t counter);
void central_device_db_remote_counter_set(int index, uint32_t counter);
/**
* @brief query last used/seen signing counter
* @param index
* @returns next expected counter, 0 after devices was added
*/
uint32_t central_device_db_local_counter_get(int index);
/**
* @brief update signing counter
* @param index
* @param counter to store
*/
void central_device_db_local_counter_set(int index, uint32_t counter);
/**
* @brief free device

View File

@ -40,7 +40,7 @@
void central_device_db_init(){}
// @returns index if successful, -1 otherwise
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk, sm_key_t csrk){
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
return -1;
}
@ -49,19 +49,45 @@ int central_device_db_count(void){
return 0;
}
/**
* @brief set remote encryption info
* @brief index
* @brief ediv
* @brief rand
* @brief ltk
*/
void central_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk){}
/**
* @brief get remote encryption info
* @brief index
* @brief ediv
* @brief rand
* @brief ltk
*/
void central_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk){}
// get device information: addr type and address
void central_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t csrk){}
// get signature key
void central_device_db_csrk(int index, sm_key_t csrk){}
void central_device_db_csrk_get(int index, sm_key_t csrk){}
// query last used/seen signing counter
uint32_t central_device_db_counter_get(int index){
uint32_t central_device_db_remote_counter_get(int index){
return 0xffffffff;
}
// update signing counter
void central_device_db_counter_set(int index, uint32_t counter){}
void central_device_db_local_counter_set(int index, uint32_t counter){}
// query last used/seen signing counter
uint32_t central_device_db_local_counter_get(int index){
return 0xffffffff;
}
// update signing counter
void central_device_db_remote_counter_set(int index, uint32_t counter){}
// free device
void central_device_db_remove(int index){}

View File

@ -86,12 +86,12 @@ int central_device_db_count(void){
return counter;
}
// free device - TODO not implemented
// free device
void central_device_db_remove(int index){
central_devices[index].addr_type = INVALID_ENTRY_ADDR_TYPE;
}
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk, sm_key_t csrk){
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
int i;
int index = -1;
for (i=0;i<CENTRAL_DEVICE_MEMORY_SIZE;i++){
@ -105,11 +105,9 @@ int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk, sm_key_t
log_info("Central Device DB adding type %u - %s", addr_type, bd_addr_to_str(addr));
log_key("irk", irk);
log_key("csrk", csrk);
central_devices[index].addr_type = addr_type;
memcpy(central_devices[index].addr, addr, 6);
memcpy(central_devices[index].csrk, csrk, 16);
memcpy(central_devices[index].irk, irk, 16);
central_devices[index].remote_counter = 0;
@ -124,22 +122,61 @@ void central_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t
if (irk) memcpy(irk, central_devices[index].irk, 16);
}
/**
* @brief set remote encryption info
* @brief index
* @brief ediv
* @brief rand
* @brief ltk
*/
void central_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk){
central_devices[index].ediv = ediv;
if (rand) memcpy(central_devices[index].rand, rand, 8);
if (ltk) memcpy(central_devices[index].ltk, ltk, 16);
}
/**
* @brief get remote encryption info
* @brief index
* @brief ediv
* @brief rand
* @brief ltk
*/
void central_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk){
if (ediv) *ediv = central_devices[index].ediv;
if (rand) memcpy(rand, central_devices[index].rand, 8);
if (ltk) memcpy(ltk, central_devices[index].ltk, 16);
}
// get signature key
void central_device_db_csrk(int index, sm_key_t csrk){
void central_device_db_csrk_get(int index, sm_key_t csrk){
if (csrk) memcpy(csrk, central_devices[index].csrk, 16);
}
void central_device_db_csrk_set(int index, sm_key_t csrk){
if (csrk) memcpy(central_devices[index].csrk, csrk, 16);
}
// query last used/seen signing counter
uint32_t central_device_db_counter_get(int index){
uint32_t central_device_db_remote_counter_get(int index){
return central_devices[index].remote_counter;
}
// update signing counter
void central_device_db_counter_set(int index, uint32_t counter){
void central_device_db_remote_counter_set(int index, uint32_t counter){
central_devices[index].remote_counter = counter;
}
// query last used/seen signing counter
uint32_t central_device_db_local_counter_get(int index){
return central_devices[index].local_counter;
}
// update signing counter
void central_device_db_local_counter_set(int index, uint32_t counter){
central_devices[index].local_counter = counter;
}
void central_device_db_dump(){
log_info("Central Device DB dump, devices: %u", central_device_db_count);
int i;

View File

@ -215,8 +215,10 @@ typedef struct sm_setup_context {
uint8_t sm_peer_rand[8];
sm_key_t sm_peer_ltk;
sm_key_t sm_peer_irk;
sm_key_t sm_peer_csrk;
uint8_t sm_peer_addr_type;
bd_addr_t sm_peer_address;
} sm_setup_context_t;
//
@ -1579,6 +1581,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
sm_conn->sm_connection_encrypted = 0;
sm_conn->sm_connection_authenticated = 0;
sm_conn->sm_connection_authorization_state = AUTHORIZATION_UNKNOWN;
sm_conn->sm_central_db_index = -1;
// prepare CSRK lookup (does not involve setup)
sm_conn->sm_csrk_lookup_state = CSRK_LOOKUP_W4_READY;
@ -1733,7 +1736,6 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
log_debug("sm_packet_handler: state %u, pdu 0x%02x", sm_conn->sm_engine_state, packet[0]);
sm_key_t csrk;
int err;
switch (sm_conn->sm_engine_state){
@ -1869,13 +1871,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
case SM_CODE_SIGNING_INFORMATION:
setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION;
swap128(&packet[1], csrk);
// store, if: it's a public address, or, we got an IRK
if (setup->sm_peer_addr_type == 0 || (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION)) {
sm_central_device_matched = central_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk, csrk);
break;
}
swap128(&packet[1], setup->sm_peer_csrk);
break;
default:
// Unexpected PDU
@ -1884,6 +1880,29 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
}
// done with key distribution?
if (sm_key_distribution_all_received()){
// store, if: it's a public address, or, we got an IRK
if (setup->sm_peer_addr_type == 0 || (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION)) {
sm_conn->sm_central_db_index = central_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk);
}
if (sm_conn->sm_central_db_index >= 0){
central_device_db_local_counter_set(sm_conn->sm_central_db_index, 0);
// store CSRK
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){
central_device_db_csrk_set(sm_conn->sm_central_db_index, setup->sm_peer_csrk);
central_device_db_remote_counter_set(sm_conn->sm_central_db_index, 0);
}
// store encryption information as Central
if (sm_conn->sm_role == 0
&& setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION
&& setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION){
central_device_db_encryption_set(sm_conn->sm_central_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk);
}
}
if (sm_conn->sm_role){
sm_conn->sm_engine_state = SM_GENERAL_IDLE;
sm_done_for_handle(sm_conn->sm_handle);