diff --git a/source/6LoWPAN/ws/ws_pae_controller.c b/source/6LoWPAN/ws/ws_pae_controller.c index 805cb07d8bc2..504aadcedf3c 100644 --- a/source/6LoWPAN/ws/ws_pae_controller.c +++ b/source/6LoWPAN/ws/ws_pae_controller.c @@ -51,7 +51,7 @@ typedef void ws_pae_timer(uint16_t ticks); typedef int8_t ws_pae_br_addr_write(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64); typedef int8_t ws_pae_br_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64); typedef void ws_pae_gtks_updated(protocol_interface_info_entry_t *interface_ptr); -typedef int8_t ws_pae_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash); +typedef int8_t ws_pae_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash, bool del_gtk_on_mismatch); typedef int8_t ws_pae_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index); typedef int8_t ws_pae_nw_info_set(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, bool updated); @@ -196,7 +196,7 @@ int8_t ws_pae_controller_bootstrap_done(protocol_interface_info_entry_t *interfa /* Trigger GTK hash update to supplicant, so it can check whether keys have been updated during bootstrap. Does nothing if GTKs are up to date. */ - ws_pae_supp_gtk_hash_update(interface_ptr, controller->gtkhash); + ws_pae_supp_gtk_hash_update(interface_ptr, controller->gtkhash, false); #endif return 0; @@ -1662,7 +1662,7 @@ int8_t ws_pae_controller_gtk_hash_update(protocol_interface_info_entry_t *interf memcpy(controller->gtkhash, gtkhash, 32); if (controller->pae_gtk_hash_update) { - return controller->pae_gtk_hash_update(interface_ptr, controller->gtkhash); + return controller->pae_gtk_hash_update(interface_ptr, controller->gtkhash, true); } return 0; diff --git a/source/6LoWPAN/ws/ws_pae_supp.c b/source/6LoWPAN/ws/ws_pae_supp.c index 6aab0d9cae4b..7e518c465beb 100644 --- a/source/6LoWPAN/ws/ws_pae_supp.c +++ b/source/6LoWPAN/ws/ws_pae_supp.c @@ -294,7 +294,7 @@ static int8_t ws_pae_supp_gtk_hash_mismatch_check(pae_supp_t *pae_supp) } // Check GTK hashes and initiate EAPOL procedure if mismatch is detected */ - gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash); + gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash, false); if (mismatch != GTK_NO_MISMATCH) { return -1; } @@ -303,7 +303,7 @@ static int8_t ws_pae_supp_gtk_hash_mismatch_check(pae_supp_t *pae_supp) return 0; } -int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash) +int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash, bool del_gtk_on_mismatch) { pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); if (!pae_supp) { @@ -311,7 +311,7 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt } // Check GTK hashes and initiate EAPOL procedure if mismatch is detected */ - gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash); + gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(pae_supp->sec_keys_nw_info->gtks, gtkhash, del_gtk_on_mismatch); if (mismatch > GTK_NO_MISMATCH) { tr_info("GTK hash update %s %s %s %s", trace_array(>khash[0], 8), diff --git a/source/6LoWPAN/ws/ws_pae_supp.h b/source/6LoWPAN/ws/ws_pae_supp.h index 1ccd78c21ea0..c991d65062c7 100644 --- a/source/6LoWPAN/ws/ws_pae_supp.h +++ b/source/6LoWPAN/ws/ws_pae_supp.h @@ -130,12 +130,13 @@ int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, * * \param interface_ptr interface * \param gtkhash GTK hash, 32 bytes + * \param del_gtk_on_mismatch Delete GTK in case of mismatch * * \return < 0 failure * \return >= 0 success * */ -int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash); +int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash, bool del_gtk_on_mismatch); /** * ws_pae_supp_nw_key_index_update key index been updated (on PAN configuration) diff --git a/source/Security/protocols/sec_prot_keys.c b/source/Security/protocols/sec_prot_keys.c index 02748f08fcd6..22268ac1f150 100644 --- a/source/Security/protocols/sec_prot_keys.c +++ b/source/Security/protocols/sec_prot_keys.c @@ -716,7 +716,7 @@ int8_t sec_prot_keys_gtk_valid_check(uint8_t *gtk) return 0; } -gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash) +gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash, bool del_gtk_on_mismatch) { uint8_t *gtk_hash_ptr = gtkhash; @@ -729,11 +729,15 @@ gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t uint32_t lifetime = sec_prot_keys_gtk_lifetime_get(gtks, i); if (lifetime > GTK_EXPIRE_MISMATCH_TIME) { tr_info("GTK mismatch %i expired time, lifetime: %"PRIu32"", i, lifetime); - if (mismatch < GTK_LIFETIME_MISMATCH) { + // Only indicate mismatch in case fresh hash is received + if (mismatch < GTK_LIFETIME_MISMATCH && del_gtk_on_mismatch) { mismatch = GTK_LIFETIME_MISMATCH; } } - sec_prot_keys_gtk_clear(gtks, i); + // Only delete in case fresh hash is received + if (del_gtk_on_mismatch) { + sec_prot_keys_gtk_clear(gtks, i); + } } } else { // Check is hash matches to existing key @@ -759,7 +763,10 @@ gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t if (mismatch < GTK_HASH_MISMATCH) { mismatch = GTK_HASH_MISMATCH; } - sec_prot_keys_gtk_clear(gtks, i); + // Only delete in case fresh hash is received + if (del_gtk_on_mismatch) { + sec_prot_keys_gtk_clear(gtks, i); + } } } } diff --git a/source/Security/protocols/sec_prot_keys.h b/source/Security/protocols/sec_prot_keys.h index 6215bdc759f5..c397a93618f8 100644 --- a/source/Security/protocols/sec_prot_keys.h +++ b/source/Security/protocols/sec_prot_keys.h @@ -806,11 +806,12 @@ int8_t sec_prot_keys_gtk_valid_check(uint8_t *gtk); * * \param gtks GTK keys * \param gtk_hash GTK hash + * \param del_gtk_on_mismatch Delete GTK in case of mismatch * * \return GTK mismatch type or no mismatch * */ -gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash); +gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash, bool del_gtk_on_mismatch); /** * sec_prot_keys_gtk_hash_empty checks if GTK hash field is empty