mesh: don't store primary network key in provisioning data

This commit is contained in:
Matthias Ringwald 2019-07-02 16:23:31 +02:00
parent de7d11c030
commit ac7c0c0957
4 changed files with 83 additions and 143 deletions

View File

@ -105,8 +105,6 @@ static int ui_pin_offset;
static const btstack_tlv_t * btstack_tlv_singleton_impl; static const btstack_tlv_t * btstack_tlv_singleton_impl;
static void * btstack_tlv_singleton_context; 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 uint16_t primary_element_address;
static int provisioned; 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); // 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){ static void mesh_provisioning_dump(const mesh_provisioning_data_t * data){
printf("UnicastAddr: 0x%02x\n", data->unicast_address); printf("UnicastAddr: 0x%02x\n", data->unicast_address);
printf("IV Index: 0x%08x\n", data->iv_index); printf("IV Index: 0x%08x\n", data->iv_index);
printf("DevKey: "); printf_hexdump(data->device_key, 16); printf("DevKey: "); printf_hexdump(data->device_key, 16);
printf("NetKey: "); printf_hexdump(data->net_key, 16); printf("Flags: 0x%02x\n", data->flags);
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);
}
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){ static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){
provisioned = 1; provisioned = 1;
// add to network key list
mesh_network_key_add_from_provisioning_data(provisioning_data);
// set unicast address // set unicast address
mesh_network_set_primary_element_address(provisioning_data->unicast_address); mesh_network_set_primary_element_address(provisioning_data->unicast_address);
mesh_lower_transport_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); mesh_set_iv_index(provisioning_data->iv_index);
// set device_key // set device_key
mesh_transport_set_device_key(provisioning_data->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 // for secure beacon
mesh_flags = provisioning_data->flags; mesh_flags = provisioning_data->flags;
// dump data // dump data
mesh_provisioning_dump(provisioning_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); printf("Provisioning data available: %u\n", prov_len ? 1 : 0);
if (prov_len){ if (prov_len){
mesh_setup_from_provisioning_data(&provisioning_data); 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 { } else {
mesh_setup_without_provisiong_data(); 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) #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){ 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; if (packet_type != HCI_EVENT_PACKET) return;
mesh_provisioning_data_t provisioning_data; mesh_provisioning_data_t provisioning_data;
mesh_network_key_t * network_key; mesh_network_key_t * primary_network_key;
switch(packet[0]){ switch(packet[0]){
case HCI_EVENT_MESH_META: case HCI_EVENT_MESH_META:
switch(packet[2]){ 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: case MESH_SUBEVENT_PB_PROV_COMPLETE:
printf("Provisioning complete\n"); 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); memcpy(provisioning_data.device_key, provisioning_device_data_get_device_key(), 16);
provisioning_data.iv_index = provisioning_device_data_get_iv_index(); provisioning_data.iv_index = provisioning_device_data_get_iv_index();
provisioning_data.flags = provisioning_device_data_get_flags(); provisioning_data.flags = provisioning_device_data_get_flags();
provisioning_data.unicast_address = provisioning_device_data_get_unicast_address(); provisioning_data.unicast_address = provisioning_device_data_get_unicast_address();
network_key = provisioning_device_data_get_network_key(); // get primary netkey
memcpy(provisioning_data.net_key, network_key->net_key, 16); primary_network_key = provisioning_device_data_get_network_key();
memcpy(provisioning_data.network_id, network_key->network_id, 8); mesh_network_key_dump(primary_network_key);
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();
// delete old model to appkey bindings // add to network keys
mesh_delete_appkey_lists(); 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)); 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 // setup after provisioned
mesh_setup_from_provisioning_data(&provisioning_data); mesh_setup_from_provisioning_data(&provisioning_data);
// start advertising with node id after provisioning // 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 // start sending Secure Network Beacons
beacon_secure_network_start(network_key); beacon_secure_network_start(primary_network_key);
break; break;
default: 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); 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){ static void send_pts_unsegmented_access_messsage(void){
uint8_t access_pdu_data[16]; uint8_t access_pdu_data[16];

View File

@ -938,7 +938,7 @@ void mesh_store_network_key(mesh_network_key_t * network_key){
data.version = network_key->version; data.version = network_key->version;
memcpy(data.encryption_key, network_key->encryption_key, 16); memcpy(data.encryption_key, network_key->encryption_key, 16);
memcpy(data.privacy_key, network_key->privacy_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){ 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++){ for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
mesh_persistent_net_key_t data; mesh_persistent_net_key_t data;
uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index); 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)); int netkey_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
if (app_key_len == 0) continue; if (netkey_len != sizeof(mesh_persistent_net_key_t)) continue;
mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get(); mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
if (network_key == NULL) return; 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->encryption_key, data.encryption_key, 16);
memcpy(network_key->privacy_key, data.privacy_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); 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("- 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); printf_hexdump(network_key->net_key, 16);
@ -981,7 +986,7 @@ void mesh_delete_network_keys(void){
printf("Delete Network Keys\n"); printf("Delete Network Keys\n");
uint16_t internal_index; 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); mesh_delete_network_key(internal_index);
} }
} }
@ -997,7 +1002,7 @@ typedef struct {
} mesh_persistent_app_key_t; } mesh_persistent_app_key_t;
static uint32_t mesh_transport_key_tag_for_internal_index(uint16_t internal_index){ 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){ 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; key->akf = 1;
memcpy(key->key, data.key, 16); memcpy(key->key, data.key, 16);
mesh_transport_key_add(key); 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); printf_hexdump(key->key, 16);
} }
} }

