From 0882d02cd26985658f09856bdb4aedd48004d287 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 9 Jul 2019 11:01:27 +0200 Subject: [PATCH] mesh: implement IV Index Recovery procedure --- src/mesh/mesh_network.c | 9 ++++++++- src/mesh/mesh_network.h | 18 ++++++++++++++++++ test/mesh/mesh_access.c | 29 ++++++++++++++++------------- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/mesh/mesh_network.c b/src/mesh/mesh_network.c index 2d155905d..19b6cb670 100644 --- a/src/mesh/mesh_network.c +++ b/src/mesh/mesh_network.c @@ -47,8 +47,9 @@ #include "mesh_keys.h" #include "mesh_foundation.h" #include "btstack_util.h" -#include "btstack_memory.h" +#include "btstack_debug.h" #include "btstack_event.h" +#include "btstack_memory.h" #ifdef ENABLE_MESH_ADV_BEARER #include "mesh/adv_bearer.h" @@ -1012,6 +1013,12 @@ void mesh_iv_update_completed(void){ global_iv_update_active = 0; } +void mesh_iv_index_recovered(uint8_t iv_update_active, uint32_t iv_index){ + log_info("mesh_iv_index_recovered: active %u, index %u", iv_update_active, (int) iv_index); + global_iv_index = iv_index; + global_iv_update_active = iv_update_active; +} + // Network PDU Getter uint8_t mesh_network_nid(mesh_network_pdu_t * network_pdu){ return network_pdu->data[0] & 0x7f; diff --git a/src/mesh/mesh_network.h b/src/mesh/mesh_network.h index 975e31a36..1e116a6dc 100644 --- a/src/mesh/mesh_network.h +++ b/src/mesh/mesh_network.h @@ -383,10 +383,28 @@ uint32_t mesh_get_iv_index(void); uint32_t mesh_get_iv_index_for_tx(void); +/** + * @brief Get IV Update state + */ int mesh_iv_update_active(void); + +/** + * @brief Trigger IV Update + */ void mesh_trigger_iv_update(void); + +/** + * @breif IV update was completed + */ void mesh_iv_update_completed(void); +/** + * @brief IV Index was recovered + * @param iv_update_active + * @param iv_index + */ +void mesh_iv_index_recovered(uint8_t iv_update_active, uint32_t iv_index); + // Testing only void mesh_network_received_message(const uint8_t * pdu_data, uint8_t pdu_len, uint8_t flags); void mesh_network_process_proxy_configuration_message(const uint8_t * pdu_data, uint8_t pdu_len); diff --git a/test/mesh/mesh_access.c b/test/mesh/mesh_access.c index 055fd6667..43bc2de48 100644 --- a/test/mesh/mesh_access.c +++ b/test/mesh/mesh_access.c @@ -1634,12 +1634,11 @@ static void mesh_access_secure_network_beacon_handler(uint8_t packet_type, uint1 uint32_t beacon_iv_index = big_endian_read_32(packet, 10); uint32_t local_iv_index = mesh_get_iv_index(); - int32_t iv_index_delta = (int32_t)(beacon_iv_index - local_iv_update_active); + int32_t iv_index_delta = (int32_t)(beacon_iv_index - local_iv_index); - // "If a node in Normal Operation receives a Secure Network beacon with an IV index greater than the last known IV Index + 1..." - if (local_iv_update_active == 0 && iv_index_delta > 1){ - // "... it may initiate an IV Index Recovery procedure, see Section 3.10.6." - // TODO: initiate IV Index Recovery procedure + // "If a node in Normal Operation receives a Secure Network beacon with an IV index less than the last known IV Index or greater than + // the last known IV Index + 42, the Secure Network beacon shall be ignored." + if (iv_index_delta < 0 || iv_index_delta > 42){ return; } @@ -1653,12 +1652,6 @@ static void mesh_access_secure_network_beacon_handler(uint8_t packet_type, uint1 return; } - // "If a node in Normal Operation receives a Secure Network beacon with an IV index less than the last known IV Index or greater than - // the last known IV Index + 42, the Secure Network beacon shall be ignored." - if (iv_index_delta < 0 || iv_index_delta > 42){ - return; - } - // "If this node is a member of a primary subnet and receives a Secure Network beacon on a secondary subnet with an IV Index greater than // the last known IV Index of the primary subnet, the Secure Network beacon shall be ignored." int member_of_primary_subnet = mesh_subnet_get_by_netkey_index(0) != NULL; @@ -1667,9 +1660,19 @@ static void mesh_access_secure_network_beacon_handler(uint8_t packet_type, uint1 return; } - // TODO: validate IV index w.r.t. local index + // "If a node in Normal Operation receives a Secure Network beacon with an IV index greater than the last known IV Index + 1..." + // "... it may initiate an IV Index Recovery procedure, see Section 3.10.6." + if (local_iv_update_active == 0 && iv_index_delta > 1){ + // "Upon receiving and successfully authenticating a Secure Network beacon for a primary subnet... " + int beacon_on_primary_subnet = subnet->netkey_index == 0; + if (!beacon_on_primary_subnet) return; + // "... whose IV Index is 1 or more higher than the current known IV Index, the node shall " + // " set its current IV Index and its current IV Update procedure state from the values in this Secure Network beacon." + mesh_iv_index_recovered(beacon_iv_update_active, beacon_iv_index); + return; + } - if (mesh_iv_update_active()){ + if (local_iv_update_active == 0){ if (beacon_iv_update_active){ mesh_trigger_iv_update(); }