From ac7c0c095701bcf198f0f62fa7441c328afe3e27 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 2 Jul 2019 16:23:31 +0200 Subject: [PATCH] mesh: don't store primary network key in provisioning data --- test/mesh/mesh.c | 137 ++++++++++++---------------------- test/mesh/mesh_access.c | 17 +++-- test/mesh/mesh_message_test.c | 50 ++++--------- test/mesh/provisioning.h | 22 +++--- 4 files changed, 83 insertions(+), 143 deletions(-) diff --git a/test/mesh/mesh.c b/test/mesh/mesh.c index 1cdd7997a..52a7c5fee 100644 --- a/test/mesh/mesh.c +++ b/test/mesh/mesh.c @@ -105,8 +105,6 @@ static int ui_pin_offset; static const btstack_tlv_t * btstack_tlv_singleton_impl; static void * btstack_tlv_singleton_context; -static uint8_t beacon_key[16]; -static uint8_t network_id[8]; static uint16_t primary_element_address; static int provisioned; @@ -133,64 +131,28 @@ static void mesh_print_hex(const char * name, const uint8_t * data, uint16_t len // printf("%20s: 0x%x", name, (int) value); // } +static void mesh_network_key_dump(const mesh_network_key_t * key){ + printf("NetKey: "); printf_hexdump(key->net_key, 16); + printf("-- Derived from NetKey --\n"); + printf("NID: 0x%02x\n", key->nid); + printf("NetworkID: "); printf_hexdump(key->network_id, 8); + printf("BeaconKey: "); printf_hexdump(key->beacon_key, 16); + printf("EncryptionKey: "); printf_hexdump(key->encryption_key, 16); + printf("PrivacyKey: "); printf_hexdump(key->privacy_key, 16); + printf("IdentityKey: "); printf_hexdump(key->identity_key, 16); +} + static void mesh_provisioning_dump(const mesh_provisioning_data_t * data){ printf("UnicastAddr: 0x%02x\n", data->unicast_address); printf("IV Index: 0x%08x\n", data->iv_index); printf("DevKey: "); printf_hexdump(data->device_key, 16); - printf("NetKey: "); printf_hexdump(data->net_key, 16); - printf("-- Derived from NetKey --\n"); - printf("NID: 0x%02x\n", data->nid); - printf("NetworkID: "); printf_hexdump(data->network_id, 8); - printf("BeaconKey: "); printf_hexdump(data->beacon_key, 16); - printf("EncryptionKey: "); printf_hexdump(data->encryption_key, 16); - printf("PrivacyKey: "); printf_hexdump(data->privacy_key, 16); - printf("IdentityKey: "); printf_hexdump(data->identity_key, 16); -} + printf("Flags: 0x%02x\n", data->flags); -static void mesh_network_key_add_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){ - - // get key - mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); - - // internal index 0 for primary network key - network_key->internal_index = 0; - - // get single instance - memset(network_key, 0, sizeof(mesh_network_key_t)); - - // NetKey - memcpy(network_key->net_key, provisioning_data->net_key, 16); - - // IdentityKey - memcpy(network_key->identity_key, provisioning_data->identity_key, 16); - - // BeaconKey - memcpy(network_key->beacon_key, provisioning_data->beacon_key, 16); - - // NID - network_key->nid = provisioning_data->nid; - - // EncryptionKey - memcpy(network_key->encryption_key, provisioning_data->encryption_key, 16); - - // PrivacyKey - memcpy(network_key->privacy_key, provisioning_data->privacy_key, 16); - - // NetworkID - memcpy(network_key->network_id, provisioning_data->network_id, 8); - - // setup advertisement with network id - network_key->advertisement_with_network_id.adv_length = gatt_bearer_setup_advertising_with_network_id(network_key->advertisement_with_network_id.adv_data, network_key->network_id); - - // finally add - mesh_network_key_add(network_key); } static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){ provisioned = 1; - // add to network key list - mesh_network_key_add_from_provisioning_data(provisioning_data); // set unicast address mesh_network_set_primary_element_address(provisioning_data->unicast_address); mesh_lower_transport_set_primary_element_address(provisioning_data->unicast_address); @@ -201,12 +163,10 @@ static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * p mesh_set_iv_index(provisioning_data->iv_index); // set device_key mesh_transport_set_device_key(provisioning_data->device_key); - // copy beacon key and network id - // memcpy(identity_key, provisioning_data->identity_key, 16); - memcpy(beacon_key, provisioning_data->beacon_key, 16); - memcpy(network_id, provisioning_data->network_id, 8); + // for secure beacon mesh_flags = provisioning_data->flags; + // dump data mesh_provisioning_dump(provisioning_data); @@ -339,26 +299,27 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack printf("Provisioning data available: %u\n", prov_len ? 1 : 0); if (prov_len){ mesh_setup_from_provisioning_data(&provisioning_data); + // load network keys + mesh_load_network_keys(); + // load app keys + mesh_load_app_keys(); + // load model to appkey bindings + mesh_load_appkey_lists(); + // load virtual addresses + mesh_load_virtual_addresses(); + // load model subscriptions + mesh_load_subscriptions(); + // load model publications + mesh_load_publications(); + // load foundation state + mesh_foundation_state_load(); + + // dump PTS MeshOptions.ini + mesh_pts_dump_mesh_options(); + } else { mesh_setup_without_provisiong_data(); } - // load network keys - mesh_load_network_keys(); - // load app keys - mesh_load_app_keys(); - // load model to appkey bindings - mesh_load_appkey_lists(); - // load virtual addresses - mesh_load_virtual_addresses(); - // load model subscriptions - mesh_load_subscriptions(); - // load model publications - mesh_load_publications(); - // load foundation state - mesh_foundation_state_load(); - - // dump PTS MeshOptions.ini - mesh_pts_dump_mesh_options(); #if defined(ENABLE_MESH_ADV_BEARER) || defined(ENABLE_MESH_PB_ADV) @@ -404,7 +365,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ if (packet_type != HCI_EVENT_PACKET) return; mesh_provisioning_data_t provisioning_data; - mesh_network_key_t * network_key; + mesh_network_key_t * primary_network_key; switch(packet[0]){ case HCI_EVENT_MESH_META: switch(packet[2]){ @@ -427,37 +388,36 @@ static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t cha case MESH_SUBEVENT_PB_PROV_COMPLETE: printf("Provisioning complete\n"); + // delete old data + mesh_delete_network_keys(); + mesh_delete_app_keys(); + mesh_delete_appkey_lists(); + + // get provisioning data memcpy(provisioning_data.device_key, provisioning_device_data_get_device_key(), 16); provisioning_data.iv_index = provisioning_device_data_get_iv_index(); provisioning_data.flags = provisioning_device_data_get_flags(); provisioning_data.unicast_address = provisioning_device_data_get_unicast_address(); - network_key = provisioning_device_data_get_network_key(); - memcpy(provisioning_data.net_key, network_key->net_key, 16); - memcpy(provisioning_data.network_id, network_key->network_id, 8); - memcpy(provisioning_data.identity_key, network_key->identity_key, 16); - memcpy(provisioning_data.beacon_key, network_key->beacon_key, 16); - memcpy(provisioning_data.encryption_key, network_key->encryption_key, 16); - memcpy(provisioning_data.privacy_key, network_key->privacy_key, 16); - provisioning_data.nid = network_key->nid; - - // delete old app keys - mesh_delete_app_keys(); + // get primary netkey + primary_network_key = provisioning_device_data_get_network_key(); + mesh_network_key_dump(primary_network_key); - // delete old model to appkey bindings - mesh_delete_appkey_lists(); + // add to network keys + mesh_network_key_add(primary_network_key); - // store in TLV + // store provisioning data and primary network key in TLV btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, 'PROV', (uint8_t *) &provisioning_data, sizeof(mesh_provisioning_data_t)); + mesh_store_network_key(primary_network_key); // setup after provisioned mesh_setup_from_provisioning_data(&provisioning_data); // start advertising with node id after provisioning - mesh_proxy_set_advertising_with_node_id(network_key->netkey_index, MESH_NODE_IDENTITY_STATE_ADVERTISING_RUNNING); + mesh_proxy_set_advertising_with_node_id(primary_network_key->netkey_index, MESH_NODE_IDENTITY_STATE_ADVERTISING_RUNNING); // start sending Secure Network Beacons - beacon_secure_network_start(network_key); + beacon_secure_network_start(primary_network_key); break; default: @@ -618,7 +578,6 @@ static void send_pts_network_messsage(int type){ mesh_network_send(0, ctl, ttl, seq, src, dst, lower_transport_pdu_data, lower_transport_pdu_len); } - static void send_pts_unsegmented_access_messsage(void){ uint8_t access_pdu_data[16]; diff --git a/test/mesh/mesh_access.c b/test/mesh/mesh_access.c index fddeecaf3..ef68e4c54 100644 --- a/test/mesh/mesh_access.c +++ b/test/mesh/mesh_access.c @@ -938,7 +938,7 @@ void mesh_store_network_key(mesh_network_key_t * network_key){ data.version = network_key->version; memcpy(data.encryption_key, network_key->encryption_key, 16); memcpy(data.privacy_key, network_key->privacy_key, 16); - btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data)); + btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(mesh_persistent_net_key_t)); } void mesh_delete_network_key(uint16_t internal_index){ @@ -955,8 +955,8 @@ void mesh_load_network_keys(void){ for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){ mesh_persistent_net_key_t data; uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index); - int app_key_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data)); - if (app_key_len == 0) continue; + int netkey_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data)); + if (netkey_len != sizeof(mesh_persistent_net_key_t)) continue; mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); if (network_key == NULL) return; @@ -971,6 +971,11 @@ void mesh_load_network_keys(void){ memcpy(network_key->encryption_key, data.encryption_key, 16); memcpy(network_key->privacy_key, data.privacy_key, 16); +#ifdef ENABLE_GATT_BEARER + // setup advertisement with network id + network_key->advertisement_with_network_id.adv_length = gatt_bearer_setup_advertising_with_network_id(network_key->advertisement_with_network_id.adv_data, network_key->network_id); +#endif + mesh_network_key_add(network_key); printf("- internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid); printf_hexdump(network_key->net_key, 16); @@ -981,7 +986,7 @@ void mesh_delete_network_keys(void){ printf("Delete Network Keys\n"); uint16_t internal_index; - for (internal_index = 0; internal_index < MAX_NR_MESH_TRANSPORT_KEYS; internal_index++){ + for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){ mesh_delete_network_key(internal_index); } } @@ -997,7 +1002,7 @@ typedef struct { } mesh_persistent_app_key_t; static uint32_t mesh_transport_key_tag_for_internal_index(uint16_t internal_index){ - return ((uint32_t) 'M' << 24) | ((uint32_t) 'N' << 16) | ((uint32_t) internal_index); + return ((uint32_t) 'M' << 24) | ((uint32_t) 'A' << 16) | ((uint32_t) internal_index); } void mesh_store_app_key(uint16_t internal_index, uint16_t netkey_index, uint16_t appkey_index, uint8_t aid, const uint8_t * application_key){ @@ -1041,7 +1046,7 @@ void mesh_load_app_keys(void){ key->akf = 1; memcpy(key->key, data.key, 16); mesh_transport_key_add(key); - printf("- internal index 0x%x, AppKey Index 0x%06x, , AID %02x: ", key->internal_index, key->appkey_index, key->aid); + printf("- internal index 0x%x, AppKey Index 0x%06x, AID %02x: ", key->internal_index, key->appkey_index, key->aid); printf_hexdump(key->key, 16); } } diff --git a/test/mesh/mesh_message_test.c b/test/mesh/mesh_message_test.c index bb07dc08c..c792c08f0 100644 --- a/test/mesh/mesh_message_test.c +++ b/test/mesh/mesh_message_test.c @@ -145,26 +145,6 @@ static void btstack_print_hex(const uint8_t * data, uint16_t len, char separator } #endif -static void add_network_key_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){ - - // get key - mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); - - // get single instance - memset(network_key, 0, sizeof(mesh_network_key_t)); - - // NID - network_key->nid = provisioning_data->nid; - - // PrivacyKey - memcpy(network_key->privacy_key, provisioning_data->privacy_key, 16); - - // EncryptionKey - memcpy(network_key->encryption_key, provisioning_data->encryption_key, 16); - - mesh_network_key_add(network_key); -} - static mesh_transport_key_t test_application_key; static void mesh_application_key_set(uint16_t netkey_index, uint16_t appkey_index, uint8_t aid, const uint8_t *application_key) { test_application_key.netkey_index = netkey_index; @@ -176,27 +156,27 @@ static void mesh_application_key_set(uint16_t netkey_index, uint16_t appkey_inde } static void load_network_key_nid_68(void){ - mesh_provisioning_data_t provisioning_data; - provisioning_data.nid = 0x68; - btstack_parse_hex("0953fa93e7caac9638f58820220a398e", 16, provisioning_data.encryption_key); - btstack_parse_hex("8b84eedec100067d670971dd2aa700cf", 16, provisioning_data.privacy_key); - add_network_key_from_provisioning_data(&provisioning_data); + mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); + network_key->nid = 0x68; + btstack_parse_hex("0953fa93e7caac9638f58820220a398e", 16, network_key->encryption_key); + btstack_parse_hex("8b84eedec100067d670971dd2aa700cf", 16, network_key->privacy_key); + mesh_network_key_add(network_key); } static void load_network_key_nid_5e(void){ - mesh_provisioning_data_t provisioning_data; - provisioning_data.nid = 0x5e; - btstack_parse_hex("be635105434859f484fc798e043ce40e", 16, provisioning_data.encryption_key); - btstack_parse_hex("5d396d4b54d3cbafe943e051fe9a4eb8", 16, provisioning_data.privacy_key); - add_network_key_from_provisioning_data(&provisioning_data); + mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); + network_key->nid = 0x5e; + btstack_parse_hex("be635105434859f484fc798e043ce40e", 16, network_key->encryption_key); + btstack_parse_hex("5d396d4b54d3cbafe943e051fe9a4eb8", 16, network_key->privacy_key); + mesh_network_key_add(network_key); } static void load_network_key_nid_10(void){ - mesh_provisioning_data_t provisioning_data; - provisioning_data.nid = 0x10; - btstack_parse_hex("3a4fe84a6cc2c6a766ea93f1084d4039", 16, provisioning_data.encryption_key); - btstack_parse_hex("f695fcce709ccface4d8b7a1e6e39d25", 16, provisioning_data.privacy_key); - add_network_key_from_provisioning_data(&provisioning_data); + mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); + network_key->nid = 0x10; + btstack_parse_hex("3a4fe84a6cc2c6a766ea93f1084d4039", 16, network_key->encryption_key); + btstack_parse_hex("f695fcce709ccface4d8b7a1e6e39d25", 16, network_key->privacy_key); + mesh_network_key_add(network_key); } static void load_provisioning_data_test_message(void){ diff --git a/test/mesh/provisioning.h b/test/mesh/provisioning.h index 11c25cd4e..bd8d19ac6 100644 --- a/test/mesh/provisioning.h +++ b/test/mesh/provisioning.h @@ -125,22 +125,18 @@ typedef enum { } mesh_identification_type_t; typedef struct { + // DevKey = k1(ECDHSecret, ProvisioningSalt, “prdk”) uint8_t device_key[16]; - uint8_t flags; - uint32_t iv_index; + + // Unicast Address uint16_t unicast_address; - // net_key and derived data - uint8_t net_key[16]; - // k1 - uint8_t identity_key[16]; - uint8_t beacon_key[16]; - // k2 - uint8_t nid; - uint8_t encryption_key[16]; - uint8_t privacy_key[16]; - // k3 - uint8_t network_id[8]; + // Key Refresh Phase 0 vs. 2, IV Update Active + uint8_t flags; + + // IV Index + uint32_t iv_index; + } mesh_provisioning_data_t; #ifdef __cplusplus