Skip to content

Commit d8dd18d

Browse files
author
Mika Leppänen
committed
Added ignoring of incoming security messages and improved EAP-TLS startup
If supplicant authentication is not ongoing (during bootstrap or re-authentication), supplicant now ignores incoming security protocol messages. This results that e.g. if initial EAPOL-key message results mac TX failure, but authenticator has received the message (ack is lost), and authenticator starts EAP-TLS after the supplicant has returned to discover state, supplicant does not start EAP-TLS negotiation. Improved authenticator functionality on EAP-TLS identity request state. If supplicant has not received or has ignored the EAP-TLS identity request (e.g. because of mac TX failure) and authenticator receives initial EAPOL-key message from supplicant, authenticator now re-sends the the EAP-TLS identity request right away.
1 parent 7350634 commit d8dd18d

File tree

4 files changed

+92
-5
lines changed

4 files changed

+92
-5
lines changed

source/6LoWPAN/ws/ws_pae_lib.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,20 @@ void ws_pae_lib_supp_timer_ticks_set(supp_entry_t *entry, uint32_t ticks)
291291
entry->ticks = ticks;
292292
}
293293

294+
void ws_pae_lib_supp_timer_ticks_add(supp_entry_t *entry, uint32_t ticks)
295+
{
296+
entry->ticks += ticks;
297+
}
298+
299+
bool ws_pae_lib_supp_timer_is_running(supp_entry_t *entry)
300+
{
301+
if (entry->ticks == 0) {
302+
return false;
303+
}
304+
305+
return true;
306+
}
307+
294308
void ws_pae_lib_supp_list_to_active(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, supp_entry_t *entry)
295309
{
296310
if (entry->active) {

source/6LoWPAN/ws/ws_pae_lib.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,25 @@ void ws_pae_lib_supp_delete(supp_entry_t *entry);
272272
*/
273273
void ws_pae_lib_supp_timer_ticks_set(supp_entry_t *entry, uint32_t ticks);
274274

275+
/**
276+
* ws_pae_lib_supp_timer_ticks_add adds supplicant timer ticks
277+
*
278+
* \param entry supplicant entry
279+
* \param ticks ticks
280+
*
281+
*/
282+
void ws_pae_lib_supp_timer_ticks_add(supp_entry_t *entry, uint32_t ticks);
283+
284+
/**
285+
* ws_pae_lib_supp_timer_is_running checks whether supplicant timer is running
286+
*
287+
* \param entry supplicant entry
288+
*
289+
* \return TRUE timer is running, FALSE timer is not running
290+
*
291+
*/
292+
bool ws_pae_lib_supp_timer_is_running(supp_entry_t *entry);
293+
275294
/**
276295
* ws_pae_lib_supp_list_to_active move supplicant to active supplicants list
277296
*

source/6LoWPAN/ws/ws_pae_supp.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@
6666
// Wait for re-authentication after GTK update
6767
#define WAIT_FOR_REAUTHENTICATION_TICKS 120 * 10 // 120 seconds
6868

69+
// Ticks added to wait for authenticator timer when authentication protocol is started (e.g. EAP-TLS)
70+
#define START_AUTHENTICATION_TICKS 5 * 10 // 10 seconds
71+
6972
// How many times in maximum stored keys are used for authentication
7073
#define STORED_KEYS_MAXIMUM_USE_COUNT 1
7174

@@ -146,6 +149,7 @@ static int8_t ws_pae_supp_event_send(kmp_service_t *service, void *data);
146149
static void ws_pae_supp_tasklet_handler(arm_event_s *event);
147150
static void ws_pae_supp_initial_trickle_timer_start(pae_supp_t *pae_supp);
148151
static void ws_pae_supp_initial_last_interval_trickle_timer_start(pae_supp_t *pae_supp);
152+
static bool ws_pae_supp_authentication_ongoing(pae_supp_t *pae_supp);
149153
static int8_t ws_pae_supp_timer_if_start(kmp_service_t *service, kmp_api_t *kmp);
150154
static int8_t ws_pae_supp_timer_if_stop(kmp_service_t *service, kmp_api_t *kmp);
151155
static int8_t ws_pae_supp_timer_start(pae_supp_t *pae_supp);
@@ -823,7 +827,7 @@ void ws_pae_supp_fast_timer(uint16_t ticks)
823827
bool running = ws_pae_lib_supp_timer_update(&pae_supp->entry, ticks, kmp_service_timer_if_timeout);
824828

825829
// Checks whether timer needs to be active
826-
if (!pae_supp->initial_key_timer && !pae_supp->auth_trickle_running && !running) {
830+
if (!ws_pae_supp_authentication_ongoing(pae_supp) && !running) {
827831
tr_debug("PAE idle");
828832
// If not already completed, restart bootstrap
829833
ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_UNSPEC);
@@ -833,6 +837,17 @@ void ws_pae_supp_fast_timer(uint16_t ticks)
833837
}
834838
}
835839

840+
static bool ws_pae_supp_authentication_ongoing(pae_supp_t *pae_supp)
841+
{
842+
/* When either bootstrap initial authentication or re-authentication is ongoing */
843+
if (pae_supp->initial_key_timer || pae_supp->auth_trickle_running ||
844+
ws_pae_lib_supp_timer_is_running(&pae_supp->entry)) {
845+
return true;
846+
}
847+
848+
return false;
849+
}
850+
836851
void ws_pae_supp_slow_timer(uint16_t seconds)
837852
{
838853
ns_list_foreach(pae_supp_t, pae_supp, &pae_supp_list) {
@@ -1105,7 +1120,9 @@ static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_
11051120
return NULL;
11061121
}
11071122

1108-
if (!pae_supp->entry_address_active) {
1123+
// If target address is not set or authentication is not ongoing
1124+
if (!pae_supp->entry_address_active || !ws_pae_supp_authentication_ongoing(pae_supp)) {
1125+
tr_info("Incoming KMP rejected, auth not ongoing, type: %i ", type);
11091126
// Does no longer wait for authentication, ignores message
11101127
return NULL;
11111128
}
@@ -1131,6 +1148,9 @@ static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_
11311148
// Create new instance
11321149
kmp = ws_pae_supp_kmp_create_and_start(service, type, pae_supp);
11331150

1151+
// Adds ticks to wait for authenticator to continue timer
1152+
ws_pae_lib_supp_timer_ticks_add(&pae_supp->entry, START_AUTHENTICATION_TICKS);
1153+
11341154
// For EAP-TLS create also TLS in addition to EAP-TLS
11351155
if (type == IEEE_802_1X_MKA) {
11361156
if (ws_pae_lib_kmp_list_type_get(&pae_supp->entry.kmp_list, TLS_PROT) != NULL) {
@@ -1239,7 +1259,6 @@ static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e
12391259
tr_info("Initial EAPOL-Key TX failure, target: %s", trace_array(kmp_address_eui_64_get(&pae_supp->entry.addr), 8));
12401260
ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_TX_NO_ACK);
12411261
}
1242-
12431262
}
12441263

12451264
static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp)

source/Security/protocols/eap_tls_sec_prot/auth_eap_tls_sec_prot.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,24 @@ typedef enum {
5353
EAP_TLS_STATE_FINISHED = SEC_STATE_FINISHED
5454
} eap_tls_sec_prot_state_e;
5555

56+
// Filters initial EAPOL-key re-transmission bursts
57+
#define BURST_FILTER_TIMER_TIMEOUT 5 * 10
58+
59+
// How many times initial EAPOL-key is accepted on wait for identity response state
60+
#define INITIAL_EAPOL_KEY_MAX_COUNT 2
61+
5662
typedef struct {
5763
sec_prot_common_t common; /**< Common data */
5864
sec_prot_t *tls_prot; /**< TLS security protocol */
5965
eapol_pdu_t recv_eapol_pdu; /**< Received EAPOL PDU */
6066
tls_data_t tls_send; /**< EAP-TLS send buffer */
6167
tls_data_t tls_recv; /**< EAP-TLS receive buffer */
68+
uint16_t burst_filt_timer; /**< Burst filter timer */
6269
uint8_t eap_id_seq; /**< EAP sequence */
6370
uint8_t recv_eap_id_seq; /**< Last received EAP sequence */
6471
uint8_t eap_code; /**< Received EAP code */
6572
uint8_t eap_type; /**< Received EAP type */
73+
uint8_t init_key_cnt; /**< How many time initial EAPOL-key has been received */
6674
int8_t tls_result; /**< Result of TLS operation */
6775
bool wait_tls: 1; /**< Wait TLS (ECC calculation) before sending EAP-TLS message */
6876
bool tls_ongoing: 1; /**< TLS handshake is ongoing */
@@ -151,13 +159,15 @@ static int8_t auth_eap_tls_sec_prot_init(sec_prot_t *prot)
151159
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_INIT);
152160

153161
data->tls_prot = NULL;
162+
data->burst_filt_timer = BURST_FILTER_TIMER_TIMEOUT;
154163
data->eap_id_seq = 0;
155164
data->recv_eap_id_seq = 0;
156165
data->eap_code = 0;
157166
data->eap_type = 0;
158167
eap_tls_sec_prot_lib_message_init(&data->tls_recv);
159168
eap_tls_sec_prot_lib_message_init(&data->tls_send);
160-
data->tls_result = EAP_TLS_RESULT_ERROR;
169+
data->tls_result = EAP_TLS_RESULT_ERROR;
170+
data->init_key_cnt = 0;
161171
data->wait_tls = false;
162172
data->tls_ongoing = false;
163173
data->send_pending = false;
@@ -186,13 +196,31 @@ static int8_t auth_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_
186196

187197
// Decoding is successful
188198
if (eapol_parse_pdu_header(pdu, size, &data->recv_eapol_pdu)) {
189-
// Handle only EAP messages (ignore initial EAPOL-key retransmissions)
199+
// Handle EAP messages
190200
if (data->recv_eapol_pdu.packet_type == EAPOL_EAP_TYPE) {
191201
data->eap_code = data->recv_eapol_pdu.msg.eap.eap_code;
192202
data->eap_type = data->recv_eapol_pdu.msg.eap.type;
193203

194204
// Call state machine
195205
prot->state_machine(prot);
206+
} else if (data->recv_eapol_pdu.packet_type == EAPOL_KEY_TYPE &&
207+
sec_prot_state_get(&data->common) == EAP_TLS_STATE_RESPONSE_ID) {
208+
/* If initial EAPOL-key transmission arrives to first EAP-TLS wait state i.e.
209+
* when waiting for identity response, triggers re-transmission of identity
210+
* request. This allows the supplicant to start EAP-TLS right away, if it has
211+
* missed the original identity request.
212+
*/
213+
if (data->burst_filt_timer == 0 && data->init_key_cnt < INITIAL_EAPOL_KEY_MAX_COUNT) {
214+
tr_info("EAP-TLS: initial EAPOL-key recv, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
215+
sec_prot_result_set(&data->common, SEC_RESULT_TIMEOUT);
216+
// Call state machine
217+
prot->state_machine(prot);
218+
// Resets trickle timer to give time for supplicant to answer
219+
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
220+
data->init_key_cnt++;
221+
}
222+
// Filters repeated initial EAPOL-key messages
223+
data->burst_filt_timer = BURST_FILTER_TIMER_TIMEOUT;
196224
}
197225
ret_val = 0;
198226
}
@@ -288,6 +316,13 @@ static int8_t auth_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_c
288316
static void auth_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
289317
{
290318
eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
319+
320+
if (data->burst_filt_timer > ticks) {
321+
data->burst_filt_timer -= ticks;
322+
} else {
323+
data->burst_filt_timer = 0;
324+
}
325+
291326
sec_prot_timer_timeout_handle(prot, &data->common, &eap_tls_trickle_params, ticks);
292327
}
293328

0 commit comments

Comments
 (0)