diff --git a/platform/posix/le_device_db_fs.c b/platform/posix/le_device_db_fs.c index 060e4c583..e0a99dd77 100644 --- a/platform/posix/le_device_db_fs.c +++ b/platform/posix/le_device_db_fs.c @@ -61,6 +61,7 @@ typedef struct le_device_memory_db { uint8_t key_size; uint8_t authenticated; uint8_t authorized; + uint8_t secure_connection; #ifdef ENABLE_LE_SIGNED_WRITE // Signed Writes by remote @@ -87,7 +88,12 @@ typedef struct le_device_memory_db { #define DB_PATH_TEMPLATE (LE_DEVICE_DB_PATH "btstack_at_%s_le_device_db.txt") -const char * csv_header = "# addr_type, addr, irk, ltk, ediv, rand[8], key_size, authenticated, authorized, remote_csrk, remote_counter, local_csrk, local_counter"; +#ifdef ENABLE_LE_SIGNED_WRITE +const char * csv_header = "# addr_type, addr, irk, ltk, ediv, rand[8], key_size, authenticated, authorized, remote_csrk, remote_counter, local_csrk, local_counter, secure_connection"; +#else +const char * csv_header = "# addr_type, addr, irk, ltk, ediv, rand[8], key_size, authenticated, authorized, secure_connection"; +#endif + static char db_path[sizeof(DB_PATH_TEMPLATE) - 2 + 17 + 1]; static le_device_memory_db_t le_devices[LE_DEVICE_MEMORY_SIZE]; @@ -165,6 +171,7 @@ static void le_device_db_store(void) { write_hex(wFile, le_devices[i].local_csrk, 16); write_value(wFile, le_devices[i].local_counter, 2); #endif + write_value(wFile, le_devices[i].secure_connection, 1); fwrite("\n", 1, 1, wFile); } fclose(wFile); @@ -213,6 +220,7 @@ static void le_device_db_read(void){ // read entries int i; for (i=0 ; i= 0){ + int d = fgetc(wFile); + le_devices[i].secure_connection = nibble_for_char(c) << 4 | nibble_for_char(d); + // read newline + fgetc(wFile); + } } exit: fclose(wFile); @@ -310,9 +324,9 @@ void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk) if (irk) memcpy(irk, le_devices[index].irk, 16); } -void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized){ - log_info("Central Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u", - index, ediv, key_size, authenticated, authorized); +void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized, int secure_connection){ + log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u, secure connection %u", + index, ediv, key_size, authenticated, authorized, secure_connection); le_device_memory_db_t * device = &le_devices[index]; device->ediv = ediv; if (rand) memcpy(device->rand, rand, 8); @@ -320,20 +334,22 @@ void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_k device->key_size = key_size; device->authenticated = authenticated; device->authorized = authorized; + device->secure_connection = secure_connection; le_device_db_store(); } -void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized){ +void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized, int * secure_connection){ le_device_memory_db_t * device = &le_devices[index]; - log_info("Central Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u", - index, device->ediv, device->key_size, device->authenticated, device->authorized); + log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u, secure connection %u", + index, device->ediv, device->key_size, device->authenticated, device->authorized, device->secure_connection); if (ediv) *ediv = device->ediv; if (rand) memcpy(rand, device->rand, 8); if (ltk) memcpy(ltk, device->ltk, 16); if (key_size) *key_size = device->key_size; if (authenticated) *authenticated = device->authenticated; if (authorized) *authorized = device->authorized; + if (secure_connection) *secure_connection = device->secure_connection; } #ifdef ENABLE_LE_SIGNED_WRITE diff --git a/platform/wiced/le_device_db_wiced_dct.c b/platform/wiced/le_device_db_wiced_dct.c index 130b355ee..a9b8783db 100644 --- a/platform/wiced/le_device_db_wiced_dct.c +++ b/platform/wiced/le_device_db_wiced_dct.c @@ -73,6 +73,8 @@ typedef struct le_device_nvm { uint8_t key_size; uint8_t authenticated; uint8_t authorized; + uint8_t secure_connection; + sm_key_t ltk; // Stored pairing information allows to re-establish an enncrypted connection @@ -243,14 +245,14 @@ int le_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){ return absolute_index; } -void le_device_db_encryption_set(int device_index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized){ +void le_device_db_encryption_set(int device_index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized, int secure_connection){ int absolute_index = le_device_db_get_absolute_index_for_device_index(device_index); le_device_nvm_t entry; le_device_db_entry_read(absolute_index, &entry); - log_info("set encryption for #%u, ediv 0x%04x, key size %u, authenticated %u, authorized %u", - absolute_index, ediv, key_size, authenticated, authorized); + log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u, secure connection %u", + device_index, ediv, key_size, authenticated, authorized, secure_connection); entry.ediv = ediv; if (rand) memcpy(entry.rand, rand, 8); @@ -258,18 +260,19 @@ void le_device_db_encryption_set(int device_index, uint16_t ediv, uint8_t rand[8 entry.key_size = key_size; entry.authenticated = authenticated; entry.authorized = authorized; + entry.secure_connection = secure_connection; le_device_db_entry_write(absolute_index, &entry); } -void le_device_db_encryption_get(int device_index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized){ +void le_device_db_encryption_get(int device_index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized, int * secure_connection){ int absolute_index = le_device_db_get_absolute_index_for_device_index(device_index); le_device_nvm_t entry; le_device_db_entry_read(absolute_index, &entry); - log_info("encryption for #%u, ediv x%04x, keysize %u, authenticated %u, authorized %u", - absolute_index, entry.ediv, entry.key_size, entry.authenticated, entry.authorized); + log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u, secure connection %u", + device_index, entry.ediv, entry.key_size, entry.authenticated, entry.authorized, entry.secure_connection); if (ediv) *ediv = entry.ediv; if (rand) memcpy(rand, entry.rand, 8); @@ -277,6 +280,7 @@ void le_device_db_encryption_get(int device_index, uint16_t * ediv, uint8_t rand if (key_size) *key_size = entry.key_size; if (authenticated) *authenticated = entry.authenticated; if (authorized) *authorized = entry.authorized; + if (secure_connection) *secure_connection = entry.secure_connection; } void le_device_db_dump(void){ diff --git a/src/ble/le_device_db.h b/src/ble/le_device_db.h index 02630a3ed..7070a03f8 100644 --- a/src/ble/le_device_db.h +++ b/src/ble/le_device_db.h @@ -113,8 +113,9 @@ void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk) * @brief key size * @brief authenticated * @brief authorized + * @breif secure_connection */ -void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized); +void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized, int secure_connection); /** * @brief get remote encryption info @@ -125,8 +126,9 @@ void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_k * @brief key size * @brief authenticated * @brief authorized + * @breif secure_connection */ -void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized); +void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized, int * secure_connection); #ifdef ENABLE_LE_SIGNED_WRITE diff --git a/src/ble/le_device_db_memory.c b/src/ble/le_device_db_memory.c index db9834463..101a597ab 100644 --- a/src/ble/le_device_db_memory.c +++ b/src/ble/le_device_db_memory.c @@ -63,6 +63,7 @@ typedef struct le_device_memory_db { uint8_t key_size; uint8_t authenticated; uint8_t authorized; + uint8_t secure_connection; #ifdef ENABLE_LE_SIGNED_WRITE // Signed Writes by remote @@ -146,9 +147,9 @@ void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk) if (irk) memcpy(irk, le_devices[index].irk, 16); } -void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized){ - log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u", - index, ediv, key_size, authenticated, authorized); +void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized, int secure_connection){ + log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u, secure connection %u", + index, ediv, key_size, authenticated, authorized, secure_connection); le_device_memory_db_t * device = &le_devices[index]; device->ediv = ediv; if (rand) memcpy(device->rand, rand, 8); @@ -156,18 +157,20 @@ void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_k device->key_size = key_size; device->authenticated = authenticated; device->authorized = authorized; + device->secure_connection = secure_connection; } -void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized){ +void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized, int * secure_connection){ le_device_memory_db_t * device = &le_devices[index]; - log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u", - index, device->ediv, device->key_size, device->authenticated, device->authorized); + log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u, secure connection %u", + index, entry.ediv, entry.key_size, entry.authenticated, entry.authorized, entry.secure_connection); if (ediv) *ediv = device->ediv; if (rand) memcpy(rand, device->rand, 8); if (ltk) memcpy(ltk, device->ltk, 16); if (key_size) *key_size = device->key_size; if (authenticated) *authenticated = device->authenticated; if (authorized) *authorized = device->authorized; + if (secure_connection) *secure_connection = device->secure_connection; } #ifdef ENABLE_LE_SIGNED_WRITE diff --git a/src/ble/le_device_db_tlv.c b/src/ble/le_device_db_tlv.c index 0257401da..b3570dd5d 100644 --- a/src/ble/le_device_db_tlv.c +++ b/src/ble/le_device_db_tlv.c @@ -66,9 +66,11 @@ typedef struct le_device_db_entry_t { sm_key_t ltk; uint16_t ediv; uint8_t rand[8]; + uint8_t key_size; uint8_t authenticated; uint8_t authorized; + uint8_t secure_connection; #ifdef ENABLE_LE_SIGNED_WRITE // Signed Writes by remote @@ -290,7 +292,7 @@ void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk) if (irk) memcpy(irk, entry.irk, 16); } -void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized){ +void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized, int secure_connection){ // fetch entry le_device_db_entry_t entry; @@ -298,20 +300,21 @@ void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_k if (!ok) return; // update - log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u", - index, ediv, key_size, authenticated, authorized); + log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u, secure connection %u", + index, ediv, key_size, authenticated, authorized, secure_connection); entry.ediv = ediv; if (rand) memcpy(entry.rand, rand, 8); if (ltk) memcpy(entry.ltk, ltk, 16); entry.key_size = key_size; entry.authenticated = authenticated; entry.authorized = authorized; + entry.secure_connection = secure_connection; // store le_device_db_tlv_store(index, &entry); } -void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized){ +void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized, int * secure_connection){ // fetch entry le_device_db_entry_t entry; @@ -319,14 +322,15 @@ void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm if (!ok) return; // update user fields - log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u", - index, entry.ediv, entry.key_size, entry.authenticated, entry.authorized); + log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u, secure connection %u", + index, entry.ediv, entry.key_size, entry.authenticated, entry.authorized, entry.secure_connection); if (ediv) *ediv = entry.ediv; if (rand) memcpy(rand, entry.rand, 8); if (ltk) memcpy(ltk, entry.ltk, 16); if (key_size) *key_size = entry.key_size; if (authenticated) *authenticated = entry.authenticated; if (authorized) *authorized = entry.authorized; + if (secure_connection) *secure_connection = entry.secure_connection; } #ifdef ENABLE_LE_SIGNED_WRITE diff --git a/src/ble/sm.c b/src/ble/sm.c index d1d0537a9..582d97350 100644 --- a/src/ble/sm.c +++ b/src/ble/sm.c @@ -1175,7 +1175,7 @@ static void sm_address_resolution_handle_event(address_resolution_event_t event) break; } #ifdef ENABLE_LE_CENTRAL - le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL); + le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); have_ltk = !sm_is_null_key(ltk); pairing_need = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; log_info("central: pairing request local %u, remote %u => action %u. have_ltk %u", @@ -1317,7 +1317,7 @@ static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ uint8_t zero_rand[8]; memset(zero_rand, 0, 8); le_device_db_encryption_set(le_db_index, 0, zero_rand, setup->sm_ltk, sm_conn->sm_actual_encryption_key_size, - sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED); + sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 1); } // store encryption information for legacy pairing: peer LTK, EDIV, RAND @@ -1325,7 +1325,7 @@ static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ && (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION )){ log_info("sm: set encryption information (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, - sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED); + sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 0); } } @@ -1781,14 +1781,16 @@ static void sm_load_security_info(sm_connection_t * sm_connection){ int encryption_key_size; int authenticated; int authorized; + int secure_connection; // fetch data from device db - incl. authenticated/authorized/key size. Note all sm_connection_X require encryption enabled le_device_db_encryption_get(sm_connection->sm_le_db_index, &setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, - &encryption_key_size, &authenticated, &authorized); - log_info("db index %u, key size %u, authenticated %u, authorized %u", sm_connection->sm_le_db_index, encryption_key_size, authenticated, authorized); + &encryption_key_size, &authenticated, &authorized, &secure_connection); + log_info("db index %u, key size %u, authenticated %u, authorized %u, secure connetion %u", sm_connection->sm_le_db_index, encryption_key_size, authenticated, authorized, secure_connection); sm_connection->sm_actual_encryption_key_size = encryption_key_size; sm_connection->sm_connection_authenticated = authenticated; sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN; + sm_connection->sm_connection_sc = secure_connection; } #endif @@ -1801,6 +1803,8 @@ static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_con sm_connection->sm_actual_encryption_key_size = (setup->sm_local_rand[7] & 0x0f) + 1; // no db for authenticated flag hack: flag is stored in bit 4 of LSB sm_connection->sm_connection_authenticated = (setup->sm_local_rand[7] & 0x10) >> 4; + // Legacy paring -> not SC + sm_connection->sm_connection_sc = 0; log_info("sm: received ltk request with key size %u, authenticated %u", sm_connection->sm_actual_encryption_key_size, sm_connection->sm_connection_authenticated); sm_connection->sm_engine_state = SM_RESPONDER_PH4_Y_GET_ENC; @@ -3966,7 +3970,7 @@ void sm_request_pairing(hci_con_handle_t con_handle){ switch (sm_conn->sm_irk_lookup_state){ case IRK_LOOKUP_SUCCEEDED: #ifndef ENABLE_LE_CENTRAL_AUTO_ENCRYPTION - le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL); + le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); int have_ltk = !sm_is_null_key(ltk); log_info("have ltk %u", have_ltk); // trigger 'pairing complete' event on encryption change diff --git a/src/hci.h b/src/hci.h index 876b458af..e1be5816c 100644 --- a/src/hci.h +++ b/src/hci.h @@ -388,6 +388,7 @@ typedef struct sm_connection { irk_lookup_state_t sm_irk_lookup_state; uint8_t sm_connection_encrypted; uint8_t sm_connection_authenticated; // [0..1] + uint8_t sm_connection_sc; uint8_t sm_actual_encryption_key_size; sm_pairing_packet_t sm_m_preq; // only used during c1 authorization_state_t sm_connection_authorization_state;