mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-28 16:11:24 +00:00
mesh: trigger key refresh transitions via secure network beacons
This commit is contained in:
parent
89e0288a85
commit
2951b4690d
@ -41,6 +41,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "mesh/mesh_upper_transport.h"
|
#include "mesh/mesh_upper_transport.h"
|
||||||
|
#include "mesh/beacon.h"
|
||||||
#include "mesh_access.h"
|
#include "mesh_access.h"
|
||||||
#include "btstack_memory.h"
|
#include "btstack_memory.h"
|
||||||
#include "btstack_debug.h"
|
#include "btstack_debug.h"
|
||||||
@ -50,6 +51,7 @@
|
|||||||
#define MEST_TRANSACTION_TIMEOUT_MS 6000
|
#define MEST_TRANSACTION_TIMEOUT_MS 6000
|
||||||
|
|
||||||
static void mesh_access_message_process_handler(mesh_pdu_t * pdu);
|
static void mesh_access_message_process_handler(mesh_pdu_t * pdu);
|
||||||
|
static void mesh_access_secure_network_beacon_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size);
|
||||||
|
|
||||||
static uint16_t primary_element_address;
|
static uint16_t primary_element_address;
|
||||||
|
|
||||||
@ -80,6 +82,9 @@ void mesh_access_init(void){
|
|||||||
|
|
||||||
// register with upper transport
|
// register with upper transport
|
||||||
mesh_upper_transport_register_access_message_handler(&mesh_access_message_process_handler);
|
mesh_upper_transport_register_access_message_handler(&mesh_access_message_process_handler);
|
||||||
|
|
||||||
|
// register for secure network beacons
|
||||||
|
beacon_register_for_secure_network_beacons(&mesh_access_secure_network_beacon_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mesh_access_emit_state_update_bool(btstack_packet_handler_t * event_handler, uint8_t element_index, uint32_t model_identifier,
|
void mesh_access_emit_state_update_bool(btstack_packet_handler_t * event_handler, uint8_t element_index, uint32_t model_identifier,
|
||||||
@ -1341,3 +1346,70 @@ void mesh_access_state_changed(mesh_model_t * mesh_model){
|
|||||||
publication_model->publish_now = 1;
|
publication_model->publish_now = 1;
|
||||||
mesh_model_publication_run(NULL);
|
mesh_model_publication_run(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mesh_access_netkey_finalize(mesh_network_key_t * network_key){
|
||||||
|
mesh_network_key_remove(network_key);
|
||||||
|
mesh_delete_network_key(network_key->internal_index);
|
||||||
|
btstack_memory_mesh_network_key_free(network_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mesh_access_secure_network_beacon_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){
|
||||||
|
UNUSED(channel);
|
||||||
|
if (packet_type != MESH_BEACON_PACKET) return;
|
||||||
|
|
||||||
|
// lookup subnet and netkey by network id
|
||||||
|
uint8_t * beacon_network_id = &packet[2];
|
||||||
|
mesh_subnet_iterator_t it;
|
||||||
|
mesh_subnet_iterator_init(&it);
|
||||||
|
mesh_subnet_t * subnet = NULL;
|
||||||
|
mesh_network_key_t * network_key = NULL;
|
||||||
|
uint8_t new_key = 0;
|
||||||
|
while (mesh_subnet_iterator_has_more(&it)){
|
||||||
|
mesh_subnet_t * item = mesh_subnet_iterator_get_next(&it);
|
||||||
|
if (memcmp(item->old_key->network_id, beacon_network_id, 8) == 0 ) {
|
||||||
|
subnet = item;
|
||||||
|
network_key = item->old_key;
|
||||||
|
}
|
||||||
|
if (item->new_key != NULL && memcmp(item->new_key->network_id, beacon_network_id, 8) == 0 ) {
|
||||||
|
subnet = item;
|
||||||
|
network_key = item->new_key;
|
||||||
|
new_key = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (subnet == NULL) return;
|
||||||
|
|
||||||
|
// Key refresh via secure network beacons that are authenticated with new netkey
|
||||||
|
if (new_key){
|
||||||
|
// either first or second phase (in phase 0, new key is not set)
|
||||||
|
int key_refresh_flag = packet[1] & 1;
|
||||||
|
if (key_refresh_flag){
|
||||||
|
// transition to phase 3 from either phase 1 or 2
|
||||||
|
switch (subnet->key_refresh){
|
||||||
|
case MESH_KEY_REFRESH_FIRST_PHASE:
|
||||||
|
case MESH_KEY_REFRESH_SECOND_PHASE:
|
||||||
|
// -- revoke old key
|
||||||
|
mesh_access_netkey_finalize(subnet->old_key);
|
||||||
|
subnet->old_key = subnet->new_key;
|
||||||
|
subnet->new_key = NULL;
|
||||||
|
// -- update state
|
||||||
|
subnet->key_refresh = MESH_KEY_REFRESH_NOT_ACTIVE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// transition to phase 2 from either phase 1
|
||||||
|
switch (subnet->key_refresh){
|
||||||
|
case MESH_KEY_REFRESH_FIRST_PHASE:
|
||||||
|
// -- update state
|
||||||
|
subnet->key_refresh = MESH_KEY_REFRESH_SECOND_PHASE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: IV Update
|
||||||
|
}
|
||||||
|
@ -336,6 +336,8 @@ void mesh_delete_network_key(uint16_t internal_index);
|
|||||||
void mesh_delete_network_keys(void);
|
void mesh_delete_network_keys(void);
|
||||||
void mesh_load_network_keys(void);
|
void mesh_load_network_keys(void);
|
||||||
|
|
||||||
|
void mesh_access_netkey_finalize(mesh_network_key_t * network_key);
|
||||||
|
|
||||||
// Mesh Appkeys
|
// 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_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_key(uint16_t internal_index);
|
||||||
|
@ -930,12 +930,6 @@ static void config_netkey_update_handler(mesh_model_t * mesh_model, mesh_pdu_t *
|
|||||||
mesh_network_key_derive(&configuration_server_cmac_request, new_network_key, config_netkey_update_derived, subnet);
|
mesh_network_key_derive(&configuration_server_cmac_request, new_network_key, config_netkey_update_derived, subnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_netkey_finalize(mesh_network_key_t * network_key){
|
|
||||||
mesh_network_key_remove(network_key);
|
|
||||||
mesh_delete_network_key(network_key->internal_index);
|
|
||||||
btstack_memory_mesh_network_key_free(network_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void config_netkey_delete_handler(mesh_model_t * mesh_model, mesh_pdu_t * pdu) {
|
static void config_netkey_delete_handler(mesh_model_t * mesh_model, mesh_pdu_t * pdu) {
|
||||||
mesh_access_parser_state_t parser;
|
mesh_access_parser_state_t parser;
|
||||||
mesh_access_parser_init(&parser, (mesh_pdu_t *) pdu);
|
mesh_access_parser_init(&parser, (mesh_pdu_t *) pdu);
|
||||||
@ -960,12 +954,12 @@ static void config_netkey_delete_handler(mesh_model_t * mesh_model, mesh_pdu_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete old/current key
|
// delete old/current key
|
||||||
config_netkey_finalize(subnet->old_key);
|
mesh_access_netkey_finalize(subnet->old_key);
|
||||||
subnet->old_key = NULL;
|
subnet->old_key = NULL;
|
||||||
|
|
||||||
// delete new key
|
// delete new key
|
||||||
if (subnet->new_key != NULL){
|
if (subnet->new_key != NULL){
|
||||||
config_netkey_finalize(subnet->new_key);
|
mesh_access_netkey_finalize(subnet->new_key);
|
||||||
subnet->new_key = NULL;
|
subnet->new_key = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2128,7 +2122,7 @@ static void config_key_refresh_phase_set_handler(mesh_model_t *mesh_model, mesh_
|
|||||||
case MESH_KEY_REFRESH_SECOND_PHASE:
|
case MESH_KEY_REFRESH_SECOND_PHASE:
|
||||||
// key refresh phase 3 entered
|
// key refresh phase 3 entered
|
||||||
// -- revoke old key
|
// -- revoke old key
|
||||||
config_netkey_finalize(subnet->old_key);
|
mesh_access_netkey_finalize(subnet->old_key);
|
||||||
subnet->old_key = subnet->new_key;
|
subnet->old_key = subnet->new_key;
|
||||||
subnet->new_key = NULL;
|
subnet->new_key = NULL;
|
||||||
// -- update state
|
// -- update state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user