mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-28 06:39:49 +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 <stdarg.h>
|
||||
#include "mesh/mesh_upper_transport.h"
|
||||
#include "mesh/beacon.h"
|
||||
#include "mesh_access.h"
|
||||
#include "btstack_memory.h"
|
||||
#include "btstack_debug.h"
|
||||
@ -50,6 +51,7 @@
|
||||
#define MEST_TRANSACTION_TIMEOUT_MS 6000
|
||||
|
||||
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;
|
||||
|
||||
@ -80,6 +82,9 @@ void mesh_access_init(void){
|
||||
|
||||
// register with upper transport
|
||||
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,
|
||||
@ -1341,3 +1346,70 @@ void mesh_access_state_changed(mesh_model_t * mesh_model){
|
||||
publication_model->publish_now = 1;
|
||||
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_load_network_keys(void);
|
||||
|
||||
void mesh_access_netkey_finalize(mesh_network_key_t * network_key);
|
||||
|
||||
// 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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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) {
|
||||
mesh_access_parser_state_t parser;
|
||||
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
|
||||
config_netkey_finalize(subnet->old_key);
|
||||
mesh_access_netkey_finalize(subnet->old_key);
|
||||
subnet->old_key = NULL;
|
||||
|
||||
// delete new key
|
||||
if (subnet->new_key != NULL){
|
||||
config_netkey_finalize(subnet->new_key);
|
||||
mesh_access_netkey_finalize(subnet->new_key);
|
||||
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:
|
||||
// key refresh phase 3 entered
|
||||
// -- revoke old key
|
||||
config_netkey_finalize(subnet->old_key);
|
||||
mesh_access_netkey_finalize(subnet->old_key);
|
||||
subnet->old_key = subnet->new_key;
|
||||
subnet->new_key = NULL;
|
||||
// -- update state
|
||||
|
Loading…
x
Reference in New Issue
Block a user