Skip to content

Commit 2417093

Browse files
author
Mika Leppänen
committed
Added limits to number of EAP-TLS and TLS sessions
Added limits to PAE authenticator for simultaneous ongoing EAP-TLS and TLS sessions. For EAP-TLS the limit is three simultaneous sessions. For TLS, the limit is one session after the Client Hello has been received (i.e. limits EAP-TLS Client Certificate handling). Added random from 3 to 30 seconds to supplicant initial EAPOL-Key sending, to spread out the requests that arrive to authenticator from multiple supplicants. Also added functions to EAPOL TLS library for mbed TLS platform memory using nsdynmemlibrary. Functions are currently disabled.
1 parent 6845ab8 commit 2417093

File tree

7 files changed

+208
-21
lines changed

7 files changed

+208
-21
lines changed

source/6LoWPAN/ws/ws_pae_auth.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
// Wait for for supplicant to indicate activity (e.g. to send a message)
5757
#define WAIT_FOR_AUTHENTICATION_TICKS 5 * 60 * 10 // 5 minutes
5858

59+
// Maximum number of simultaneous EAP-TLS negotiations
60+
#define MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS 3
61+
5962
typedef struct {
6063
ns_list_link_t link; /**< Link */
6164
kmp_service_t *kmp_service; /**< KMP service */
@@ -849,6 +852,17 @@ static void ws_pae_auth_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e
849852
return;
850853
}
851854

855+
if (next_type == IEEE_802_1X_MKA) {
856+
/* For EAP-TLS, limits the number of ongoing negotiations. If limit
857+
is reached, supplicant must re-send initial EAPOL-Key to try again
858+
using its trickle schedule */
859+
uint16_t ongoing_eap_tls_cnt = ws_pae_lib_supp_list_kmp_count(&pae_auth->active_supp_list, IEEE_802_1X_MKA);
860+
if (ongoing_eap_tls_cnt >= MAX_SIMULTANEOUS_EAP_TLS_NEGOTIATIONS) {
861+
tr_info("EAP-TLS max ongoing reached, count %i, ignored: eui-64: %s", ongoing_eap_tls_cnt, trace_array(kmp_address_eui_64_get(supp_entry->addr), 8));
862+
return;
863+
}
864+
}
865+
852866
// Create new instance
853867
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, next_type, supp_entry);
854868
if (!new_kmp) {

source/6LoWPAN/ws/ws_pae_lib.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,19 @@ void ws_pae_lib_supp_list_to_inactive(supp_list_t *active_supp_list, supp_list_t
307307
entry->addr = addr;
308308
}
309309

310+
uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type)
311+
{
312+
uint16_t kmp_count = 0;
313+
314+
ns_list_foreach(supp_entry_t, entry, supp_list) {
315+
ns_list_foreach(kmp_entry_t, kmp_entry, &entry->kmp_list) {
316+
if (kmp_api_type_get(kmp_entry->kmp) == type) {
317+
kmp_count++;
318+
}
319+
}
320+
}
321+
322+
return kmp_count;
323+
}
324+
310325
#endif /* HAVE_WS */

source/6LoWPAN/ws/ws_pae_lib.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,15 @@ void ws_pae_lib_supp_list_to_active(supp_list_t *active_supp_list, supp_list_t *
279279
*/
280280
void ws_pae_lib_supp_list_to_inactive(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, supp_entry_t *entry);
281281

282+
/**
283+
* ws_pae_lib_supp_list_kmp_count counts the number of KMPs of a certain type in a list of supplicants
284+
*
285+
* \param supp_list list of supplicants
286+
* \param type KMP type
287+
*
288+
* \return number of KMPs in the supplicant list
289+
*
290+
*/
291+
uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type);
292+
282293
#endif /* WS_PAE_AUTH_H_ */

source/6LoWPAN/ws/ws_pae_supp.c

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@
6767
#define WAIT_FOR_REAUTHENTICATION_TICKS 120 * 10 // 120 seconds
6868

6969
// How many times in maximum stored keys are used for authentication
70-
#define STORED_KEYS_MAXIMUM_USE_COUNT 2
70+
#define STORED_KEYS_MAXIMUM_USE_COUNT 2
71+
72+
// Delay for sending the initial EAPOL-Key
73+
#define INITIAL_KEY_TIMER_MIN 3
74+
#define INITIAL_KEY_TIMER_MAX 30
7175

