mesh: persist network keys

This commit is contained in:
Matthias Ringwald 2019-06-13 17:09:39 +02:00
parent 4517f741ac
commit 9162eb2998
5 changed files with 113 additions and 11 deletions

View File

@ -28,8 +28,9 @@
#define HCI_ACL_PAYLOAD_SIZE 1000
#define HCI_INCOMING_PRE_BUFFER_SIZE 4
#define MAX_NR_LE_DEVICE_DB_ENTRIES 4
#define MAX_NR_MESH_TRANSPORT_KEYS 16
#define MAX_NR_LE_DEVICE_DB_ENTRIES 4
#define MAX_NR_MESH_NETWORK_KEYS 4
#define MAX_NR_MESH_TRANSPORT_KEYS 16
#define MAX_NR_MESH_VIRTUAL_ADDRESSES 16
#define NVM_NUM_LINK_KEYS 2

View File

@ -433,6 +433,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
} 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
@ -845,12 +847,13 @@ static void stdin_process(char cmd){
break;
case '8':
btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, 'PROV');
mesh_delete_network_keys();
mesh_delete_app_keys();
mesh_delete_appkey_lists();
mesh_delete_virtual_addresses();
mesh_delete_subscriptions();
mesh_delete_publications();
printf("Provisioning data, app keys, model to app key lists, virtual addresses, model subscriptions deleted\n");
printf("Provisioning data, net keys, app keys, model to app key lists, virtual addresses, model subscriptions deleted\n");
setup_advertising_unprovisioned();
break;
case 'p':

View File

@ -670,10 +670,94 @@ int mesh_model_contains_subscription(mesh_model_t * mesh_model, uint16_t address
return 0;
}
static uint32_t mesh_transport_key_tag_for_internal_index(uint16_t internal_index){
return ((uint32_t) 'M' << 24) | ((uint32_t) 'A' << 16) | ((uint32_t) internal_index);
static uint32_t mesh_network_key_tag_for_internal_index(uint16_t internal_index){
return ((uint32_t) 'M' << 24) | ((uint32_t) 'N' << 16) | ((uint32_t) internal_index);
}
// Mesh Network Keys
typedef struct {
uint16_t netkey_index;
// net_key from provisioner or Config Model Client
uint8_t net_key[16];
// derivative data
// k1
uint8_t identity_key[16];
uint8_t beacon_key[16];
// k3
uint8_t network_id[8];
// k2
uint8_t nid;
uint8_t encryption_key[16];
uint8_t privacy_key[16];
} mesh_persistent_net_key_t;
void mesh_store_network_key(mesh_network_key_t * network_key){
mesh_access_setup_tlv();
mesh_persistent_net_key_t data;
printf("Store NetKey: 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);
uint32_t tag = mesh_network_key_tag_for_internal_index(network_key->internal_index);
data.netkey_index = network_key->netkey_index;
memcpy(data.net_key, network_key->net_key, 16);
memcpy(data.identity_key, network_key->identity_key, 16);
memcpy(data.beacon_key, network_key->beacon_key, 16);
memcpy(data.network_id, network_key->network_id, 8);
data.nid = network_key->nid;
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));
}
void mesh_delete_network_key(uint16_t internal_index){
mesh_access_setup_tlv();
uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
}
void mesh_load_network_keys(void){
mesh_access_setup_tlv();
printf("Load Network Keys\n");
uint16_t internal_index;
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;
mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
if (network_key == NULL) return;
network_key->netkey_index = data.netkey_index;
memcpy(network_key->net_key, data.net_key, 16);
memcpy(network_key->identity_key, data.identity_key, 16);
memcpy(network_key->beacon_key, data.beacon_key, 16);
memcpy(network_key->network_id, data.network_id, 8);
network_key->nid = data.nid;
memcpy(network_key->encryption_key, data.encryption_key, 16);
memcpy(network_key->privacy_key, data.privacy_key, 16);
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);
}
}
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++){
mesh_delete_network_key(internal_index);
}
}
// Mesh App Keys
typedef struct {
@ -683,6 +767,10 @@ typedef struct {
uint8_t key[16];
} 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);
}
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){
mesh_access_setup_tlv();

View File

@ -41,6 +41,7 @@
#include <stdint.h>
#include "btstack_linked_list.h"
#include "ble/mesh/mesh_lower_transport.h"
#include "mesh_keys.h"
#ifdef __cplusplus
extern "C"
@ -200,11 +201,16 @@ uint16_t mesh_pdu_appkey_index(mesh_pdu_t * pdu);
uint16_t mesh_pdu_len(mesh_pdu_t * pdu);
uint8_t * mesh_pdu_data(mesh_pdu_t * pdu);
// Mesh NetKey List
void mesh_store_network_key(mesh_network_key_t * network_key);
void mesh_delete_network_key(uint16_t internal_index);
void mesh_delete_net_keys(void);
void mesh_load_net_keys(void);
// Mesh Appkeys
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_delete_app_key(uint16_t internal_index);
void mesh_delete_app_keys(void);
void mesh_load_app_keys(void);
// Mesh Model Subscriptions

View File

@ -805,7 +805,8 @@ static void config_netkey_add_handler(mesh_model_t * mesh_model, mesh_pdu_t * pd
}
} else {
// check limit for pts
if (config_netkey_list_max && mesh_network_key_list_count() >= config_netkey_list_max){
uint16_t internal_index = mesh_network_key_get_free_index();
if (internal_index == 0 || (config_netkey_list_max && mesh_network_key_list_count() >= config_netkey_list_max)){
status = MESH_FOUNDATION_STATUS_INSUFFICIENT_RESOURCES;
} else {
// setup new key
@ -814,7 +815,8 @@ static void config_netkey_add_handler(mesh_model_t * mesh_model, mesh_pdu_t * pd
status = MESH_FOUNDATION_STATUS_INSUFFICIENT_RESOURCES;
} else {
access_pdu_in_process = pdu;
new_network_key->netkey_index = new_netkey_index;
new_network_key->internal_index = internal_index;
new_network_key->netkey_index = new_netkey_index;
memcpy(new_network_key->net_key, new_netkey, 16);
mesh_network_key_derive(&configuration_server_cmac_request, new_network_key, config_netkey_add_or_update_derived, new_network_key);
return;
@ -848,16 +850,18 @@ static void config_netkey_update_handler(mesh_model_t * mesh_model, mesh_pdu_t *
}
// setup new key
uint16_t internal_index = mesh_network_key_get_free_index();
mesh_network_key_t * new_network_key = btstack_memory_mesh_network_key_get();
if (new_network_key == NULL){
if (internal_index == 0 || new_network_key == NULL){
config_netkey_status(mesh_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu), MESH_FOUNDATION_STATUS_INSUFFICIENT_RESOURCES, netkey_index);
mesh_access_message_processed(access_pdu_in_process);
return;
}
access_pdu_in_process = pdu;
new_network_key->netkey_index = netkey_index;
new_network_key->key_refresh = 1;
new_network_key->internal_index = internal_index;
new_network_key->netkey_index = netkey_index;
new_network_key->key_refresh = 1;
memcpy(new_network_key->net_key, new_netkey, 16);
mesh_network_key_derive(&configuration_server_cmac_request, new_network_key, config_netkey_add_or_update_derived, new_network_key);
}