mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-21 12:40:42 +00:00
mesh: move key refresh and secure beacon data from mesh_network_key_t to mesh_subnet_t
This commit is contained in:
parent
b1dda14141
commit
2fa98d7e52
@ -113,7 +113,7 @@ static void beacon_timer_handler(btstack_timer_source_t * ts){
|
||||
#endif
|
||||
|
||||
static void mesh_secure_network_beacon_auth_value_calculated(void * arg){
|
||||
mesh_network_key_t * mesh_network_key = (mesh_network_key_t *) arg;
|
||||
mesh_subnet_t * mesh_subnet = (mesh_subnet_t *) arg;
|
||||
|
||||
memcpy(&mesh_beacon_data[14], mesh_secure_network_beacon_auth_value, 8);
|
||||
mesh_beacon_len = SECURE_NETWORK_BEACON_LEN;
|
||||
@ -122,14 +122,14 @@ static void mesh_secure_network_beacon_auth_value_calculated(void * arg){
|
||||
printf("- ");
|
||||
printf_hexdump(mesh_beacon_data, mesh_beacon_len);
|
||||
|
||||
mesh_network_key->beacon_state = MESH_SECURE_NETWORK_BEACON_AUTH_VALUE;
|
||||
mesh_subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_AUTH_VALUE;
|
||||
|
||||
mesh_secure_network_beacon_run(NULL);
|
||||
}
|
||||
|
||||
static uint8_t mesh_secure_network_beacon_get_flags(mesh_network_key_t * mesh_network_key){
|
||||
static uint8_t mesh_secure_network_beacon_get_flags(mesh_subnet_t * mesh_subnet){
|
||||
uint8_t mesh_flags = 0;
|
||||
if (mesh_network_key->key_refresh != MESH_KEY_REFRESH_NOT_ACTIVE){
|
||||
if (mesh_subnet->key_refresh != MESH_KEY_REFRESH_NOT_ACTIVE){
|
||||
mesh_flags |= 1;
|
||||
}
|
||||
|
||||
@ -137,16 +137,18 @@ static uint8_t mesh_secure_network_beacon_get_flags(mesh_network_key_t * mesh_ne
|
||||
return mesh_flags;
|
||||
}
|
||||
|
||||
static void mesh_secure_network_beacon_setup(mesh_network_key_t * mesh_network_key){
|
||||
static void mesh_secure_network_beacon_setup(mesh_subnet_t * mesh_subnet){
|
||||
mesh_beacon_data[0] = BEACON_TYPE_SECURE_NETWORK;
|
||||
mesh_beacon_data[1] = mesh_secure_network_beacon_get_flags(mesh_network_key);
|
||||
memcpy(&mesh_beacon_data[2], mesh_network_key->network_id, 8);
|
||||
mesh_beacon_data[1] = mesh_secure_network_beacon_get_flags(mesh_subnet);
|
||||
// TODO: pick correct key based on key refresh phase
|
||||
|
||||
memcpy(&mesh_beacon_data[2], mesh_subnet->old_key->network_id, 8);
|
||||
big_endian_store_32(mesh_beacon_data, 10, mesh_get_iv_index());
|
||||
btstack_crypto_aes128_cmac_message(&mesh_secure_network_beacon_cmac_request, mesh_network_key->beacon_key, 13,
|
||||
&mesh_beacon_data[1], mesh_secure_network_beacon_auth_value, &mesh_secure_network_beacon_auth_value_calculated, mesh_network_key);
|
||||
btstack_crypto_aes128_cmac_message(&mesh_secure_network_beacon_cmac_request, mesh_subnet->old_key->beacon_key, 13,
|
||||
&mesh_beacon_data[1], mesh_secure_network_beacon_auth_value, &mesh_secure_network_beacon_auth_value_calculated, mesh_subnet);
|
||||
}
|
||||
|
||||
static void mesh_secure_network_beacon_update_interval(mesh_network_key_t * subnet){
|
||||
static void mesh_secure_network_beacon_update_interval(mesh_subnet_t * subnet){
|
||||
uint32_t min_observation_period_ms = 2 * subnet->beacon_interval_ms;
|
||||
uint32_t actual_observation_period = btstack_time_delta(btstack_run_loop_get_time_ms(), subnet->beacon_observation_start_ms);
|
||||
|
||||
@ -175,10 +177,10 @@ static void mesh_secure_network_beacon_run(btstack_timer_source_t * ts){
|
||||
uint32_t next_timeout_ms = 0;
|
||||
|
||||
// iterate over all networks
|
||||
mesh_network_key_iterator_t it;
|
||||
mesh_network_key_iterator_init(&it);
|
||||
while (mesh_network_key_iterator_has_more(&it)){
|
||||
mesh_network_key_t * subnet = mesh_network_key_iterator_get_next(&it);
|
||||
mesh_subnet_iterator_t it;
|
||||
mesh_subnet_iterator_init(&it);
|
||||
while (mesh_subnet_iterator_has_more(&it)){
|
||||
mesh_subnet_t * subnet = mesh_subnet_iterator_get_next(&it);
|
||||
switch (subnet->beacon_state){
|
||||
case MESH_SECURE_NETWORK_BEACON_W4_INTERVAL:
|
||||
// update beacon interval
|
||||
@ -266,12 +268,13 @@ static void beacon_handle_secure_beacon(uint8_t * packet, uint16_t size){
|
||||
|
||||
// lookup subnet by network id
|
||||
uint8_t * beacon_network_id = &packet[2];
|
||||
mesh_network_key_iterator_t it;
|
||||
mesh_network_key_iterator_init(&it);
|
||||
mesh_network_key_t * subnet = NULL;
|
||||
while (mesh_network_key_iterator_has_more(&it)){
|
||||
mesh_network_key_t * item = mesh_network_key_iterator_get_next(&it);
|
||||
if (memcmp(item->network_id, beacon_network_id, 8) != 0 ) continue;
|
||||
mesh_subnet_iterator_t it;
|
||||
mesh_subnet_iterator_init(&it);
|
||||
mesh_subnet_t * subnet = NULL;
|
||||
while (mesh_subnet_iterator_has_more(&it)){
|
||||
mesh_subnet_t * item = mesh_subnet_iterator_get_next(&it);
|
||||
// TODO: handle old/new keys
|
||||
if (memcmp(item->old_key->network_id, beacon_network_id, 8) != 0 ) continue;
|
||||
subnet = item;
|
||||
break;
|
||||
}
|
||||
@ -292,7 +295,8 @@ static void beacon_handle_secure_beacon(uint8_t * packet, uint16_t size){
|
||||
mesh_secure_network_beacon_active = 1;
|
||||
memcpy(mesh_secure_network_beacon_validate_buffer, &packet[0], SECURE_NETWORK_BEACON_LEN);
|
||||
|
||||
btstack_crypto_aes128_cmac_message(&mesh_secure_network_beacon_cmac_request, subnet->beacon_key, 13,
|
||||
// TODO: handle odl/new keys
|
||||
btstack_crypto_aes128_cmac_message(&mesh_secure_network_beacon_cmac_request, subnet->old_key->beacon_key, 13,
|
||||
&mesh_secure_network_beacon_validate_buffer[1], mesh_secure_network_beacon_auth_value, &beacon_handle_secure_beacon_auth_value_calculated, subnet);
|
||||
}
|
||||
|
||||
@ -314,7 +318,7 @@ static void beacon_handle_beacon_packet(uint8_t packet_type, uint16_t channel, u
|
||||
|
||||
#ifdef ENABLE_MESH_ADV_BEARER
|
||||
static void beacon_adv_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
mesh_network_key_iterator_t it;
|
||||
mesh_subnet_iterator_t it;
|
||||
switch (packet_type){
|
||||
case HCI_EVENT_PACKET:
|
||||
switch(packet[0]){
|
||||
@ -327,9 +331,9 @@ static void beacon_adv_packet_handler (uint8_t packet_type, uint16_t channel, ui
|
||||
break;
|
||||
}
|
||||
// secure beacon state machine
|
||||
mesh_network_key_iterator_init(&it);
|
||||
while (mesh_network_key_iterator_has_more(&it)){
|
||||
mesh_network_key_t * subnet = mesh_network_key_iterator_get_next(&it);
|
||||
mesh_subnet_iterator_init(&it);
|
||||
while (mesh_subnet_iterator_has_more(&it)){
|
||||
mesh_subnet_t * subnet = mesh_subnet_iterator_get_next(&it);
|
||||
switch (subnet->beacon_state){
|
||||
case MESH_SECURE_NETWORK_BEACON_W2_SEND_ADV:
|
||||
adv_bearer_send_beacon(mesh_beacon_data, mesh_beacon_len);
|
||||
@ -361,10 +365,10 @@ static void beacon_adv_packet_handler (uint8_t packet_type, uint16_t channel, ui
|
||||
#ifdef ENABLE_MESH_GATT_BEARER
|
||||
// handle MESH_SUBEVENT_PROXY_DISCONNECTED and MESH_SUBEVENT_CAN_SEND_NOW
|
||||
static void beacon_gatt_handle_mesh_event(uint8_t mesh_subevent){
|
||||
mesh_network_key_iterator_t it;
|
||||
mesh_network_key_iterator_init(&it);
|
||||
while (mesh_network_key_iterator_has_more(&it)){
|
||||
mesh_network_key_t * subnet = mesh_network_key_iterator_get_next(&it);
|
||||
mesh_subnet_iterator_t it;
|
||||
mesh_subnet_iterator_init(&it);
|
||||
while (mesh_subnet_iterator_has_more(&it)){
|
||||
mesh_subnet_t * subnet = mesh_subnet_iterator_get_next(&it);
|
||||
switch (subnet->beacon_state){
|
||||
case MESH_SECURE_NETWORK_BEACON_W2_SEND_GATT:
|
||||
// skip send on MESH_SUBEVENT_PROXY_DISCONNECTED
|
||||
@ -451,12 +455,12 @@ void beacon_unprovisioned_device_stop(void){
|
||||
|
||||
// secure network beacons
|
||||
|
||||
void beacon_secure_network_start(mesh_network_key_t * mesh_network_key){
|
||||
void beacon_secure_network_start(mesh_subnet_t * mesh_subnet){
|
||||
// default interval
|
||||
mesh_network_key->beacon_interval_ms = SECURE_NETWORK_BEACON_INTERVAL_MIN_MS;
|
||||
mesh_network_key->beacon_state = MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE;
|
||||
mesh_network_key->beacon_observation_start_ms = btstack_run_loop_get_time_ms();
|
||||
mesh_network_key->beacon_observation_counter = 0;
|
||||
mesh_subnet->beacon_interval_ms = SECURE_NETWORK_BEACON_INTERVAL_MIN_MS;
|
||||
mesh_subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE;
|
||||
mesh_subnet->beacon_observation_start_ms = btstack_run_loop_get_time_ms();
|
||||
mesh_subnet->beacon_observation_counter = 0;
|
||||
|
||||
// start sending
|
||||
mesh_secure_network_beacon_run(NULL);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <stdint.h>
|
||||
#include "btstack_defines.h"
|
||||
#include "mesh_keys.h"
|
||||
#include "mesh/mesh_network.h"
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
@ -65,9 +66,9 @@ void beacon_unprovisioned_device_stop(void);
|
||||
|
||||
/**
|
||||
* Start sending Secure Network Beacons on given subnet
|
||||
* @param mesh_network_key subnet
|
||||
* @param mesh_subnet
|
||||
*/
|
||||
void beacon_secure_network_start(mesh_network_key_t * mesh_network_key);
|
||||
void beacon_secure_network_start(mesh_subnet_t * mesh_subnet);
|
||||
|
||||
/**
|
||||
* Register Beacon handler for unprovisioned device beacons
|
||||
|
@ -56,13 +56,13 @@ LDFLAGS += -lCppUTest -lCppUTestExt
|
||||
mesh: mesh.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} pb_adv.o pb_gatt.o mesh_foundation.o mesh_provisioning_service_server.o mesh_crypto.o provisioning_device.o mesh_network.o mesh_peer.o mesh_lower_transport.o mesh_upper_transport.o mesh_virtual_addresses.o mesh_keys.o mesh_proxy.o mesh_access.o mesh_configuration_server.o mesh_generic_server.o mesh_generic_level_server.o mesh_generic_client.o mesh_generic_level_client.o mesh.o
|
||||
${CC} $(filter-out mesh.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
provisioner: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_OBJ} pb_adv.o mesh_crypto.o provisioning_provisioner.o mesh_keys.o mesh_foundation.o provisioner.o
|
||||
provisioner: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_OBJ} pb_adv.o mesh_crypto.o provisioning_provisioner.o mesh_keys.o mesh_foundation.o mesh_network.o provisioner.o
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
mesh_message_test: mesh_foundation.o mesh_message_test.c mesh_network.o mesh_peer.o mesh_lower_transport.o mesh_upper_transport.o mesh_virtual_addresses.o mesh_keys.o mesh_crypto.o btstack_memory.o btstack_memory_pool.o btstack_util.o btstack_crypto.o btstack_linked_list.o hci_dump.o uECC.o mock.o rijndael.o hci_cmd.o
|
||||
g++ $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
sniffer: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_OBJ} mesh_keys.o mesh_foundation.o sniffer.c
|
||||
sniffer: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_OBJ} mesh_keys.o mesh_network.o mesh_foundation.o sniffer.c
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
provisioning_device_test: provisioning_device_test.cpp uECC.o mesh_crypto.o provisioning_device.o btstack_crypto.o btstack_util.o btstack_linked_list.o mock.o rijndael.o hci_cmd.o hci_dump.o
|
||||
|
@ -324,9 +324,9 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
||||
#if defined(ENABLE_MESH_ADV_BEARER) || defined(ENABLE_MESH_PB_ADV)
|
||||
|
||||
// start sending Secure Network Beacon
|
||||
mesh_network_key_t * network_key = mesh_network_key_list_get(0);
|
||||
if (network_key){
|
||||
beacon_secure_network_start(network_key);
|
||||
mesh_subnet_t * subnet = mesh_subnet_get_by_netkey_index(0);
|
||||
if (subnet){
|
||||
beacon_secure_network_start(subnet);
|
||||
}
|
||||
|
||||
// setup scanning
|
||||
@ -366,6 +366,8 @@ static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t cha
|
||||
if (packet_type != HCI_EVENT_PACKET) return;
|
||||
mesh_provisioning_data_t provisioning_data;
|
||||
mesh_network_key_t * primary_network_key;
|
||||
mesh_subnet_t * primary_subnet;
|
||||
|
||||
switch(packet[0]){
|
||||
case HCI_EVENT_MESH_META:
|
||||
switch(packet[2]){
|
||||
@ -420,7 +422,8 @@ static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t cha
|
||||
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(primary_network_key);
|
||||
primary_subnet = mesh_subnet_get_by_netkey_index(0);
|
||||
beacon_secure_network_start(primary_subnet);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -843,11 +843,13 @@ static void config_netkey_add_handler(mesh_model_t * mesh_model, mesh_pdu_t * pd
|
||||
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
|
||||
mesh_network_key_t * new_network_key = btstack_memory_mesh_network_key_get();
|
||||
if (new_network_key == NULL){
|
||||
status = MESH_FOUNDATION_STATUS_INSUFFICIENT_RESOURCES;
|
||||
} else {
|
||||
// TODO: check if subnet could get created
|
||||
access_pdu_in_process = pdu;
|
||||
new_network_key->internal_index = internal_index;
|
||||
new_network_key->netkey_index = new_netkey_index;
|
||||
@ -900,7 +902,6 @@ static void config_netkey_update_handler(mesh_model_t * mesh_model, mesh_pdu_t *
|
||||
access_pdu_in_process = pdu;
|
||||
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);
|
||||
}
|
||||
@ -2041,14 +2042,14 @@ static void config_key_refresh_phase_get_handler(mesh_model_t *mesh_model, mesh_
|
||||
mesh_access_parser_state_t parser;
|
||||
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
||||
uint16_t netkey_index = mesh_access_parser_get_u16(&parser);
|
||||
mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index);
|
||||
mesh_subnet_t * subnet = mesh_subnet_get_by_netkey_index(netkey_index);
|
||||
|
||||
uint8_t status = MESH_FOUNDATION_STATUS_INVALID_NETKEY_INDEX;
|
||||
mesh_key_refresh_state_t key_refresh_state = MESH_KEY_REFRESH_NOT_ACTIVE;
|
||||
|
||||
if (network_key != NULL){
|
||||
if (subnet != NULL){
|
||||
status = MESH_FOUNDATION_STATUS_SUCCESS;
|
||||
key_refresh_state = network_key->key_refresh;
|
||||
key_refresh_state = subnet->key_refresh;
|
||||
}
|
||||
|
||||
config_key_refresh_phase_status(mesh_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu), status, netkey_index, key_refresh_state);
|
||||
@ -2060,30 +2061,30 @@ static void config_key_refresh_phase_set_handler(mesh_model_t *mesh_model, mesh_
|
||||
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
||||
uint16_t netkey_index = mesh_access_parser_get_u16(&parser);
|
||||
uint8_t key_refresh_phase_transition = mesh_access_parser_get_u8(&parser);
|
||||
mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index);
|
||||
mesh_subnet_t * subnet = mesh_subnet_get_by_netkey_index(netkey_index);
|
||||
|
||||
uint8_t status = MESH_FOUNDATION_STATUS_INVALID_NETKEY_INDEX;
|
||||
|
||||
if (network_key != NULL){
|
||||
if (subnet != NULL){
|
||||
status = MESH_FOUNDATION_STATUS_SUCCESS;
|
||||
|
||||
switch (key_refresh_phase_transition){
|
||||
case 0x02:
|
||||
switch (network_key->key_refresh){
|
||||
switch (subnet->key_refresh){
|
||||
case MESH_KEY_REFRESH_FIRST_PHASE:
|
||||
case MESH_KEY_REFRESH_SECOND_PHASE:
|
||||
network_key->key_refresh = MESH_KEY_REFRESH_SECOND_PHASE;
|
||||
subnet->key_refresh = MESH_KEY_REFRESH_SECOND_PHASE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x03:
|
||||
switch (network_key->key_refresh){
|
||||
switch (subnet->key_refresh){
|
||||
case MESH_KEY_REFRESH_FIRST_PHASE:
|
||||
case MESH_KEY_REFRESH_SECOND_PHASE:
|
||||
// TODO: invoke Key Refresh Phase 3, then
|
||||
// set network_key->key_refresh = MESH_KEY_REFRESH_NOT_ACTIVE;
|
||||
// set subnet->key_refresh = MESH_KEY_REFRESH_NOT_ACTIVE;
|
||||
printf("TODO: invoke Key Refresh Phase 3, then set key refresh phase to MESH_KEY_REFRESH_NOT_ACTIVE\n");
|
||||
break;
|
||||
default:
|
||||
@ -2096,7 +2097,7 @@ static void config_key_refresh_phase_set_handler(mesh_model_t *mesh_model, mesh_
|
||||
}
|
||||
}
|
||||
|
||||
config_key_refresh_phase_status(mesh_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu), status, netkey_index, network_key->key_refresh);
|
||||
config_key_refresh_phase_status(mesh_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu), status, netkey_index, subnet->key_refresh);
|
||||
mesh_access_message_processed(pdu);
|
||||
}
|
||||
|
||||
|
@ -97,21 +97,12 @@ typedef struct {
|
||||
uint8_t encryption_key[16];
|
||||
uint8_t privacy_key[16];
|
||||
|
||||
// key refresh
|
||||
mesh_key_refresh_state_t key_refresh;
|
||||
|
||||
// subnet state
|
||||
uint8_t node_id_advertisement_running;
|
||||
|
||||
// advertisement data for proxy
|
||||
adv_bearer_connectable_advertisement_data_item_t advertisement_with_network_id;
|
||||
|
||||
// secure network beacons
|
||||
mesh_secure_network_beacon_state_t beacon_state;
|
||||
uint32_t beacon_interval_ms;
|
||||
uint32_t beacon_observation_start_ms;
|
||||
uint16_t beacon_observation_counter;
|
||||
|
||||
} mesh_network_key_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -274,10 +274,6 @@ static void stdin_process(char cmd){
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mesh_get_iv_index(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btstack_main(void);
|
||||
int btstack_main(void)
|
||||
{
|
||||
|
@ -282,10 +282,6 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
}
|
||||
/* LISTING_END */
|
||||
|
||||
uint32_t mesh_get_iv_index(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btstack_main(void);
|
||||
int btstack_main(void)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user