7276
const char *NW_INFO_FILE = "pae_nw_info";
7377
const char *KEYS_FILE = "pae_keys";
@@ -88,6 +92,7 @@ typedef struct {
8892
ws_pae_supp_nw_key_index_set *nw_key_index_set; /**< Key index set callback */
8993
supp_entry_t entry; /**< Supplicant data */
9094
kmp_addr_t target_addr; /**< EAPOL target (parent) address */
95+
uint16_t initial_key_timer; /**< Timer to trigger initial EAPOL-Key */
9196
trickle_t auth_trickle_timer; /**< Trickle timer for re-sending initial EAPOL-key or for GTK mismatch */
9297
trickle_params_t auth_trickle_params; /**< Trickle parameters for initial EAPOL-key or for GTK mismatch */
9398
sec_prot_gtk_keys_t gtks; /**< GTKs */
@@ -102,12 +107,11 @@ typedef struct {
102107
} pae_supp_t;
103108

104109

105-
#define TRICKLE_IMIN_120_SECS 120
110+
#define TRICKLE_IMIN_180_SECS 180
106111

107-
// Imin from 1-255 minutes and Imax 1-8 doublings
108112
static trickle_params_t initial_eapol_key_trickle_params = {
109-
.Imin = TRICKLE_IMIN_120_SECS, /* 120 second; ticks are 100ms */
110-
.Imax = TRICKLE_IMIN_120_SECS << 1, /* 240 second */
113+
.Imin = TRICKLE_IMIN_180_SECS, /* 180 second; ticks are 1 second */
114+
.Imax = TRICKLE_IMIN_180_SECS << 1, /* 360 second */
111115
.k = 0, /* infinity - no consistency checking */
112116
.TimerExpirations = 3
113117
};
@@ -180,20 +184,13 @@ int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr,
180184

181185
pae_supp->auth_requested = true;
182186

183-
// Sends initial EAPOL-Key message
184-
if (ws_pae_supp_initial_key_send(pae_supp) < 0) {
185-
pae_supp->auth_completed(interface_ptr, false);
186-
}
187-
188-
// Starts trickle
189-
pae_supp->auth_trickle_params = initial_eapol_key_trickle_params;
190-
trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params);
191-
pae_supp->auth_trickle_running = true;
187+
// Randomizes the sending of initial EAPOL-Key messsage
188+
pae_supp->initial_key_timer = randLIB_get_random_in_range(INITIAL_KEY_TIMER_MIN, INITIAL_KEY_TIMER_MAX);
192189

193190
// Starts supplicant timer
194191
ws_pae_supp_timer_start(pae_supp);
195192

196-
tr_debug("PAE active");
193+
tr_debug("PAE active, timer %i", pae_supp->initial_key_timer);
197194

198195
return 1;
199196
}
@@ -523,6 +520,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
523520
pae_supp->auth_completed = NULL;
524521
pae_supp->nw_key_insert = NULL;
525522
pae_supp->nw_key_index_set = NULL;
523+
pae_supp->initial_key_timer = 0;
526524
pae_supp->auth_trickle_running = false;
527525
pae_supp->nw_keys_used_cnt = 0;
528526
pae_supp->timer_settings = timer_settings;
@@ -715,7 +713,7 @@ void ws_pae_supp_fast_timer(uint16_t ticks)
715713
bool running = ws_pae_lib_supp_timer_update(&pae_supp->entry, ticks, kmp_service_timer_if_timeout);
716714

717715
// Checks whether timer needs to be active
718-
if (!pae_supp->auth_trickle_running && !running) {
716+
if (!pae_supp->initial_key_timer && !pae_supp->auth_trickle_running && !running) {
719717

720718
tr_debug("PAE idle");
721719
// Sets target/parent address to null
@@ -751,6 +749,23 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
751749
}
752750
sec_prot_keys_gtk_lifetime_decrement(&pae_supp->gtks, i, seconds);
753751
}
752+
753+
if (pae_supp->initial_key_timer > 0) {
754+
if (pae_supp->initial_key_timer > seconds) {
755+
pae_supp->initial_key_timer -= seconds;
756+
} else {
757+
pae_supp->initial_key_timer = 0;
758+
759+
// Sends initial EAPOL-Key message
760+
ws_pae_supp_initial_key_send(pae_supp);
761+
762+
// Starts trickle
763+
pae_supp->auth_trickle_params = initial_eapol_key_trickle_params;
764+
trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params);
765+
pae_supp->auth_trickle_running = true;
766+
}
767+
768+
}
754769
}
755770
}
756771