View File

@ -145,26 +145,6 @@ static void btstack_print_hex(const uint8_t * data, uint16_t len, char separator
} }
#endif #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 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) { 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; 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){ static void load_network_key_nid_68(void){
mesh_provisioning_data_t provisioning_data; mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
provisioning_data.nid = 0x68; network_key->nid = 0x68;
btstack_parse_hex("0953fa93e7caac9638f58820220a398e", 16, provisioning_data.encryption_key); btstack_parse_hex("0953fa93e7caac9638f58820220a398e", 16, network_key->encryption_key);
btstack_parse_hex("8b84eedec100067d670971dd2aa700cf", 16, provisioning_data.privacy_key); btstack_parse_hex("8b84eedec100067d670971dd2aa700cf", 16, network_key->privacy_key);
add_network_key_from_provisioning_data(&provisioning_data); mesh_network_key_add(network_key);
} }
static void load_network_key_nid_5e(void){ static void load_network_key_nid_5e(void){
mesh_provisioning_data_t provisioning_data; mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
provisioning_data.nid = 0x5e; network_key->nid = 0x5e;
btstack_parse_hex("be635105434859f484fc798e043ce40e", 16, provisioning_data.encryption_key); btstack_parse_hex("be635105434859f484fc798e043ce40e", 16, network_key->encryption_key);
btstack_parse_hex("5d396d4b54d3cbafe943e051fe9a4eb8", 16, provisioning_data.privacy_key); btstack_parse_hex("5d396d4b54d3cbafe943e051fe9a4eb8", 16, network_key->privacy_key);
add_network_key_from_provisioning_data(&provisioning_data); mesh_network_key_add(network_key);
} }
static void load_network_key_nid_10(void){ static void load_network_key_nid_10(void){
mesh_provisioning_data_t provisioning_data; mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
provisioning_data.nid = 0x10; network_key->nid = 0x10;
btstack_parse_hex("3a4fe84a6cc2c6a766ea93f1084d4039", 16, provisioning_data.encryption_key); btstack_parse_hex("3a4fe84a6cc2c6a766ea93f1084d4039", 16, network_key->encryption_key);
btstack_parse_hex("f695fcce709ccface4d8b7a1e6e39d25", 16, provisioning_data.privacy_key); btstack_parse_hex("f695fcce709ccface4d8b7a1e6e39d25", 16, network_key->privacy_key);
add_network_key_from_provisioning_data(&provisioning_data); mesh_network_key_add(network_key);
} }
static void load_provisioning_data_test_message(void){ static void load_provisioning_data_test_message(void){

View File

@ -125,22 +125,18 @@ typedef enum {
} mesh_identification_type_t; } mesh_identification_type_t;
typedef struct { typedef struct {
// DevKey = k1(ECDHSecret, ProvisioningSalt, “prdk”)
uint8_t device_key[16]; uint8_t device_key[16];
uint8_t flags;
uint32_t iv_index; // Unicast Address
uint16_t unicast_address; uint16_t unicast_address;
// net_key and derived data // Key Refresh Phase 0 vs. 2, IV Update Active
uint8_t net_key[16]; uint8_t flags;
// k1
uint8_t identity_key[16]; // IV Index
uint8_t beacon_key[16]; uint32_t iv_index;
// k2
uint8_t nid;
uint8_t encryption_key[16];
uint8_t privacy_key[16];
// k3
uint8_t network_id[8];
} mesh_provisioning_data_t; } mesh_provisioning_data_t;
#ifdef __cplusplus #ifdef __cplusplus