diff --git a/source/6LoWPAN/ws/ws_cfg_settings.c b/source/6LoWPAN/ws/ws_cfg_settings.c index 5da0292b1d9..74ae9dd51d1 100644 --- a/source/6LoWPAN/ws/ws_cfg_settings.c +++ b/source/6LoWPAN/ws/ws_cfg_settings.c @@ -467,10 +467,10 @@ static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; - cfg->sec_prot.initial_key_imin = SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; - cfg->sec_prot.initial_key_imax = SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; - cfg->sec_prot.initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; + cfg->sec_prot.initial_key_retry_min = SMALL_NW_INITIAL_KEY_RETRY_MIN_SECS; + cfg->sec_prot.initial_key_retry_max = SMALL_NW_INITIAL_KEY_RETRY_MAX_SECS; + cfg->sec_prot.initial_key_retry_max_limit = SMALL_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS; + cfg->sec_prot.initial_key_retry_cnt = SMALL_NW_INITIAL_KEY_RETRY_COUNT; // Multicast timing configuration cfg->mpl.mpl_trickle_imin = MPL_SMALL_IMIN; @@ -510,10 +510,10 @@ static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; - cfg->sec_prot.initial_key_imin = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; - cfg->sec_prot.initial_key_imax = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; - cfg->sec_prot.initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; + cfg->sec_prot.initial_key_retry_min = MEDIUM_NW_INITIAL_KEY_RETRY_MIN_SECS; + cfg->sec_prot.initial_key_retry_max = MEDIUM_NW_INITIAL_KEY_RETRY_MAX_SECS; + cfg->sec_prot.initial_key_retry_max_limit = MEDIUM_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS; + cfg->sec_prot.initial_key_retry_cnt = MEDIUM_NW_INITIAL_KEY_RETRY_COUNT; // Multicast timing configuration cfg->mpl.mpl_trickle_imin = MPL_MEDIUM_IMIN; @@ -552,9 +552,9 @@ static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_LARGE; - cfg->sec_prot.initial_key_retry_delay = NONE_INITIAL_KEY_RETRY_TIMER; - cfg->sec_prot.initial_key_imin = LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; - cfg->sec_prot.initial_key_imax = LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_min = LARGE_NW_INITIAL_KEY_RETRY_MIN_SECS; + cfg->sec_prot.initial_key_retry_max = LARGE_NW_INITIAL_KEY_RETRY_MAX_SECS; + cfg->sec_prot.initial_key_retry_max_limit = LARGE_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS; cfg->sec_prot.initial_key_retry_cnt = LARGE_NW_INITIAL_KEY_RETRY_COUNT; // Multicast timing configuration @@ -595,9 +595,9 @@ static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_LARGE; - cfg->sec_prot.initial_key_retry_delay = NONE_INITIAL_KEY_RETRY_TIMER; - cfg->sec_prot.initial_key_imin = EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; - cfg->sec_prot.initial_key_imax = EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; + cfg->sec_prot.initial_key_retry_min = EXTRA_LARGE_NW_INITIAL_KEY_RETRY_MIN_SECS; + cfg->sec_prot.initial_key_retry_max = EXTRA_LARGE_NW_INITIAL_KEY_RETRY_MAX_SECS; + cfg->sec_prot.initial_key_retry_max_limit = EXTRA_LARGE_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS; cfg->sec_prot.initial_key_retry_cnt = EXTRA_LARGE_NW_INITIAL_KEY_RETRY_COUNT; // Multicast timing configuration @@ -637,10 +637,10 @@ static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg) cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS; cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; - cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; - cfg->sec_prot.initial_key_imin = SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; - cfg->sec_prot.initial_key_imax = SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; - cfg->sec_prot.initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; + cfg->sec_prot.initial_key_retry_min = SMALL_NW_INITIAL_KEY_RETRY_MIN_SECS; + cfg->sec_prot.initial_key_retry_max = SMALL_NW_INITIAL_KEY_RETRY_MAX_SECS; + cfg->sec_prot.initial_key_retry_max_limit = SMALL_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS; + cfg->sec_prot.initial_key_retry_cnt = SMALL_NW_INITIAL_KEY_RETRY_COUNT; // Multicast timing configuration for certification uses the LARGE values as it is the one mentioned ins specification cfg->mpl.mpl_trickle_imin = MPL_XLARGE_IMIN; @@ -1241,10 +1241,10 @@ static int8_t ws_cfg_sec_prot_default_set(ws_sec_prot_cfg_t *cfg) cfg->sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL; cfg->max_simult_sec_neg_tx_queue_min = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MIN; cfg->max_simult_sec_neg_tx_queue_max = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MAX; - cfg->initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER; - cfg->initial_key_imin = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS; - cfg->initial_key_imax = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS; - cfg->initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; + cfg->initial_key_retry_min = MEDIUM_NW_INITIAL_KEY_RETRY_MIN_SECS; + cfg->initial_key_retry_max = MEDIUM_NW_INITIAL_KEY_RETRY_MAX_SECS; + cfg->initial_key_retry_max_limit = MEDIUM_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS; + cfg->initial_key_retry_cnt = MEDIUM_NW_INITIAL_KEY_RETRY_COUNT; return CFG_SETTINGS_OK; } @@ -1268,10 +1268,10 @@ int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_c cfg->sec_prot_retry_timeout != new_cfg->sec_prot_retry_timeout || cfg->max_simult_sec_neg_tx_queue_min != new_cfg->max_simult_sec_neg_tx_queue_min || cfg->max_simult_sec_neg_tx_queue_max != new_cfg->max_simult_sec_neg_tx_queue_max || - cfg->initial_key_retry_delay != new_cfg->initial_key_retry_delay || - cfg->initial_key_imin != new_cfg->initial_key_retry_delay || - cfg->initial_key_imax != new_cfg->initial_key_retry_delay || - cfg->initial_key_retry_cnt != new_cfg->initial_key_retry_delay) { + cfg->initial_key_retry_min != new_cfg->initial_key_retry_min || + cfg->initial_key_retry_max != new_cfg->initial_key_retry_max || + cfg->initial_key_retry_max_limit != new_cfg->initial_key_retry_max_limit || + cfg->initial_key_retry_cnt != new_cfg->initial_key_retry_cnt) { return CFG_SETTINGS_CHANGED; } diff --git a/source/6LoWPAN/ws/ws_cfg_settings.h b/source/6LoWPAN/ws/ws_cfg_settings.h index 6fcfeec2b5c..827b45aeff6 100644 --- a/source/6LoWPAN/ws/ws_cfg_settings.h +++ b/source/6LoWPAN/ws/ws_cfg_settings.h @@ -117,10 +117,10 @@ typedef struct ws_sec_prot_cfg_s { uint8_t sec_prot_trickle_timer_exp; /**< Security protocol trickle timer expirations; default 2 */ uint16_t max_simult_sec_neg_tx_queue_min; /**< PAE authenticator max simultaneous security negotiations TX queue minimum */ uint16_t max_simult_sec_neg_tx_queue_max; /**< PAE authenticator max simultaneous security negotiations TX queue maximum */ - uint16_t initial_key_retry_delay; /**< Delay before starting initial key trickle; seconds; default 120 */ - uint16_t initial_key_imin; /**< Initial key trickle Imin; seconds; default 360 */ - uint16_t initial_key_imax; /**< Initial key trickle Imax; seconds; default 720 */ - uint8_t initial_key_retry_cnt; /**< Number of initial key retries; default 2 */ + uint16_t initial_key_retry_min; /**< Initial EAPOL-Key retry exponential backoff min; seconds; default 180 */ + uint16_t initial_key_retry_max; /**< Initial EAPOL-Key retry exponential backoff max; seconds; default 420 */ + uint16_t initial_key_retry_max_limit; /**< Initial EAPOL-Key retry exponential backoff max limit; seconds; default 720 */ + uint8_t initial_key_retry_cnt; /**< Number of initial key retries; default 4 */ } ws_sec_prot_cfg_t; /** diff --git a/source/6LoWPAN/ws/ws_config.h b/source/6LoWPAN/ws/ws_config.h index c65ab94570b..71044f21007 100644 --- a/source/6LoWPAN/ws/ws_config.h +++ b/source/6LoWPAN/ws/ws_config.h @@ -274,32 +274,51 @@ extern uint8_t DEVICE_MIN_SENS; /* * Security protocol initial EAPOL-key parameters + * + * Retry time is randomized between minimum and maximum retry time: rand(min,max). + * For each subsequent retry the maximum retry time is doubled until the maximum + * limit is reached. */ -// How long the wait is before the first initial EAPOL-key retry -#define DEFAULT_INITIAL_KEY_RETRY_TIMER 120 -#define NONE_INITIAL_KEY_RETRY_TIMER 0 - -// Small network Default trickle values for sending of initial EAPOL-key -#define SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 360 /* 6 to 8.3 minutes */ -#define SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 500 - -// Small network Default trickle values for sending of initial EAPOL-key -#define MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 360 /* 6 to 12 minutes */ -#define MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 720 - -// Large network trickle values for sending of initial EAPOL-key -#define LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 600 /* 10 to 20 minutes */ -#define LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 1200 -#define LARGE_NW_INITIAL_KEY_RETRY_COUNT 3 - -// Very slow network values for sending of initial EAPOL-key -#define EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS 600 /* 10 to 20 minutes */ -#define EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS 1200 -#define EXTRA_LARGE_NW_INITIAL_KEY_RETRY_COUNT 4 - -// How many times sending of initial EAPOL-key is retried -#define DEFAULT_INITIAL_KEY_RETRY_COUNT 2 +/* Small network initial EAPOL-key retry exponential backoff parameters + * 1st backoff 3 to 7 minutes, max 7 minutes, retries 2 + * Minimum time for sequence is 3 + 3 = 6 minutes + * Maximum time for sequence is 7 + 7 = 14 minutes + */ +#define SMALL_NW_INITIAL_KEY_RETRY_MIN_SECS 180 // 3 +#define SMALL_NW_INITIAL_KEY_RETRY_MAX_SECS 420 // 7 +#define SMALL_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS 420 // 7 +#define SMALL_NW_INITIAL_KEY_RETRY_COUNT 2 + +/* Medium network initial EAPOL-key retry exponential backoff parameters + * 1st backoff 3 to 7 minutes, max 12 minutes, retries 4 + * Minimum time for sequence is 3 + 3 + 3 + 3 = 12 minutes + * Maximum time for sequence is 7 + 12 + 12 + 12 = 43 minutes + */ +#define MEDIUM_NW_INITIAL_KEY_RETRY_MIN_SECS 180 // 3 +#define MEDIUM_NW_INITIAL_KEY_RETRY_MAX_SECS 420 // 7 +#define MEDIUM_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS 720 // 12 +#define MEDIUM_NW_INITIAL_KEY_RETRY_COUNT 4 + +/* Large network initial EAPOL-key retry exponential backoff parameters + * 1st backoff 5 to 10 minutes, max 15 minutes, retries 4 + * Minimum time for sequence is 5 + 5 + 5 + 5 = 20 minutes + * Maximum time for sequence is 10 + 15 + 15 + 15 = 55 minutes + */ +#define LARGE_NW_INITIAL_KEY_RETRY_MIN_SECS 300 // 5 +#define LARGE_NW_INITIAL_KEY_RETRY_MAX_SECS 600 // 10 +#define LARGE_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS 900 // 15 +#define LARGE_NW_INITIAL_KEY_RETRY_COUNT 4 + +/* Extra large network initial EAPOL-key retry exponential backoff parameters + * 1st backoff 5 to 10 minutes, max 20 minutes, retries 4 + * Minimum time for sequence is 5 + 5 + 5 + 5 = 20 minutes + * Maximum time for sequence is 10 + 20 + 20 + 20 = 70 minutes + */ +#define EXTRA_LARGE_NW_INITIAL_KEY_RETRY_MIN_SECS 300 // 5 +#define EXTRA_LARGE_NW_INITIAL_KEY_RETRY_MAX_SECS 600 // 10 +#define EXTRA_LARGE_NW_INITIAL_KEY_RETRY_MAX_LIMIT_SECS 1200 // 20 +#define EXTRA_LARGE_NW_INITIAL_KEY_RETRY_COUNT 4 /* * RADIUS client retry timer defaults diff --git a/source/6LoWPAN/ws/ws_pae_controller.c b/source/6LoWPAN/ws/ws_pae_controller.c index 3d1a6f81f4e..f57934fcade 100644 --- a/source/6LoWPAN/ws/ws_pae_controller.c +++ b/source/6LoWPAN/ws/ws_pae_controller.c @@ -721,11 +721,9 @@ int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_pt controller->sec_cfg.prot_cfg.sec_prot_trickle_params.k = 0; controller->sec_cfg.prot_cfg.sec_prot_trickle_params.TimerExpirations = sec_prot_cfg->sec_prot_trickle_timer_exp; controller->sec_cfg.prot_cfg.sec_prot_retry_timeout = sec_prot_cfg->sec_prot_retry_timeout * 10; - controller->sec_cfg.prot_cfg.initial_key_retry_delay = sec_prot_cfg->initial_key_retry_delay; - controller->sec_cfg.prot_cfg.initial_key_trickle_params.Imin = sec_prot_cfg->initial_key_imin; - controller->sec_cfg.prot_cfg.initial_key_trickle_params.Imax = sec_prot_cfg->initial_key_imax; - controller->sec_cfg.prot_cfg.initial_key_trickle_params.k = 0; - controller->sec_cfg.prot_cfg.initial_key_trickle_params.TimerExpirations = 2; + controller->sec_cfg.prot_cfg.initial_key_retry_min = sec_prot_cfg->initial_key_retry_min; + controller->sec_cfg.prot_cfg.initial_key_retry_max = sec_prot_cfg->initial_key_retry_max; + controller->sec_cfg.prot_cfg.initial_key_retry_max_limit = sec_prot_cfg->initial_key_retry_max_limit; controller->sec_cfg.prot_cfg.initial_key_retry_cnt = sec_prot_cfg->initial_key_retry_cnt; } diff --git a/source/6LoWPAN/ws/ws_pae_supp.c b/source/6LoWPAN/ws/ws_pae_supp.c index ea72ed6ddd4..f3753a54920 100644 --- a/source/6LoWPAN/ws/ws_pae_supp.c +++ b/source/6LoWPAN/ws/ws_pae_supp.c @@ -78,8 +78,8 @@ #define STORED_KEYS_MAXIMUM_USE_COUNT 1 // Delay for sending the initial EAPOL-Key -#define INITIAL_KEY_TIMER_MIN 3 -#define INITIAL_KEY_TIMER_MAX 30 +#define INITIAL_KEY_TIMER_MIN 1 +#define INITIAL_KEY_TIMER_MAX 3 typedef struct { ns_list_link_t link; /**< Link */ @@ -94,16 +94,17 @@ typedef struct { supp_entry_t entry; /**< Supplicant data */ kmp_addr_t target_addr; /**< EAPOL target (parent) address */ uint16_t initial_key_timer; /**< Timer to trigger initial EAPOL-Key */ - uint16_t initial_key_retry_timer; /**< Timer to trigger initial EAPOL-Key 1st retry */ - trickle_t auth_trickle_timer; /**< Trickle timer for re-sending initial EAPOL-key or for GTK mismatch */ - trickle_params_t auth_trickle_params; /**< Trickle parameters for initial EAPOL-key or for GTK mismatch */ + trickle_t gtk_req_trickle_timer; /**< Trickle timer for re-sending initial EAPOL-key on GTK mismatch */ + trickle_params_t gtk_req_trickle_params; /**< Trickle parameters for initial EAPOL-key on GTK mismatch */ uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap after bootstrap start */ uint8_t comp_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap after bootstrap completed */ sec_prot_keys_nw_info_t *sec_keys_nw_info; /**< Security keys network information */ sec_cfg_t *sec_cfg; /**< Security configuration */ uint8_t nw_keys_used_cnt; /**< How many times bootstrap has been tried with current keys */ + uint16_t initial_key_retry_max_value; /**< Initial EAPOL-Key retry exponential backoff max value */ + uint16_t initial_key_retry_timer; /**< Initial EAPOL-Key retry exponential backoff timer */ uint8_t initial_key_retry_cnt; /**< initial EAPOL-Key retry counter */ - bool auth_trickle_running : 1; /**< Initial EAPOL-Key Trickle timer running */ + bool gtk_update_trickle_running : 1; /**< GTK update Initial EAPOL-Key Trickle timer running */ bool auth_requested : 1; /**< Authentication has been requested by the bootstrap */ bool timer_running : 1; /**< Timer is running */ bool new_br_eui_64_set : 1; /**< Border router address has been set after bootstrap start */ @@ -117,9 +118,9 @@ typedef struct { #define KEY_UPDATE_RETRY_COUNT 3 #define LIFETIME_MISMATCH_RETRY_COUNT 1 /* No retries */ -// Trickle timer on how long to wait response after last retry before failing authentication -#define LAST_INTERVAL_TRICKLE_IMIN_SECS 240 /* 4 minutes */ -#define LAST_INTERVAL_TRICKLE_IMAX_SECS 240 +// Timer on how long to wait response after last retry before failing authentication +#define LAST_INTERVAL_MIN_SECS 120 /* 2 minutes */ +#define LAST_INTERVAL_MAX_SECS 240 /* 4 minutes */ static void ws_pae_supp_free(pae_supp_t *pae_supp); static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result); @@ -131,8 +132,6 @@ static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp); static pae_supp_t *ws_pae_supp_get(protocol_interface_info_entry_t *interface_ptr); static int8_t ws_pae_supp_event_send(kmp_service_t *service, void *data); static void ws_pae_supp_tasklet_handler(arm_event_s *event); -static void ws_pae_supp_initial_trickle_timer_start(pae_supp_t *pae_supp); -static void ws_pae_supp_initial_last_interval_trickle_timer_start(pae_supp_t *pae_supp); static void ws_pae_supp_initial_key_update_trickle_timer_start(pae_supp_t *pae_supp, uint8_t timer_expirations); static bool ws_pae_supp_authentication_ongoing(pae_supp_t *pae_supp); static int8_t ws_pae_supp_timer_if_start(kmp_service_t *service, kmp_api_t *kmp); @@ -220,7 +219,7 @@ int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, pae_supp->auth_requested = true; - // Randomizes the sending of initial EAPOL-Key messsage + // Randomizes the sending of initial EAPOL-Key message pae_supp->initial_key_timer = randLIB_get_random_in_range(INITIAL_KEY_TIMER_MIN, INITIAL_KEY_TIMER_MAX); // Starts supplicant timer @@ -322,7 +321,7 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt /* Mismatch, initiate EAPOL (if authentication not already ongoing or if not on wait time for the authenticator to answer) */ - if (!pae_supp->auth_trickle_running || pae_supp->initial_key_retry_cnt == 0) { + if (!pae_supp->gtk_update_trickle_running || pae_supp->initial_key_retry_cnt == 0) { uint8_t timer_expirations = KEY_UPDATE_RETRY_COUNT; // For GTK lifetime mismatch send only once if (mismatch == GTK_LIFETIME_MISMATCH) { @@ -334,7 +333,7 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt // Starts supplicant timer ws_pae_supp_timer_start(pae_supp); - tr_info("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i", pae_supp->sec_cfg->timer_cfg.gtk_request_imin, pae_supp->sec_cfg->timer_cfg.gtk_request_imax, pae_supp->sec_cfg->timer_cfg.gtk_max_mismatch, pae_supp->auth_trickle_timer.t); + tr_info("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i", pae_supp->sec_cfg->timer_cfg.gtk_request_imin, pae_supp->sec_cfg->timer_cfg.gtk_request_imax, pae_supp->sec_cfg->timer_cfg.gtk_max_mismatch, pae_supp->gtk_req_trickle_timer.t); } } @@ -426,7 +425,7 @@ static int8_t ws_pae_supp_nvm_keys_read(pae_supp_t *pae_supp) static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result) { - pae_supp->auth_trickle_running = false; + pae_supp->initial_key_retry_timer = 0; if (pae_supp->auth_requested && pae_supp->auth_completed) { pae_supp->auth_requested = false; pae_supp->auth_completed(pae_supp->interface_ptr, result, pae_supp->target_addr.eui_64); @@ -576,18 +575,19 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se pae_supp->nw_key_index_set = NULL; pae_supp->gtk_hash_ptr_get = NULL; pae_supp->initial_key_timer = 0; - pae_supp->initial_key_retry_timer = 0; pae_supp->nw_keys_used_cnt = 0; - pae_supp->initial_key_retry_cnt = DEFAULT_INITIAL_KEY_RETRY_COUNT; + pae_supp->initial_key_retry_cnt = MEDIUM_NW_INITIAL_KEY_RETRY_COUNT; pae_supp->sec_keys_nw_info = sec_keys_nw_info; pae_supp->sec_cfg = sec_cfg; - pae_supp->auth_trickle_running = false; + pae_supp->gtk_update_trickle_running = false; pae_supp->auth_requested = false; pae_supp->timer_running = false; pae_supp->new_br_eui_64_set = false; pae_supp->new_br_eui_64_fresh = false; pae_supp->comp_br_eui_64_set = false; pae_supp->entry_address_active = false; + pae_supp->initial_key_retry_max_value = 0; + pae_supp->initial_key_retry_timer = 0; ws_pae_lib_supp_init(&pae_supp->entry); @@ -787,7 +787,7 @@ void ws_pae_supp_fast_timer(uint16_t ticks) static bool ws_pae_supp_authentication_ongoing(pae_supp_t *pae_supp) { /* When either bootstrap initial authentication or re-authentication is ongoing */ - if (pae_supp->initial_key_timer || pae_supp->auth_trickle_running || + if (pae_supp->initial_key_timer || pae_supp->initial_key_retry_timer || pae_supp->gtk_update_trickle_running || ws_pae_lib_supp_timer_is_running(&pae_supp->entry)) { return true; } @@ -799,67 +799,79 @@ void ws_pae_supp_slow_timer(uint16_t seconds) { ns_list_foreach(pae_supp_t, pae_supp, &pae_supp_list) { - // Checks whether initial EAPOL-Key message needs to be re-send or new GTK request to be sent - if (pae_supp->auth_trickle_running) { - if (pae_supp->initial_key_retry_timer > 0) { - if (pae_supp->initial_key_retry_timer > seconds) { - pae_supp->initial_key_retry_timer -= seconds; - } else { - pae_supp->initial_key_retry_timer = 0; - tr_info("initial key retry timer expired"); + bool key_expired = false; + + if (pae_supp->initial_key_retry_timer > seconds) { + pae_supp->initial_key_retry_timer -= seconds; + } else if (pae_supp->initial_key_retry_timer != 0) { + pae_supp->initial_key_retry_timer = 0; + key_expired = true; + } + + if (pae_supp->gtk_update_trickle_running) { + if (trickle_timer(&pae_supp->gtk_req_trickle_timer, &pae_supp->gtk_req_trickle_params, seconds)) { + key_expired = true; + } + } + + if (key_expired) { + if (pae_supp->initial_key_retry_cnt > 0) { + // On initial EAPOL-key TX failure, check for other parents + if (pae_supp->auth_requested && pae_supp->tx_failure_on_initial_key) { + // Returns same target if no other valid targets found + const uint8_t *next_target = pae_supp->auth_next_target(pae_supp->interface_ptr, kmp_address_eui_64_get(&pae_supp->target_addr), &pae_supp->sec_keys_nw_info->key_pan_id); + kmp_address_eui_64_set(&pae_supp->target_addr, next_target); + ws_pae_supp_address_set(pae_supp, &pae_supp->target_addr); } - } else { - // Checks if trickle timer expires - if (trickle_timer(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params, seconds)) { - if (pae_supp->initial_key_retry_cnt > 0) { - // On initial EAPOL-key TX failure, check for other parents - if (pae_supp->auth_requested && pae_supp->tx_failure_on_initial_key) { - // Returns same target if no other valid targets found - const uint8_t *next_target = pae_supp->auth_next_target(pae_supp->interface_ptr, kmp_address_eui_64_get(&pae_supp->target_addr), &pae_supp->sec_keys_nw_info->key_pan_id); - kmp_address_eui_64_set(&pae_supp->target_addr, next_target); - ws_pae_supp_address_set(pae_supp, &pae_supp->target_addr); - } - pae_supp->tx_failure_on_initial_key = false; - // Sends initial EAPOL-key - if (ws_pae_supp_initial_key_send(pae_supp) < 0) { - tr_info("EAPOL-Key send failed"); - } - } + pae_supp->tx_failure_on_initial_key = false; + // Sends initial EAPOL-key + if (ws_pae_supp_initial_key_send(pae_supp) < 0) { + tr_info("EAPOL-Key send failed"); + } + } - /* Wait time for the authenticator to answer the last re-transmit expires; - fails authentication */ - if (pae_supp->initial_key_retry_cnt == 0) { - bool retry = false; - // If making key update and GTKs do not match to GTK hash - if (!pae_supp->auth_requested && ws_pae_supp_gtk_hash_mismatch_check(pae_supp) < 0) { - tr_info("GTKs do not match to GTK hash"); - retry = true; - } - auth_result_e result = AUTH_RESULT_ERR_UNSPEC; - if (pae_supp->tx_failure_on_initial_key) { - result = AUTH_RESULT_ERR_TX_ERR; - pae_supp->tx_failure_on_initial_key = false; - } - ws_pae_supp_authenticate_response(pae_supp, result); - if (retry) { - // Start trickle timer to try re-authentication - ws_pae_supp_initial_key_update_trickle_timer_start(pae_supp, KEY_UPDATE_RETRY_COUNT); - } - } else { - if (pae_supp->initial_key_retry_cnt > 0) { - pae_supp->initial_key_retry_cnt--; - } - if (pae_supp->initial_key_retry_cnt == 0) { - // Starts wait time for the authenticator to answer - tr_info("Initial EAPOL-Key wait for last re-transmit answer"); - ws_pae_supp_initial_last_interval_trickle_timer_start(pae_supp); - } - } + /* Wait time for the authenticator to answer the last re-transmit expires; + fails authentication */ + if (pae_supp->initial_key_retry_cnt == 0) { + bool retry = false; + // If making key update and GTKs do not match to GTK hash + if (!pae_supp->auth_requested && ws_pae_supp_gtk_hash_mismatch_check(pae_supp) < 0) { + tr_info("GTKs do not match to GTK hash"); + retry = true; + } + auth_result_e result = AUTH_RESULT_ERR_UNSPEC; + if (pae_supp->tx_failure_on_initial_key) { + result = AUTH_RESULT_ERR_TX_ERR; + pae_supp->tx_failure_on_initial_key = false; } + ws_pae_supp_authenticate_response(pae_supp, result); + if (retry) { + // Start trickle timer to try re-authentication + ws_pae_supp_initial_key_update_trickle_timer_start(pae_supp, KEY_UPDATE_RETRY_COUNT); + } + } else { + if (pae_supp->initial_key_retry_cnt > 1) { + pae_supp->initial_key_retry_cnt--; - // Sanity check, should be running until authentication failure - if (!trickle_running(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params)) { - ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_UNSPEC); + pae_supp->initial_key_retry_max_value *= 2; + if (pae_supp->initial_key_retry_max_value > pae_supp->sec_cfg->prot_cfg.initial_key_retry_max_limit) { + pae_supp->initial_key_retry_max_value = pae_supp->sec_cfg->prot_cfg.initial_key_retry_max_limit; + } + pae_supp->initial_key_retry_timer = randLIB_get_random_in_range( + pae_supp->sec_cfg->prot_cfg.initial_key_retry_min, + pae_supp->initial_key_retry_max_value); + + tr_info("Initial EAPOL-Key retry timer %i seconds (range [%i,%i] seconds)", + pae_supp->initial_key_retry_timer, + pae_supp->sec_cfg->prot_cfg.initial_key_retry_min, + pae_supp->initial_key_retry_max_value); + } else if (pae_supp->initial_key_retry_cnt > 0) { + pae_supp->initial_key_retry_cnt = 0; + // Starts wait time for the authenticator to answer + pae_supp->initial_key_retry_timer = randLIB_get_random_in_range( + LAST_INTERVAL_MIN_SECS, LAST_INTERVAL_MAX_SECS); + tr_info("Initial EAPOL-Key wait for last re-transmit answer %i seconds (range [120,240] seconds)", + pae_supp->initial_key_retry_timer); } } } @@ -879,71 +891,37 @@ void ws_pae_supp_slow_timer(uint16_t seconds) } else { pae_supp->initial_key_timer = 0; pae_supp->tx_failure_on_initial_key = false; + pae_supp->initial_key_retry_cnt = pae_supp->sec_cfg->prot_cfg.initial_key_retry_cnt; // Sends initial EAPOL-Key message if (ws_pae_supp_initial_key_send(pae_supp) < 0) { tr_info("EAPOL-Key send failed"); } - // Start trickle timer - ws_pae_supp_initial_trickle_timer_start(pae_supp); + // Starts initial EAPOL-key retry exponential backoff timer + pae_supp->initial_key_retry_max_value = pae_supp->sec_cfg->prot_cfg.initial_key_retry_max; + pae_supp->initial_key_retry_timer = randLIB_get_random_in_range( + pae_supp->sec_cfg->prot_cfg.initial_key_retry_min, + pae_supp->initial_key_retry_max_value); + + tr_info("Initial EAPOL-Key retry timer %i seconds (range [%i,%i] seconds)", + pae_supp->initial_key_retry_timer, + pae_supp->sec_cfg->prot_cfg.initial_key_retry_min, + pae_supp->initial_key_retry_max_value); } } } } -static void ws_pae_supp_initial_trickle_timer_start(pae_supp_t *pae_supp) -{ - /* Starts trickle for initial EAPOL-key. Default sequence has fixed delay of 2 minutes, - * one re-transmit interval, last re-transmit interval transmit time and a wait time - * for the authenticator to answer the last re-transmit. - * - * Interval I [6,12] minutes. Sequence: - * - * fixed 2 minutes delay + I + last I transmit time t + wait for answer [2,4] minutes - * - * There are two retries. Minimum time that sequence takes before authentication failure - * is 16 minutes and maximum is 30 minutes. - * - * - * Extremely slow network - * - * Starts trickle for initial EAPOL-key, Interval I [10,60] minutes. Sequence: - * I + last I transmit time t + wait for answer [2,4] minutes - * There are two retries. Minimum time that sequence takes before authentication failure - * is 22 minutes and maximum is 124 minutes. - */ - pae_supp->auth_trickle_params = pae_supp->sec_cfg->prot_cfg.initial_key_trickle_params; - pae_supp->initial_key_retry_timer = pae_supp->sec_cfg->prot_cfg.initial_key_retry_delay; - - trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); - tr_info("Initial EAPOL-Key trickle I: [%i,%i] %i, t: %i", pae_supp->auth_trickle_params.Imin, pae_supp->auth_trickle_params.Imax, pae_supp->auth_trickle_timer.I, pae_supp->auth_trickle_timer.t); - pae_supp->auth_trickle_running = true; - pae_supp->initial_key_retry_cnt = pae_supp->sec_cfg->prot_cfg.initial_key_retry_cnt; -} - -static void ws_pae_supp_initial_last_interval_trickle_timer_start(pae_supp_t *pae_supp) -{ - // Starts trickle last to wait response after last retry before failing authentication - pae_supp->auth_trickle_params.Imin = LAST_INTERVAL_TRICKLE_IMIN_SECS; - pae_supp->auth_trickle_params.Imax = LAST_INTERVAL_TRICKLE_IMAX_SECS; - pae_supp->auth_trickle_params.k = 0; - pae_supp->auth_trickle_params.TimerExpirations = 1; - // Set I to [iMin,iMax] (4 to 4 minutes) -> t is [I/2 - I] (2 minutes to 4 minutes) - trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); - tr_info("Initial EAPOL-Key trickle I: [%i,%i] %i, t: %i", pae_supp->auth_trickle_params.Imin, pae_supp->auth_trickle_params.Imax, pae_supp->auth_trickle_timer.I, pae_supp->auth_trickle_timer.t); -} - static void ws_pae_supp_initial_key_update_trickle_timer_start(pae_supp_t *pae_supp, uint8_t timer_expirations) { // Starts trickle for the key update - pae_supp->auth_trickle_params.Imin = pae_supp->sec_cfg->timer_cfg.gtk_request_imin; - pae_supp->auth_trickle_params.Imax = pae_supp->sec_cfg->timer_cfg.gtk_request_imax; - pae_supp->auth_trickle_params.k = 0; - pae_supp->auth_trickle_params.TimerExpirations = timer_expirations; - - trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); - tr_info("Initial EAPOL-Key trickle I: [%i,%i] %i, t: %i", pae_supp->auth_trickle_params.Imin, pae_supp->auth_trickle_params.Imax, pae_supp->auth_trickle_timer.I, pae_supp->auth_trickle_timer.t); - pae_supp->initial_key_retry_timer = NONE_INITIAL_KEY_RETRY_TIMER; // 0 seconds - pae_supp->auth_trickle_running = true; + pae_supp->gtk_req_trickle_params.Imin = pae_supp->sec_cfg->timer_cfg.gtk_request_imin; + pae_supp->gtk_req_trickle_params.Imax = pae_supp->sec_cfg->timer_cfg.gtk_request_imax; + pae_supp->gtk_req_trickle_params.k = 0; + pae_supp->gtk_req_trickle_params.TimerExpirations = timer_expirations; + + trickle_start(&pae_supp->gtk_req_trickle_timer, &pae_supp->gtk_req_trickle_params); + tr_info("Initial EAPOL-Key trickle I: [%i,%i] %i, t: %i", pae_supp->gtk_req_trickle_params.Imin, pae_supp->gtk_req_trickle_params.Imax, pae_supp->gtk_req_trickle_timer.I, pae_supp->gtk_req_trickle_timer.t); + pae_supp->gtk_update_trickle_running = true; pae_supp->initial_key_retry_cnt = timer_expirations; } @@ -1216,7 +1194,8 @@ static void ws_pae_supp_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e typ } // Incoming KMP protocol has started, no longer runs trickle timer for re-sending EAPOL-key message - pae_supp->auth_trickle_running = false; + pae_supp->gtk_update_trickle_running = false; + pae_supp->initial_key_retry_timer = 0; // For now, accept every KMP-CREATE.indication kmp_api_create_response(kmp, KMP_RESULT_OK); diff --git a/source/Security/protocols/sec_prot_cfg.h b/source/Security/protocols/sec_prot_cfg.h index d5fd1d218f3..adc4217281f 100644 --- a/source/Security/protocols/sec_prot_cfg.h +++ b/source/Security/protocols/sec_prot_cfg.h @@ -23,8 +23,9 @@ typedef struct sec_prot_cfg_s { trickle_params_t sec_prot_trickle_params; uint16_t sec_prot_retry_timeout; - uint16_t initial_key_retry_delay; - trickle_params_t initial_key_trickle_params; + uint16_t initial_key_retry_min; + uint16_t initial_key_retry_max; + uint16_t initial_key_retry_max_limit; uint8_t initial_key_retry_cnt; uint8_t max_ongoing_auth_constant; uint16_t max_ongoing_auth_size_scaler; diff --git a/test/nanostack/unittest/6LoWPAN/ws_cfg_settings/test_ws_cfg_settings.c b/test/nanostack/unittest/6LoWPAN/ws_cfg_settings/test_ws_cfg_settings.c index fd55216c00e..22f73bdf58f 100644 --- a/test/nanostack/unittest/6LoWPAN/ws_cfg_settings/test_ws_cfg_settings.c +++ b/test/nanostack/unittest/6LoWPAN/ws_cfg_settings/test_ws_cfg_settings.c @@ -149,10 +149,10 @@ static const ws_cfg_t ws_cfg_defaults_medium = { .sec_prot.sec_prot_trickle_timer_exp = 2, // network size affects .sec_prot.max_simult_sec_neg_tx_queue_min = 64, .sec_prot.max_simult_sec_neg_tx_queue_max = 192, - .sec_prot.initial_key_retry_delay = 120, // network size affects - .sec_prot.initial_key_imin = 360, // network size affects - .sec_prot.initial_key_imax = 720, // network size affects - .sec_prot.initial_key_retry_cnt = 2, // network size affects + .sec_prot.initial_key_retry_min = 180, // network size affects + .sec_prot.initial_key_retry_max = 420, // network size affects + .sec_prot.initial_key_retry_max_limit = 720, // network size affects + .sec_prot.initial_key_retry_cnt = 4, // network size affects }; // small network size @@ -222,9 +222,9 @@ static const ws_cfg_t ws_cfg_defaults_small = { .sec_prot.sec_prot_trickle_timer_exp = 2, // network size affects .sec_prot.max_simult_sec_neg_tx_queue_min = 64, .sec_prot.max_simult_sec_neg_tx_queue_max = 192, - .sec_prot.initial_key_retry_delay = 120, // network size affects - .sec_prot.initial_key_imin = 360, // network size affects - .sec_prot.initial_key_imax = 500, // network size affects + .sec_prot.initial_key_retry_min = 180, // network size affects + .sec_prot.initial_key_retry_max = 420, // network size affects + .sec_prot.initial_key_retry_max_limit = 420, // network size affects .sec_prot.initial_key_retry_cnt = 2, // network size affects }; @@ -295,10 +295,10 @@ static const ws_cfg_t ws_cfg_defaults_large = { .sec_prot.sec_prot_trickle_timer_exp = 2, // network size affects .sec_prot.max_simult_sec_neg_tx_queue_min = 64, .sec_prot.max_simult_sec_neg_tx_queue_max = 192, - .sec_prot.initial_key_retry_delay = 0, // network size affects - .sec_prot.initial_key_imin = 600, // network size affects - .sec_prot.initial_key_imax = 1200, // network size affects - .sec_prot.initial_key_retry_cnt = 3, // network size affects + .sec_prot.initial_key_retry_min = 300, // network size affects + .sec_prot.initial_key_retry_max = 600, // network size affects + .sec_prot.initial_key_retry_max_limit = 900, // network size affects + .sec_prot.initial_key_retry_cnt = 4, // network size affects }; // large network size @@ -368,9 +368,9 @@ static const ws_cfg_t ws_cfg_defaults_xlarge = { .sec_prot.sec_prot_trickle_timer_exp = 2, // network size affects .sec_prot.max_simult_sec_neg_tx_queue_min = 64, .sec_prot.max_simult_sec_neg_tx_queue_max = 192, - .sec_prot.initial_key_retry_delay = 0, // network size affects - .sec_prot.initial_key_imin = 600, // network size affects - .sec_prot.initial_key_imax = 1200, // network size affects + .sec_prot.initial_key_retry_min = 300, // network size affects + .sec_prot.initial_key_retry_max = 600, // network size affects + .sec_prot.initial_key_retry_max_limit = 1200, // network size affects .sec_prot.initial_key_retry_cnt = 4, // network size affects }; @@ -441,9 +441,9 @@ static const ws_cfg_t ws_cfg_defaults_certification = { .sec_prot.sec_prot_trickle_timer_exp = 2, // network size affects .sec_prot.max_simult_sec_neg_tx_queue_min = 64, .sec_prot.max_simult_sec_neg_tx_queue_max = 192, - .sec_prot.initial_key_retry_delay = 120, // network size affects - .sec_prot.initial_key_imin = 360, // network size affects - .sec_prot.initial_key_imax = 500, // network size affects + .sec_prot.initial_key_retry_min = 180, // network size affects + .sec_prot.initial_key_retry_max = 420, // network size affects + .sec_prot.initial_key_retry_max_limit = 420, // network size affects .sec_prot.initial_key_retry_cnt = 2, // network size affects };