source/Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
517517
prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
518518

519519
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISHED);
520-
data->common.ticks = 10 * 10;
521520
break;
522521

523522
case EAP_TLS_STATE_FINISHED:

source/Security/protocols/tls_sec_prot/tls_sec_prot.c

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,20 @@ typedef struct {
6363
tls_data_t tls_recv; /**< TLS receive buffer */
6464
uint32_t int_timer; /**< TLS intermediate timer timeout */
6565
uint32_t fin_timer; /**< TLS final timer timeout */
66+
bool fin_timer_timeout; /**< TLS final timer has timeouted */
6667
bool timer_running : 1; /**< TLS timer running */
6768
bool finished : 1; /**< TLS finished */
6869
bool calculating : 1; /**< TLS is calculating */
70+
bool queued : 1; /**< TLS is queued */
6971
bool library_init : 1; /**< TLS library has been initialized */
7072
tls_sec_prot_lib_int_t *tls_sec_inst; /**< TLS security library storage, SHALL BE THE LAST FIELD */
7173
} tls_sec_prot_int_t;
7274

75+
typedef struct {
76+
ns_list_link_t link; /**< Link */
77+
sec_prot_t *prot; /**< Protocol instance */
78+
} tls_sec_prot_queue_t;
79+
7380
static uint16_t tls_sec_prot_size(void);
7481
static int8_t client_tls_sec_prot_init(sec_prot_t *prot);
7582
static int8_t server_tls_sec_prot_init(sec_prot_t *prot);
@@ -93,8 +100,14 @@ static int8_t tls_sec_prot_tls_get_timer(void *handle);
93100

94101
static int8_t tls_sec_prot_tls_configure_and_connect(sec_prot_t *prot, bool is_server);
95102

103+
static bool tls_sec_prot_queue_check(sec_prot_t *prot);
104+
static bool tls_sec_prot_queue_process(sec_prot_t *prot);
105+
static void tls_sec_prot_queue_remove(sec_prot_t *prot);
106+
96107
#define tls_sec_prot_get(prot) (tls_sec_prot_int_t *) &prot->data
97108

109+
static NS_LIST_DEFINE(tls_sec_prot_queue, tls_sec_prot_queue_t, link);
110+
98111
int8_t client_tls_sec_prot_register(kmp_service_t *service)
99112
{
100113
if (!service) {
@@ -148,8 +161,10 @@ static int8_t client_tls_sec_prot_init(sec_prot_t *prot)
148161
eap_tls_sec_prot_lib_message_init(&data->tls_send);
149162
data->int_timer = 0;
150163
data->fin_timer = 0;
164+
data->fin_timer_timeout = false;
151165
data->timer_running = false;
152166
data->calculating = false;
167+
data->queued = false;
153168
data->library_init = false;
154169
return 0;
155170
}
@@ -176,8 +191,10 @@ static int8_t server_tls_sec_prot_init(sec_prot_t *prot)
176191
eap_tls_sec_prot_lib_message_init(&data->tls_send);
177192
data->int_timer = 0;
178193
data->fin_timer = 0;
194+
data->fin_timer_timeout = false;
179195
data->timer_running = false;
180196
data->calculating = false;
197+
data->queued = false;
181198
data->library_init = false;
182199
return 0;
183200
}
@@ -190,6 +207,7 @@ static void tls_sec_prot_delete(sec_prot_t *prot)
190207
if (data->library_init) {
191208
tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
192209
}
210+
tls_sec_prot_queue_remove(prot);
193211
}
194212

195213
static void tls_sec_prot_create_request(sec_prot_t *prot, sec_prot_keys_t *sec_keys)
@@ -245,13 +263,22 @@ static void tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
245263
if (data->fin_timer > ticks) {
246264
data->fin_timer -= ticks;
247265
} else {
248-
data->fin_timer = 0;
249-
prot->state_machine_call(prot);
266+
if (data->fin_timer > 0) {
267+
data->fin_timer_timeout = true;
268+
data->fin_timer = 0;
269+
}
250270
}
251271
}
252272

