From 40dc2152942119a5c5679ed67ea9ccea5f74e2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=20Lepp=C3=A4nen?= Date: Fri, 18 Sep 2020 21:34:04 +0300 Subject: [PATCH] Set frame counter increment to 1000000 Removed not needed NVM writes for PAN ID and network name on supplicant. Added frame counter maximum value check. --- source/6LoWPAN/ws/ws_config.h | 4 +-- source/6LoWPAN/ws/ws_pae_auth.c | 6 ++--- source/6LoWPAN/ws/ws_pae_controller.c | 11 +++++++-- source/6LoWPAN/ws/ws_pae_supp.c | 12 +++++---- source/Security/protocols/sec_prot_keys.c | 30 ++++++++++++++++++----- source/Security/protocols/sec_prot_keys.h | 11 ++++++++- 6 files changed, 55 insertions(+), 19 deletions(-) diff --git a/source/6LoWPAN/ws/ws_config.h b/source/6LoWPAN/ws/ws_config.h index 7866e2cee534..899b25afcd06 100644 --- a/source/6LoWPAN/ws/ws_config.h +++ b/source/6LoWPAN/ws/ws_config.h @@ -174,8 +174,8 @@ extern uint8_t DEVICE_MIN_SENS; #define FRAME_COUNTER_STORE_INTERVAL 60 // Time interval (on seconds) between checking if frame counter storing is needed #define FRAME_COUNTER_STORE_FORCE_INTERVAL (3600 * 20) // Time interval (on seconds) before frame counter storing is forced (if no other storing operations triggered) #define FRAME_COUNTER_STORE_TRIGGER 5 // Delay (on seconds) before storing, when storing of frame counters is triggered -#define FRAME_COUNTER_INCREMENT 1000 // How much frame counter is incremented on start up -#define FRAME_COUNTER_STORE_THRESHOLD 800 // How much frame counter must increment before it is stored +#define FRAME_COUNTER_INCREMENT 1000000 // How much frame counter is incremented on start up +#define FRAME_COUNTER_STORE_THRESHOLD 994999 // How much frame counter must increment before it is stored /* diff --git a/source/6LoWPAN/ws/ws_pae_auth.c b/source/6LoWPAN/ws/ws_pae_auth.c index a8752ad5ace6..942f44379d64 100644 --- a/source/6LoWPAN/ws/ws_pae_auth.c +++ b/source/6LoWPAN/ws/ws_pae_auth.c @@ -440,7 +440,7 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int // If active GTK lifetime is larger than revocation lifetime decrements active GTK lifetime if (active_lifetime > revocation_lifetime) { - sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, active_index, current_time, active_lifetime - revocation_lifetime); + sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, active_index, current_time, active_lifetime - revocation_lifetime, true); tr_info("Access revocation start, GTK active index: %i, revoked lifetime: %"PRIu32"", active_index, revocation_lifetime); } else { // Otherwise decrements lifetime of the GTK to be installed after the active one @@ -451,7 +451,7 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int uint32_t second_lifetime = sec_prot_keys_gtk_lifetime_get(pae_auth->sec_keys_nw_info->gtks, second_index); if (second_lifetime > second_revocation_lifetime) { - sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, second_index, current_time, second_lifetime - second_revocation_lifetime); + sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, second_index, current_time, second_lifetime - second_revocation_lifetime, true); tr_info("Access revocation start, GTK second active index: %i, revoked lifetime: %"PRIu32"", second_index, second_revocation_lifetime); } // Removes other keys than active and GTK to be installed next @@ -710,7 +710,7 @@ void ws_pae_auth_slow_timer(uint16_t seconds) if (!sec_prot_keys_gtk_is_set(pae_auth->sec_keys_nw_info->gtks, i)) { continue; } - uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, i, current_time, seconds); + uint32_t timer_seconds = sec_prot_keys_gtk_lifetime_decrement(pae_auth->sec_keys_nw_info->gtks, i, current_time, seconds, true); if (active_index == i) { if (!pae_auth->gtk_new_inst_req_exp) { pae_auth->gtk_new_inst_req_exp = ws_pae_timers_gtk_new_install_required(pae_auth->sec_cfg, timer_seconds); diff --git a/source/6LoWPAN/ws/ws_pae_controller.c b/source/6LoWPAN/ws/ws_pae_controller.c index cbd19d61aaf7..0a7a0650d7af 100644 --- a/source/6LoWPAN/ws/ws_pae_controller.c +++ b/source/6LoWPAN/ws/ws_pae_controller.c @@ -783,8 +783,14 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller) // Checks frame counters for (uint8_t index = 0; index < GTK_NUM; index++) { if (controller->frame_counters.counter[index].set) { - // Increments frame counters - controller->frame_counters.counter[index].frame_counter += FRAME_COUNTER_INCREMENT; + // If there is room on frame counter space + if (controller->frame_counters.counter[index].frame_counter < (UINT32_MAX - FRAME_COUNTER_INCREMENT * 2)) { + // Increments frame counters + controller->frame_counters.counter[index].frame_counter += FRAME_COUNTER_INCREMENT; + } else { + tr_error("Frame counter space exhausted"); + controller->frame_counters.counter[index].frame_counter = UINT32_MAX; + } controller->frame_counters.counter[index].stored_frame_counter = controller->frame_counters.counter[index].frame_counter; @@ -891,6 +897,7 @@ int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_pt ws_pae_controller_nw_info_read(controller, controller->sec_keys_nw_info.gtks); // Set active key back to fresh so that it can be used again after re-start sec_prot_keys_gtk_status_active_to_fresh_set(&controller->gtks); + sec_prot_keys_gtks_updated_reset(&controller->gtks); return 0; } diff --git a/source/6LoWPAN/ws/ws_pae_supp.c b/source/6LoWPAN/ws/ws_pae_supp.c index cca9cf795379..e9d28a892f31 100644 --- a/source/6LoWPAN/ws/ws_pae_supp.c +++ b/source/6LoWPAN/ws/ws_pae_supp.c @@ -549,11 +549,13 @@ int8_t ws_pae_supp_nw_info_set(protocol_interface_info_entry_t *interface_ptr, u sec_prot_keys_ptk_delete(&pae_supp->entry.sec_keys); sec_prot_keys_ptk_eui_64_delete(&pae_supp->entry.sec_keys); // Delete GTKs - sec_prot_keys_gtks_init(pae_supp->sec_keys_nw_info->gtks); - sec_prot_keys_gtks_updated_set(pae_supp->sec_keys_nw_info->gtks); - ws_pae_supp_nvm_update(pae_supp); + sec_prot_keys_gtks_clear(pae_supp->sec_keys_nw_info->gtks); + // If data is changed, store to NVM + if (sec_prot_keys_are_updated(&pae_supp->entry.sec_keys) || + sec_prot_keys_gtks_are_updated(pae_supp->sec_keys_nw_info->gtks)) { + ws_pae_supp_nvm_update(pae_supp); + } } - return 0; } @@ -888,7 +890,7 @@ void ws_pae_supp_slow_timer(uint16_t seconds) continue; } uint64_t current_time = ws_pae_current_time_get(); - sec_prot_keys_gtk_lifetime_decrement(pae_supp->sec_keys_nw_info->gtks, i, current_time, seconds); + sec_prot_keys_gtk_lifetime_decrement(pae_supp->sec_keys_nw_info->gtks, i, current_time, seconds, false); } if (pae_supp->initial_key_timer > 0) { diff --git a/source/Security/protocols/sec_prot_keys.c b/source/Security/protocols/sec_prot_keys.c index d7071e932371..ff08f74942a2 100644 --- a/source/Security/protocols/sec_prot_keys.c +++ b/source/Security/protocols/sec_prot_keys.c @@ -96,6 +96,16 @@ void sec_prot_keys_gtks_init(sec_prot_gtk_keys_t *gtks) gtks->updated = false; } +void sec_prot_keys_gtks_clear(sec_prot_gtk_keys_t *gtks) +{ + for (uint8_t i = 0; i < GTK_NUM; i++) { + if (sec_prot_keys_gtk_is_set(gtks, i)) { + gtks->updated = true; + } + } + memset(gtks, 0, sizeof(sec_prot_gtk_keys_t)); +} + void sec_prot_keys_gtks_delete(sec_prot_gtk_keys_t *gtks) { ns_dyn_mem_free(gtks); @@ -113,12 +123,15 @@ void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk, uint32_t p void sec_prot_keys_pmk_delete(sec_prot_keys_t *sec_keys) { + if (sec_keys->pmk_key_replay_cnt != 0 || sec_keys->pmk_key_replay_cnt_set || + sec_keys->pmk_lifetime != 0 || sec_keys->pmk_set) { + sec_keys->updated = true; + } memset(sec_keys->pmk, 0, PMK_LEN); sec_keys->pmk_key_replay_cnt = 0; sec_keys->pmk_key_replay_cnt_set = false; sec_keys->pmk_lifetime = 0; sec_keys->pmk_set = false; - sec_keys->updated = true; } uint8_t *sec_prot_keys_pmk_get(sec_prot_keys_t *sec_keys) @@ -222,10 +235,12 @@ void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk, uint32_t p void sec_prot_keys_ptk_delete(sec_prot_keys_t *sec_keys) { + if (sec_keys->ptk_lifetime != 0 || sec_keys->ptk_set) { + sec_keys->updated = true; + } memset(sec_keys->ptk, 0, PTK_LEN); sec_keys->ptk_lifetime = 0; sec_keys->ptk_set = false; - sec_keys->updated = true; } uint8_t *sec_prot_keys_ptk_get(sec_prot_keys_t *sec_keys) @@ -279,9 +294,11 @@ uint8_t *sec_prot_keys_ptk_eui_64_get(sec_prot_keys_t *sec_keys) void sec_prot_keys_ptk_eui_64_delete(sec_prot_keys_t *sec_keys) { + if (sec_keys->ptk_eui_64_set) { + sec_keys->updated = true; + } memset(sec_keys->ptk_eui_64, 0, 8); sec_keys->ptk_eui_64_set = false; - sec_keys->updated = true; } bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint8_t seconds) @@ -490,7 +507,7 @@ uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index return gtks->gtk[index].lifetime; } -uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds) +uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds, bool gtk_update_enable) { if (gtks->gtk[index].lifetime > seconds) { gtks->gtk[index].lifetime -= seconds; @@ -508,7 +525,7 @@ uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t diff = expirytime - gtks->gtk[index].expirytime; } // If timestamps differ for more than 5 minutes marks field as updated (and stores to NVM) - if (diff > 300) { + if (diff > 300 && gtk_update_enable) { gtks->updated = true; } @@ -588,7 +605,8 @@ int8_t sec_prot_keys_gtk_status_active_set(sec_prot_gtk_keys_t *gtks, uint8_t in } } gtks->gtk[index].status = GTK_STATUS_ACTIVE; - gtks->updated = true; + /* Changing fresh to active does not change the gtks updated state since active + keys are set to fresh on nvm read on startup */ return 0; } diff --git a/source/Security/protocols/sec_prot_keys.h b/source/Security/protocols/sec_prot_keys.h index 5050ddeec123..0304d9eb4447 100644 --- a/source/Security/protocols/sec_prot_keys.h +++ b/source/Security/protocols/sec_prot_keys.h @@ -200,6 +200,14 @@ sec_prot_gtk_keys_t *sec_prot_keys_gtks_create(void); */ void sec_prot_keys_gtks_init(sec_prot_gtk_keys_t *gtks); +/** + * sec_prot_keys_gtks_init clear GTK keys + * + * \param gtks GTK keys + * + */ +void sec_prot_keys_gtks_clear(sec_prot_gtk_keys_t *gtks); + /** * sec_prot_keys_gtks_delete frees GTK keys memory * @@ -616,11 +624,12 @@ uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index * \param index index for GTK * \param current_time current timestamp * \param seconds elapsed seconds + * \param gtk_update_enable enable GTK status to be updated * * \return new GTK lifetime * */ -uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds); +uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint64_t current_time, uint16_t seconds, bool gtk_update_enable); /** * sec_prot_keys_gtk_exptime_from_lifetime_get converts GTK lifetime to expiry time.