@@ -91,13 +91,15 @@ typedef struct {
91
91
supp_entry_t entry ; /**< Supplicant data */
92
92
kmp_addr_t target_addr ; /**< EAPOL target (parent) address */
93
93
uint16_t initial_key_timer ; /**< Timer to trigger initial EAPOL-Key */
94
+ uint16_t initial_key_retry_timer ; /**< Timer to trigger initial EAPOL-Key 1st retry */
94
95
trickle_t auth_trickle_timer ; /**< Trickle timer for re-sending initial EAPOL-key or for GTK mismatch */
95
96
trickle_params_t auth_trickle_params ; /**< Trickle parameters for initial EAPOL-key or for GTK mismatch */
96
97
sec_prot_gtk_keys_t gtks ; /**< GTKs */
97
98
uint8_t new_br_eui_64 [8 ]; /**< Border router EUI-64 indicated by bootstrap */
98
99
sec_prot_keys_nw_info_t sec_keys_nw_info ; /**< Security keys network information */
99
100
timer_settings_t * timer_settings ; /**< Timer settings */
100
101
uint8_t nw_keys_used_cnt ; /**< How many times bootstrap has been tried with current keys */
102
+ uint8_t initial_key_retry_cnt ; /**< initial EAPOL-Key retry counter */
101
103
bool auth_trickle_running : 1 ; /**< Initial EAPOL-Key Trickle timer running */
102
104
bool auth_requested : 1 ; /**< Authentication has been requested by the bootstrap */
103
105
bool timer_running : 1 ; /**< Timer is running */
@@ -106,14 +108,30 @@ typedef struct {
106
108
bool entry_address_active : 1 ;
107
109
} pae_supp_t ;
108
110
111
+ // How many times sending of initial EAPOL-key is retried
112
+ #define INITIAL_KEY_RETRY_COUNT 2
109
113
110
- #define TRICKLE_IMIN_180_SECS 180
114
+ // How long the wait is before the first initial EAPOL-key retry
115
+ #define DEFAULT_INITIAL_KEY_RETRY_TIMER 120
116
+ #define NONE_INITIAL_KEY_RETRY_TIMER 0
117
+
118
+ // Default trickle values for sending of initial EAPOL-key
119
+ #define DEFAULT_TRICKLE_IMIN_SECS 360 /* 6 to 12 minutes */
120
+ #define DEFAULT_TRICKLE_IMAX_SECS 720
121
+
122
+ // Very slow network values for sending of initial EAPOL-key
123
+ #define VERY_SLOW_NW_TRICKLE_IMIN_SECS 600 /* 10 to 60 minutes */
124
+ #define VERY_SLOW_NW_TRICKLE_IMAX_SECS 3600
125
+
126
+ // Trickle timer on how long to wait response after last retry before failing authentication
127
+ #define LAST_INTERVAL_TRICKLE_IMIN_SECS 240 /* 4 minutes */
128
+ #define LAST_INTERVAL_TRICKLE_IMAX_SECS 240
111
129
112
130
static trickle_params_t initial_eapol_key_trickle_params = {
113
- .Imin = TRICKLE_IMIN_180_SECS , /* 180 second; ticks are 1 second */
114
- .Imax = TRICKLE_IMIN_180_SECS << 1 , /* 360 second */
115
- . k = 0 , /* infinity - no consistency checking */
116
- .TimerExpirations = 3
131
+ .Imin = DEFAULT_TRICKLE_IMIN_SECS , /* 360 second; ticks are 1 second */
132
+ .Imax = DEFAULT_TRICKLE_IMAX_SECS , /* 720 second */
133
+ . k = 0 , /* infinity - no consistency checking */
134
+ .TimerExpirations = 2
117
135
};
118
136
119
137
static void ws_pae_supp_free (pae_supp_t * pae_supp );
@@ -126,6 +144,8 @@ static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp);
126
144
static pae_supp_t * ws_pae_supp_get (protocol_interface_info_entry_t * interface_ptr );
127
145
static int8_t ws_pae_supp_event_send (kmp_service_t * service , void * data );
128
146
static void ws_pae_supp_tasklet_handler (arm_event_s * event );
147
+ static void ws_pae_supp_initial_trickle_timer_start (pae_supp_t * pae_supp );
148
+ static void ws_pae_supp_initial_last_interval_trickle_timer_start (pae_supp_t * pae_supp );
129
149
static int8_t ws_pae_supp_timer_if_start (kmp_service_t * service , kmp_api_t * kmp );
130
150
static int8_t ws_pae_supp_timer_if_stop (kmp_service_t * service , kmp_api_t * kmp );
131
151
static int8_t ws_pae_supp_timer_start (pae_supp_t * pae_supp );
@@ -156,6 +176,7 @@ static const char *KEYS_FILE = KEYS_FILE_NAME;
156
176
157
177
static int8_t tasklet_id = -1 ;
158
178
static NS_LIST_DEFINE (pae_supp_list , pae_supp_t , link ) ;
179
+ static uint8_t timing_value = 0 ; // Timing value set based e.g. on network size
159
180
160
181
static void ws_pae_supp_address_set (pae_supp_t * pae_supp , kmp_addr_t * address )
161
182
{
@@ -323,14 +344,12 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
323
344
// Starts trickle
324
345
trickle_start (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params );
325
346
pae_supp -> auth_trickle_running = true;
347
+ pae_supp -> initial_key_retry_timer = 0 ;
326
348
327
349
// Starts supplicant timer
328
350
ws_pae_supp_timer_start (pae_supp );
329
351
330
352
tr_info ("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i" , pae_supp -> timer_settings -> gtk_request_imin , pae_supp -> timer_settings -> gtk_request_imax , pae_supp -> timer_settings -> gtk_max_mismatch , pae_supp -> auth_trickle_timer .t );
331
- } else {
332
- // If trickle is already running, set inconsistent heard to speed up the trickle
333
- trickle_inconsistent_heard (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params );
334
353
}
335
354
}
336
355
@@ -597,8 +616,10 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
597
616
pae_supp -> nw_key_insert = NULL ;
598
617
pae_supp -> nw_key_index_set = NULL ;
599
618
pae_supp -> initial_key_timer = 0 ;
619
+ pae_supp -> initial_key_retry_timer = 0 ;
600
620
pae_supp -> nw_keys_used_cnt = 0 ;
601
621
pae_supp -> timer_settings = timer_settings ;
622
+ pae_supp -> initial_key_retry_cnt = 0 ;
602
623
pae_supp -> auth_trickle_running = false;
603
624
pae_supp -> auth_requested = false;
604
625
pae_supp -> timer_running = false;
@@ -702,6 +723,7 @@ int8_t ws_pae_supp_delete(protocol_interface_info_entry_t *interface_ptr)
702
723
703
724
int8_t ws_pae_supp_timing_adjust (uint8_t timing )
704
725
{
726
+ timing_value = timing ;
705
727
supp_fwh_sec_prot_timing_adjust (timing );
706
728
supp_eap_sec_prot_timing_adjust (timing );
707
729
return 0 ;
@@ -817,14 +839,38 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
817
839
818
840
// Checks whether initial EAPOL-Key message needs to be re-send or new GTK request to be sent
819
841
if (pae_supp -> auth_trickle_running ) {
820
- if (trickle_timer (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params , seconds )) {
821
- if (ws_pae_supp_initial_key_send (pae_supp ) < 0 ) {
822
- tr_info ("EAPOL-Key send failed" );
842
+ if (pae_supp -> initial_key_retry_timer > 0 ) {
843
+ if (pae_supp -> initial_key_retry_timer > seconds ) {
844
+ pae_supp -> initial_key_retry_timer -= seconds ;
845
+ } else {
846
+ pae_supp -> initial_key_retry_timer = 0 ;
847
+ tr_info ("initial key retry timer expired" );
848
+ }
849
+ } else {
850
+ // Checks if trickle timer expires
851
+ if (trickle_timer (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params , seconds )) {
852
+ if (pae_supp -> initial_key_retry_cnt < INITIAL_KEY_RETRY_COUNT ) {
853
+ if (ws_pae_supp_initial_key_send (pae_supp ) < 0 ) {
854
+ tr_info ("EAPOL-Key send failed" );
855
+ }
856
+ }
857
+ pae_supp -> initial_key_retry_cnt ++ ;
858
+
859
+ /* Wait time for the authenticator to answer the last re-transmit expires;
860
+ fails authentication */
861
+ if (pae_supp -> initial_key_retry_cnt > INITIAL_KEY_RETRY_COUNT ) {
862
+ ws_pae_supp_authenticate_response (pae_supp , AUTH_RESULT_ERR_UNSPEC );
863
+ } else if (pae_supp -> initial_key_retry_cnt == INITIAL_KEY_RETRY_COUNT ) {
864
+ // Starts wait time for the authenticator to answer
865
+ tr_info ("Initial EAPOL-Key wait for last re-transmit answer" );
866
+ ws_pae_supp_initial_last_interval_trickle_timer_start (pae_supp );
867
+ }
868
+ }
869
+
870
+ // Sanity check, should be running until authentication failure
871
+ if (!trickle_running (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params )) {
872
+ ws_pae_supp_authenticate_response (pae_supp , AUTH_RESULT_ERR_UNSPEC );
823
873
}
824
- }
825
- // Maximum number of trickle expires, authentication fails
826
- if (!trickle_running (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params )) {
827
- ws_pae_supp_authenticate_response (pae_supp , AUTH_RESULT_ERR_UNSPEC );
828
874
}
829
875
}
830
876
@@ -846,16 +892,61 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
846
892
if (ws_pae_supp_initial_key_send (pae_supp ) < 0 ) {
847
893
tr_info ("EAPOL-Key send failed" );
848
894
}
849
-
850
- // Starts trickle
851
- pae_supp -> auth_trickle_params = initial_eapol_key_trickle_params ;
852
- trickle_start (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params );
853
- pae_supp -> auth_trickle_running = true;
895
+ // Start trickle timer
896
+ ws_pae_supp_initial_trickle_timer_start (pae_supp );
854
897
}
855
898
}
856
899
}
857
900
}
858
901
902
+ static void ws_pae_supp_initial_trickle_timer_start (pae_supp_t * pae_supp )
903
+ {
904
+ pae_supp -> auth_trickle_params = initial_eapol_key_trickle_params ;
905
+
906
+ // Very fast, medium and slow network
907
+ if (timing_value < 25 ) {
908
+ /* Starts trickle for initial EAPOL-key. Sequence has fixed delay of 2 minutes,
909
+ * one re-transmit interval, last re-transmit interval transmit time and a wait time
910
+ * for the authenticator to answer the last re-transmit.
911
+ *
912
+ * Interval I [6,12] minutes. Sequence:
913
+ *
914
+ * fixed 2 minutes delay + I + last I transmit time t + wait for answer [2,4] minutes
915
+ *
916
+ * There are two retries. Minimum time that sequence takes before authentication failure
917
+ * is 16 minutes and maximum is 30 minutes.
918
+ */
919
+ pae_supp -> initial_key_retry_timer = DEFAULT_INITIAL_KEY_RETRY_TIMER ; // 2 minutes
920
+ } else {
921
+ /* Extremely slow network
922
+ *
923
+ * Starts trickle for initial EAPOL-key, Interval I [10,60] minutes. Sequence:
924
+ * I + last I transmit time t + wait for answer [2,4] minutes
925
+ * There are two retries. Minimum time that sequence takes before authentication failure
926
+ * is 22 minutes and maximum is 124 minutes.
927
+ */
928
+ pae_supp -> auth_trickle_params .Imin = VERY_SLOW_NW_TRICKLE_IMIN_SECS ;
929
+ pae_supp -> auth_trickle_params .Imax = VERY_SLOW_NW_TRICKLE_IMAX_SECS ;
930
+ pae_supp -> initial_key_retry_timer = NONE_INITIAL_KEY_RETRY_TIMER ; // 0 seconds
931
+ }
932
+ trickle_start (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params );
933
+ 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 );
934
+ pae_supp -> auth_trickle_running = true;
935
+ pae_supp -> initial_key_retry_cnt = 0 ;
936
+ }
937
+
938
+ static void ws_pae_supp_initial_last_interval_trickle_timer_start (pae_supp_t * pae_supp )
939
+ {
940
+ // Starts trickle last to wait response after last retry before failing authentication
941
+ pae_supp -> auth_trickle_params = initial_eapol_key_trickle_params ;
942
+ pae_supp -> auth_trickle_params .Imin = LAST_INTERVAL_TRICKLE_IMIN_SECS ;
943
+ pae_supp -> auth_trickle_params .Imax = LAST_INTERVAL_TRICKLE_IMAX_SECS ;
944
+ pae_supp -> auth_trickle_params .TimerExpirations = 1 ;
945
+ // Set I to [iMin,iMax] (4 to 4 minutes) -> t is [I/2 - I] (2 minutes to 4 minutes)
946
+ trickle_start (& pae_supp -> auth_trickle_timer , & pae_supp -> auth_trickle_params );
947
+ 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 );
948
+ }
949
+
859
950
static int8_t ws_pae_supp_timer_if_start (kmp_service_t * service , kmp_api_t * kmp )
860
951
{
861
952
pae_supp_t * pae_supp = ws_pae_supp_by_kmp_service_get (service );
0 commit comments