253-
if (data->calculating) {
254-
prot->state_machine(prot);
273+
/* Checks if TLS sessions queue is enabled, and if queue is enabled whether the
274+
session is first in the queue i.e. allowed to process */
275+
if (tls_sec_prot_queue_process(prot)) {
276+
if (data->fin_timer_timeout) {
277+
data->fin_timer_timeout = false;
278+
prot->state_machine(prot);
279+
} else if (data->calculating || data->queued) {
280+
prot->state_machine(prot);
281+
}
255282
}
256283

257284
sec_prot_timer_timeout_handle(prot, &data->common, NULL, ticks);
@@ -350,6 +377,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
350377
{
351378
tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
352379
int8_t result;
380+
bool client_hello = false;
353381

354382
switch (sec_prot_state_get(&data->common)) {
355383
case TLS_STATE_INIT:
@@ -362,6 +390,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
362390
tr_debug("TLS: start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
363391

364392
prot->timer_start(prot);
393+
client_hello = true;
365394

366395
sec_prot_state_set(prot, &data->common, TLS_STATE_CREATE_RESP);
367396

@@ -391,6 +420,14 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
391420
break;
392421

393422
case TLS_STATE_PROCESS:
423+
// If not client hello, reserves slot on TLS queue
424+
if (!client_hello && !tls_sec_prot_queue_check(prot)) {
425+
data->queued = true;
426+
return;
427+
} else {
428+
data->queued = false;
429+
}
430+
394431
result = tls_sec_prot_lib_process((tls_security_t *) &data->tls_sec_inst);
395432

396433
if (result == TLS_SEC_PROT_LIB_CALCULATING) {
@@ -428,6 +465,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
428465
prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
429466
sec_prot_state_set(prot, &data->common, TLS_STATE_FINISHED);
430467

468+
tls_sec_prot_queue_remove(prot);
431469
tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
432470
data->library_init = false;
433471
break;
@@ -570,4 +608,69 @@ static int8_t tls_sec_prot_tls_configure_and_connect(sec_prot_t *prot, bool is_s
570608
return 0;
571609
}
572610

611+
static bool tls_sec_prot_queue_check(sec_prot_t *prot)
612+
{
613+
bool queue_add = true;
614+
bool queue_continue = false;
615+
bool first_entry = true;
616+
617+
// Checks if TLS queue is empty or this instance is the first entry
618+
if (ns_list_is_empty(&tls_sec_prot_queue)) {
619+
queue_continue = true;
620+
} else {
621+
622+
ns_list_foreach(tls_sec_prot_queue_t, entry, &tls_sec_prot_queue) {
623+
if (entry->prot == prot) {
624+
queue_add = false;
625+
if (first_entry) {
626+
queue_continue = true;
627+
break;
628+
} else {
629+
queue_continue = false;
630+
}
631+
}
632+
first_entry = false;
633+
}
634+
}
635+
636+
// Adds entry to queue if not there already
637+
if (queue_add) {
638+
tr_debug("TLS QUEUE add%s, eui-64: %s", first_entry ? " first" : "", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
639+
tls_sec_prot_queue_t *entry = ns_dyn_mem_temporary_alloc(sizeof(tls_sec_prot_queue_t));
640+
if (entry) {
641+
entry->prot = prot;
642+
ns_list_add_to_end(&tls_sec_prot_queue, entry);
643+
}
644+
}
645+
646+
return queue_continue;
647+
}
648+
649+
static bool tls_sec_prot_queue_process(sec_prot_t *prot)
650+
{
651+
if (ns_list_is_empty(&tls_sec_prot_queue)) {
652+
return true;
653+
}
654+
655+
ns_list_foreach(tls_sec_prot_queue_t, entry, &tls_sec_prot_queue) {
656+
if (entry->prot == prot) {
657+
return true;
658+
}
659+
return false;
660+
}
661+
662+
return false;
663+
}
664+
665+
static void tls_sec_prot_queue_remove(sec_prot_t *prot)
666+
{
667+
ns_list_foreach_safe(tls_sec_prot_queue_t, entry, &tls_sec_prot_queue) {
668+
if (entry->prot == prot) {
669+
ns_list_remove(&tls_sec_prot_queue, entry);
670+
ns_dyn_mem_free(entry);
671+
tr_debug("TLS QUEUE remove%s, eui-64: %s", ns_list_is_empty(&tls_sec_prot_queue) ? " last" : "", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
672+
}
673+
}
674+
}
675+
573676
#endif /* HAVE_WS */

0 commit comments

Comments
 (0)