Skip to content

Commit 4185734

Browse files
author
Mika Leppänen
committed
Improved EAPOL key update retry logic
EAPOL key update now checks after all retries have been done, whether GTKs are up to date (by comparing to latest GTK hash). If they are not, it initiates a new key update rigth away. Previously EAPOL waited for PAN version update before initiating the key update. Also added a check that if key update procedure is on the last interval (waiting for the authenticator to answer the last retry), and GTK hash changes, EAPOL key update is retried rigth away.
1 parent 8bda176 commit 4185734

File tree

3 files changed

+54
-8
lines changed

3 files changed

+54
-8
lines changed

source/6LoWPAN/ws/ws_pae_controller.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_pt
679679
controller->pae_gtk_hash_update = ws_pae_supp_gtk_hash_update;
680680
controller->pae_nw_key_index_update = ws_pae_supp_nw_key_index_update;
681681

682-
ws_pae_supp_cb_register(controller->interface_ptr, controller->auth_completed, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_active_nw_key_set);
682+
ws_pae_supp_cb_register(controller->interface_ptr, controller->auth_completed, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_active_nw_key_set, ws_pae_controller_gtk_hash_ptr_get);
683683

684684
ws_pae_controller_frame_counter_read(controller);
685685

@@ -1203,7 +1203,7 @@ int8_t ws_pae_controller_gtk_hash_update(protocol_interface_info_entry_t *interf
12031203
memcpy(controller->gtkhash, gtkhash, 32);
12041204

12051205
if (controller->pae_gtk_hash_update) {
1206-
return controller->pae_gtk_hash_update(interface_ptr, gtkhash);
1206+
return controller->pae_gtk_hash_update(interface_ptr, controller->gtkhash);
12071207
}
12081208

12091209
return 0;

source/6LoWPAN/ws/ws_pae_supp.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ typedef struct {
9191
ws_pae_supp_auth_completed *auth_completed; /**< Authentication completed callback, continue bootstrap */
9292
ws_pae_supp_nw_key_insert *nw_key_insert; /**< Key insert callback */
9393
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 */
9495
supp_entry_t entry; /**< Supplicant data */
9596
kmp_addr_t target_addr; /**< EAPOL target (parent) address */
9697
uint16_t initial_key_timer; /**< Timer to trigger initial EAPOL-Key */
@@ -114,6 +115,10 @@ typedef struct {
114115
// How many times sending of initial EAPOL-key is retried
115116
#define INITIAL_KEY_RETRY_COUNT 2
116117

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+
117122
// How long the wait is before the first initial EAPOL-key retry
118123
#define DEFAULT_INITIAL_KEY_RETRY_TIMER 120
119124
#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
163168
static kmp_api_t *ws_pae_supp_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, pae_supp_t *pae_supp);
164169
static int8_t ws_pae_supp_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
165170
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);
166172

167173
static void ws_pae_supp_kmp_api_create_confirm(kmp_api_t *kmp, kmp_result_e result);
168174
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)
317323
return 0;
318324
}
319325

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+
320343
int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash)
321344
{
322345
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
333356
trace_array(&gtkhash[16], 8),
334357
trace_array(&gtkhash[24], 8));
335358

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;
339363
// For GTK lifetime mismatch send only once
340364
if (mismatch == GTK_LIFETIME_MISMATCH) {
341-
timer_expirations = 1;
365+
timer_expirations = LIFETIME_MISMATCH_RETRY_COUNT;
342366
}
343367
// Start trickle timer
344368
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
581605
sec_keys_nw_info->updated = false;
582606
}
583607

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)
585609
{
586610
pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr);
587611
if (!pae_supp) {
@@ -591,6 +615,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
591615
pae_supp->auth_completed = completed;
592616
pae_supp->nw_key_insert = nw_key_insert;
593617
pae_supp->nw_key_index_set = nw_key_index_set;
618+
pae_supp->gtk_hash_ptr_get = gtk_hash_ptr_get;
594619
}
595620

596621
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
612637
pae_supp->auth_completed = NULL;
613638
pae_supp->nw_key_insert = NULL;
614639
pae_supp->nw_key_index_set = NULL;
640+
pae_supp->gtk_hash_ptr_get = NULL;
615641
pae_supp->initial_key_timer = 0;
616642
pae_supp->initial_key_retry_timer = 0;
617643
pae_supp->nw_keys_used_cnt = 0;
@@ -866,7 +892,17 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
866892
/* Wait time for the authenticator to answer the last re-transmit expires;
867893
fails authentication */
868894
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+
}
869901
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+
}
870906
} else {
871907
if (pae_supp->initial_key_retry_cnt > 0) {
872908
pae_supp->initial_key_retry_cnt--;

source/6LoWPAN/ws/ws_pae_supp.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,16 @@ typedef void ws_pae_supp_auth_completed(protocol_interface_info_entry_t *interfa
236236
*/
237237
typedef int8_t ws_pae_supp_nw_key_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks);
238238

239+
/**
240+
* ws_pae_supp_gtk_hash_ptr_get get pointer to GTK hash storage callback
241+
*
242+
* \param interface_ptr interface
243+
*
244+
* \return pointer to GTK has storage or NULL
245+
*
246+
*/
247+
typedef uint8_t *ws_pae_supp_gtk_hash_ptr_get(protocol_interface_info_entry_t *interface_ptr);
248+
239249
/**
240250
* ws_pae_supp_cb_register register PEA supplicant callbacks
241251
*
@@ -245,7 +255,7 @@ typedef int8_t ws_pae_supp_nw_key_insert(protocol_interface_info_entry_t *interf
245255
* \param nw_key_index_set network send key index callback
246256
*
247257
*/
248-
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);
258+
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);
249259

250260
#else
251261

0 commit comments

Comments
 (0)