@@ -91,6 +91,7 @@ typedef struct {
91
91
ws_pae_supp_auth_completed * auth_completed ; /**< Authentication completed callback, continue bootstrap */
92
92
ws_pae_supp_nw_key_insert * nw_key_insert ; /**< Key insert callback */
93
93
ws_pae_supp_nw_key_index_set * nw_key_index_set ; /**< Key index set callback */
94
+ ws_pae_supp_gtk_hash_ptr_get * gtk_hash_ptr_get ; /**< Get pointer to GTK hash storage callback */
94
95
supp_entry_t entry ; /**< Supplicant data */
95
96
kmp_addr_t target_addr ; /**< EAPOL target (parent) address */
96
97
uint16_t initial_key_timer ; /**< Timer to trigger initial EAPOL-Key */
@@ -114,6 +115,10 @@ typedef struct {
114
115
// How many times sending of initial EAPOL-key is retried
115
116
#define INITIAL_KEY_RETRY_COUNT 2
116
117
118
+ // How many times sending of initial EAPOL-key is initiated on key update
119
+ #define KEY_UPDATE_RETRY_COUNT 3
120
+ #define LIFETIME_MISMATCH_RETRY_COUNT 1 /* No retries */
121
+
117
122
// How long the wait is before the first initial EAPOL-key retry
118
123
#define DEFAULT_INITIAL_KEY_RETRY_TIMER 120
119
124
#define NONE_INITIAL_KEY_RETRY_TIMER 0
@@ -163,6 +168,7 @@ static kmp_api_t *ws_pae_supp_kmp_tx_status_ind(kmp_service_t *service, uint8_t
163
168
static kmp_api_t * ws_pae_supp_kmp_create_and_start (kmp_service_t * service , kmp_type_e type , pae_supp_t * pae_supp );
164
169
static int8_t ws_pae_supp_eapol_pdu_address_check (protocol_interface_info_entry_t * interface_ptr , const uint8_t * eui_64 );
165
170
static int8_t ws_pae_supp_parent_eui_64_get (protocol_interface_info_entry_t * interface_ptr , uint8_t * eui_64 );
171
+ static int8_t ws_pae_supp_gtk_hash_mismatch_check (pae_supp_t * pae_supp );
166
172
167
173
static void ws_pae_supp_kmp_api_create_confirm (kmp_api_t * kmp , kmp_result_e result );
168
174
static void ws_pae_supp_kmp_api_create_indication (kmp_api_t * kmp , kmp_type_e type , kmp_addr_t * addr );
@@ -317,6 +323,23 @@ int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr)
317
323
return 0 ;
318
324
}
319
325
326
+ static int8_t ws_pae_supp_gtk_hash_mismatch_check (pae_supp_t * pae_supp )
327
+ {
328
+ uint8_t * gtkhash = pae_supp -> gtk_hash_ptr_get (pae_supp -> interface_ptr );
329
+ if (!gtkhash ) {
330
+ return -1 ;
331
+ }
332
+
333
+ // Check GTK hashes and initiate EAPOL procedure if mismatch is detected */
334
+ gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update (& pae_supp -> gtks , gtkhash );
335
+ if (mismatch != GTK_NO_MISMATCH ) {
336
+ return -1 ;
337
+ }
338
+
339
+ tr_info ("GTKs match to GTK hash" );
340
+ return 0 ;
341
+ }
342
+
320
343
int8_t ws_pae_supp_gtk_hash_update (protocol_interface_info_entry_t * interface_ptr , uint8_t * gtkhash )
321
344
{
322
345
pae_supp_t * pae_supp = ws_pae_supp_get (interface_ptr );
@@ -333,12 +356,13 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
333
356
trace_array (& gtkhash [16 ], 8 ),
334
357
trace_array (& gtkhash [24 ], 8 ));
335
358
336
- // Mismatch, initiate EAPOL
337
- if (!pae_supp -> auth_trickle_running ) {
338
- uint8_t timer_expirations = 3 ;
359
+ /* Mismatch, initiate EAPOL (if authentication not already ongoing or if not on
360
+ wait time for the authenticator to answer) */
361
+ if (!pae_supp -> auth_trickle_running || pae_supp -> initial_key_retry_cnt == 0 ) {
362
+ uint8_t timer_expirations = KEY_UPDATE_RETRY_COUNT ;
339
363
// For GTK lifetime mismatch send only once
340
364
if (mismatch == GTK_LIFETIME_MISMATCH ) {
341
- timer_expirations = 1 ;
365
+ timer_expirations = LIFETIME_MISMATCH_RETRY_COUNT ;
342
366
}
343
367
// Start trickle timer
344
368
ws_pae_supp_initial_key_update_trickle_timer_start (pae_supp , timer_expirations );
@@ -581,7 +605,7 @@ static void ws_pae_supp_keys_nw_info_init(sec_prot_keys_nw_info_t *sec_keys_nw_i
581
605
sec_keys_nw_info -> updated = false;
582
606
}
583
607
584
- void ws_pae_supp_cb_register (protocol_interface_info_entry_t * interface_ptr , ws_pae_supp_auth_completed * completed , ws_pae_supp_nw_key_insert * nw_key_insert , ws_pae_supp_nw_key_index_set * nw_key_index_set )
608
+ void ws_pae_supp_cb_register (protocol_interface_info_entry_t * interface_ptr , ws_pae_supp_auth_completed * completed , ws_pae_supp_nw_key_insert * nw_key_insert , ws_pae_supp_nw_key_index_set * nw_key_index_set , ws_pae_supp_gtk_hash_ptr_get * gtk_hash_ptr_get )
585
609
{
586
610
pae_supp_t * pae_supp = ws_pae_supp_get (interface_ptr );
587
611
if (!pae_supp ) {
@@ -591,6 +615,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
591
615
pae_supp -> auth_completed = completed ;
592
616
pae_supp -> nw_key_insert = nw_key_insert ;
593
617
pae_supp -> nw_key_index_set = nw_key_index_set ;
618
+ pae_supp -> gtk_hash_ptr_get = gtk_hash_ptr_get ;
594
619
}
595
620
596
621
int8_t ws_pae_supp_init (protocol_interface_info_entry_t * interface_ptr , const sec_prot_certs_t * certs , timer_settings_t * timer_settings )
@@ -612,6 +637,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
612
637
pae_supp -> auth_completed = NULL ;
613
638
pae_supp -> nw_key_insert = NULL ;
614
639
pae_supp -> nw_key_index_set = NULL ;
640
+ pae_supp -> gtk_hash_ptr_get = NULL ;
615
641
pae_supp -> initial_key_timer = 0 ;
616
642
pae_supp -> initial_key_retry_timer = 0 ;
617
643
pae_supp -> nw_keys_used_cnt = 0 ;
@@ -866,7 +892,17 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
866
892
/* Wait time for the authenticator to answer the last re-transmit expires;
867
893
fails authentication */
868
894
if (pae_supp -> initial_key_retry_cnt == 0 ) {
895
+ bool retry = false;
896
+ // If making key update and GTKs do not match to GTK hash
897
+ if (!pae_supp -> auth_requested && ws_pae_supp_gtk_hash_mismatch_check (pae_supp ) < 0 ) {
898
+ tr_info ("GTKs do not match to GTK hash" );
899
+ retry = true;
900
+ }
869
901
ws_pae_supp_authenticate_response (pae_supp , AUTH_RESULT_ERR_UNSPEC );
902
+ if (retry ) {
903
+ // Start trickle timer to try re-authentication
904
+ ws_pae_supp_initial_key_update_trickle_timer_start (pae_supp , KEY_UPDATE_RETRY_COUNT );
905
+ }
870
906
} else {
871
907
if (pae_supp -> initial_key_retry_cnt > 0 ) {
872
908
pae_supp -> initial_key_retry_cnt -- ;
0 commit comments