Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers supp_eap_tls_sec_prot.c Source File

supp_eap_tls_sec_prot.c

00001 /*
00002  * Copyright (c) 2019, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "nsconfig.h"
00019 #include <string.h>
00020 #include "ns_types.h"
00021 #include "ns_list.h"
00022 #include "ns_trace.h"
00023 #include "nsdynmemLIB.h"
00024 #include "fhss_config.h "
00025 #include "NWK_INTERFACE/Include/protocol.h"
00026 #include "6LoWPAN/ws/ws_config.h"
00027 #include "Security/kmp/kmp_addr.h"
00028 #include "Security/kmp/kmp_api.h"
00029 #include "Security/PANA/pana_eap_header.h"
00030 #include "Security/eapol/eapol_helper.h"
00031 #include "Security/protocols/sec_prot_certs.h"
00032 #include "Security/protocols/sec_prot_keys.h"
00033 #include "Security/protocols/sec_prot.h"
00034 #include "Security/protocols/sec_prot_lib.h"
00035 #include "Security/protocols/eap_tls_sec_prot/eap_tls_sec_prot_lib.h"
00036 #include "Security/protocols/eap_tls_sec_prot/supp_eap_tls_sec_prot.h"
00037 
00038 #ifdef HAVE_WS
00039 
00040 #define TRACE_GROUP "eaps"
00041 
00042 typedef enum {
00043     EAP_TLS_STATE_INIT = SEC_STATE_INIT,
00044     EAP_TLS_STATE_CREATE_REQ = SEC_STATE_CREATE_REQ,
00045     EAP_TLS_STATE_CREATE_RESP = SEC_STATE_CREATE_RESP,
00046     EAP_TLS_STATE_CREATE_IND = SEC_STATE_CREATE_IND,
00047 
00048     EAP_TLS_STATE_REQUEST_ID = SEC_STATE_FIRST,
00049     EAP_TLS_STATE_REQUEST_TLS_EAP,
00050     EAP_TLS_STATE_REQUEST,
00051 
00052     EAP_TLS_STATE_FINISH = SEC_STATE_FINISH,
00053     EAP_TLS_STATE_FINISHED = SEC_STATE_FINISHED
00054 } eap_tls_sec_prot_state_e;
00055 
00056 // Filters EAP re-transmission bursts that arrive with same EAP sequence number
00057 #define BURST_FILTER_TIMER_TIMEOUT                  5 * 10
00058 
00059 typedef struct {
00060     sec_prot_common_t             common;           /**< Common data */
00061     sec_prot_t                    *tls_prot;        /**< TLS security protocol */
00062     eapol_pdu_t                   recv_eapol_pdu;   /**< Received EAPOL PDU */
00063     tls_data_t                    tls_send;         /**< EAP-TLS send buffer */
00064     tls_data_t                    tls_recv;         /**< EAP-TLS receive buffer */
00065     uint16_t                      burst_filt_timer; /**< Burst filter timer */
00066     uint8_t                       eap_id_seq;       /**< EAP sequence */
00067     uint8_t                       eap_code;         /**< Received EAP code */
00068     uint8_t                       eap_type;         /**< Received EAP type */
00069     int8_t                        tls_result;       /**< Result of TLS operation */
00070     bool                          wait_tls: 1;      /**< Wait TLS (ECC calculation) before sending EAP-TLS message */
00071     bool                          tls_ongoing: 1;   /**< TLS handshake is ongoing */
00072     bool                          send_pending: 1;  /**< TLS data is not yet send to network */
00073 } eap_tls_sec_prot_int_t;
00074 
00075 #define FWH_RETRY_TIMEOUT_SMALL 330*10 // retry timeout for small network additional 30 seconds for authenticator delay
00076 #define FWH_RETRY_TIMEOUT_LARGE 750*10 // retry timeout for large network additional 30 seconds for authenticator delay
00077 
00078 static uint16_t retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
00079 
00080 static uint16_t supp_eap_tls_sec_prot_size(void);
00081 static int8_t supp_eap_tls_sec_prot_init(sec_prot_t *prot);
00082 
00083 static void supp_eap_tls_sec_prot_create_response(sec_prot_t *prot, sec_prot_result_e result);
00084 static void supp_eap_tls_sec_prot_delete(sec_prot_t *prot);
00085 static int8_t supp_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t size);
00086 
00087 static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot);
00088 
00089 static int8_t supp_eap_tls_sec_prot_message_handle(sec_prot_t *prot);
00090 static int8_t supp_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_code, uint8_t eap_type, uint8_t tls_state);
00091 
00092 static void supp_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks);
00093 static int8_t supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot);
00094 static void supp_eap_tls_sec_prot_delete_tls(sec_prot_t *prot);
00095 
00096 static void supp_eap_tls_sec_prot_seq_id_update(sec_prot_t *prot);
00097 
00098 #define eap_tls_sec_prot_get(prot) (eap_tls_sec_prot_int_t *) &prot->data
00099 
00100 int8_t supp_eap_tls_sec_prot_register(kmp_service_t *service)
00101 {
00102     if (!service) {
00103         return -1;
00104     }
00105 
00106     if (kmp_service_sec_protocol_register(service, IEEE_802_1X_MKA, supp_eap_tls_sec_prot_size, supp_eap_tls_sec_prot_init) < 0) {
00107         return -1;
00108     }
00109 
00110     return 0;
00111 }
00112 
00113 int8_t supp_eap_sec_prot_timing_adjust(uint8_t timing)
00114 {
00115     if (timing < 16) {
00116         retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
00117     } else {
00118         retry_timeout = FWH_RETRY_TIMEOUT_LARGE;
00119     }
00120     return 0;
00121 }
00122 
00123 
00124 static uint16_t supp_eap_tls_sec_prot_size(void)
00125 {
00126     return sizeof(eap_tls_sec_prot_int_t);
00127 }
00128 
00129 static int8_t supp_eap_tls_sec_prot_init(sec_prot_t *prot)
00130 {
00131     prot->create_req = 0;
00132     prot->create_resp = supp_eap_tls_sec_prot_create_response;
00133     prot->receive = supp_eap_tls_sec_prot_receive;
00134     prot->delete = supp_eap_tls_sec_prot_delete;
00135     prot->state_machine = supp_eap_tls_sec_prot_state_machine;
00136     prot->timer_timeout = supp_eap_tls_sec_prot_timer_timeout;
00137 
00138     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00139     sec_prot_init(&data->common);
00140     sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_INIT);
00141 
00142     data->tls_prot = NULL;
00143     data->burst_filt_timer = 0;
00144     data->eap_id_seq = 0;
00145     data->eap_code = 0;
00146     data->eap_type = 0;
00147     eap_tls_sec_prot_lib_message_init(&data->tls_recv);
00148     eap_tls_sec_prot_lib_message_init(&data->tls_send);
00149     data->tls_result = EAP_TLS_RESULT_ERROR;
00150     data->wait_tls = false;
00151     data->tls_ongoing = false;
00152     return 0;
00153 }
00154 
00155 static void supp_eap_tls_sec_prot_delete(sec_prot_t *prot)
00156 {
00157     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00158     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00159     eap_tls_sec_prot_lib_message_free(&data->tls_recv);
00160 }
00161 
00162 static void supp_eap_tls_sec_prot_create_response(sec_prot_t *prot, sec_prot_result_e result)
00163 {
00164     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00165 
00166     // Call state machine
00167     sec_prot_result_set(&data->common, result);
00168     prot->state_machine_call(prot);
00169 }
00170 
00171 static int8_t supp_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t size)
00172 {
00173     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00174     int8_t ret_val = -1;
00175 
00176     // Decoding is successful
00177     if (eapol_parse_pdu_header(pdu, size, &data->recv_eapol_pdu)) {
00178         // Handle only EAP messages (should never receive EAPOL-key messages during EAP-TLS)
00179         if (data->recv_eapol_pdu.packet_type == EAPOL_EAP_TYPE) {
00180             data->eap_code = data->recv_eapol_pdu.msg.eap.eap_code;
00181             data->eap_type = data->recv_eapol_pdu.msg.eap.type;
00182 
00183             // Call state machine
00184             prot->state_machine(prot);
00185         }
00186         ret_val = 0;
00187     }
00188 
00189     memset(&data->recv_eapol_pdu, 0, sizeof(eapol_pdu_t));
00190     data->eap_code = 0;
00191     data->eap_type = 0;
00192 
00193     return ret_val;
00194 }
00195 
00196 static int8_t supp_eap_tls_sec_prot_message_handle(sec_prot_t *prot)
00197 {
00198     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00199 
00200     uint8_t *data_ptr = data->recv_eapol_pdu.msg.eap.data_ptr;
00201     uint16_t length = data->recv_eapol_pdu.msg.eap.length;
00202 
00203     tr_info("EAP-TLS recv %s type %s id %i flags %x len %i", eap_msg_trace[data->eap_code - 1],
00204             data->eap_type == EAP_IDENTITY ? "IDENTITY" : "TLS", data->recv_eapol_pdu.msg.eap.id_seq,
00205             length >= 6 ? data_ptr[0] : 0, length);
00206 
00207     uint8_t new_seq_id = false;
00208     // New sequence identifier received
00209     if (data->recv_eapol_pdu.msg.eap.id_seq > data->eap_id_seq) {
00210         data->burst_filt_timer = BURST_FILTER_TIMER_TIMEOUT;
00211         new_seq_id = true;
00212     } else if (data->recv_eapol_pdu.msg.eap.id_seq == data->eap_id_seq) {
00213         if (data->burst_filt_timer > 0) {
00214             /* If retransmission arrives when burst filter timer is running, ignores it
00215                and starts timer again */
00216             data->burst_filt_timer = BURST_FILTER_TIMER_TIMEOUT;
00217             return EAP_TLS_MSG_DECODE_ERROR;
00218         } else {
00219             // If retransmission arrives after timeout, starts timer again
00220             data->burst_filt_timer = BURST_FILTER_TIMER_TIMEOUT;
00221         }
00222     } else if (data->recv_eapol_pdu.msg.eap.id_seq < data->eap_id_seq) {
00223         // Already received sequence ID is received again, ignore
00224         return EAP_TLS_MSG_DECODE_ERROR;
00225     }
00226 
00227     if (data->eap_type == EAP_IDENTITY) {
00228         return EAP_TLS_MSG_IDENTITY;
00229     }
00230 
00231     if (!data_ptr || length < 6) {
00232         return EAP_TLS_MSG_DECODE_ERROR;
00233     }
00234 
00235     length -= 5; // EAP fields: code, id, length, type
00236 
00237     return eap_tls_sec_prot_lib_message_handle(data_ptr, length, new_seq_id, &data->tls_send, &data->tls_recv);
00238 }
00239 
00240 static int8_t supp_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_code, uint8_t eap_type, uint8_t tls_state)
00241 {
00242     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00243 
00244     uint8_t flags = 0xff;
00245     // EAP-TLS flags field is always present during TLS exchange
00246     if (tls_state == EAP_TLS_EXCHANGE_ONGOING) {
00247         flags = 0x00;
00248     }
00249 
00250     if (eap_code == EAP_RESPONSE) {
00251         if (eap_type == EAP_IDENTITY) {
00252             const uint8_t identity[] = {"Anonymous"};
00253             const uint8_t identity_size = sizeof(identity) - 1;
00254             if (data->tls_send.total_len != identity_size) {
00255                 eap_tls_sec_prot_lib_message_allocate(&data->tls_send, TLS_HEAD_LEN, identity_size);
00256                 if (!data->tls_send.data) {
00257                     return -1;
00258                 }
00259                 memcpy(data->tls_send.data + TLS_HEAD_LEN, identity, identity_size);
00260             }
00261             flags = 0xff;
00262         }
00263     } else {
00264         return -1;
00265     }
00266 
00267     uint16_t eapol_pdu_size;
00268     uint8_t *eapol_decoded_data = eap_tls_sec_prot_lib_message_build(eap_code, eap_type, &flags, data->eap_id_seq, prot->header_size, &data->tls_send, &eapol_pdu_size);
00269     if (!eapol_decoded_data) {
00270         return -1;
00271     }
00272 
00273     tr_info("EAP-TLS: send %s type %s id %i flags %x len %i", eap_msg_trace[eap_code - 1],
00274             eap_type == EAP_IDENTITY ? "IDENTITY" : "TLS", data->eap_id_seq, flags, eapol_pdu_size);
00275 
00276     if (prot->send(prot, eapol_decoded_data, eapol_pdu_size + prot->header_size) < 0) {
00277         return -1;
00278     }
00279 
00280     return 0;
00281 }
00282 
00283 static void supp_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
00284 {
00285     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00286 
00287     if (data->burst_filt_timer > ticks) {
00288         data->burst_filt_timer -= ticks;
00289     } else {
00290         data->burst_filt_timer = 0;
00291     }
00292 
00293     sec_prot_timer_timeout_handle(prot, &data->common, NULL, ticks);
00294 }
00295 
00296 static void supp_eap_tls_sec_prot_tls_create_confirm(sec_prot_t *tls_prot, sec_prot_result_e result)
00297 {
00298     if (result != SEC_RESULT_OK) {
00299         sec_prot_t *prot = tls_prot->type_get(tls_prot, SEC_PROT_TYPE_EAP_TLS);
00300         if (!prot) {
00301             return;
00302         }
00303 
00304         eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00305 
00306         sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISH);
00307     }
00308 }
00309 
00310 static void supp_eap_tls_sec_prot_tls_finished_indication(sec_prot_t *tls_prot, sec_prot_result_e result, sec_prot_keys_t *sec_keys)
00311 {
00312     (void) sec_keys;
00313 
00314     sec_prot_t *prot = tls_prot->type_get(tls_prot, SEC_PROT_TYPE_EAP_TLS);
00315     if (!prot) {
00316         return;
00317     }
00318 
00319     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00320 
00321     if (result == SEC_RESULT_OK) {
00322         data->tls_result = EAP_TLS_RESULT_HANDSHAKE_OVER;
00323         tr_info("EAP-TLS: handshake success");
00324     } else if (result == SEC_RESULT_CONF_ERROR) {
00325         data->tls_result = EAP_TLS_RESULT_HANDSHAKE_FATAL_ERROR;
00326         tr_error("EAP-TLS: handshake fatal error");
00327     } else {
00328         // On failure has sent ALERT
00329         data->tls_result = EAP_TLS_RESULT_HANDSHAKE_FAILED;
00330         tr_error("EAP-TLS: handshake failed");
00331     }
00332 
00333     data->tls_ongoing = false;
00334 
00335     if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_OVER || data->tls_result == EAP_TLS_RESULT_HANDSHAKE_FATAL_ERROR) {
00336         // On fatal error and on success calls state machine to sent empty EAP-TLS message
00337         prot->state_machine_call(prot);
00338     }
00339 }
00340 
00341 static int8_t supp_eap_tls_sec_prot_tls_send(sec_prot_t *tls_prot, void *pdu, uint16_t size)
00342 {
00343     sec_prot_t *prot = tls_prot->type_get(tls_prot, SEC_PROT_TYPE_EAP_TLS);
00344     if (!prot) {
00345         return -1;
00346     }
00347 
00348     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00349 
00350     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00351 
00352     data->tls_send.data = pdu;
00353     data->tls_send.total_len = size;
00354     data->tls_send.handled_len = 0;
00355 
00356     data->send_pending = true;
00357 
00358     prot->state_machine_call(prot);
00359 
00360     return 0;
00361 }
00362 
00363 static int8_t supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
00364 {
00365     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00366     if (data->tls_prot) {
00367         return 0;
00368     }
00369 
00370     data->tls_prot = prot->type_get(prot, SEC_PROT_TYPE_TLS);
00371     if (!data->tls_prot) {
00372         return -1;
00373     }
00374 
00375     data->tls_prot->header_size = TLS_HEAD_LEN;
00376     data->tls_prot->sec_keys = prot->sec_keys;
00377 
00378     data->tls_prot->create_conf = supp_eap_tls_sec_prot_tls_create_confirm;
00379     data->tls_prot->create_ind = NULL;
00380     data->tls_prot->finished_ind = supp_eap_tls_sec_prot_tls_finished_indication;
00381     data->tls_prot->send = supp_eap_tls_sec_prot_tls_send;
00382 
00383     data->tls_ongoing = true;
00384 
00385     return 0;
00386 }
00387 
00388 static void supp_eap_tls_sec_prot_delete_tls(sec_prot_t *prot)
00389 {
00390     // Triggers TLS to terminate if it is not already terminating by its own
00391     sec_prot_t *tls_prot = prot->type_get(prot, SEC_PROT_TYPE_TLS);
00392     if (tls_prot) {
00393         tls_prot->finished_send(tls_prot);
00394     }
00395 }
00396 
00397 static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
00398 {
00399     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00400     int8_t result;
00401 
00402     // EAP-TLS supplicant state machine
00403     switch (sec_prot_state_get(&data->common)) {
00404         case EAP_TLS_STATE_INIT:
00405             tr_info("EAP-TLS init");
00406             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST_ID);
00407             prot->timer_start(prot);
00408             break;
00409 
00410         // Wait EAP request, Identity (starts handshake on supplicant)
00411         case EAP_TLS_STATE_REQUEST_ID:
00412 
00413             // Handle EAP request, Identity
00414             if (supp_eap_tls_sec_prot_message_handle(prot) != EAP_TLS_MSG_IDENTITY) {
00415                 return;
00416             }
00417 
00418             // Set retry timeout based on network size
00419             data->common.ticks = retry_timeout;
00420 
00421             // Store sequence ID
00422             supp_eap_tls_sec_prot_seq_id_update(prot);
00423 
00424             tr_info("EAP-TLS start");
00425 
00426             // Send KMP-CREATE.indication
00427             prot->create_ind(prot);
00428             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_CREATE_RESP);
00429             break;
00430 
00431         // Wait KMP-CREATE.response
00432         case EAP_TLS_STATE_CREATE_RESP:
00433             if (sec_prot_result_ok_check(&data->common)) {
00434                 // Send EAP response, Identity
00435                 supp_eap_tls_sec_prot_message_send(prot, EAP_RESPONSE, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE);
00436 
00437                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST_TLS_EAP);
00438             } else {
00439                 // Ready to be deleted
00440                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISHED);
00441             }
00442             break;
00443 
00444         case EAP_TLS_STATE_REQUEST_TLS_EAP:
00445 
00446             // Handle EAP request (expected TLS EAP start)
00447             result = supp_eap_tls_sec_prot_message_handle(prot);
00448 
00449             if (result == EAP_TLS_MSG_IDENTITY) {
00450                 // If received EAP request, Identity: re-send EAP response, Identity
00451                 supp_eap_tls_sec_prot_message_send(prot, EAP_RESPONSE, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE);
00452                 return;
00453             }
00454 
00455             // Handle EAP request, TLS EAP start
00456             if (result != EAP_TLS_MSG_START) {
00457                 return;
00458             }
00459 
00460             // Store sequence ID
00461             supp_eap_tls_sec_prot_seq_id_update(prot);
00462 
00463             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST);
00464             data->common.ticks = retry_timeout;
00465 
00466             // Initialize TLS protocol
00467             if (supp_eap_tls_sec_prot_init_tls(prot) < 0) {
00468                 tr_error("TLS init failed");
00469                 // If fatal error terminates EAP-TLS
00470                 sec_prot_result_set(&data->common, SEC_RESULT_ERROR);
00471                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISH);
00472                 return;
00473             }
00474             // Request TLS to start (send client hello)
00475             data->tls_prot->create_req(data->tls_prot, prot->sec_keys);
00476             break;
00477 
00478         case EAP_TLS_STATE_REQUEST:
00479 
00480             // EAP success
00481             if (data->eap_code == EAP_SUCCESS) {
00482                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISH);
00483                 return;
00484             } else if (data->eap_code == EAP_FAILURE) {
00485                 sec_prot_result_set(&data->common, SEC_RESULT_ERROR);
00486                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISH);
00487                 return;
00488             } else if (data->eap_code == EAP_REQ) {
00489                 // EAP request, handle EAP request, TLS EAP
00490                 result = supp_eap_tls_sec_prot_message_handle(prot);
00491                 if (result == EAP_TLS_MSG_DECODE_ERROR) {
00492                     return;
00493                 }
00494 
00495                 // Store sequence ID
00496                 supp_eap_tls_sec_prot_seq_id_update(prot);
00497 
00498                 // All fragments received for a message
00499                 if (result == EAP_TLS_MSG_RECEIVE_DONE && data->tls_ongoing) {
00500                     // Call TLS
00501                     data->tls_prot->receive(data->tls_prot, data->tls_recv.data, data->tls_recv.total_len);
00502                     eap_tls_sec_prot_lib_message_init(&data->tls_recv);
00503                     sec_prot_timer_trickle_stop(&data->common);
00504                     if (data->send_pending || data->tls_result != EAP_TLS_RESULT_HANDSHAKE_FAILED) {
00505                         data->wait_tls = true;
00506                     }
00507                 }
00508                 // Wait TLS to process the received message
00509                 if (data->wait_tls) {
00510                     return;
00511                 }
00512             } else {
00513                 data->wait_tls = false;
00514                 if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_FATAL_ERROR) {
00515                     // If fatal error terminates EAP-TLS (TLS init has failed)
00516                     sec_prot_result_set(&data->common, SEC_RESULT_ERROR);
00517                     sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISH);
00518                     return;
00519                 } else if (!data->tls_send.data) {
00520                     // If no more data send response, TLS EAP (empty)
00521                     eap_tls_sec_prot_lib_message_allocate(&data->tls_send, TLS_HEAD_LEN, 0);
00522                 }
00523             }
00524             // Send EAP response
00525             supp_eap_tls_sec_prot_message_send(prot, EAP_RESPONSE, EAP_TLS, EAP_TLS_EXCHANGE_ONGOING);
00526             data->send_pending = false;
00527 
00528             // Add more time for re-send if no response
00529             data->common.ticks = retry_timeout;
00530 
00531             break;
00532 
00533         case EAP_TLS_STATE_FINISH:
00534             tr_info("EAP-TLS finish");
00535 
00536             // KMP-FINISHED.indication,
00537             prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
00538             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISHED);
00539             break;
00540 
00541         case EAP_TLS_STATE_FINISHED:
00542             tr_info("EAP-TLS finished");
00543             supp_eap_tls_sec_prot_delete_tls(prot);
00544             prot->timer_stop(prot);
00545             prot->finished(prot);
00546             break;
00547 
00548         default:
00549             break;
00550     }
00551 }
00552 
00553 static void supp_eap_tls_sec_prot_seq_id_update(sec_prot_t *prot)
00554 {
00555     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00556     data->eap_id_seq = data->recv_eapol_pdu.msg.eap.id_seq;
00557 }
00558 
00559 #endif /* HAVE_WS */
00560